* ports all the tg junk for icemoon, not yet changed to make it all compile * fixes * fixes * fixes * fixes * fixes * new stuff * whew * fixes * it compiles, now to fix the maps * fixes the maps * fixes solars + removes the space tiles in the toxins burn chamber * nukes the SpawnTerrain proc used for tg geysers * linter fix * fix * fixes the non matching turf atmos (hopefully) * more mapping fixes * dmm2tgm * unfucks changeturf for the more_caves * fixes the volanic subtypes of the other thing * fixes the stupid fucking tile placing list * some map fixes, fixes the station_ruin loader shitting out errors this commit took 2 hours of my fucking life * fixes a bunch of mismatch atmos in ruins * fixes wendigo cave having no air * backwards couch backwards couch * fixes the SM up * wendigos can't runtime when butchering if you can't butcher them 😎 * makes the wendigo fight have the same atmos as the surrounding icemoon * Tweaks atmos mixture from o2=22;n2=82;TEMP=180 to o2=18;n2=63;TEMP=180, making lavaland weapons actually work * makes the wendigo screech shake not completely aids * fixes snowlegion portals dropping proper legions instead of skeles * brings the engioutpost ruin over as well * whoopps * empty commit to reroll bots * Fixes pirates, ops, the mining base, and gives pirates and ops drills * fixes lone ops and ninjas * fixes the snowed plating getting fucked when tiles are placed on it * removes some OP junk from the wabbajack pool (aka removes non-antag headslugs again) * more bug fixes * empty commit to reroll bots * hopefully finally kills the active turfs on the library ruin Co-authored-by: kevinz000 <2003111+kevinz000@users.noreply.github.com>
This commit is contained in:
@@ -161,10 +161,14 @@
|
||||
#define ATMOS_TANK_O2 "o2=100000;TEMP=293.15"
|
||||
#define ATMOS_TANK_N2 "n2=100000;TEMP=293.15"
|
||||
#define ATMOS_TANK_AIRMIX "o2=2644;n2=10580;TEMP=293.15"
|
||||
|
||||
//LAVALAND
|
||||
#define LAVALAND_EQUIPMENT_EFFECT_PRESSURE 50 //what pressure you have to be under to increase the effect of equipment meant for lavaland
|
||||
#define LAVALAND_DEFAULT_ATMOS "o2=14;n2=23;TEMP=300"
|
||||
|
||||
//SNOSTATION
|
||||
#define ICEMOON_DEFAULT_ATMOS "o2=17;n2=63;TEMP=180"
|
||||
|
||||
//ATMOSIA GAS MONITOR TAGS
|
||||
#define ATMOS_GAS_MONITOR_INPUT_O2 "o2_in"
|
||||
#define ATMOS_GAS_MONITOR_OUTPUT_O2 "o2_out"
|
||||
|
||||
@@ -110,7 +110,8 @@
|
||||
#define COMSIG_TURF_MULTIZ_NEW "turf_multiz_new" //from base of turf/New(): (turf/source, direction)
|
||||
|
||||
// /atom/movable signals
|
||||
#define COMSIG_MOVABLE_PRE_MOVE "movable_pre_move" //from base of atom/movable/Moved(): (/atom)
|
||||
#define COMSIG_MOVABLE_PRE_MOVE "movable_pre_move" ///from base of atom/movable/Moved(): (/atom)
|
||||
#define COMPONENT_MOVABLE_BLOCK_PRE_MOVE 1
|
||||
#define COMSIG_MOVABLE_MOVED "movable_moved" //from base of atom/movable/Moved(): (/atom, dir)
|
||||
#define COMSIG_MOVABLE_CROSS "movable_cross" //from base of atom/movable/Cross(): (/atom/movable)
|
||||
#define COMSIG_MOVABLE_CROSSED "movable_crossed" //from base of atom/movable/Crossed(): (/atom/movable)
|
||||
|
||||
@@ -174,7 +174,10 @@ GLOBAL_LIST_INIT(clawfootmob, typecacheof(list(
|
||||
/mob/living/simple_animal/pet/fox,
|
||||
/mob/living/simple_animal/chicken,
|
||||
/mob/living/simple_animal/hostile/bear,
|
||||
/mob/living/simple_animal/hostile/jungle/mega_arachnid
|
||||
/mob/living/simple_animal/hostile/jungle/mega_arachnid,
|
||||
/mob/living/simple_animal/hostile/asteroid/ice_whelp,
|
||||
/mob/living/simple_animal/hostile/asteroid/wolf,
|
||||
/mob/living/simple_animal/hostile/asteroid/polarbear
|
||||
)))
|
||||
|
||||
GLOBAL_LIST_INIT(barefootmob, typecacheof(list(
|
||||
|
||||
@@ -38,8 +38,15 @@ require only minor tweaks.
|
||||
#define ZTRAIT_VR "Virtual Reality"
|
||||
#define ZTRAIT_SPACE_RUINS "Space Ruins"
|
||||
#define ZTRAIT_LAVA_RUINS "Lava Ruins"
|
||||
#define ZTRAIT_ICE_RUINS "Ice Ruins"
|
||||
#define ZTRAIT_ICE_RUINS_UNDERGROUND "Ice Ruins Underground"
|
||||
#define ZTRAIT_ISOLATED_RUINS "Isolated Ruins" //Placing ruins on z levels with this trait will use turf reservation instead of usual placement.
|
||||
|
||||
//boolean - weather types that occur on the level
|
||||
#define ZTRAIT_SNOWSTORM "Weather_Snowstorm"
|
||||
#define ZTRAIT_ASHSTORM "Weather_Ashstorm"
|
||||
#define ZTRAIT_ACIDRAIN "Weather_Acidrain"
|
||||
|
||||
// number - bombcap is multiplied by this before being applied to bombs
|
||||
#define ZTRAIT_BOMBCAP_MULTIPLIER "Bombcap Multiplier"
|
||||
|
||||
@@ -68,6 +75,7 @@ require only minor tweaks.
|
||||
#define ZTRAITS_SPACE list(ZTRAIT_LINKAGE = CROSSLINKED, ZTRAIT_SPACE_RUINS = TRUE)
|
||||
#define ZTRAITS_LAVALAND list(\
|
||||
ZTRAIT_MINING = TRUE, \
|
||||
ZTRAIT_ASHSTORM = TRUE, \
|
||||
ZTRAIT_LAVA_RUINS = TRUE, \
|
||||
ZTRAIT_BOMBCAP_MULTIPLIER = 5, \
|
||||
ZTRAIT_BASETURF = /turf/open/lava/smooth/lava_land_surface)
|
||||
|
||||
@@ -265,6 +265,7 @@
|
||||
#define WIZARD_AGE_MIN 30 //youngest a wizard can be
|
||||
#define APPRENTICE_AGE_MIN 29 //youngest an apprentice can be
|
||||
#define SHOES_SLOWDOWN 0 //How much shoes slow you down by default. Negative values speed you up
|
||||
#define SHOES_SPEED_SLIGHT SHOES_SLOWDOWN - 1 // slightest speed boost to movement
|
||||
#define POCKET_STRIP_DELAY 40 //time taken (in deciseconds) to search somebody's pockets
|
||||
#define DOOR_CRUSH_DAMAGE 15 //the amount of damage that airlocks deal when they crush you
|
||||
|
||||
@@ -288,10 +289,4 @@
|
||||
|
||||
#define HUMAN_FIRE_STACK_ICON_NUM 3
|
||||
|
||||
#define PULL_PRONE_SLOWDOWN 0.6
|
||||
#define FIREMAN_CARRY_SLOWDOWN 0
|
||||
#define PIGGYBACK_CARRY_SLOWDOWN 1
|
||||
//slowdown when in softcrit. Note that crawling slowdown will also apply at the same time!
|
||||
#define SOFTCRIT_ADD_SLOWDOWN 2
|
||||
//slowdown when crawling
|
||||
#define CRAWLING_ADD_SLOWDOWN 4
|
||||
#define SLEEP_CHECK_DEATH(X) sleep(X); if(QDELETED(src) || stat == DEAD) return;
|
||||
|
||||
10
code/__DEFINES/mobs/slowdowns.dm
Normal file
10
code/__DEFINES/mobs/slowdowns.dm
Normal file
@@ -0,0 +1,10 @@
|
||||
/// How much someone is slowed from pulling a prone human
|
||||
#define PULL_PRONE_SLOWDOWN 0.6
|
||||
/// How much someone is slowed from fireman carrying a human
|
||||
#define FIREMAN_CARRY_SLOWDOWN 0
|
||||
/// How much someone is slowed by piggybacking a human
|
||||
#define PIGGYBACK_CARRY_SLOWDOWN 1
|
||||
/// slowdown when in softcrit. Note that crawling slowdown will also apply at the same time!
|
||||
#define SOFTCRIT_ADD_SLOWDOWN 2
|
||||
/// slowdown when crawling
|
||||
#define CRAWLING_ADD_SLOWDOWN 4
|
||||
@@ -38,11 +38,12 @@
|
||||
#define BLOCK_GAS_SMOKE_EFFECT (1<<2) //blocks the effect that chemical clouds would have on a mob --glasses, mask and helmets ONLY!
|
||||
#define ALLOWINTERNALS (1<<3) //mask allows internals
|
||||
#define NOSLIP (1<<4) //prevents from slipping on wet floors, in space etc
|
||||
#define THICKMATERIAL (1<<5) //prevents syringes, parapens and hypos if the external suit or helmet (if targeting head) has this flag. Example: space suits, biosuit, bombsuits, thick suits that cover your body.
|
||||
#define VOICEBOX_TOGGLABLE (1<<6) //The voicebox in this clothing can be toggled.
|
||||
#define VOICEBOX_DISABLED (1<<7) //The voicebox is currently turned off.
|
||||
#define IGNORE_HAT_TOSS (1<<8) //Hats with negative effects when worn (i.e the tinfoil hat).
|
||||
#define SCAN_REAGENTS (1<<9) // Allows helmets and glasses to scan reagents.
|
||||
#define NOSLIP_ICE (1<<5) //prevents from slipping on frozen floors
|
||||
#define THICKMATERIAL (1<<6) //prevents syringes, parapens and hypos if the external suit or helmet (if targeting head) has this flag. Example: space suits, biosuit, bombsuits, thick suits that cover your body.
|
||||
#define VOICEBOX_TOGGLABLE (1<<7) //The voicebox in this clothing can be toggled.
|
||||
#define VOICEBOX_DISABLED (1<<8) //The voicebox is currently turned off.
|
||||
#define IGNORE_HAT_TOSS (1<<9) //Hats with negative effects when worn (i.e the tinfoil hat).
|
||||
#define SCAN_REAGENTS (1<<10) // Allows helmets and glasses to scan reagents.
|
||||
|
||||
// Flags for the organ_flags var on /obj/item/organ
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
#define FREQ_ENGINEERING 1357 // Engineering comms frequency, orange
|
||||
#define FREQ_SECURITY 1359 // Security comms frequency, red
|
||||
|
||||
#define FREQ_HOLOGRID_SOLUTION 1433
|
||||
#define FREQ_STATUS_DISPLAYS 1435
|
||||
#define FREQ_ATMOS_ALARMS 1437 // air alarms <-> alert computers
|
||||
#define FREQ_ATMOS_CONTROL 1439 // air alarms <-> vents and scrubbers
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
|
||||
#define STATUS_EFFECT_CRUSHERMARK /datum/status_effect/crusher_mark //if struck with a proto-kinetic crusher, takes a ton of damage
|
||||
|
||||
#define STATUS_EFFECT_SAWBLEED /datum/status_effect/saw_bleed //if the bleed builds up enough, takes a ton of damage
|
||||
#define STATUS_EFFECT_SAWBLEED /datum/status_effect/stacking/saw_bleed //if the bleed builds up enough, takes a ton of damage
|
||||
|
||||
#define STATUS_EFFECT_NECKSLICE /datum/status_effect/neck_slice //Creates the flavor messages for the neck-slice
|
||||
|
||||
|
||||
@@ -58,6 +58,11 @@ GLOBAL_LIST_INIT(typecache_powerfailure_safe_areas, typecacheof(/area/engine/eng
|
||||
else if(isarea(areatype))
|
||||
var/area/areatemp = areatype
|
||||
areatype = areatemp.type
|
||||
else if(islist(areatype))
|
||||
var/list/turfs = list()
|
||||
for(var/A in areatype)
|
||||
turfs += get_area_turfs(A)
|
||||
return turfs
|
||||
else if(!ispath(areatype))
|
||||
return null
|
||||
|
||||
|
||||
@@ -434,6 +434,29 @@ Turf and target are separate in case you want to teleport some distance from a t
|
||||
|
||||
return locate(x,y,A.z)
|
||||
|
||||
/**
|
||||
* Get ranged target turf, but with direct targets as opposed to directions
|
||||
*
|
||||
* Starts at atom A and gets the exact angle between A and target
|
||||
* Moves from A with that angle, Range amount of times, until it stops, bound to map size
|
||||
* Arguments:
|
||||
* * A - Initial Firer / Position
|
||||
* * target - Target to aim towards
|
||||
* * range - Distance of returned target turf from A
|
||||
* * offset - Angle offset, 180 input would make the returned target turf be in the opposite direction
|
||||
*/
|
||||
/proc/get_ranged_target_turf_direct(atom/A, atom/target, range, offset)
|
||||
var/angle = arctan(target.x - A.x, target.y - A.y)
|
||||
if(offset)
|
||||
angle += offset
|
||||
var/turf/T = get_turf(A)
|
||||
for(var/i in 1 to range)
|
||||
var/turf/check = locate(A.x + cos(angle) * i, A.y + sin(angle) * i, A.z)
|
||||
if(!check)
|
||||
break
|
||||
T = check
|
||||
|
||||
return T
|
||||
|
||||
// returns turf relative to A offset in dx and dy tiles
|
||||
// bound to map limits
|
||||
|
||||
@@ -348,6 +348,11 @@
|
||||
config_entry_value = 16
|
||||
min_val = 0
|
||||
|
||||
/datum/config_entry/number/icemoon_budget
|
||||
config_entry_value = 90
|
||||
integer = FALSE
|
||||
min_val = 0
|
||||
|
||||
/datum/config_entry/number/station_space_budget
|
||||
config_entry_value = 10
|
||||
min_val = 0
|
||||
|
||||
@@ -16,6 +16,8 @@ SUBSYSTEM_DEF(mapping)
|
||||
var/list/ruins_templates = list()
|
||||
var/list/space_ruins_templates = list()
|
||||
var/list/lava_ruins_templates = list()
|
||||
var/list/ice_ruins_templates = list()
|
||||
var/list/ice_ruins_underground_templates = list()
|
||||
var/list/station_ruins_templates = list()
|
||||
var/datum/space_level/isolated_ruins_z //Created on demand during ruin loading.
|
||||
|
||||
@@ -102,19 +104,32 @@ SUBSYSTEM_DEF(mapping)
|
||||
loading_ruins = TRUE
|
||||
var/list/lava_ruins = levels_by_trait(ZTRAIT_LAVA_RUINS)
|
||||
if (lava_ruins.len)
|
||||
seedRuins(lava_ruins, CONFIG_GET(number/lavaland_budget), /area/lavaland/surface/outdoors/unexplored, lava_ruins_templates)
|
||||
seedRuins(lava_ruins, CONFIG_GET(number/lavaland_budget), list(/area/lavaland/surface/outdoors/unexplored), lava_ruins_templates)
|
||||
for (var/lava_z in lava_ruins)
|
||||
spawn_rivers(lava_z)
|
||||
|
||||
var/list/ice_ruins = levels_by_trait(ZTRAIT_ICE_RUINS)
|
||||
if (ice_ruins.len)
|
||||
// needs to be whitelisted for underground too so place_below ruins work
|
||||
seedRuins(ice_ruins, CONFIG_GET(number/icemoon_budget), list(/area/icemoon/surface/outdoors/unexplored, /area/icemoon/underground/unexplored), ice_ruins_templates)
|
||||
for (var/ice_z in ice_ruins)
|
||||
spawn_rivers(ice_z, 4, /turf/open/openspace/icemoon, /area/icemoon/surface/outdoors/unexplored/rivers)
|
||||
|
||||
var/list/ice_ruins_underground = levels_by_trait(ZTRAIT_ICE_RUINS_UNDERGROUND)
|
||||
if (ice_ruins_underground.len)
|
||||
seedRuins(ice_ruins_underground, CONFIG_GET(number/icemoon_budget), list(/area/icemoon/underground/unexplored), ice_ruins_underground_templates)
|
||||
for (var/ice_z in ice_ruins_underground)
|
||||
spawn_rivers(ice_z, 4, level_trait(ice_z, ZTRAIT_BASETURF), /area/icemoon/underground/unexplored/rivers)
|
||||
|
||||
// Generate deep space ruins
|
||||
var/list/space_ruins = levels_by_trait(ZTRAIT_SPACE_RUINS)
|
||||
if (space_ruins.len)
|
||||
seedRuins(space_ruins, CONFIG_GET(number/space_budget), /area/space, space_ruins_templates)
|
||||
seedRuins(space_ruins, CONFIG_GET(number/space_budget), list(/area/space), space_ruins_templates)
|
||||
|
||||
// Generate station space ruins
|
||||
var/list/station_ruins = levels_by_trait(ZTRAIT_STATION)
|
||||
if (station_ruins.len)
|
||||
seedRuins(station_ruins, CONFIG_GET(number/station_space_budget), /area/space/station_ruins, station_ruins_templates)
|
||||
seedRuins(station_ruins, (SSmapping.config.station_ruin_budget < 0) ? CONFIG_GET(number/station_space_budget) : SSmapping.config.station_ruin_budget, list(/area/space/station_ruins), station_ruins_templates)
|
||||
SSmapping.seedStation()
|
||||
loading_ruins = FALSE
|
||||
#endif
|
||||
@@ -182,6 +197,8 @@ SUBSYSTEM_DEF(mapping)
|
||||
ruins_templates = SSmapping.ruins_templates
|
||||
space_ruins_templates = SSmapping.space_ruins_templates
|
||||
lava_ruins_templates = SSmapping.lava_ruins_templates
|
||||
ice_ruins_templates = SSmapping.ice_ruins_templates
|
||||
ice_ruins_underground_templates = SSmapping.ice_ruins_underground_templates
|
||||
station_ruins_templates = SSmapping.station_ruins_templates
|
||||
shuttle_templates = SSmapping.shuttle_templates
|
||||
shelter_templates = SSmapping.shelter_templates
|
||||
@@ -268,7 +285,7 @@ SUBSYSTEM_DEF(mapping)
|
||||
// load mining
|
||||
if(config.minetype == "lavaland")
|
||||
LoadGroup(FailedZs, "Lavaland", "map_files/Mining", "Lavaland.dmm", default_traits = ZTRAITS_LAVALAND)
|
||||
else if (!isnull(config.minetype))
|
||||
else if (!isnull(config.minetype) && config.minetype != "none")
|
||||
INIT_ANNOUNCE("WARNING: An unknown minetype '[config.minetype]' was set! This is being ignored! Update the maploader code!")
|
||||
#endif
|
||||
|
||||
@@ -372,6 +389,7 @@ GLOBAL_LIST_EMPTY(the_station_areas)
|
||||
// Still supporting bans by filename
|
||||
var/list/banned = generateMapList("[global.config.directory]/lavaruinblacklist.txt")
|
||||
banned += generateMapList("[global.config.directory]/spaceruinblacklist.txt")
|
||||
banned += generateMapList("[global.config.directory]/iceruinblacklist.txt")
|
||||
banned += generateMapList("[global.config.directory]/stationruinblacklist.txt")
|
||||
|
||||
for(var/item in sortList(subtypesof(/datum/map_template/ruin), /proc/cmp_ruincost_priority))
|
||||
@@ -389,6 +407,10 @@ GLOBAL_LIST_EMPTY(the_station_areas)
|
||||
|
||||
if(istype(R, /datum/map_template/ruin/lavaland))
|
||||
lava_ruins_templates[R.name] = R
|
||||
else if(istype(R, /datum/map_template/ruin/icemoon/underground))
|
||||
ice_ruins_underground_templates[R.name] = R
|
||||
else if(istype(R, /datum/map_template/ruin/icemoon))
|
||||
ice_ruins_templates[R.name] = R
|
||||
else if(istype(R, /datum/map_template/ruin/space))
|
||||
space_ruins_templates[R.name] = R
|
||||
else if(istype(R, /datum/map_template/ruin/station))
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
/datum/component/knockback
|
||||
/// distance the atom will be thrown
|
||||
var/throw_distance
|
||||
/// whether this can throw anchored targets (tables, etc)
|
||||
var/throw_anchored
|
||||
/// whether this is a gentle throw (default false means people thrown into walls are stunned / take damage)
|
||||
var/throw_gentle
|
||||
|
||||
/datum/component/knockback/Initialize(throw_distance=1)
|
||||
/datum/component/knockback/Initialize(throw_distance=1, throw_gentle=FALSE)
|
||||
if(!isitem(parent) && !ishostile(parent) && !isgun(parent) && !ismachinery(parent) && !isstructure(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
src.throw_distance = throw_distance
|
||||
src.throw_anchored = throw_anchored
|
||||
src.throw_gentle = throw_gentle
|
||||
|
||||
/datum/component/knockback/RegisterWithParent()
|
||||
. = ..()
|
||||
@@ -22,17 +27,29 @@
|
||||
. = ..()
|
||||
UnregisterSignal(parent, list(COMSIG_ITEM_AFTERATTACK, COMSIG_HOSTILE_ATTACKINGTARGET, COMSIG_PROJECTILE_ON_HIT))
|
||||
|
||||
/// triggered after an item attacks something
|
||||
/datum/component/knockback/proc/item_afterattack(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters)
|
||||
if(!proximity_flag)
|
||||
return
|
||||
do_knockback(target, user, get_dir(source, target))
|
||||
|
||||
/// triggered after a hostile simplemob attacks something
|
||||
/datum/component/knockback/proc/hostile_attackingtarget(mob/living/simple_animal/hostile/attacker, atom/target)
|
||||
do_knockback(target, attacker, get_dir(attacker, target))
|
||||
|
||||
/// triggered after a projectile hits something
|
||||
/datum/component/knockback/proc/projectile_hit(atom/fired_from, atom/movable/firer, atom/target, Angle)
|
||||
do_knockback(target, null, angle2dir(Angle))
|
||||
|
||||
|
||||
/**
|
||||
* Throw a target in a direction
|
||||
*
|
||||
* Arguments:
|
||||
* * target - Target atom to throw
|
||||
* * thrower - Thing that caused this atom to be thrown
|
||||
* * throw_dir - Direction to throw the atom
|
||||
*/
|
||||
/datum/component/knockback/proc/do_knockback(atom/target, mob/thrower, throw_dir)
|
||||
if(!ismovable(target) || throw_dir == null)
|
||||
return
|
||||
@@ -43,4 +60,4 @@
|
||||
throw_dir = turn(throw_dir, 180)
|
||||
throw_distance *= -1
|
||||
var/atom/throw_target = get_edge_target_turf(throwee, throw_dir)
|
||||
throwee.safe_throw_at(throw_target, throw_distance, 1, thrower)
|
||||
throwee.safe_throw_at(throw_target, throw_distance, 1, thrower) //, gentle = throw_gentle)
|
||||
|
||||
31
code/datums/elements/snail_crawl.dm
Normal file
31
code/datums/elements/snail_crawl.dm
Normal file
@@ -0,0 +1,31 @@
|
||||
/datum/element/snailcrawl
|
||||
element_flags = ELEMENT_DETACH
|
||||
|
||||
/datum/element/snailcrawl/Attach(datum/target)
|
||||
. = ..()
|
||||
if(!ismovable(target))
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
var/P
|
||||
if(iscarbon(target))
|
||||
P = .proc/snail_crawl
|
||||
else
|
||||
P = .proc/lubricate
|
||||
RegisterSignal(target, COMSIG_MOVABLE_MOVED, P)
|
||||
|
||||
/datum/element/snailcrawl/Detach(mob/living/carbon/target)
|
||||
. = ..()
|
||||
UnregisterSignal(target, COMSIG_MOVABLE_MOVED)
|
||||
if(istype(target))
|
||||
target.remove_movespeed_modifier(/datum/movespeed_modifier/snail_crawl)
|
||||
|
||||
/datum/element/snailcrawl/proc/snail_crawl(mob/living/carbon/snail)
|
||||
if(snail.resting && !snail.buckled && lubricate(snail))
|
||||
snail.add_movespeed_modifier(/datum/movespeed_modifier/snail_crawl)
|
||||
else
|
||||
snail.remove_movespeed_modifier(/datum/movespeed_modifier/snail_crawl)
|
||||
|
||||
/datum/element/snailcrawl/proc/lubricate(atom/movable/snail)
|
||||
var/turf/open/OT = get_turf(snail)
|
||||
if(istype(OT))
|
||||
OT.MakeSlippery(TURF_WET_LUBE, 20)
|
||||
return TRUE
|
||||
112
code/datums/ruins/icemoon.dm
Normal file
112
code/datums/ruins/icemoon.dm
Normal file
@@ -0,0 +1,112 @@
|
||||
// Hey! Listen! Update \config\iceruinblacklist.txt with your new ruins!
|
||||
|
||||
/datum/map_template/ruin/icemoon
|
||||
prefix = "_maps/RandomRuins/IceRuins/"
|
||||
allow_duplicates = FALSE
|
||||
cost = 5
|
||||
|
||||
// above ground only
|
||||
|
||||
/datum/map_template/ruin/icemoon/lust
|
||||
name = "Ruin of Lust"
|
||||
id = "lust"
|
||||
description = "Not exactly what you expected."
|
||||
suffix = "icemoon_surface_lust.dmm"
|
||||
|
||||
/datum/map_template/ruin/icemoon/asteroid
|
||||
name = "Asteroid Site"
|
||||
id = "asteroidsite"
|
||||
description = "Surprised to see us here?"
|
||||
suffix = "icemoon_surface_asteroid.dmm"
|
||||
|
||||
/datum/map_template/ruin/icemoon/hotsprings
|
||||
name = "Hot Springs"
|
||||
id = "hotsprings"
|
||||
description = "Just relax and take a dip, nothing will go wrong, I swear!"
|
||||
suffix = "icemoon_surface_hotsprings.dmm"
|
||||
|
||||
/datum/map_template/ruin/icemoon/engioutpost
|
||||
name = "Engineer Outpost"
|
||||
id = "engioutpost"
|
||||
description = "Blown up by an unfortunate accident."
|
||||
suffix = "icemoon_surface_engioutpost.dmm"
|
||||
|
||||
/datum/map_template/ruin/icemoon/fountain
|
||||
name = "Fountain Hall"
|
||||
id = "fountain"
|
||||
description = "The fountain has a warning on the side. DANGER: May have undeclared side effects that only become obvious when implemented."
|
||||
prefix = "_maps/RandomRuins/AnywhereRuins/"
|
||||
suffix = "fountain_hall.dmm"
|
||||
|
||||
// above and below ground together
|
||||
|
||||
/datum/map_template/ruin/icemoon/mining_site
|
||||
name = "Mining Site"
|
||||
id = "miningsite"
|
||||
description = "Ruins of a site where people once mined with primitive tools for ore."
|
||||
suffix = "icemoon_surface_mining_site.dmm"
|
||||
always_place = TRUE
|
||||
always_spawn_with = list(/datum/map_template/ruin/icemoon/underground/mining_site_below = PLACE_BELOW)
|
||||
|
||||
/datum/map_template/ruin/icemoon/underground/mining_site_below
|
||||
name = "Mining Site Underground"
|
||||
id = "miningsite-underground"
|
||||
description = "Who knew ladders could be so useful?"
|
||||
suffix = "icemoon_underground_mining_site.dmm"
|
||||
unpickable = TRUE
|
||||
|
||||
// below ground only
|
||||
|
||||
/datum/map_template/ruin/icemoon/underground
|
||||
name = "underground ruin"
|
||||
|
||||
/datum/map_template/ruin/icemoon/underground/abandonedvillage
|
||||
name = "Abandoned Village"
|
||||
id = "abandonedvillage"
|
||||
description = "Who knows what lies within?"
|
||||
suffix = "icemoon_underground_abandoned_village.dmm"
|
||||
|
||||
/datum/map_template/ruin/icemoon/underground/library
|
||||
name = "Buried Library"
|
||||
id = "buriedlibrary"
|
||||
description = "A once grand library, now lost to the confines of the Ice Moon."
|
||||
suffix = "icemoon_underground_library.dmm"
|
||||
|
||||
/datum/map_template/ruin/icemoon/underground/wrath
|
||||
name = "Ruin of Wrath"
|
||||
id = "wrath"
|
||||
description = "You'll fight and fight and just keep fighting."
|
||||
suffix = "icemoon_underground_wrath.dmm"
|
||||
|
||||
/datum/map_template/ruin/icemoon/underground/lavaland
|
||||
name = "Lavaland Site"
|
||||
id = "lavalandsite"
|
||||
description = "I guess we never really left you huh?"
|
||||
suffix = "icemoon_underground_lavaland.dmm"
|
||||
|
||||
/datum/map_template/ruin/icemoon/underground/puzzle
|
||||
name = "Ancient Puzzle"
|
||||
id = "puzzle"
|
||||
description = "Mystery to be solved."
|
||||
suffix = "icemoon_underground_puzzle.dmm"
|
||||
|
||||
/datum/map_template/ruin/icemoon/underground/bathhouse
|
||||
name = "Bath House"
|
||||
id = "bathhouse"
|
||||
description = "A taste of paradise, locked in the hell of the Ice Moon."
|
||||
suffix = "icemoon_underground_bathhouse.dmm"
|
||||
|
||||
/datum/map_template/ruin/icemoon/underground/wendigo_cave
|
||||
name = "Wendigo Cave"
|
||||
id = "wendigocave"
|
||||
description = "Into the jaws of the beast."
|
||||
suffix = "icemoon_underground_wendigo_cave.dmm"
|
||||
|
||||
/datum/map_template/ruin/icemoon/underground/free_golem
|
||||
name = "Free Golem Ship"
|
||||
id = "golem-ship"
|
||||
description = "Lumbering humanoids, made out of precious metals, move inside this ship. They frequently leave to mine more minerals, which they somehow turn into more of them. \
|
||||
Seem very intent on research and individual liberty, and also geology-based naming?"
|
||||
prefix = "_maps/RandomRuins/AnywhereRuins/"
|
||||
suffix = "golem_ship.dmm"
|
||||
allow_duplicates = FALSE
|
||||
@@ -67,7 +67,8 @@
|
||||
description = "Lumbering humanoids, made out of precious metals, move inside this ship. They frequently leave to mine more minerals, which they somehow turn into more of them. \
|
||||
Seem very intent on research and individual liberty, and also geology based naming?"
|
||||
cost = 20
|
||||
suffix = "lavaland_surface_golem_ship.dmm"
|
||||
prefix = "_maps/RandomRuins/AnywhereRuins/"
|
||||
suffix = "golem_ship.dmm"
|
||||
allow_duplicates = FALSE
|
||||
|
||||
/datum/map_template/ruin/lavaland/animal_hospital
|
||||
@@ -175,7 +176,8 @@
|
||||
name = "Fountain Hall"
|
||||
id = "fountain"
|
||||
description = "The fountain has a warning on the side. DANGER: May have undeclared side effects that only become obvious when implemented."
|
||||
suffix = "lavaland_surface_fountain_hall.dmm"
|
||||
prefix = "_maps/RandomRuins/AnywhereRuins/"
|
||||
suffix = "fountain_hall.dmm"
|
||||
cost = 5
|
||||
allow_duplicates = FALSE
|
||||
|
||||
|
||||
@@ -391,78 +391,34 @@
|
||||
owner.underlays -= marked_underlay //if this is being called, we should have an owner at this point.
|
||||
..()
|
||||
|
||||
/datum/status_effect/saw_bleed
|
||||
/datum/status_effect/stacking/saw_bleed
|
||||
id = "saw_bleed"
|
||||
duration = -1 //removed under specific conditions
|
||||
tick_interval = 6
|
||||
alert_type = null
|
||||
var/mutable_appearance/bleed_overlay
|
||||
var/mutable_appearance/bleed_underlay
|
||||
var/bleed_amount = 3
|
||||
var/bleed_buildup = 3
|
||||
var/delay_before_decay = 5
|
||||
delay_before_decay = 5
|
||||
stack_threshold = 10
|
||||
max_stacks = 10
|
||||
overlay_file = 'icons/effects/bleed.dmi'
|
||||
underlay_file = 'icons/effects/bleed.dmi'
|
||||
overlay_state = "bleed"
|
||||
underlay_state = "bleed"
|
||||
var/bleed_damage = 200
|
||||
var/needs_to_bleed = FALSE
|
||||
|
||||
/datum/status_effect/saw_bleed/Destroy()
|
||||
if(owner)
|
||||
owner.cut_overlay(bleed_overlay)
|
||||
owner.underlays -= bleed_underlay
|
||||
QDEL_NULL(bleed_overlay)
|
||||
return ..()
|
||||
/datum/status_effect/stacking/saw_bleed/fadeout_effect()
|
||||
new /obj/effect/temp_visual/bleed(get_turf(owner))
|
||||
|
||||
/datum/status_effect/saw_bleed/on_apply()
|
||||
if(owner.stat == DEAD)
|
||||
return FALSE
|
||||
bleed_overlay = mutable_appearance('icons/effects/bleed.dmi', "bleed[bleed_amount]")
|
||||
bleed_underlay = mutable_appearance('icons/effects/bleed.dmi', "bleed[bleed_amount]")
|
||||
var/icon/I = icon(owner.icon, owner.icon_state, owner.dir)
|
||||
var/icon_height = I.Height()
|
||||
bleed_overlay.pixel_x = -owner.pixel_x
|
||||
bleed_overlay.pixel_y = FLOOR(icon_height * 0.25, 1)
|
||||
bleed_overlay.transform = matrix() * (icon_height/world.icon_size) //scale the bleed overlay's size based on the target's icon size
|
||||
bleed_underlay.pixel_x = -owner.pixel_x
|
||||
bleed_underlay.transform = matrix() * (icon_height/world.icon_size) * 3
|
||||
bleed_underlay.alpha = 40
|
||||
owner.add_overlay(bleed_overlay)
|
||||
owner.underlays += bleed_underlay
|
||||
return ..()
|
||||
/datum/status_effect/stacking/saw_bleed/threshold_cross_effect()
|
||||
owner.adjustBruteLoss(bleed_damage)
|
||||
var/turf/T = get_turf(owner)
|
||||
new /obj/effect/temp_visual/bleed/explode(T)
|
||||
for(var/d in GLOB.alldirs)
|
||||
new /obj/effect/temp_visual/dir_setting/bloodsplatter(T, d)
|
||||
playsound(T, "desceration", 100, TRUE, -1)
|
||||
|
||||
/datum/status_effect/saw_bleed/tick()
|
||||
if(owner.stat == DEAD)
|
||||
qdel(src)
|
||||
else
|
||||
add_bleed(-1)
|
||||
|
||||
/datum/status_effect/saw_bleed/proc/add_bleed(amount)
|
||||
owner.cut_overlay(bleed_overlay)
|
||||
owner.underlays -= bleed_underlay
|
||||
bleed_amount += amount
|
||||
if(bleed_amount)
|
||||
if(bleed_amount >= 10)
|
||||
needs_to_bleed = TRUE
|
||||
qdel(src)
|
||||
else
|
||||
if(amount > 0)
|
||||
tick_interval += delay_before_decay
|
||||
bleed_overlay.icon_state = "bleed[bleed_amount]"
|
||||
bleed_underlay.icon_state = "bleed[bleed_amount]"
|
||||
owner.add_overlay(bleed_overlay)
|
||||
owner.underlays += bleed_underlay
|
||||
else
|
||||
qdel(src)
|
||||
|
||||
/datum/status_effect/saw_bleed/on_remove()
|
||||
. = ..()
|
||||
if(needs_to_bleed)
|
||||
var/turf/T = get_turf(owner)
|
||||
new /obj/effect/temp_visual/bleed/explode(T)
|
||||
for(var/d in GLOB.alldirs)
|
||||
new /obj/effect/temp_visual/dir_setting/bloodsplatter(T, d)
|
||||
playsound(T, "desceration", 200, 1, -1)
|
||||
owner.adjustBruteLoss(bleed_damage)
|
||||
else
|
||||
new /obj/effect/temp_visual/bleed(get_turf(owner))
|
||||
/datum/status_effect/stacking/saw_bleed/bloodletting
|
||||
id = "bloodletting"
|
||||
stack_threshold = 7
|
||||
max_stacks = 7
|
||||
bleed_damage = 20
|
||||
|
||||
/datum/status_effect/neck_slice
|
||||
id = "neck_slice"
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
var/duration = -1 //How long the status effect lasts in DECISECONDS. Enter -1 for an effect that never ends unless removed through some means.
|
||||
var/tick_interval = 10 //How many deciseconds between ticks, approximately. Leave at 10 for every second.
|
||||
var/mob/living/owner //The mob affected by the status effect.
|
||||
var/status_type = STATUS_EFFECT_UNIQUE //How many of the effect can be on one mob, and what happens when you try to add another
|
||||
var/on_remove_on_mob_delete = FALSE //if we call on_remove() when the mob is deleted
|
||||
var/examine_text //If defined, this text will appear when the mob is examined - to use he, she etc. use "SUBJECTPRONOUN" and replace it in the examines themselves
|
||||
var/alert_type = /obj/screen/alert/status_effect //the alert thrown by the status effect, contains name and description
|
||||
@@ -16,6 +15,8 @@
|
||||
/// If this is TRUE, the user will have sprint forcefully disabled while this is active.
|
||||
var/blocks_sprint = FALSE
|
||||
var/obj/screen/alert/status_effect/linked_alert = null //the alert itself, if it exists
|
||||
/// How many of the effect can be on one mob, and what happens when you try to add another
|
||||
var/status_type = STATUS_EFFECT_UNIQUE
|
||||
|
||||
/datum/status_effect/New(list/arguments)
|
||||
on_creation(arglist(arguments))
|
||||
@@ -67,6 +68,9 @@
|
||||
|
||||
/datum/status_effect/proc/tick() //Called every tick.
|
||||
|
||||
/datum/status_effect/proc/before_remove() //! Called before being removed; returning FALSE will cancel removal
|
||||
return TRUE
|
||||
|
||||
/datum/status_effect/proc/on_remove() //Called whenever the buff expires or is removed; do note that at the point this is called, it is out of the owner's status_effects but owner is not yet null
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
REMOVE_TRAIT(owner, TRAIT_COMBAT_MODE_LOCKED, src)
|
||||
@@ -123,12 +127,13 @@
|
||||
S1 = new effect(arguments)
|
||||
. = S1
|
||||
|
||||
/mob/living/proc/remove_status_effect(effect) //removes all of a given status effect from this mob, returning TRUE if at least one was removed
|
||||
/mob/living/proc/remove_status_effect(effect, ...) //removes all of a given status effect from this mob, returning TRUE if at least one was removed
|
||||
. = FALSE
|
||||
var/list/arguments = args.Copy(2)
|
||||
if(status_effects)
|
||||
var/datum/status_effect/S1 = effect
|
||||
for(var/datum/status_effect/S in status_effects)
|
||||
if(initial(S1.id) == S.id)
|
||||
if(initial(S1.id) == S.id && S.before_remove(arguments))
|
||||
qdel(S)
|
||||
. = TRUE
|
||||
|
||||
@@ -147,3 +152,129 @@
|
||||
for(var/datum/status_effect/S in status_effects)
|
||||
if(initial(S1.id) == S.id)
|
||||
. += S
|
||||
|
||||
//////////////////////
|
||||
// STACKING EFFECTS //
|
||||
//////////////////////
|
||||
|
||||
/datum/status_effect/stacking
|
||||
id = "stacking_base"
|
||||
duration = -1 //removed under specific conditions
|
||||
alert_type = null
|
||||
var/stacks = 0 //how many stacks are accumulated, also is # of stacks that target will have when first applied
|
||||
var/delay_before_decay //deciseconds until ticks start occuring, which removes stacks (first stack will be removed at this time plus tick_interval)
|
||||
tick_interval = 10 //deciseconds between decays once decay starts
|
||||
var/stack_decay = 1 //how many stacks are lost per tick (decay trigger)
|
||||
var/stack_threshold //special effects trigger when stacks reach this amount
|
||||
var/max_stacks //stacks cannot exceed this amount
|
||||
var/consumed_on_threshold = TRUE //if status should be removed once threshold is crossed
|
||||
var/threshold_crossed = FALSE //set to true once the threshold is crossed, false once it falls back below
|
||||
var/overlay_file
|
||||
var/underlay_file
|
||||
var/overlay_state // states in .dmi must be given a name followed by a number which corresponds to a number of stacks. put the state name without the number in these state vars
|
||||
var/underlay_state // the number is concatonated onto the string based on the number of stacks to get the correct state name
|
||||
var/mutable_appearance/status_overlay
|
||||
var/mutable_appearance/status_underlay
|
||||
|
||||
/datum/status_effect/stacking/proc/threshold_cross_effect() //what happens when threshold is crossed
|
||||
|
||||
/datum/status_effect/stacking/proc/stacks_consumed_effect() //runs if status is deleted due to threshold being crossed
|
||||
|
||||
/datum/status_effect/stacking/proc/fadeout_effect() //runs if status is deleted due to being under one stack
|
||||
|
||||
/datum/status_effect/stacking/proc/stack_decay_effect() //runs every time tick() causes stacks to decay
|
||||
|
||||
/datum/status_effect/stacking/proc/on_threshold_cross()
|
||||
threshold_cross_effect()
|
||||
if(consumed_on_threshold)
|
||||
stacks_consumed_effect()
|
||||
qdel(src)
|
||||
|
||||
/datum/status_effect/stacking/proc/on_threshold_drop()
|
||||
|
||||
/datum/status_effect/stacking/proc/can_have_status()
|
||||
return owner.stat != DEAD
|
||||
|
||||
/datum/status_effect/stacking/proc/can_gain_stacks()
|
||||
return owner.stat != DEAD
|
||||
|
||||
/datum/status_effect/stacking/tick()
|
||||
if(!can_have_status())
|
||||
qdel(src)
|
||||
else
|
||||
add_stacks(-stack_decay)
|
||||
stack_decay_effect()
|
||||
|
||||
/datum/status_effect/stacking/proc/add_stacks(stacks_added)
|
||||
if(stacks_added > 0 && !can_gain_stacks())
|
||||
return FALSE
|
||||
owner.cut_overlay(status_overlay)
|
||||
owner.underlays -= status_underlay
|
||||
stacks += stacks_added
|
||||
if(stacks > 0)
|
||||
if(stacks >= stack_threshold && !threshold_crossed) //threshold_crossed check prevents threshold effect from occuring if changing from above threshold to still above threshold
|
||||
threshold_crossed = TRUE
|
||||
on_threshold_cross()
|
||||
if(consumed_on_threshold)
|
||||
return
|
||||
else if(stacks < stack_threshold && threshold_crossed)
|
||||
threshold_crossed = FALSE //resets threshold effect if we fall below threshold so threshold effect can trigger again
|
||||
on_threshold_drop()
|
||||
if(stacks_added > 0)
|
||||
tick_interval += delay_before_decay //refreshes time until decay
|
||||
stacks = min(stacks, max_stacks)
|
||||
status_overlay.icon_state = "[overlay_state][stacks]"
|
||||
status_underlay.icon_state = "[underlay_state][stacks]"
|
||||
owner.add_overlay(status_overlay)
|
||||
owner.underlays += status_underlay
|
||||
else
|
||||
fadeout_effect()
|
||||
qdel(src) //deletes status if stacks fall under one
|
||||
|
||||
/datum/status_effect/stacking/on_creation(mob/living/new_owner, stacks_to_apply)
|
||||
. = ..()
|
||||
if(.)
|
||||
add_stacks(stacks_to_apply)
|
||||
|
||||
/datum/status_effect/stacking/on_apply()
|
||||
if(!can_have_status())
|
||||
return FALSE
|
||||
status_overlay = mutable_appearance(overlay_file, "[overlay_state][stacks]")
|
||||
status_underlay = mutable_appearance(underlay_file, "[underlay_state][stacks]")
|
||||
var/icon/I = icon(owner.icon, owner.icon_state, owner.dir)
|
||||
var/icon_height = I.Height()
|
||||
status_overlay.pixel_x = -owner.pixel_x
|
||||
status_overlay.pixel_y = FLOOR(icon_height * 0.25, 1)
|
||||
status_overlay.transform = matrix() * (icon_height/world.icon_size) //scale the status's overlay size based on the target's icon size
|
||||
status_underlay.pixel_x = -owner.pixel_x
|
||||
status_underlay.transform = matrix() * (icon_height/world.icon_size) * 3
|
||||
status_underlay.alpha = 40
|
||||
owner.add_overlay(status_overlay)
|
||||
owner.underlays += status_underlay
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/stacking/Destroy()
|
||||
if(owner)
|
||||
owner.cut_overlay(status_overlay)
|
||||
owner.underlays -= status_underlay
|
||||
QDEL_NULL(status_overlay)
|
||||
return ..()
|
||||
|
||||
/// Status effect from multiple sources, when all sources are removed, so is the effect
|
||||
/datum/status_effect/grouped
|
||||
status_type = STATUS_EFFECT_MULTIPLE //! Adds itself to sources and destroys itself if one exists already, there are never multiple
|
||||
var/list/sources = list()
|
||||
|
||||
/datum/status_effect/grouped/on_creation(mob/living/new_owner, source)
|
||||
var/datum/status_effect/grouped/existing = new_owner.has_status_effect(type)
|
||||
if(existing)
|
||||
existing.sources |= source
|
||||
qdel(src)
|
||||
return FALSE
|
||||
else
|
||||
sources |= source
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/grouped/before_remove(source)
|
||||
sources -= source
|
||||
return !length(sources)
|
||||
|
||||
@@ -1,49 +1,96 @@
|
||||
//The effects of weather occur across an entire z-level. For instance, lavaland has periodic ash storms that scorch most unprotected creatures.
|
||||
/**
|
||||
* Causes weather to occur on a z level in certain area types
|
||||
*
|
||||
* The effects of weather occur across an entire z-level. For instance, lavaland has periodic ash storms that scorch most unprotected creatures.
|
||||
* Weather always occurs on different z levels at different times, regardless of weather type.
|
||||
* Can have custom durations, targets, and can automatically protect indoor areas.
|
||||
*
|
||||
*/
|
||||
|
||||
/datum/weather
|
||||
/// name of weather
|
||||
var/name = "space wind"
|
||||
/// description of weather
|
||||
var/desc = "Heavy gusts of wind blanket the area, periodically knocking down anyone caught in the open."
|
||||
|
||||
var/telegraph_message = "<span class='warning'>The wind begins to pick up.</span>" //The message displayed in chat to foreshadow the weather's beginning
|
||||
var/telegraph_duration = 300 //In deciseconds, how long from the beginning of the telegraph until the weather begins
|
||||
var/telegraph_sound //The sound file played to everyone on an affected z-level
|
||||
var/telegraph_overlay //The overlay applied to all tiles on the z-level
|
||||
/// The message displayed in chat to foreshadow the weather's beginning
|
||||
var/telegraph_message = "<span class='warning'>The wind begins to pick up.</span>"
|
||||
|
||||
var/weather_message = "<span class='userdanger'>The wind begins to blow ferociously!</span>" //Displayed in chat once the weather begins in earnest
|
||||
var/weather_duration = 1200 //In deciseconds, how long the weather lasts once it begins
|
||||
var/weather_duration_lower = 1200 //See above - this is the lowest possible duration
|
||||
var/weather_duration_upper = 1500 //See above - this is the highest possible duration
|
||||
/// In deciseconds, how long from the beginning of the telegraph until the weather begins
|
||||
var/telegraph_duration = 300
|
||||
/// The sound file played to everyone on an affected z-level
|
||||
var/telegraph_sound
|
||||
/// The overlay applied to all tiles on the z-level
|
||||
var/telegraph_overlay
|
||||
/// Displayed in chat once the weather begins in earnest
|
||||
var/weather_message = "<span class='userdanger'>The wind begins to blow ferociously!</span>"
|
||||
///In deciseconds, how long the weather lasts once it begins
|
||||
var/weather_duration = 1200
|
||||
///See above - this is the lowest possible duration
|
||||
var/weather_duration_lower = 1200
|
||||
///See above - this is the highest possible duration
|
||||
var/weather_duration_upper = 1500
|
||||
/// Looping sound while weather is occuring
|
||||
var/weather_sound
|
||||
/// Area overlay while the weather is occuring
|
||||
var/weather_overlay
|
||||
/// Color to apply to the area while weather is occuring
|
||||
var/weather_color = null
|
||||
|
||||
var/end_message = "<span class='danger'>The wind relents its assault.</span>" //Displayed once the weather is over
|
||||
var/end_duration = 300 //In deciseconds, how long the "wind-down" graphic will appear before vanishing entirely
|
||||
/// Displayed once the weather is over
|
||||
var/end_message = "<span class='danger'>The wind relents its assault.</span>"
|
||||
/// In deciseconds, how long the "wind-down" graphic will appear before vanishing entirely
|
||||
var/end_duration = 300
|
||||
/// Sound that plays while weather is ending
|
||||
var/end_sound
|
||||
/// Area overlay while weather is ending
|
||||
var/end_overlay
|
||||
|
||||
var/area_type = /area/space //Types of area to affect
|
||||
var/list/impacted_areas = list() //Areas to be affected by the weather, calculated when the weather begins
|
||||
var/list/protected_areas = list()//Areas that are protected and excluded from the affected areas.
|
||||
var/impacted_z_levels // The list of z-levels that this weather is actively affecting
|
||||
/// Types of area to affect
|
||||
var/area_type = /area/space
|
||||
/// TRUE value protects areas with outdoors marked as false, regardless of area type
|
||||
var/protect_indoors = FALSE
|
||||
/// Areas to be affected by the weather, calculated when the weather begins
|
||||
var/list/impacted_areas = list()
|
||||
|
||||
var/overlay_layer = AREA_LAYER //Since it's above everything else, this is the layer used by default. TURF_LAYER is below mobs and walls if you need to use that.
|
||||
var/aesthetic = FALSE //If the weather has no purpose other than looks
|
||||
var/immunity_type = "storm" //Used by mobs to prevent them from being affected by the weather
|
||||
/// Areas that are protected and excluded from the affected areas.
|
||||
var/list/protected_areas = list()
|
||||
/// The list of z-levels that this weather is actively affecting
|
||||
var/impacted_z_levels
|
||||
|
||||
var/stage = END_STAGE //The stage of the weather, from 1-4
|
||||
/// Since it's above everything else, this is the layer used by default. TURF_LAYER is below mobs and walls if you need to use that.
|
||||
var/overlay_layer = AREA_LAYER
|
||||
/// Plane for the overlay
|
||||
var/overlay_plane = BLACKNESS_PLANE
|
||||
/// If the weather has no purpose but aesthetics.
|
||||
var/aesthetic = FALSE
|
||||
/// Used by mobs to prevent them from being affected by the weather
|
||||
var/immunity_type = "storm"
|
||||
|
||||
// These are read by the weather subsystem and used to determine when and where to run the weather.
|
||||
var/probability = 0 // Weight amongst other eligible weather. If zero, will never happen randomly.
|
||||
var/target_trait = ZTRAIT_STATION // The z-level trait to affect when run randomly or when not overridden.
|
||||
/// The stage of the weather, from 1-4
|
||||
var/stage = END_STAGE
|
||||
|
||||
/// Weight amongst other eligible weather. if zero, will never happen randomly.
|
||||
var/probability = 0
|
||||
/// The z-level trait to affect when run randomly or when not overridden.
|
||||
var/target_trait = ZTRAIT_STATION
|
||||
|
||||
/// Whether a barometer can predict when the weather will happen
|
||||
var/barometer_predictable = FALSE
|
||||
var/next_hit_time = 0 //For barometers to know when the next storm will hit
|
||||
/// For barometers to know when the next storm will hit
|
||||
var/next_hit_time = 0
|
||||
|
||||
/datum/weather/New(z_levels)
|
||||
..()
|
||||
impacted_z_levels = z_levels
|
||||
|
||||
/**
|
||||
* Telegraphs the beginning of the weather on the impacted z levels
|
||||
*
|
||||
* Sends sounds and details to mobs in the area
|
||||
* Calculates duration and hit areas, and makes a callback for the actual weather to start
|
||||
*
|
||||
*/
|
||||
/datum/weather/proc/telegraph()
|
||||
if(stage == STARTUP_STAGE)
|
||||
return
|
||||
@@ -58,6 +105,8 @@
|
||||
affectareas -= get_areas(V)
|
||||
for(var/V in affectareas)
|
||||
var/area/A = V
|
||||
if(protect_indoors && !A.outdoors)
|
||||
continue
|
||||
if(A.z in impacted_z_levels)
|
||||
impacted_areas |= A
|
||||
weather_duration = rand(weather_duration_lower, weather_duration_upper)
|
||||
@@ -72,6 +121,13 @@
|
||||
SEND_SOUND(M, sound(telegraph_sound))
|
||||
addtimer(CALLBACK(src, .proc/start), telegraph_duration)
|
||||
|
||||
/**
|
||||
* Starts the actual weather and effects from it
|
||||
*
|
||||
* Updates area overlays and sends sounds and messages to mobs to notify them
|
||||
* Begins dealing effects from weather to mobs in the area
|
||||
*
|
||||
*/
|
||||
/datum/weather/proc/start()
|
||||
if(stage >= MAIN_STAGE)
|
||||
return
|
||||
@@ -86,6 +142,13 @@
|
||||
SEND_SOUND(M, sound(weather_sound))
|
||||
addtimer(CALLBACK(src, .proc/wind_down), weather_duration)
|
||||
|
||||
/**
|
||||
* Weather enters the winding down phase, stops effects
|
||||
*
|
||||
* Updates areas to be in the winding down phase
|
||||
* Sends sounds and messages to mobs to notify them
|
||||
*
|
||||
*/
|
||||
/datum/weather/proc/wind_down()
|
||||
if(stage >= WIND_DOWN_STAGE)
|
||||
return
|
||||
@@ -100,6 +163,13 @@
|
||||
SEND_SOUND(M, sound(end_sound))
|
||||
addtimer(CALLBACK(src, .proc/end), end_duration)
|
||||
|
||||
/**
|
||||
* Fully ends the weather
|
||||
*
|
||||
* Effects no longer occur and area overlays are removed
|
||||
* Removes weather from processing completely
|
||||
*
|
||||
*/
|
||||
/datum/weather/proc/end()
|
||||
if(stage == END_STAGE)
|
||||
return 1
|
||||
@@ -115,7 +185,11 @@
|
||||
if(can_weather_act(L))
|
||||
weather_act(L)
|
||||
|
||||
/datum/weather/proc/can_weather_act(mob/living/L) //Can this weather impact a mob?
|
||||
/**
|
||||
* Returns TRUE if the living mob can be affected by the weather
|
||||
*
|
||||
*/
|
||||
/datum/weather/proc/can_weather_act(mob/living/L)
|
||||
var/turf/mob_turf = get_turf(L)
|
||||
if(mob_turf && !(mob_turf.z in impacted_z_levels))
|
||||
return
|
||||
@@ -123,11 +197,19 @@
|
||||
return
|
||||
if(!(get_area(L) in impacted_areas))
|
||||
return
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/datum/weather/proc/weather_act(mob/living/L) //What effect does this weather have on the hapless mob?
|
||||
/**
|
||||
* Affects the mob with whatever the weather does
|
||||
*
|
||||
*/
|
||||
/datum/weather/proc/weather_act(mob/living/L)
|
||||
return
|
||||
|
||||
/**
|
||||
* Updates the overlays on impacted areas
|
||||
*
|
||||
*/
|
||||
/datum/weather/proc/update_areas()
|
||||
for(var/V in impacted_areas)
|
||||
var/area/N = V
|
||||
|
||||
@@ -17,8 +17,9 @@
|
||||
end_message = "<span class='boldannounce'>The downpour gradually slows to a light shower. It should be safe outside now.</span>"
|
||||
end_sound = 'sound/ambience/acidrain_end.ogg'
|
||||
|
||||
area_type = /area/lavaland/surface/outdoors
|
||||
target_trait = ZTRAIT_MINING
|
||||
area_type = /area
|
||||
protect_indoors = TRUE
|
||||
target_trait = ZTRAIT_ACIDRAIN
|
||||
|
||||
immunity_type = "acid" // temp
|
||||
|
||||
|
||||
@@ -16,8 +16,9 @@
|
||||
end_duration = 300
|
||||
end_overlay = "light_ash"
|
||||
|
||||
area_type = /area/lavaland/surface/outdoors
|
||||
target_trait = ZTRAIT_MINING
|
||||
area_type = /area
|
||||
protect_indoors = TRUE
|
||||
target_trait = ZTRAIT_ASHSTORM
|
||||
|
||||
immunity_type = "ash"
|
||||
|
||||
|
||||
@@ -15,8 +15,9 @@
|
||||
end_duration = 100
|
||||
end_message = "<span class='boldannounce'>The snowfall dies down, it should be safe to go outside again.</span>"
|
||||
|
||||
area_type = /area/awaymission/snowdin/outside
|
||||
target_trait = ZTRAIT_AWAY
|
||||
area_type = /area
|
||||
protect_indoors = TRUE
|
||||
target_trait = ZTRAIT_SNOWSTORM
|
||||
|
||||
immunity_type = "snow"
|
||||
|
||||
|
||||
@@ -11,13 +11,27 @@
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
invisibility = INVISIBILITY_LIGHTING
|
||||
|
||||
var/map_name // Set in New(); preserves the name set by the map maker, even if renamed by the Blueprints.
|
||||
/// Set in New(); preserves the name set by the map maker, even if renamed by the Blueprints.
|
||||
var/map_name
|
||||
|
||||
var/valid_territory = TRUE // If it's a valid territory for gangs to claim
|
||||
var/blob_allowed = TRUE // Does it count for blobs score? By default, all areas count.
|
||||
var/clockwork_warp_allowed = TRUE // Can servants warp into this area from Reebe?
|
||||
/// If it's valid territory for gangs/cults to summon
|
||||
var/valid_territory = TRUE
|
||||
/// if blobs can spawn there and if it counts towards their score.
|
||||
var/blob_allowed = TRUE
|
||||
/// whether servants can warp into this area from Reebe
|
||||
var/clockwork_warp_allowed = TRUE
|
||||
/// Message to display when the clockwork warp fails
|
||||
var/clockwork_warp_fail = "The structure there is too dense for warping to pierce. (This is normal in high-security areas.)"
|
||||
|
||||
/// If mining tunnel generation is allowed in this area
|
||||
var/tunnel_allowed = FALSE
|
||||
/// If flora are allowed to spawn in this area randomly through tunnel generation
|
||||
var/flora_allowed = FALSE
|
||||
/// if mobs can be spawned by natural random generation
|
||||
var/mob_spawn_allowed = FALSE
|
||||
/// If megafauna can be spawned by natural random generation
|
||||
var/megafauna_spawn_allowed = FALSE
|
||||
|
||||
var/fire = null
|
||||
var/atmos = TRUE
|
||||
var/atmosalm = FALSE
|
||||
@@ -25,11 +39,14 @@
|
||||
var/lightswitch = TRUE
|
||||
|
||||
var/requires_power = TRUE
|
||||
var/always_unpowered = FALSE // This gets overridden to 1 for space in area/Initialize().
|
||||
/// This gets overridden to 1 for space in area/Initialize().
|
||||
var/always_unpowered = FALSE
|
||||
|
||||
var/outdoors = FALSE //For space, the asteroid, lavaland, etc. Used with blueprints to determine if we are adding a new area (vs editing a station room)
|
||||
/// For space, the asteroid, lavaland, etc. Used with blueprints to determine if we are adding a new area (vs editing a station room)
|
||||
var/outdoors = FALSE
|
||||
|
||||
var/areasize = 0 //Size of the area in open turfs, only calculated for indoors areas.
|
||||
/// Size of the area in open turfs, only calculated for indoors areas.
|
||||
var/areasize = 0
|
||||
|
||||
var/power_equip = TRUE
|
||||
var/power_light = TRUE
|
||||
@@ -43,9 +60,12 @@
|
||||
var/static_environ
|
||||
|
||||
var/has_gravity = 0
|
||||
var/noteleport = FALSE //Are you forbidden from teleporting to the area? (centcom, mobs, wizard, hand teleporter)
|
||||
var/hidden = FALSE //Hides area from player Teleport function.
|
||||
var/safe = FALSE //Is the area teleport-safe: no space / radiation / aggresive mobs / other dangers
|
||||
/// Are you forbidden from teleporting to the area? (centcom, mobs, wizard, hand teleporter)
|
||||
var/noteleport = FALSE
|
||||
/// Hides area from player Teleport function.
|
||||
var/hidden = FALSE
|
||||
/// Is the area teleport-safe: no space / radiation / aggresive mobs / other dangers
|
||||
var/safe = FALSE
|
||||
/// If false, loading multiple maps with this area type will create multiple instances.
|
||||
var/unique = TRUE
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
/area/mine
|
||||
icon_state = "mining"
|
||||
has_gravity = STANDARD_GRAVITY
|
||||
flora_allowed = TRUE
|
||||
|
||||
/area/mine/explored
|
||||
name = "Mine"
|
||||
@@ -17,6 +18,7 @@
|
||||
outdoors = TRUE
|
||||
flags_1 = NONE
|
||||
ambientsounds = MINING
|
||||
flora_allowed = FALSE
|
||||
|
||||
/area/mine/unexplored
|
||||
name = "Mine"
|
||||
@@ -31,6 +33,7 @@
|
||||
outdoors = TRUE
|
||||
flags_1 = NONE
|
||||
ambientsounds = MINING
|
||||
tunnel_allowed = TRUE
|
||||
|
||||
/area/mine/lobby
|
||||
name = "Mining Station"
|
||||
@@ -82,6 +85,7 @@
|
||||
icon_state = "mining"
|
||||
has_gravity = STANDARD_GRAVITY
|
||||
flags_1 = NONE
|
||||
flora_allowed = TRUE
|
||||
|
||||
/area/lavaland/surface
|
||||
name = "Lavaland"
|
||||
@@ -114,9 +118,79 @@
|
||||
|
||||
/area/lavaland/surface/outdoors/unexplored //monsters and ruins spawn here
|
||||
icon_state = "unexplored"
|
||||
tunnel_allowed = TRUE
|
||||
mob_spawn_allowed = TRUE
|
||||
|
||||
/area/lavaland/surface/outdoors/unexplored/danger //megafauna will also spawn here
|
||||
icon_state = "danger"
|
||||
megafauna_spawn_allowed = TRUE
|
||||
|
||||
/area/lavaland/surface/outdoors/explored
|
||||
name = "Lavaland Labor Camp"
|
||||
flora_allowed = FALSE
|
||||
|
||||
|
||||
|
||||
/**********************Ice Moon Areas**************************/
|
||||
|
||||
/area/icemoon
|
||||
icon_state = "mining"
|
||||
has_gravity = STANDARD_GRAVITY
|
||||
flags_1 = NONE
|
||||
flora_allowed = TRUE
|
||||
blob_allowed = FALSE
|
||||
|
||||
/area/icemoon/surface
|
||||
name = "Icemoon"
|
||||
icon_state = "explored"
|
||||
always_unpowered = TRUE
|
||||
poweralm = FALSE
|
||||
power_environ = FALSE
|
||||
power_equip = FALSE
|
||||
power_light = FALSE
|
||||
requires_power = TRUE
|
||||
ambientsounds = MINING
|
||||
|
||||
/area/icemoon/underground
|
||||
name = "Icemoon Caves"
|
||||
outdoors = TRUE
|
||||
always_unpowered = TRUE
|
||||
requires_power = TRUE
|
||||
poweralm = FALSE
|
||||
power_environ = FALSE
|
||||
power_equip = FALSE
|
||||
power_light = FALSE
|
||||
ambientsounds = MINING
|
||||
|
||||
/area/icemoon/underground/unexplored // mobs and megafauna and ruins spawn here
|
||||
name = "Icemoon Caves"
|
||||
icon_state = "unexplored"
|
||||
tunnel_allowed = TRUE
|
||||
mob_spawn_allowed = TRUE
|
||||
megafauna_spawn_allowed = TRUE
|
||||
|
||||
/area/icemoon/underground/unexplored/rivers // rivers spawn here
|
||||
icon_state = "danger"
|
||||
|
||||
/area/icemoon/underground/explored
|
||||
name = "Icemoon Underground"
|
||||
flora_allowed = FALSE
|
||||
|
||||
/area/icemoon/surface/outdoors
|
||||
name = "Icemoon Wastes"
|
||||
outdoors = TRUE
|
||||
|
||||
/area/icemoon/surface/outdoors/labor_camp
|
||||
name = "Icemoon Labor Camp"
|
||||
flora_allowed = FALSE
|
||||
|
||||
/area/icemoon/surface/outdoors/unexplored //monsters and ruins spawn here
|
||||
icon_state = "unexplored"
|
||||
tunnel_allowed = TRUE
|
||||
mob_spawn_allowed = TRUE
|
||||
|
||||
/area/icemoon/surface/outdoors/unexplored/rivers // rivers spawn here
|
||||
icon_state = "danger"
|
||||
|
||||
/area/icemoon/surface/outdoors/unexplored/rivers/no_monsters
|
||||
mob_spawn_allowed = FALSE
|
||||
|
||||
9
code/game/area/areas/ruins/icemoon.dm
Normal file
9
code/game/area/areas/ruins/icemoon.dm
Normal file
@@ -0,0 +1,9 @@
|
||||
// Icemoon Ruins
|
||||
|
||||
/area/ruin/unpowered/buried_library
|
||||
name = "Buried Library"
|
||||
icon_state = "dk_yellow"
|
||||
|
||||
/area/ruin/powered/bathhouse
|
||||
name = "Bath House"
|
||||
icon_state = "dk_yellow"
|
||||
@@ -20,6 +20,9 @@
|
||||
if(!newloc.Enter(src, src.loc))
|
||||
return
|
||||
|
||||
if (SEND_SIGNAL(src, COMSIG_MOVABLE_PRE_MOVE, newloc) & COMPONENT_MOVABLE_BLOCK_PRE_MOVE)
|
||||
return
|
||||
|
||||
// Past this is the point of no return
|
||||
var/atom/oldloc = loc
|
||||
var/area/oldarea = get_area(oldloc)
|
||||
|
||||
@@ -642,6 +642,9 @@
|
||||
for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list)
|
||||
if(isturf(L.loc))
|
||||
spawn_locs += L.loc
|
||||
for(var/obj/effect/landmark/loneopspawn/L in GLOB.landmarks_list)
|
||||
if(isturf(L.loc))
|
||||
spawn_locs += L.loc
|
||||
if(!spawn_locs.len)
|
||||
return FALSE
|
||||
spawn_loc = pick(spawn_locs)
|
||||
|
||||
@@ -313,6 +313,11 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player)
|
||||
name = "carpspawn"
|
||||
icon_state = "carp_spawn"
|
||||
|
||||
// lone op (optional)
|
||||
/obj/effect/landmark/loneopspawn
|
||||
name = "loneop+ninjaspawn"
|
||||
icon_state = "snukeop_spawn"
|
||||
|
||||
// observer-start.
|
||||
/obj/effect/landmark/observer_start
|
||||
name = "Observer-Start"
|
||||
@@ -512,3 +517,9 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player)
|
||||
/obj/effect/landmark/stationroom/lavaland/station
|
||||
templates = list("Public Mining Base" = 3)
|
||||
icon = 'icons/rooms/Lavaland/Mining.dmi'
|
||||
|
||||
// handled in portals.dm, id connected to one-way portal
|
||||
/obj/effect/landmark/portal_exit
|
||||
name = "portal exit"
|
||||
icon_state = "portal_exit"
|
||||
var/id
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
var/allow_anchored = FALSE
|
||||
var/innate_accuracy_penalty = 0
|
||||
var/last_effect = 0
|
||||
var/force_teleport = FALSE
|
||||
|
||||
/obj/effect/portal/anom
|
||||
name = "wormhole"
|
||||
@@ -162,7 +163,7 @@
|
||||
no_effect = TRUE
|
||||
else
|
||||
last_effect = world.time
|
||||
if(do_teleport(M, real_target, innate_accuracy_penalty, no_effects = no_effect, channel = teleport_channel))
|
||||
if(do_teleport(M, real_target, innate_accuracy_penalty, no_effects = no_effect, channel = teleport_channel, forced = force_teleport))
|
||||
if(istype(M, /obj/item/projectile))
|
||||
var/obj/item/projectile/P = M
|
||||
P.ignore_source_check = TRUE
|
||||
@@ -183,3 +184,47 @@
|
||||
else
|
||||
real_target = get_turf(linked)
|
||||
return real_target
|
||||
|
||||
/obj/effect/portal/permanent
|
||||
name = "permanent portal"
|
||||
desc = "An unwavering portal that will never fade."
|
||||
hardlinked = FALSE // dont qdel my portal nerd
|
||||
force_teleport = TRUE // force teleports because they're a mapmaker tool
|
||||
var/id // var edit or set id in map editor
|
||||
|
||||
/obj/effect/portal/permanent/proc/set_linked()
|
||||
if(!id)
|
||||
return
|
||||
for(var/obj/effect/portal/permanent/P in GLOB.portals - src)
|
||||
if(P.id == id)
|
||||
P.linked = src
|
||||
linked = P
|
||||
break
|
||||
|
||||
/obj/effect/portal/permanent/teleport(atom/movable/M, force = FALSE)
|
||||
set_linked() // update portal links
|
||||
. = ..()
|
||||
|
||||
/obj/effect/portal/permanent/one_way // doesn't have a return portal, can have multiple exits, /obj/effect/landmark/portal_exit to mark them
|
||||
name = "one-way portal"
|
||||
desc = "You get the feeling that this might not be the safest thing you've ever done."
|
||||
|
||||
/obj/effect/portal/permanent/one_way/set_linked()
|
||||
if(!id)
|
||||
return
|
||||
var/list/possible_turfs = list()
|
||||
for(var/obj/effect/landmark/portal_exit/PE in GLOB.landmarks_list)
|
||||
if(PE.id == id)
|
||||
var/turf/T = get_turf(PE)
|
||||
if(T)
|
||||
possible_turfs |= T
|
||||
if(possible_turfs.len)
|
||||
hard_target = pick(possible_turfs)
|
||||
|
||||
/obj/effect/portal/permanent/one_way/one_use
|
||||
name = "one-use portal"
|
||||
desc = "This is probably the worst decision you'll ever make in your life."
|
||||
|
||||
/obj/effect/portal/permanent/one_way/one_use/teleport(atom/movable/M, force = FALSE)
|
||||
. = ..()
|
||||
qdel(src)
|
||||
|
||||
@@ -351,6 +351,12 @@
|
||||
light_color = "#FFAA44"
|
||||
flashlight_power = 0.8
|
||||
|
||||
/obj/item/flashlight/lantern/jade
|
||||
name = "jade lantern"
|
||||
desc = "An ornate, green lantern."
|
||||
color = LIGHT_COLOR_GREEN
|
||||
light_color = LIGHT_COLOR_GREEN
|
||||
|
||||
/obj/item/flashlight/slime
|
||||
gender = PLURAL
|
||||
name = "glowing slime extract"
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
level = 1
|
||||
var/trigger_mob = TRUE
|
||||
var/trigger_item = FALSE
|
||||
var/specific_item = null
|
||||
var/trigger_silent = FALSE
|
||||
var/sound/trigger_sound = 'sound/effects/pressureplate.ogg'
|
||||
var/obj/item/assembly/signaler/sigdev = null
|
||||
@@ -35,6 +36,8 @@
|
||||
. = ..()
|
||||
if(!can_trigger || !active)
|
||||
return
|
||||
if(trigger_item && !istype(AM, specific_item))
|
||||
return
|
||||
if(trigger_mob && isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
to_chat(L, "<span class='warning'>You feel something click beneath you!</span>")
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* Fork
|
||||
* Kitchen knives
|
||||
* Ritual Knife
|
||||
* Bloodletter
|
||||
* Butcher's cleaver
|
||||
* Combat Knife
|
||||
* Rolling Pins
|
||||
@@ -97,6 +98,28 @@
|
||||
righthand_file = 'icons/mob/inhands/equipment/kitchen_righthand.dmi'
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
|
||||
/obj/item/kitchen/knife/bloodletter
|
||||
name = "bloodletter"
|
||||
desc = "An occult looking dagger that is cold to the touch. Somehow, the flawless orb on the pommel is made entirely of liquid blood."
|
||||
icon = 'icons/obj/ice_moon/artifacts.dmi'
|
||||
icon_state = "bloodletter"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
/// Bleed stacks applied when an organic mob target is hit
|
||||
var/bleed_stacks_per_hit = 3
|
||||
|
||||
/obj/item/kitchen/knife/bloodletter/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
. = ..()
|
||||
if(!isliving(target) || !proximity_flag)
|
||||
return
|
||||
var/mob/living/M = target
|
||||
if(!(M.mob_biotypes & MOB_ORGANIC))
|
||||
return
|
||||
var/datum/status_effect/stacking/saw_bleed/bloodletting/B = M.has_status_effect(/datum/status_effect/stacking/saw_bleed/bloodletting)
|
||||
if(!B)
|
||||
M.apply_status_effect(/datum/status_effect/stacking/saw_bleed/bloodletting, bleed_stacks_per_hit)
|
||||
else
|
||||
B.add_stacks(bleed_stacks_per_hit)
|
||||
|
||||
/obj/item/kitchen/knife/butcher
|
||||
name = "butcher's cleaver"
|
||||
icon_state = "butch"
|
||||
|
||||
146
code/game/objects/items/puzzle_pieces.dm
Normal file
146
code/game/objects/items/puzzle_pieces.dm
Normal file
@@ -0,0 +1,146 @@
|
||||
//**************
|
||||
//*****Keys*******************
|
||||
//************** ** **
|
||||
/obj/item/keycard
|
||||
name = "security keycard"
|
||||
desc = "This feels like it belongs to a door."
|
||||
icon = 'icons/obj/puzzle_small.dmi'
|
||||
icon_state = "keycard"
|
||||
force = 0
|
||||
throwforce = 0
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
throw_speed = 1
|
||||
throw_range = 7
|
||||
resistance_flags = INDESTRUCTIBLE | FIRE_PROOF | ACID_PROOF | LAVA_PROOF
|
||||
var/puzzle_id = null
|
||||
|
||||
//Two test keys for use alongside the two test doors.
|
||||
/obj/item/keycard/cheese
|
||||
name = "cheese keycard"
|
||||
desc = "Look, I still don't understand the reference. What the heck is a keyzza?"
|
||||
color = "#f0da12"
|
||||
puzzle_id = "cheese"
|
||||
|
||||
/obj/item/keycard/swordfish
|
||||
name = "titanic keycard"
|
||||
desc = "Smells like it was at the bottom of a harbor."
|
||||
color = "#3bbbdb"
|
||||
puzzle_id = "swordfish"
|
||||
|
||||
//***************
|
||||
//*****Doors*****
|
||||
//***************
|
||||
|
||||
/obj/machinery/door/keycard
|
||||
name = "locked door"
|
||||
desc = "This door only opens when a keycard is swiped. It looks virtually indestructable."
|
||||
icon = 'icons/obj/doors/puzzledoor/default.dmi'
|
||||
icon_state = "door_closed"
|
||||
explosion_block = 3
|
||||
heat_proof = TRUE
|
||||
max_integrity = 600
|
||||
armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100)
|
||||
resistance_flags = INDESTRUCTIBLE | FIRE_PROOF | ACID_PROOF | LAVA_PROOF
|
||||
damage_deflection = 70
|
||||
/// Make sure that the key has the same puzzle_id as the keycard door!
|
||||
var/puzzle_id = null
|
||||
/// Message that occurs when the door is opened
|
||||
var/open_message = "The door beeps, and slides opens."
|
||||
|
||||
//Standard Expressions to make keycard doors basically un-cheeseable
|
||||
/obj/machinery/door/keycard/Bumped(atom/movable/AM)
|
||||
return !density && ..()
|
||||
|
||||
/obj/machinery/door/keycard/emp_act(severity)
|
||||
return
|
||||
|
||||
/obj/machinery/door/keycard/ex_act(severity, target)
|
||||
return
|
||||
|
||||
/obj/machinery/door/keycard/try_to_activate_door(mob/user)
|
||||
add_fingerprint(user)
|
||||
if(operating)
|
||||
return
|
||||
|
||||
/obj/machinery/door/keycard/attackby(obj/item/I, mob/user, params)
|
||||
. = ..()
|
||||
if(istype(I,/obj/item/keycard))
|
||||
var/obj/item/keycard/key = I
|
||||
if((!puzzle_id || puzzle_id == key.puzzle_id) && density)
|
||||
if(open_message)
|
||||
to_chat(user, "<span class='notice'>[open_message]</span>")
|
||||
open()
|
||||
return
|
||||
else if(puzzle_id != key.puzzle_id)
|
||||
to_chat(user, "<span class='notice'>[src] buzzes. This must not be the right key.</span>")
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='notice'>This door doesn't appear to close.</span>")
|
||||
return
|
||||
|
||||
//Test doors. Gives admins a few doors to use quickly should they so choose.
|
||||
/obj/machinery/door/keycard/cheese
|
||||
name = "blue airlock"
|
||||
desc = "Smells like... pizza?"
|
||||
puzzle_id = "cheese"
|
||||
|
||||
/obj/machinery/door/keycard/swordfish
|
||||
name = "blue airlock"
|
||||
desc = "If nautical nonsense be something you wish."
|
||||
puzzle_id = "swordfish"
|
||||
|
||||
//*************************
|
||||
//***Box Pushing Puzzles***
|
||||
//*************************
|
||||
//We're working off a subtype of pressureplates, which should work just a BIT better now.
|
||||
/obj/structure/holobox
|
||||
name = "holobox"
|
||||
desc = "A hard-light box, containing a secure decryption key."
|
||||
icon = 'icons/obj/puzzle_small.dmi'
|
||||
icon_state = "laserbox"
|
||||
density = TRUE
|
||||
resistance_flags = INDESTRUCTIBLE | FIRE_PROOF | ACID_PROOF | LAVA_PROOF
|
||||
|
||||
//Uses the pressure_plate settings for a pretty basic custom pattern that waits for a specific item to trigger. Easy enough to retool for mapping purposes or subtypes.
|
||||
/obj/item/pressure_plate/hologrid
|
||||
name = "hologrid"
|
||||
desc = "A high power, electronic input port for a holobox, which can unlock the hologrid's storage compartment. Safe to stand on."
|
||||
icon = 'icons/obj/puzzle_small.dmi'
|
||||
icon_state = "lasergrid"
|
||||
anchored = TRUE
|
||||
trigger_mob = FALSE
|
||||
trigger_item = TRUE
|
||||
specific_item = /obj/structure/holobox
|
||||
removable_signaller = FALSE //Being a pressure plate subtype, this can also use signals.
|
||||
roundstart_signaller_freq = FREQ_HOLOGRID_SOLUTION //Frequency is kept on it's own default channel however.
|
||||
active = TRUE
|
||||
trigger_delay = 10
|
||||
resistance_flags = INDESTRUCTIBLE | FIRE_PROOF | ACID_PROOF | LAVA_PROOF
|
||||
var/reward = /obj/item/reagent_containers/food/snacks/cookie
|
||||
var/claimed = FALSE
|
||||
|
||||
/obj/item/pressure_plate/hologrid/examine(mob/user)
|
||||
. = ..()
|
||||
if(claimed)
|
||||
. += "<span class='notice'>This one appears to be spent already.</span>"
|
||||
|
||||
/obj/item/pressure_plate/hologrid/trigger()
|
||||
if(!claimed)
|
||||
new reward(loc)
|
||||
flick("lasergrid_a",src)
|
||||
icon_state = "lasergrid_full"
|
||||
claimed = TRUE
|
||||
|
||||
/obj/item/pressure_plate/hologrid/Crossed(atom/movable/AM)
|
||||
. = ..()
|
||||
if(trigger_item && istype(AM, specific_item) && !claimed)
|
||||
AM.anchored = TRUE
|
||||
flick("laserbox_burn", AM)
|
||||
trigger()
|
||||
sleep(15)
|
||||
qdel(AM)
|
||||
|
||||
// snowflake code until undertile elements
|
||||
/obj/item/pressure_plate/hologrid/hide()
|
||||
. = ..()
|
||||
anchored = TRUE
|
||||
@@ -178,6 +178,11 @@ GLOBAL_LIST_INIT(leather_recipes, list ( \
|
||||
icon_state = "sinew"
|
||||
novariants = TRUE
|
||||
|
||||
/obj/item/stack/sheet/sinew/wolf
|
||||
name = "wolf sinew"
|
||||
desc = "Long stringy filaments which came from the insides of a wolf."
|
||||
singular_name = "wolf sinew"
|
||||
|
||||
|
||||
GLOBAL_LIST_INIT(sinew_recipes, list ( \
|
||||
new/datum/stack_recipe("sinew restraints", /obj/item/restraints/handcuffs/sinew, 1), \
|
||||
@@ -202,6 +207,11 @@ GLOBAL_LIST_INIT(sinew_recipes, list ( \
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
layer = MOB_LAYER
|
||||
|
||||
/obj/item/stack/sheet/animalhide/goliath_hide/polar_bear_hide
|
||||
name = "polar bear hides"
|
||||
desc = "Pieces of a polar bear's fur, these might be able to make your suit a bit more durable to attack from the local fauna."
|
||||
icon_state = "polar_bear_hide"
|
||||
singular_name = "polar bear hide"
|
||||
|
||||
/obj/item/stack/sheet/animalhide/ashdrake
|
||||
name = "ash drake hide"
|
||||
|
||||
@@ -350,11 +350,28 @@
|
||||
icon = 'icons/obj/flora/rocks.dmi'
|
||||
resistance_flags = FIRE_PROOF
|
||||
density = TRUE
|
||||
/// Itemstack that is dropped when a rock is mined with a pickaxe
|
||||
var/obj/item/stack/mineResult = /obj/item/stack/ore/glass/basalt
|
||||
/// Amount of the itemstack to drop
|
||||
var/mineAmount = 20
|
||||
|
||||
/obj/structure/flora/rock/Initialize()
|
||||
. = ..()
|
||||
icon_state = "[icon_state][rand(1,3)]"
|
||||
|
||||
/obj/structure/flora/rock/attackby(obj/item/W, mob/user, params)
|
||||
if(!mineResult || W.tool_behaviour != TOOL_MINING)
|
||||
return ..()
|
||||
if(flags_1 & NODECONSTRUCT_1)
|
||||
return ..()
|
||||
to_chat(user, "<span class='notice'>You start mining...</span>")
|
||||
if(W.use_tool(src, user, 40, volume=50))
|
||||
to_chat(user, "<span class='notice'>You finish mining the rock.</span>")
|
||||
if(mineResult && mineAmount)
|
||||
new mineResult(get_turf(src), mineAmount)
|
||||
SSblackbox.record_feedback("tally", "pick_used_mining", 1, W.type)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/flora/rock/pile
|
||||
icon_state = "lavarocks"
|
||||
desc = "A pile of rocks."
|
||||
|
||||
178
code/game/objects/structures/icemoon/cave_entrance.dm
Normal file
178
code/game/objects/structures/icemoon/cave_entrance.dm
Normal file
@@ -0,0 +1,178 @@
|
||||
GLOBAL_LIST_INIT(ore_probability, list(/obj/item/stack/ore/uranium = 50,
|
||||
/obj/item/stack/ore/iron = 100,
|
||||
/obj/item/stack/ore/plasma = 75,
|
||||
/obj/item/stack/ore/silver = 50,
|
||||
/obj/item/stack/ore/gold = 50,
|
||||
/obj/item/stack/ore/diamond = 25,
|
||||
/obj/item/stack/ore/bananium = 5,
|
||||
/obj/item/stack/ore/titanium = 75))
|
||||
|
||||
/obj/structure/spawner/ice_moon
|
||||
name = "cave entrance"
|
||||
desc = "A hole in the ground, filled with monsters ready to defend it."
|
||||
icon = 'icons/mob/nest.dmi'
|
||||
icon_state = "hole"
|
||||
faction = list("mining")
|
||||
max_mobs = 3
|
||||
max_integrity = 250
|
||||
mob_types = list(/mob/living/simple_animal/hostile/asteroid/wolf)
|
||||
move_resist = INFINITY
|
||||
anchored = TRUE
|
||||
|
||||
/obj/structure/spawner/ice_moon/Initialize()
|
||||
. = ..()
|
||||
clear_rock()
|
||||
|
||||
/**
|
||||
* Clears rocks around the spawner when it is created
|
||||
*
|
||||
*/
|
||||
/obj/structure/spawner/ice_moon/proc/clear_rock()
|
||||
for(var/turf/F in RANGE_TURFS(2, src))
|
||||
if(abs(src.x - F.x) + abs(src.y - F.y) > 3)
|
||||
continue
|
||||
if(ismineralturf(F))
|
||||
var/turf/closed/mineral/M = F
|
||||
M.ScrapeAway(null, CHANGETURF_IGNORE_AIR)
|
||||
|
||||
/obj/structure/spawner/ice_moon/deconstruct(disassembled)
|
||||
destroy_effect()
|
||||
drop_loot()
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* Effects and messages created when the spawner is destroyed
|
||||
*
|
||||
*/
|
||||
/obj/structure/spawner/ice_moon/proc/destroy_effect()
|
||||
playsound(loc,'sound/effects/explosionfar.ogg', 200, TRUE)
|
||||
visible_message("<span class='boldannounce'>[src] collapses, sealing everything inside!</span>\n<span class='warning'>Ores fall out of the cave as it is destroyed!</span>")
|
||||
|
||||
/**
|
||||
* Drops items after the spawner is destroyed
|
||||
*
|
||||
*/
|
||||
/obj/structure/spawner/ice_moon/proc/drop_loot()
|
||||
for(var/type in GLOB.ore_probability)
|
||||
var/chance = GLOB.ore_probability[type]
|
||||
if(!prob(chance))
|
||||
continue
|
||||
new type(loc, rand(5, 10))
|
||||
|
||||
/obj/structure/spawner/ice_moon/polarbear
|
||||
max_mobs = 1
|
||||
spawn_time = 60 SECONDS
|
||||
mob_types = list(/mob/living/simple_animal/hostile/asteroid/polarbear)
|
||||
|
||||
/obj/structure/spawner/ice_moon/polarbear/clear_rock()
|
||||
for(var/turf/F in RANGE_TURFS(1, src))
|
||||
if(ismineralturf(F))
|
||||
var/turf/closed/mineral/M = F
|
||||
M.ScrapeAway(null, CHANGETURF_IGNORE_AIR)
|
||||
|
||||
/obj/structure/spawner/ice_moon/demonic_portal
|
||||
name = "demonic portal"
|
||||
desc = "A portal that goes to another world, normal creatures couldn't survive there."
|
||||
icon_state = "nether"
|
||||
mob_types = list(/mob/living/simple_animal/hostile/asteroid/ice_demon)
|
||||
light_range = 1
|
||||
light_color = LIGHT_COLOR_RED
|
||||
|
||||
/obj/structure/spawner/ice_moon/demonic_portal/clear_rock()
|
||||
for(var/turf/F in RANGE_TURFS(3, src))
|
||||
if(abs(src.x - F.x) + abs(src.y - F.y) > 5)
|
||||
continue
|
||||
if(ismineralturf(F))
|
||||
var/turf/closed/mineral/M = F
|
||||
M.ScrapeAway(null, CHANGETURF_IGNORE_AIR)
|
||||
|
||||
/obj/structure/spawner/ice_moon/demonic_portal/destroy_effect()
|
||||
new /obj/effect/collapsing_demonic_portal(loc)
|
||||
|
||||
/obj/structure/spawner/ice_moon/demonic_portal/drop_loot()
|
||||
return
|
||||
|
||||
/obj/structure/spawner/ice_moon/demonic_portal/ice_whelp
|
||||
mob_types = list(/mob/living/simple_animal/hostile/asteroid/ice_whelp)
|
||||
|
||||
/obj/structure/spawner/ice_moon/demonic_portal/snowlegion
|
||||
mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow/tendril)
|
||||
|
||||
/obj/effect/collapsing_demonic_portal
|
||||
name = "collapsing demonic portal"
|
||||
desc = "It's slowly fading!"
|
||||
layer = TABLE_LAYER
|
||||
icon = 'icons/mob/nest.dmi'
|
||||
icon_state = "nether"
|
||||
anchored = TRUE
|
||||
density = TRUE
|
||||
|
||||
/obj/effect/collapsing_demonic_portal/Initialize()
|
||||
. = ..()
|
||||
playsound(loc,'sound/effects/tendril_destroyed.ogg', 200, FALSE, 50, TRUE, TRUE)
|
||||
visible_message("<span class='boldannounce'>[src] begins to collapse, cutting it off from this world!</span>")
|
||||
animate(src, transform = matrix().Scale(0, 1), alpha = 50, time = 5 SECONDS)
|
||||
addtimer(CALLBACK(src, .proc/collapse), 5 SECONDS)
|
||||
|
||||
/obj/effect/collapsing_demonic_portal/proc/collapse()
|
||||
visible_message("<span class='warning'>Something slips out of [src]!</span>")
|
||||
var/loot = rand(1, 28)
|
||||
switch(loot)
|
||||
if(1)
|
||||
new /obj/item/clothing/suit/space/hardsuit/cult(loc)
|
||||
if(2)
|
||||
new /obj/item/clothing/glasses/godeye(loc)
|
||||
if(3)
|
||||
new /obj/item/reagent_containers/glass/bottle/potion/flight(loc)
|
||||
if(4)
|
||||
new /obj/item/organ/heart/cursed/wizard(loc)
|
||||
if(5)
|
||||
new /obj/item/jacobs_ladder(loc)
|
||||
if(6)
|
||||
new /obj/item/rod_of_asclepius(loc)
|
||||
if(7)
|
||||
new /obj/item/warp_cube/red(loc)
|
||||
if(8)
|
||||
new /obj/item/wisp_lantern(loc)
|
||||
if(9)
|
||||
new /obj/item/immortality_talisman(loc)
|
||||
if(10)
|
||||
new /obj/item/book/granter/spell/summonitem(loc)
|
||||
if(11)
|
||||
new /obj/item/clothing/neck/necklace/memento_mori(loc)
|
||||
if(12)
|
||||
new /obj/item/borg/upgrade/modkit/lifesteal(loc)
|
||||
new /obj/item/bedsheet/cult(loc)
|
||||
if(13)
|
||||
new /obj/item/disk/design_disk/modkit_disc/mob_and_turf_aoe(loc)
|
||||
if(14)
|
||||
new /obj/item/disk/design_disk/modkit_disc/bounty(loc)
|
||||
if(15)
|
||||
new /obj/item/ship_in_a_bottle(loc)
|
||||
new /obj/item/oar(loc)
|
||||
if(16)
|
||||
new /obj/item/seeds/gatfruit(loc)
|
||||
if(17)
|
||||
new /obj/item/reagent_containers/food/drinks/drinkingglass/filled/nuka_cola(loc)
|
||||
if(18)
|
||||
new /obj/item/assembly/signaler/anomaly/bluespace(loc)
|
||||
if(19)
|
||||
new /obj/item/disk/design_disk/modkit_disc/resonator_blast(loc)
|
||||
if(20)
|
||||
new /obj/item/disk/design_disk/modkit_disc/rapid_repeater(loc)
|
||||
if(21)
|
||||
new /obj/item/slimepotion/transference(loc)
|
||||
if(22)
|
||||
new /obj/item/slime_extract/adamantine(loc)
|
||||
if(23)
|
||||
new /obj/item/weldingtool/abductor(loc)
|
||||
if(24)
|
||||
new /obj/structure/elite_tumor(loc)
|
||||
if(25)
|
||||
new /mob/living/simple_animal/hostile/retaliate/clown/clownhulk(loc)
|
||||
if(26)
|
||||
new /obj/item/clothing/shoes/winterboots/ice_boots(loc)
|
||||
if(27)
|
||||
new /obj/item/book/granter/spell/sacredflame(loc)
|
||||
if(28)
|
||||
new /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/doom(loc)
|
||||
86
code/game/objects/structures/lavaland/geyser.dm
Normal file
86
code/game/objects/structures/lavaland/geyser.dm
Normal file
@@ -0,0 +1,86 @@
|
||||
//If you look at the "geyser_soup" overlay icon_state, you'll see that the first frame has 25 ticks.
|
||||
//That's because the first 18~ ticks are completely skipped for some ungodly weird fucking byond reason
|
||||
|
||||
/obj/structure/geyser
|
||||
name = "geyser"
|
||||
icon = 'icons/obj/lavaland/terrain.dmi'
|
||||
icon_state = "geyser"
|
||||
anchored = TRUE
|
||||
|
||||
var/erupting_state = null //set to null to get it greyscaled from "[icon_state]_soup". Not very usable with the whole random thing, but more types can be added if you change the spawn prob
|
||||
var/activated = FALSE //whether we are active and generating chems
|
||||
var/reagent_id = /datum/reagent/fuel/oil
|
||||
var/potency = 2 //how much reagents we add every process (2 seconds)
|
||||
var/max_volume = 500
|
||||
var/start_volume = 50
|
||||
|
||||
/obj/structure/geyser/proc/start_chemming()
|
||||
activated = TRUE
|
||||
create_reagents(max_volume, DRAINABLE)
|
||||
reagents.add_reagent(reagent_id, start_volume)
|
||||
START_PROCESSING(SSfluids, src) //It's main function is to be plumbed, so use SSfluids
|
||||
if(erupting_state)
|
||||
icon_state = erupting_state
|
||||
else
|
||||
var/mutable_appearance/I = mutable_appearance('icons/obj/lavaland/terrain.dmi', "[icon_state]_soup")
|
||||
I.color = mix_color_from_reagents(reagents.reagent_list)
|
||||
add_overlay(I)
|
||||
|
||||
/obj/structure/geyser/process()
|
||||
if(activated && reagents.total_volume <= reagents.maximum_volume) //this is also evaluated in add_reagent, but from my understanding proc calls are expensive
|
||||
reagents.add_reagent(reagent_id, potency)
|
||||
|
||||
/obj/structure/geyser/plunger_act(obj/item/plunger/P, mob/living/user, _reinforced)
|
||||
if(!_reinforced)
|
||||
to_chat(user, "<span class='warning'>The [P.name] isn't strong enough!</span>")
|
||||
return
|
||||
if(activated)
|
||||
to_chat(user, "<span class'warning'>The [name] is already active!</span>")
|
||||
return
|
||||
|
||||
to_chat(user, "<span class='notice'>You start vigorously plunging [src]!</span>")
|
||||
if(do_after(user, 50 * P.plunge_mod, target = src) && !activated)
|
||||
start_chemming()
|
||||
|
||||
/obj/structure/geyser/random
|
||||
erupting_state = null
|
||||
var/list/options = list(/datum/reagent/clf3 = 10, /datum/reagent/water/hollowwater = 10, /datum/reagent/medicine/omnizine/protozine = 6, /datum/reagent/wittel = 1)
|
||||
|
||||
/obj/structure/geyser/random/Initialize()
|
||||
. = ..()
|
||||
reagent_id = pickweight(options)
|
||||
|
||||
/obj/item/plunger
|
||||
name = "plunger"
|
||||
desc = "It's a plunger for plunging."
|
||||
icon = 'icons/obj/watercloset.dmi'
|
||||
icon_state = "plunger"
|
||||
|
||||
slot_flags = ITEM_SLOT_MASK
|
||||
|
||||
var/plunge_mod = 1 //time*plunge_mod = total time we take to plunge an object
|
||||
var/reinforced = FALSE //whether we do heavy duty stuff like geysers
|
||||
|
||||
/obj/item/plunger/attack_obj(obj/O, mob/living/user)
|
||||
if(!O.plunger_act(src, user, reinforced))
|
||||
return ..()
|
||||
|
||||
/obj/item/plunger/throw_impact(atom/hit_atom, datum/thrownthing/tt)
|
||||
. = ..()
|
||||
if(tt.target_zone != BODY_ZONE_HEAD)
|
||||
return
|
||||
if(iscarbon(hit_atom))
|
||||
var/mob/living/carbon/H = hit_atom
|
||||
if(!H.wear_mask)
|
||||
H.equip_to_slot_if_possible(src, ITEM_SLOT_MASK)
|
||||
H.visible_message("<span class='warning'>The plunger slams into [H]'s face!</span>", "<span class='warning'>The plunger suctions to your face!</span>")
|
||||
|
||||
/obj/item/plunger/reinforced
|
||||
name = "reinforced plunger"
|
||||
desc = "It's an M. 7 Reinforced Plunger© for heavy duty plunging."
|
||||
icon_state = "reinforced_plunger"
|
||||
|
||||
reinforced = TRUE
|
||||
plunge_mod = 0.8
|
||||
|
||||
custom_premium_price = 1200
|
||||
@@ -25,6 +25,9 @@
|
||||
/obj/structure/spawner/lavaland/legion
|
||||
mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril)
|
||||
|
||||
/obj/structure/spawner/lavaland/icewatcher
|
||||
mob_types = list(/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/icewing)
|
||||
|
||||
GLOBAL_LIST_INIT(tendrils, list())
|
||||
/obj/structure/spawner/lavaland/Initialize()
|
||||
. = ..()
|
||||
@@ -94,4 +97,4 @@ GLOBAL_LIST_INIT(tendrils, list())
|
||||
for(var/turf/T in range(2,src))
|
||||
if(!T.density)
|
||||
T.TerraformTurf(/turf/open/chasm/lavaland, /turf/open/chasm/lavaland, flags = CHANGETURF_INHERIT_AIR)
|
||||
qdel(src)
|
||||
qdel(src)
|
||||
|
||||
@@ -134,6 +134,15 @@
|
||||
icon = 'icons/turf/walls.dmi'
|
||||
icon_state = "icerock"
|
||||
|
||||
/turf/closed/indestructible/rock/snow/ice/ore
|
||||
icon = 'icons/turf/walls/icerock_wall.dmi'
|
||||
icon_state = "icerock"
|
||||
smooth = SMOOTH_MORE|SMOOTH_BORDER
|
||||
canSmoothWith = list (/turf/closed)
|
||||
pixel_x = -4
|
||||
pixel_y = -4
|
||||
|
||||
|
||||
/turf/closed/indestructible/paper
|
||||
name = "thick paper wall"
|
||||
desc = "A wall layered with impenetrable sheets of paper."
|
||||
|
||||
@@ -110,6 +110,9 @@
|
||||
if(prob(12))
|
||||
icon_state = "necro[rand(2,3)]"
|
||||
|
||||
/turf/open/indestructible/necropolis/ice
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
/turf/open/indestructible/necropolis/air
|
||||
initial_gas_mix = OPENTURF_DEFAULT_ATMOS
|
||||
|
||||
|
||||
@@ -146,3 +146,13 @@ GLOBAL_DATUM_INIT(openspace_backdrop_one_for_all, /atom/movable/openspace_backdr
|
||||
PlaceOnTop(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/turf/open/openspace/icemoon
|
||||
name = "ice chasm"
|
||||
baseturfs = /turf/open/openspace/icemoon
|
||||
can_cover_up = FALSE
|
||||
can_build_on = FALSE
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
/turf/open/openspace/icemoon/can_zFall(atom/movable/A, levels = 1, turf/target)
|
||||
return TRUE
|
||||
|
||||
@@ -88,6 +88,15 @@
|
||||
light_power = 0.65 //less bright, too
|
||||
light_color = LIGHT_COLOR_LAVA //let's just say you're falling into lava, that makes sense right
|
||||
|
||||
// Chasms for Ice moon, with planetary atmos and glow
|
||||
/turf/open/chasm/icemoon
|
||||
icon = 'icons/turf/floors/icechasms.dmi'
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
planetary_atmos = TRUE
|
||||
baseturfs = /turf/open/chasm/icemoon
|
||||
light_range = 1.9
|
||||
light_power = 0.65
|
||||
light_color = LIGHT_COLOR_PURPLE
|
||||
|
||||
// Chasms for the jungle, with planetary atmos and a different icon
|
||||
/turf/open/chasm/jungle
|
||||
@@ -115,4 +124,4 @@
|
||||
. = ..()
|
||||
var/turf/T = safepick(get_area_turfs(/area/fabric_of_reality))
|
||||
if(T)
|
||||
set_target(T)
|
||||
set_target(T)
|
||||
|
||||
@@ -48,7 +48,9 @@
|
||||
"oldburning","light-on-r","light-on-y","light-on-g","light-on-b", "wood", "carpetsymbol", "carpetstar",
|
||||
"carpetcorner", "carpetside", "carpet", "ironsand1", "ironsand2", "ironsand3", "ironsand4", "ironsand5",
|
||||
"ironsand6", "ironsand7", "ironsand8", "ironsand9", "ironsand10", "ironsand11",
|
||||
"ironsand12", "ironsand13", "ironsand14", "ironsand15")
|
||||
"ironsand12", "ironsand13", "ironsand14", "ironsand15",
|
||||
"snow", "snow0", "snow1", "snow2", "snow3", "snow4", "snow5", "snow6", "snow7", "snow8", "snow9", "snow10", "snow11", "snow12", "snow-ice", "snow_dug",
|
||||
"unsmooth", "smooth", "1-i", "2-i", "3-i", "4-i", "1-n", "2-n", "3-s", "4-s", "1-w", "2-e", "3-w", "4-e", "1-nw", "2-ne", "3-sw", "4-se", "1-f", "2-f", "3-f", "4-f")
|
||||
if(broken || burnt || (icon_state in icons_to_ignore_at_floor_init)) //so damaged/burned tiles or plating icons aren't saved as the default
|
||||
icon_regular_floor = "floor"
|
||||
else
|
||||
|
||||
@@ -13,11 +13,15 @@
|
||||
barefootstep = FOOTSTEP_SAND
|
||||
clawfootstep = FOOTSTEP_SAND
|
||||
heavyfootstep = FOOTSTEP_GENERIC_HEAVY
|
||||
/// Environment type for the turf
|
||||
var/environment_type = "asteroid"
|
||||
/// Base turf type to be created by the tunnel
|
||||
var/turf_type = /turf/open/floor/plating/asteroid //Because caves do whacky shit to revert to normal
|
||||
var/floor_variance = 20 //probability floor has a different icon state
|
||||
/// Probability the floor has a different icon state
|
||||
var/floor_variance = 20
|
||||
attachment_holes = FALSE
|
||||
var/obj/item/stack/digResult = /obj/item/stack/ore/glass/basalt
|
||||
/// Whether the turf has been dug or not
|
||||
var/dug
|
||||
|
||||
/turf/open/floor/plating/asteroid/Initialize()
|
||||
@@ -27,6 +31,7 @@
|
||||
if(prob(floor_variance))
|
||||
icon_state = "[environment_type][rand(0,12)]"
|
||||
|
||||
/// Drops itemstack when dug and changes icon
|
||||
/turf/open/floor/plating/asteroid/proc/getDug()
|
||||
new digResult(src, 5)
|
||||
if(postdig_icon_change)
|
||||
@@ -35,6 +40,7 @@
|
||||
icon_state = "[environment_type]_dug"
|
||||
dug = TRUE
|
||||
|
||||
/// If the user can dig the turf
|
||||
/turf/open/floor/plating/asteroid/proc/can_dig(mob/user)
|
||||
if(!dug)
|
||||
return TRUE
|
||||
@@ -135,16 +141,30 @@
|
||||
#define SPAWN_BUBBLEGUM 6
|
||||
|
||||
/turf/open/floor/plating/asteroid/airless/cave
|
||||
/// Length of the tunnel
|
||||
var/length = 100
|
||||
/// Mobs that can spawn in the tunnel, weighted list
|
||||
var/list/mob_spawn_list
|
||||
/// Megafauna that can spawn in the tunnel, weighted list
|
||||
var/list/megafauna_spawn_list
|
||||
/// Flora that can spawn in the tunnel, weighted list
|
||||
var/list/flora_spawn_list
|
||||
/// Turf type to choose when spawning in tunnel at 1% chance, weighted list
|
||||
var/list/choose_turf_type
|
||||
/// if the tunnel should keep being created
|
||||
var/sanity = 1
|
||||
/// Cave direction to move
|
||||
var/forward_cave_dir = 1
|
||||
/// Backwards cave direction for tracking
|
||||
var/backward_cave_dir = 2
|
||||
/// If the tunnel is moving backwards
|
||||
var/going_backwards = TRUE
|
||||
/// If this is a cave creating type
|
||||
var/has_data = FALSE
|
||||
/// The non-cave creating type
|
||||
var/data_having_type = /turf/open/floor/plating/asteroid/airless/cave/has_data
|
||||
/// Option tunnel width, wegihted list
|
||||
var/list/pick_tunnel_width
|
||||
turf_type = /turf/open/floor/plating/asteroid/airless
|
||||
|
||||
/turf/open/floor/plating/asteroid/airless/cave/has_data //subtype for producing a tunnel with given data
|
||||
@@ -163,6 +183,47 @@
|
||||
/turf/open/floor/plating/asteroid/airless/cave/volcanic/has_data //subtype for producing a tunnel with given data
|
||||
has_data = TRUE
|
||||
|
||||
/turf/open/floor/plating/asteroid/airless/cave/snow
|
||||
gender = PLURAL
|
||||
name = "snow"
|
||||
desc = "Looks cold."
|
||||
icon = 'icons/turf/snow.dmi'
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/icemoon
|
||||
icon_state = "snow"
|
||||
icon_plating = "snow"
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
slowdown = 2
|
||||
environment_type = "snow"
|
||||
flags_1 = NONE
|
||||
planetary_atmos = TRUE
|
||||
burnt_states = list("snow_dug")
|
||||
bullet_sizzle = TRUE
|
||||
bullet_bounce_sound = null
|
||||
digResult = /obj/item/stack/sheet/mineral/snow
|
||||
mob_spawn_list = list(/mob/living/simple_animal/hostile/asteroid/wolf = 50, /obj/structure/spawner/ice_moon = 3, \
|
||||
/mob/living/simple_animal/hostile/asteroid/polarbear = 30, /obj/structure/spawner/ice_moon/polarbear = 3, \
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow = 50, /mob/living/simple_animal/hostile/asteroid/goldgrub = 10)
|
||||
|
||||
flora_spawn_list = list(/obj/structure/flora/tree/pine = 2, /obj/structure/flora/grass/both = 12)
|
||||
data_having_type = /turf/open/floor/plating/asteroid/airless/cave/snow/has_data
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/icemoon
|
||||
choose_turf_type = list(/turf/open/floor/plating/asteroid/snow/icemoon = 19, /turf/open/floor/plating/ice/icemoon = 1)
|
||||
pick_tunnel_width = list("1" = 6, "2" = 1)
|
||||
|
||||
/turf/open/floor/plating/asteroid/airless/cave/snow/underground
|
||||
mob_spawn_list = list(/mob/living/simple_animal/hostile/asteroid/ice_demon = 50, /obj/structure/spawner/ice_moon/demonic_portal = 3, \
|
||||
/mob/living/simple_animal/hostile/asteroid/ice_whelp = 30, /obj/structure/spawner/ice_moon/demonic_portal/ice_whelp = 3, \
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow = 50, /obj/structure/spawner/ice_moon/demonic_portal/snowlegion = 3)
|
||||
flora_spawn_list = list(/obj/structure/flora/rock/icy = 6, /obj/structure/flora/rock/pile/icy = 6)
|
||||
data_having_type = /turf/open/floor/plating/asteroid/airless/cave/snow/underground/has_data
|
||||
choose_turf_type = null
|
||||
|
||||
/turf/open/floor/plating/asteroid/airless/cave/snow/has_data //subtype for producing a tunnel with given data
|
||||
has_data = TRUE
|
||||
|
||||
/turf/open/floor/plating/asteroid/airless/cave/snow/underground/has_data //subtype for producing a tunnel with given data
|
||||
has_data = TRUE
|
||||
|
||||
/turf/open/floor/plating/asteroid/airless/cave/Initialize()
|
||||
if (!mob_spawn_list)
|
||||
mob_spawn_list = list(/mob/living/simple_animal/hostile/asteroid/goldgrub = 1, /mob/living/simple_animal/hostile/asteroid/goliath = 5, /mob/living/simple_animal/hostile/asteroid/basilisk = 4, /mob/living/simple_animal/hostile/asteroid/hivelord = 3)
|
||||
@@ -175,6 +236,7 @@
|
||||
if(!has_data)
|
||||
produce_tunnel_from_data()
|
||||
|
||||
/// Sets the tunnel length and direction
|
||||
/turf/open/floor/plating/asteroid/airless/cave/proc/get_cave_data(set_length, exclude_dir = -1)
|
||||
// If set_length (arg1) isn't defined, get a random length; otherwise assign our length to the length arg.
|
||||
if(!set_length)
|
||||
@@ -187,6 +249,7 @@
|
||||
// Get the opposite direction of our facing direction
|
||||
backward_cave_dir = angle2dir(dir2angle(forward_cave_dir) + 180)
|
||||
|
||||
/// Gets the tunnel length and direction then makes the tunnel
|
||||
/turf/open/floor/plating/asteroid/airless/cave/proc/produce_tunnel_from_data(tunnel_length, excluded_dir = -1)
|
||||
get_cave_data(tunnel_length, excluded_dir)
|
||||
// Make our tunnels
|
||||
@@ -196,10 +259,22 @@
|
||||
// Kill ourselves by replacing ourselves with a normal floor.
|
||||
SpawnFloor(src)
|
||||
|
||||
/**
|
||||
* Makes the tunnel and spawns things inside of it
|
||||
*
|
||||
* Picks a tunnel width for the tunnel and then starts spawning turfs in the direction it moves in
|
||||
* Can randomly change directions of the tunnel, stops if it hits the edge of the map, or a no tunnel area
|
||||
* Can randomly make new tunnels out of itself
|
||||
*
|
||||
*/
|
||||
/turf/open/floor/plating/asteroid/airless/cave/proc/make_tunnel(dir)
|
||||
var/turf/closed/mineral/tunnel = src
|
||||
var/next_angle = pick(45, -45)
|
||||
|
||||
var/tunnel_width = 1
|
||||
if(pick_tunnel_width)
|
||||
tunnel_width = text2num(pickweight(pick_tunnel_width))
|
||||
|
||||
for(var/i = 0; i < length; i++)
|
||||
if(!sanity)
|
||||
break
|
||||
@@ -210,9 +285,11 @@
|
||||
|
||||
// Expand the edges of our tunnel
|
||||
for(var/edge_angle in L)
|
||||
var/turf/closed/mineral/edge = get_step(tunnel, angle2dir(dir2angle(dir) + edge_angle))
|
||||
if(istype(edge))
|
||||
SpawnFloor(edge)
|
||||
var/turf/closed/mineral/edge = tunnel
|
||||
for(var/current_tunnel_width = 1 to tunnel_width)
|
||||
edge = get_step(edge, angle2dir(dir2angle(dir) + edge_angle))
|
||||
if(istype(edge))
|
||||
SpawnFloor(edge)
|
||||
|
||||
if(!sanity)
|
||||
break
|
||||
@@ -223,9 +300,12 @@
|
||||
if(istype(tunnel))
|
||||
// Small chance to have forks in our tunnel; otherwise dig our tunnel.
|
||||
if(i > 3 && prob(20))
|
||||
if(istype(tunnel.loc, /area/mine/explored) || (istype(tunnel.loc, /area/lavaland/surface/outdoors) && !istype(tunnel.loc, /area/lavaland/surface/outdoors/unexplored)))
|
||||
sanity = 0
|
||||
break
|
||||
if(isarea(tunnel.loc))
|
||||
|
||||
var/area/A = tunnel.loc
|
||||
if(!A.tunnel_allowed)
|
||||
sanity = 0
|
||||
break
|
||||
var/turf/open/floor/plating/asteroid/airless/cave/C = tunnel.ChangeTurf(data_having_type, null, CHANGETURF_IGNORE_AIR)
|
||||
C.going_backwards = FALSE
|
||||
C.produce_tunnel_from_data(rand(10, 15), dir)
|
||||
@@ -241,26 +321,35 @@
|
||||
setDir(angle2dir(dir2angle(dir) )+ next_angle)
|
||||
|
||||
|
||||
/// Spawns the floor of the tunnel and any type of structure or mob it can have
|
||||
/turf/open/floor/plating/asteroid/airless/cave/proc/SpawnFloor(turf/T)
|
||||
for(var/S in RANGE_TURFS(1, src))
|
||||
var/turf/NT = S
|
||||
if(!NT || isspaceturf(NT) || istype(NT.loc, /area/mine/explored) || (istype(NT.loc, /area/lavaland/surface/outdoors) && !istype(NT.loc, /area/lavaland/surface/outdoors/unexplored)))
|
||||
sanity = 0
|
||||
break
|
||||
if(!sanity)
|
||||
var/area/A = T.loc
|
||||
if(!A.tunnel_allowed)
|
||||
sanity = 0
|
||||
return
|
||||
SpawnFlora(T)
|
||||
|
||||
SpawnMonster(T)
|
||||
if(choose_turf_type)
|
||||
turf_type = pickweight(choose_turf_type)
|
||||
if(turf_type == initial(turf_type)) // Don't spawn different turf types under flora or terrain
|
||||
var/spawned_flora = FALSE
|
||||
if(is_mining_level(z))
|
||||
spawned_flora = SpawnFlora(T)
|
||||
if(!spawned_flora) // no rocks beneath mob spawners / mobs.
|
||||
SpawnMonster(T)
|
||||
T.ChangeTurf(turf_type, null, CHANGETURF_IGNORE_AIR)
|
||||
|
||||
/// Spawns a random mob or megafauna in the tunnel
|
||||
/turf/open/floor/plating/asteroid/airless/cave/proc/SpawnMonster(turf/T)
|
||||
if(!isarea(loc))
|
||||
return
|
||||
var/area/A = loc
|
||||
if(prob(30))
|
||||
if(istype(loc, /area/mine/explored) || !istype(loc, /area/lavaland/surface/outdoors/unexplored))
|
||||
if(!A.mob_spawn_allowed)
|
||||
return
|
||||
var/randumb = pickweight(mob_spawn_list)
|
||||
if(!randumb)
|
||||
return
|
||||
while(randumb == SPAWN_MEGAFAUNA)
|
||||
if(istype(loc, /area/lavaland/surface/outdoors/unexplored/danger)) //this is danger. it's boss time.
|
||||
if(A.megafauna_spawn_allowed && megafauna_spawn_list && megafauna_spawn_list.len) //this is danger. it's boss time.
|
||||
var/maybe_boss = pickweight(megafauna_spawn_list)
|
||||
if(megafauna_spawn_list[maybe_boss])
|
||||
randumb = maybe_boss
|
||||
@@ -278,22 +367,26 @@
|
||||
return //prevents tendrils spawning in each other's collapse range
|
||||
|
||||
new randumb(T)
|
||||
return
|
||||
return TRUE
|
||||
|
||||
#undef SPAWN_MEGAFAUNA
|
||||
#undef SPAWN_BUBBLEGUM
|
||||
|
||||
/// Spawns a random flora in the tunnel, can spawn clumps of them.
|
||||
/turf/open/floor/plating/asteroid/airless/cave/proc/SpawnFlora(turf/T)
|
||||
if(prob(12))
|
||||
if(istype(loc, /area/mine/explored) || istype(loc, /area/lavaland/surface/outdoors/explored))
|
||||
return
|
||||
if(isarea(loc))
|
||||
var/area/A = loc
|
||||
if(!A.flora_allowed)
|
||||
return
|
||||
var/randumb = pickweight(flora_spawn_list)
|
||||
for(var/obj/structure/flora/ash/F in range(4, T)) //Allows for growing patches, but not ridiculous stacks of flora
|
||||
if(!randumb)
|
||||
return
|
||||
for(var/obj/structure/flora/F in range(4, T)) // Allows for growing patches, but not ridiculous stacks of flora
|
||||
if(!istype(F, randumb))
|
||||
return
|
||||
new randumb(T)
|
||||
|
||||
|
||||
return TRUE
|
||||
|
||||
/turf/open/floor/plating/asteroid/snow
|
||||
gender = PLURAL
|
||||
@@ -322,6 +415,15 @@
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/turf/open/floor/plating/asteroid/snow/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
/turf/open/lava/plasma/ice_moon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
baseturfs = /turf/open/lava/plasma/ice_moon
|
||||
planetary_atmos = TRUE
|
||||
|
||||
/turf/open/floor/plating/asteroid/snow/ice
|
||||
name = "icy snow"
|
||||
desc = "Looks colder."
|
||||
@@ -336,6 +438,15 @@
|
||||
clawfootstep = FOOTSTEP_HARD_CLAW
|
||||
heavyfootstep = FOOTSTEP_GENERIC_HEAVY
|
||||
|
||||
/turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
planetary_atmos = TRUE
|
||||
|
||||
/turf/open/floor/plating/asteroid/snow/ice/icemoon/solarpanel
|
||||
icon = 'icons/turf/floors.dmi'
|
||||
icon_state = "solarpanel"
|
||||
|
||||
/turf/open/floor/plating/asteroid/snow/ice/burn_tile()
|
||||
return FALSE
|
||||
|
||||
@@ -347,4 +458,4 @@
|
||||
|
||||
/turf/open/floor/plating/asteroid/snow/atmosphere
|
||||
initial_gas_mix = FROZEN_ATMOS
|
||||
planetary_atmos = FALSE
|
||||
planetary_atmos = FALSE
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
icon_state = "plating"
|
||||
initial_gas_mix = AIRLESS_ATMOS
|
||||
|
||||
/turf/open/floor/plating/icemoon
|
||||
icon_state = "plating"
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
/turf/open/floor/plating/abductor
|
||||
name = "alien floor"
|
||||
icon_state = "alienpod1"
|
||||
@@ -209,6 +213,8 @@
|
||||
/turf/open/floor/plating/ice/burn_tile()
|
||||
return
|
||||
|
||||
/turf/open/floor/plating/ice/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
/turf/open/floor/plating/snowed
|
||||
name = "snowed-over plating"
|
||||
@@ -240,4 +246,6 @@
|
||||
/turf/open/floor/plating/snowed/temperatre
|
||||
temperature = 255.37
|
||||
|
||||
/turf/open/floor/plating/snowed/smoothed/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
|
||||
@@ -147,6 +147,11 @@
|
||||
var/mineralChance = 13
|
||||
var/display_icon_state = "rock"
|
||||
|
||||
/turf/closed/mineral/random/more_caves
|
||||
mineralSpawnChanceList = list(/turf/closed/mineral/uranium = 5, /turf/closed/mineral/diamond = 1, /turf/closed/mineral/gold = 10,
|
||||
/turf/closed/mineral/silver = 12, /turf/closed/mineral/plasma = 20, /turf/closed/mineral/iron = 40, /turf/closed/mineral/titanium = 11,
|
||||
/turf/closed/mineral/gibtonite = 4, /turf/open/floor/plating/asteroid/airless/cave = 15, /turf/closed/mineral/bscrystal = 1)
|
||||
|
||||
/turf/closed/mineral/random/Initialize()
|
||||
|
||||
mineralSpawnChanceList = typelist("mineralSpawnChanceList", mineralSpawnChanceList)
|
||||
@@ -195,11 +200,27 @@
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturfs = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
|
||||
defer_change = 1
|
||||
defer_change = TRUE
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/uranium/volcanic = 35, /turf/closed/mineral/diamond/volcanic = 30, /turf/closed/mineral/gold/volcanic = 45, /turf/closed/mineral/titanium/volcanic = 45,
|
||||
/turf/closed/mineral/silver/volcanic = 50, /turf/closed/mineral/plasma/volcanic = 50, /turf/closed/mineral/bscrystal/volcanic = 20)
|
||||
|
||||
/turf/closed/mineral/random/high_chance/snow
|
||||
name = "snowy mountainside"
|
||||
icon = 'icons/turf/mining.dmi'
|
||||
smooth_icon = 'icons/turf/walls/mountain_wall.dmi'
|
||||
icon_state = "mountainrock"
|
||||
smooth = SMOOTH_MORE|SMOOTH_BORDER
|
||||
canSmoothWith = list (/turf/closed)
|
||||
defer_change = TRUE
|
||||
environment_type = "snow"
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/uranium/ice/icemoon = 35, /turf/closed/mineral/diamond/ice/icemoon = 30, /turf/closed/mineral/gold/ice/icemoon = 45, /turf/closed/mineral/titanium/ice/icemoon = 45,
|
||||
/turf/closed/mineral/silver/ice/icemoon = 50, /turf/closed/mineral/plasma/ice/icemoon = 50, /turf/closed/mineral/bscrystal/ice/icemoon = 20)
|
||||
|
||||
/turf/closed/mineral/random/high_chance/earth_like
|
||||
icon_state = "rock_highchance_oxy"
|
||||
turf_type = /turf/open/floor/plating/asteroid
|
||||
@@ -236,7 +257,7 @@
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturfs = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
|
||||
defer_change = 1
|
||||
defer_change = TRUE
|
||||
|
||||
mineralChance = 10
|
||||
mineralSpawnChanceList = list(
|
||||
@@ -244,6 +265,36 @@
|
||||
/turf/closed/mineral/silver/volcanic = 12, /turf/closed/mineral/plasma/volcanic = 20, /turf/closed/mineral/iron/volcanic = 40,
|
||||
/turf/closed/mineral/gibtonite/volcanic = 4, /turf/open/floor/plating/asteroid/airless/cave/volcanic = 1, /turf/closed/mineral/bscrystal/volcanic = 1)
|
||||
|
||||
/turf/closed/mineral/random/volcanic/more_caves
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/uranium/volcanic = 5, /turf/closed/mineral/diamond/volcanic = 1, /turf/closed/mineral/gold/volcanic = 10, /turf/closed/mineral/titanium/volcanic = 11,
|
||||
/turf/closed/mineral/silver/volcanic = 12, /turf/closed/mineral/plasma/volcanic = 20, /turf/closed/mineral/iron/volcanic = 40,
|
||||
/turf/closed/mineral/gibtonite/volcanic = 4, /turf/open/floor/plating/asteroid/airless/cave/volcanic = 15, /turf/closed/mineral/bscrystal/volcanic = 1)
|
||||
|
||||
/turf/closed/mineral/random/snow
|
||||
name = "snowy mountainside"
|
||||
icon = 'icons/turf/mining.dmi'
|
||||
smooth_icon = 'icons/turf/walls/mountain_wall.dmi'
|
||||
icon_state = "mountainrock"
|
||||
smooth = SMOOTH_MORE|SMOOTH_BORDER
|
||||
canSmoothWith = list (/turf/closed)
|
||||
defer_change = TRUE
|
||||
environment_type = "snow"
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
mineralChance = 10
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/uranium/ice/icemoon = 5, /turf/closed/mineral/diamond/ice/icemoon = 1, /turf/closed/mineral/gold/ice/icemoon = 10, /turf/closed/mineral/titanium/ice/icemoon = 11,
|
||||
/turf/closed/mineral/silver/ice/icemoon = 12, /turf/closed/mineral/plasma/ice/icemoon = 20, /turf/closed/mineral/iron/ice/icemoon = 40,
|
||||
/turf/closed/mineral/gibtonite/ice/icemoon = 4, /turf/open/floor/plating/asteroid/airless/cave/snow = 1, /turf/closed/mineral/bscrystal/ice/icemoon = 1)
|
||||
|
||||
/turf/closed/mineral/random/snow/no_caves
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/uranium/ice/icemoon = 5, /turf/closed/mineral/diamond/ice/icemoon = 1, /turf/closed/mineral/gold/ice/icemoon = 10, /turf/closed/mineral/titanium/ice/icemoon = 11,
|
||||
/turf/closed/mineral/silver/ice/icemoon = 12, /turf/closed/mineral/plasma/ice/icemoon = 20, /turf/closed/mineral/iron/ice/icemoon = 40,
|
||||
/turf/closed/mineral/gibtonite/ice/icemoon = 4, /turf/closed/mineral/bscrystal/ice/icemoon = 1)
|
||||
|
||||
/turf/closed/mineral/random/labormineral
|
||||
mineralSpawnChanceList = list(
|
||||
@@ -252,18 +303,51 @@
|
||||
/turf/closed/mineral/gibtonite = 2)
|
||||
icon_state = "rock_labor"
|
||||
|
||||
/turf/closed/mineral/random/snow/underground
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/uranium/ice/icemoon = 5, /turf/closed/mineral/diamond/ice/icemoon = 1, /turf/closed/mineral/gold/ice/icemoon = 10, /turf/closed/mineral/titanium/ice/icemoon = 11,
|
||||
/turf/closed/mineral/silver/ice/icemoon = 12, /turf/closed/mineral/plasma/ice/icemoon = 20, /turf/closed/mineral/iron/ice/icemoon = 40,
|
||||
/turf/closed/mineral/gibtonite/ice/icemoon = 4, /turf/open/floor/plating/asteroid/airless/cave/snow/underground = 1, /turf/closed/mineral/bscrystal/ice/icemoon = 1)
|
||||
|
||||
/turf/closed/mineral/random/snow/more_caves
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/uranium/ice/icemoon = 5, /turf/closed/mineral/diamond/ice/icemoon = 1, /turf/closed/mineral/gold/ice/icemoon = 10, /turf/closed/mineral/titanium/ice/icemoon = 11,
|
||||
/turf/closed/mineral/silver/ice/icemoon = 12, /turf/closed/mineral/plasma/ice/icemoon = 20, /turf/closed/mineral/iron/ice/icemoon = 40,
|
||||
/turf/closed/mineral/gibtonite/ice/icemoon = 4, /turf/open/floor/plating/asteroid/airless/cave/snow = 15, /turf/closed/mineral/bscrystal/ice/icemoon = 1)
|
||||
|
||||
|
||||
/turf/closed/mineral/random/labormineral/volcanic
|
||||
environment_type = "basalt"
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturfs = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
|
||||
defer_change = 1
|
||||
defer_change = TRUE
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/uranium/volcanic = 3, /turf/closed/mineral/diamond/volcanic = 1, /turf/closed/mineral/gold/volcanic = 8, /turf/closed/mineral/titanium/volcanic = 8,
|
||||
/turf/closed/mineral/silver/volcanic = 20, /turf/closed/mineral/plasma/volcanic = 30, /turf/closed/mineral/bscrystal/volcanic = 1, /turf/closed/mineral/gibtonite/volcanic = 2,
|
||||
/turf/closed/mineral/iron/volcanic = 95)
|
||||
|
||||
//Subtypes for placing ores manually.
|
||||
/turf/closed/mineral/random/labormineral/ice
|
||||
name = "snowy mountainside"
|
||||
icon = 'icons/turf/mining.dmi'
|
||||
smooth_icon = 'icons/turf/walls/mountain_wall.dmi'
|
||||
icon_state = "mountainrock"
|
||||
smooth = SMOOTH_MORE|SMOOTH_BORDER
|
||||
canSmoothWith = list (/turf/closed)
|
||||
defer_change = TRUE
|
||||
environment_type = "snow"
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
defer_change = TRUE
|
||||
mineralSpawnChanceList = list(
|
||||
/turf/closed/mineral/uranium/ice/icemoon = 3, /turf/closed/mineral/diamond/ice/icemoon = 1, /turf/closed/mineral/gold/ice/icemoon = 8, /turf/closed/mineral/titanium/ice/icemoon = 8,
|
||||
/turf/closed/mineral/silver/ice/icemoon = 20, /turf/closed/mineral/plasma/ice/icemoon = 30, /turf/closed/mineral/bscrystal/ice/icemoon = 1, /turf/closed/mineral/gibtonite/ice/icemoon = 2,
|
||||
/turf/closed/mineral/iron/ice/icemoon = 95)
|
||||
|
||||
|
||||
|
||||
/turf/closed/mineral/iron
|
||||
mineralType = /obj/item/stack/ore/iron
|
||||
@@ -294,6 +378,11 @@
|
||||
initial_gas_mix = FROZEN_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/iron/ice/icemoon
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
|
||||
/turf/closed/mineral/uranium
|
||||
mineralType = /obj/item/stack/ore/uranium
|
||||
@@ -306,7 +395,21 @@
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturfs = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
|
||||
defer_change = 1
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/uranium/ice
|
||||
environment_type = "snow_cavern"
|
||||
icon_state = "icerock_Uranium"
|
||||
smooth_icon = 'icons/turf/walls/icerock_wall.dmi'
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice
|
||||
initial_gas_mix = FROZEN_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/uranium/ice/icemoon
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
/turf/closed/mineral/uranium/earth_like
|
||||
icon_state = "rock_oxy"
|
||||
@@ -327,7 +430,7 @@
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturfs = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
|
||||
defer_change = 1
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/diamond/earth_like
|
||||
icon_state = "rock_oxy"
|
||||
@@ -345,6 +448,11 @@
|
||||
initial_gas_mix = FROZEN_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/diamond/ice/icemoon
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
|
||||
/turf/closed/mineral/gold
|
||||
mineralType = /obj/item/stack/ore/gold
|
||||
@@ -357,7 +465,7 @@
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturfs = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
|
||||
defer_change = 1
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/gold/earth_like
|
||||
icon_state = "rock_oxy"
|
||||
@@ -366,6 +474,19 @@
|
||||
initial_gas_mix = OPENTURF_DEFAULT_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/gold/ice
|
||||
environment_type = "snow_cavern"
|
||||
icon_state = "icerock_gold"
|
||||
smooth_icon = 'icons/turf/walls/icerock_wall.dmi'
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice
|
||||
initial_gas_mix = FROZEN_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/gold/ice/icemoon
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
/turf/closed/mineral/silver
|
||||
mineralType = /obj/item/stack/ore/silver
|
||||
@@ -378,7 +499,7 @@
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturfs = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
|
||||
defer_change = 1
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/silver/earth_like
|
||||
icon_state = "rock_oxy"
|
||||
@@ -387,6 +508,19 @@
|
||||
initial_gas_mix = OPENTURF_DEFAULT_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/silver/ice
|
||||
environment_type = "snow_cavern"
|
||||
icon_state = "icerock_silver"
|
||||
smooth_icon = 'icons/turf/walls/icerock_wall.dmi'
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice
|
||||
initial_gas_mix = FROZEN_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/silver/ice/icemoon
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
/turf/closed/mineral/titanium
|
||||
mineralType = /obj/item/stack/ore/titanium
|
||||
@@ -399,7 +533,7 @@
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturfs = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
|
||||
defer_change = 1
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/titanium/earth_like
|
||||
icon_state = "rock_oxy"
|
||||
@@ -408,6 +542,19 @@
|
||||
initial_gas_mix = OPENTURF_DEFAULT_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/titanium/ice
|
||||
environment_type = "snow_cavern"
|
||||
icon_state = "icerock_titanium"
|
||||
smooth_icon = 'icons/turf/walls/icerock_wall.dmi'
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice
|
||||
initial_gas_mix = FROZEN_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/titanium/ice/icemoon
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
/turf/closed/mineral/plasma
|
||||
mineralType = /obj/item/stack/ore/plasma
|
||||
@@ -420,7 +567,7 @@
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturfs = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
|
||||
defer_change = 1
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/plasma/earth_like
|
||||
icon_state = "rock_oxy"
|
||||
@@ -438,6 +585,10 @@
|
||||
initial_gas_mix = FROZEN_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/plasma/ice/icemoon
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
|
||||
/turf/closed/mineral/bananium
|
||||
@@ -454,6 +605,21 @@
|
||||
initial_gas_mix = OPENTURF_DEFAULT_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/bananium/ice
|
||||
environment_type = "snow_cavern"
|
||||
icon_state = "icerock_Bananium"
|
||||
smooth_icon = 'icons/turf/walls/icerock_wall.dmi'
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice
|
||||
initial_gas_mix = FROZEN_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/bananium/ice/icemoon
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
|
||||
/turf/closed/mineral/bscrystal
|
||||
mineralType = /obj/item/stack/ore/bluespace_crystal
|
||||
mineralAmt = 1
|
||||
@@ -466,7 +632,7 @@
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturfs = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
|
||||
defer_change = 1
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/bscrystal/earth_like
|
||||
icon_state = "rock_oxy"
|
||||
@@ -475,6 +641,19 @@
|
||||
initial_gas_mix = OPENTURF_DEFAULT_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/bscrystal/ice
|
||||
environment_type = "snow_cavern"
|
||||
icon_state = "icerock_BScrystal"
|
||||
smooth_icon = 'icons/turf/walls/icerock_wall.dmi'
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice
|
||||
initial_gas_mix = FROZEN_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/bscrystal/ice/icemoon
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
/turf/closed/mineral/volcanic
|
||||
environment_type = "basalt"
|
||||
@@ -486,7 +665,7 @@
|
||||
environment_type = "basalt"
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturfs = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
defer_change = 1
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/earth_like
|
||||
icon_state = "rock_oxy"
|
||||
@@ -506,7 +685,7 @@
|
||||
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
|
||||
environment_type = "waste"
|
||||
turf_type = /turf/open/floor/plating/ashplanet/rocky
|
||||
defer_change = 1
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/snowmountain
|
||||
name = "snowy mountainside"
|
||||
@@ -521,6 +700,11 @@
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/snowmountain/icemoon
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
/turf/closed/mineral/snowmountain/cavern
|
||||
name = "ice cavern rock"
|
||||
icon = 'icons/turf/mining.dmi'
|
||||
@@ -532,6 +716,11 @@
|
||||
environment_type = "snow_cavern"
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice
|
||||
|
||||
/turf/closed/mineral/snowmountain/cavern/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
//GIBTONITE
|
||||
|
||||
/turf/closed/mineral/gibtonite
|
||||
@@ -634,7 +823,7 @@
|
||||
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
baseturfs = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
|
||||
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
|
||||
defer_change = 1
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/gibtonite/earth_like
|
||||
icon_state = "rock_oxy"
|
||||
@@ -642,3 +831,18 @@
|
||||
baseturfs = /turf/open/floor/plating/asteroid
|
||||
initial_gas_mix = OPENTURF_DEFAULT_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
|
||||
/turf/closed/mineral/gibtonite/ice
|
||||
environment_type = "snow_cavern"
|
||||
icon_state = "icerock_Gibtonite"
|
||||
smooth_icon = 'icons/turf/walls/icerock_wall.dmi'
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice
|
||||
initial_gas_mix = FROZEN_ATMOS
|
||||
defer_change = TRUE
|
||||
|
||||
/turf/closed/mineral/gibtonite/ice/icemoon
|
||||
turf_type = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
baseturfs = /turf/open/floor/plating/asteroid/snow/ice/icemoon
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
@@ -705,10 +705,17 @@
|
||||
var/list/names = list()
|
||||
names += "---- Space Ruins ----"
|
||||
for(var/name in SSmapping.space_ruins_templates)
|
||||
names[name] = list(SSmapping.space_ruins_templates[name], ZTRAIT_SPACE_RUINS, /area/space)
|
||||
names[name] = list(SSmapping.space_ruins_templates[name], ZTRAIT_SPACE_RUINS, list(/area/space))
|
||||
names += "---- Lava Ruins ----"
|
||||
for(var/name in SSmapping.lava_ruins_templates)
|
||||
names[name] = list(SSmapping.lava_ruins_templates[name], ZTRAIT_LAVA_RUINS, /area/lavaland/surface/outdoors/unexplored)
|
||||
names[name] = list(SSmapping.lava_ruins_templates[name], ZTRAIT_LAVA_RUINS, list(/area/lavaland/surface/outdoors/unexplored))
|
||||
names += "---- Ice Ruins ----"
|
||||
for(var/name in SSmapping.ice_ruins_templates)
|
||||
names[name] = list(SSmapping.ice_ruins_templates[name], ZTRAIT_ICE_RUINS, list(/area/icemoon/surface/outdoors/unexplored, /area/icemoon/underground/unexplored))
|
||||
names += "---- Ice Underground Ruins ----"
|
||||
for(var/name in SSmapping.ice_ruins_underground_templates)
|
||||
names[name] = list(SSmapping.ice_ruins_underground_templates[name], ZTRAIT_ICE_RUINS_UNDERGROUND, list(/area/icemoon/underground/unexplored))
|
||||
|
||||
var/ruinname = input("Select ruin", "Spawn Ruin") as null|anything in names
|
||||
var/data = names[ruinname]
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list)
|
||||
if(isturf(L.loc))
|
||||
spawn_locs += L.loc
|
||||
for(var/obj/effect/landmark/loneopspawn/L in GLOB.landmarks_list)
|
||||
if(isturf(L.loc))
|
||||
spawn_locs += L.loc
|
||||
|
||||
if(!spawn_locs)
|
||||
message_admins("No valid spawn locations found, aborting...")
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
. = TRUE
|
||||
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/assembly/signaler/attackby(obj/item/W, mob/user, params)
|
||||
if(issignaler(W))
|
||||
var/obj/item/assembly/signaler/signaler2 = W
|
||||
@@ -162,7 +162,6 @@
|
||||
return
|
||||
return ..(signal)
|
||||
|
||||
|
||||
// Embedded signaller used in anomalies.
|
||||
/obj/item/assembly/signaler/anomaly
|
||||
name = "anomaly core"
|
||||
@@ -179,12 +178,53 @@
|
||||
return FALSE
|
||||
if(signal.data["code"] != code)
|
||||
return FALSE
|
||||
if(suicider)
|
||||
manual_suicide(suicider)
|
||||
for(var/obj/effect/anomaly/A in get_turf(src))
|
||||
A.anomalyNeutralize()
|
||||
return TRUE
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/attack_self()
|
||||
return
|
||||
/obj/item/assembly/signaler/anomaly/manual_suicide(mob/living/carbon/user)
|
||||
user.visible_message("<span class='suicide'>[user]'s [src] is reacting to the radio signal, warping [user.p_their()] body!</span>")
|
||||
user.suiciding = TRUE
|
||||
user.suicide_log()
|
||||
user.gib()
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/attackby(obj/item/I, mob/user, params)
|
||||
if(I.tool_behaviour == TOOL_ANALYZER)
|
||||
to_chat(user, "<span class='notice'>Analyzing... [src]'s stabilized field is fluctuating along frequency [format_frequency(frequency)], code [code].</span>")
|
||||
..()
|
||||
|
||||
//Anomaly cores
|
||||
/obj/item/assembly/signaler/anomaly/pyro
|
||||
name = "\improper pyroclastic anomaly core"
|
||||
desc = "The neutralized core of a pyroclastic anomaly. It feels warm to the touch. It'd probably be valuable for research."
|
||||
icon_state = "pyro core"
|
||||
anomaly_type = /obj/effect/anomaly/pyro
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/grav
|
||||
name = "\improper gravitational anomaly core"
|
||||
desc = "The neutralized core of a gravitational anomaly. It feels much heavier than it looks. It'd probably be valuable for research."
|
||||
icon_state = "grav core"
|
||||
anomaly_type = /obj/effect/anomaly/grav
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/flux
|
||||
name = "\improper flux anomaly core"
|
||||
desc = "The neutralized core of a flux anomaly. Touching it makes your skin tingle. It'd probably be valuable for research."
|
||||
icon_state = "flux core"
|
||||
anomaly_type = /obj/effect/anomaly/flux
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/bluespace
|
||||
name = "\improper bluespace anomaly core"
|
||||
desc = "The neutralized core of a bluespace anomaly. It keeps phasing in and out of view. It'd probably be valuable for research."
|
||||
icon_state = "anomaly core"
|
||||
anomaly_type = /obj/effect/anomaly/bluespace
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/vortex
|
||||
name = "\improper vortex anomaly core"
|
||||
desc = "The neutralized core of a vortex anomaly. It won't sit still, as if some invisible force is acting on it. It'd probably be valuable for research."
|
||||
icon_state = "vortex core"
|
||||
anomaly_type = /obj/effect/anomaly/bhole
|
||||
|
||||
/obj/item/assembly/signaler/cyborg
|
||||
|
||||
|
||||
@@ -143,6 +143,13 @@
|
||||
max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes
|
||||
|
||||
/obj/item/clothing/shoes/winterboots/ice_boots
|
||||
name = "ice hiking boots"
|
||||
desc = "A pair of winter boots with special grips on the bottom, designed to prevent slipping on frozen surfaces."
|
||||
icon_state = "iceboots"
|
||||
item_state = "iceboots"
|
||||
clothing_flags = NOSLIP_ICE
|
||||
|
||||
/obj/item/clothing/shoes/winterboots/christmasbootsr
|
||||
name = "red christmas boots"
|
||||
desc = "A pair of fluffy red christmas boots!"
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
var/list/spawn_locs = list()
|
||||
for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list)
|
||||
spawn_locs += L.loc
|
||||
for(var/obj/effect/landmark/loneopspawn/L in GLOB.landmarks_list)
|
||||
spawn_locs += L.loc
|
||||
if(!spawn_locs.len)
|
||||
return MAP_ERROR
|
||||
|
||||
|
||||
@@ -58,6 +58,9 @@
|
||||
var/list/candidates = pollGhostCandidates("Do you wish to be considered for pirate crew?", ROLE_TRAITOR)
|
||||
shuffle_inplace(candidates)
|
||||
|
||||
if(!SSmapping.empty_space)
|
||||
SSmapping.empty_space = SSmapping.add_new_zlevel("Empty Area For Pirates", list(ZTRAIT_LINKAGE = SELFLOOPING))
|
||||
|
||||
var/datum/map_template/shuttle/pirate/default/ship = new
|
||||
var/x = rand(TRANSITIONEDGE,world.maxx - TRANSITIONEDGE - ship.width)
|
||||
var/y = rand(TRANSITIONEDGE,world.maxy - TRANSITIONEDGE - ship.height)
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
var/traits = null
|
||||
var/space_ruin_levels = 2
|
||||
var/space_empty_levels = 1
|
||||
var/station_ruin_budget = -1 // can be set to manually override the station ruins budget on maps that don't support station ruins, stopping the error from being unable to place the ruins.
|
||||
|
||||
var/minetype = "lavaland"
|
||||
|
||||
@@ -134,6 +135,9 @@
|
||||
log_world("map_config space_empty_levels is not a number!")
|
||||
return
|
||||
|
||||
if("station_ruin_budget" in json)
|
||||
station_ruin_budget = json["station_ruin_budget"]
|
||||
|
||||
temp = json["year_offset"]
|
||||
if (isnum(temp))
|
||||
year_offset = temp
|
||||
|
||||
@@ -11,9 +11,17 @@
|
||||
|
||||
for(var/turf/check in get_affected_turfs(central_turf,1))
|
||||
var/area/new_area = get_area(check)
|
||||
if(!(istype(new_area, allowed_areas)) || check.flags_1 & NO_RUINS_1)
|
||||
valid = FALSE
|
||||
valid = FALSE // set to false before we check
|
||||
if(check.flags_1 & NO_RUINS_1)
|
||||
break
|
||||
for(var/type in allowed_areas)
|
||||
if(istype(new_area, type)) // it's at least one of our types so it's whitelisted
|
||||
valid = TRUE
|
||||
break
|
||||
|
||||
if(!valid)
|
||||
break
|
||||
|
||||
|
||||
if(!valid)
|
||||
continue
|
||||
@@ -51,7 +59,7 @@
|
||||
new /obj/effect/landmark/ruin(center, src)
|
||||
return center
|
||||
|
||||
/proc/seedRuins(list/z_levels = null, budget = 0, whitelist = /area/space, list/potentialRuins)
|
||||
/proc/seedRuins(list/z_levels = null, budget = 0, whitelist = list(/area/space), list/potentialRuins)
|
||||
if(!z_levels || !z_levels.len)
|
||||
WARNING("No Z levels provided - Not generating ruins")
|
||||
return
|
||||
|
||||
@@ -659,6 +659,7 @@
|
||||
nemesis_factions = list("mining", "boss")
|
||||
var/transform_cooldown
|
||||
var/swiping = FALSE
|
||||
var/bleed_stacks_per_hit = 3
|
||||
total_mass = 2.75
|
||||
total_mass_on = 5
|
||||
|
||||
@@ -701,12 +702,11 @@
|
||||
user.changeNext_move(CLICK_CD_MELEE * 0.5) //when closed, it attacks very rapidly
|
||||
|
||||
/obj/item/melee/transforming/cleaving_saw/nemesis_effects(mob/living/user, mob/living/target)
|
||||
var/datum/status_effect/saw_bleed/B = target.has_status_effect(STATUS_EFFECT_SAWBLEED)
|
||||
var/datum/status_effect/stacking/saw_bleed/B = target.has_status_effect(STATUS_EFFECT_SAWBLEED)
|
||||
if(!B)
|
||||
if(!active) //This isn't in the above if-check so that the else doesn't care about active
|
||||
target.apply_status_effect(STATUS_EFFECT_SAWBLEED)
|
||||
target.apply_status_effect(STATUS_EFFECT_SAWBLEED,bleed_stacks_per_hit)
|
||||
else
|
||||
B.add_bleed(B.bleed_buildup)
|
||||
B.add_stacks(bleed_stacks_per_hit)
|
||||
|
||||
/obj/item/melee/transforming/cleaving_saw/attack(mob/living/target, mob/living/carbon/human/user)
|
||||
if(!active || swiping || !target.density || get_turf(target) == get_turf(user))
|
||||
|
||||
@@ -24,13 +24,18 @@
|
||||
/mob/living/carbon/human/slip(knockdown_amount, obj/O, lube)
|
||||
if(HAS_TRAIT(src, TRAIT_NOSLIPALL))
|
||||
return 0
|
||||
if (!(lube&GALOSHES_DONT_HELP))
|
||||
if (!(lube & GALOSHES_DONT_HELP))
|
||||
if(HAS_TRAIT(src, TRAIT_NOSLIPWATER))
|
||||
return 0
|
||||
if(shoes && istype(shoes, /obj/item/clothing))
|
||||
var/obj/item/clothing/CS = shoes
|
||||
if (CS.clothing_flags & NOSLIP)
|
||||
return 0
|
||||
if (lube & SLIDE_ICE)
|
||||
if(shoes && istype(shoes, /obj/item/clothing))
|
||||
var/obj/item/clothing/CS = shoes
|
||||
if (CS.clothing_flags & NOSLIP_ICE)
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/experience_pressure_difference()
|
||||
|
||||
@@ -265,4 +265,12 @@ Difficulty: Medium
|
||||
desc = "The sweet blood, oh, it sings to me."
|
||||
invisibility = 100
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/doom
|
||||
name = "hostile-environment miner"
|
||||
desc = "A miner destined to hop across dimensions for all eternity, hunting anomalous creatures."
|
||||
speed = 8
|
||||
move_to_delay = 8
|
||||
ranged_cooldown_time = 8
|
||||
dash_cooldown = 8
|
||||
|
||||
#undef MINER_DASH_RANGE
|
||||
|
||||
@@ -0,0 +1,361 @@
|
||||
/*
|
||||
Difficulty: Extremely Hard
|
||||
*/
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner
|
||||
name = "demonic-frost miner"
|
||||
desc = "An extremely geared miner, driven crazy or possessed by the demonic forces here, either way a terrifying enemy."
|
||||
health = 1500
|
||||
maxHealth = 1500
|
||||
icon_state = "demonic_miner"
|
||||
icon_living = "demonic_miner"
|
||||
icon = 'icons/mob/icemoon/icemoon_monsters.dmi'
|
||||
attacktext = "pummels"
|
||||
attack_sound = 'sound/weapons/sonic_jackhammer.ogg'
|
||||
mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
|
||||
light_color = "#E4C7C5"
|
||||
movement_type = GROUND
|
||||
weather_immunities = list("snow")
|
||||
speak_emote = list("roars")
|
||||
armour_penetration = 100
|
||||
melee_damage_lower = 10
|
||||
melee_damage_upper = 10
|
||||
aggro_vision_range = 18 // large vision range so combat doesn't abruptly end when someone runs a bit away
|
||||
rapid_melee = 4
|
||||
speed = 20
|
||||
move_to_delay = 20
|
||||
ranged = TRUE
|
||||
crusher_loot = list(/obj/effect/decal/remains/plasma, /obj/item/crusher_trophy/ice_block_talisman)
|
||||
loot = list(/obj/effect/decal/remains/plasma)
|
||||
wander = FALSE
|
||||
del_on_death = TRUE
|
||||
blood_volume = BLOOD_VOLUME_NORMAL
|
||||
deathmessage = "falls to the ground, decaying into plasma particles."
|
||||
deathsound = "bodyfall"
|
||||
attack_action_types = list(/datum/action/innate/megafauna_attack/frost_orbs,
|
||||
/datum/action/innate/megafauna_attack/snowball_machine_gun,
|
||||
/datum/action/innate/megafauna_attack/ice_shotgun)
|
||||
/// Modifies the speed of the projectiles the demonic frost miner shoots out
|
||||
var/projectile_speed_multiplier = 1
|
||||
/// If the demonic frost miner is in its enraged state
|
||||
var/enraged = FALSE
|
||||
/// If the demonic frost miner is currently transforming to its enraged state
|
||||
var/enraging = FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/knockback, 7, FALSE, TRUE)
|
||||
AddComponent(/datum/component/lifesteal, 50)
|
||||
|
||||
/datum/action/innate/megafauna_attack/frost_orbs
|
||||
name = "Fire Frost Orbs"
|
||||
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
||||
button_icon_state = "sniper_zoom"
|
||||
chosen_message = "<span class='colossus'>You are now sending out frost orbs to track in on a target.</span>"
|
||||
chosen_attack_num = 1
|
||||
|
||||
/datum/action/innate/megafauna_attack/snowball_machine_gun
|
||||
name = "Fire Snowball Machine Gun"
|
||||
icon_icon = 'icons/obj/guns/energy.dmi'
|
||||
button_icon_state = "kineticgun"
|
||||
chosen_message = "<span class='colossus'>You are now firing a snowball machine gun at a target.</span>"
|
||||
chosen_attack_num = 2
|
||||
|
||||
/datum/action/innate/megafauna_attack/ice_shotgun
|
||||
name = "Fire Ice Shotgun"
|
||||
icon_icon = 'icons/obj/guns/projectile.dmi'
|
||||
button_icon_state = "shotgun"
|
||||
chosen_message = "<span class='colossus'>You are now firing shotgun ice blasts.</span>"
|
||||
chosen_attack_num = 3
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/OpenFire()
|
||||
check_enraged()
|
||||
projectile_speed_multiplier = 1 - enraged * 0.25
|
||||
SetRecoveryTime(100, 100)
|
||||
|
||||
if(client)
|
||||
switch(chosen_attack)
|
||||
if(1)
|
||||
frost_orbs()
|
||||
if(2)
|
||||
snowball_machine_gun()
|
||||
if(3)
|
||||
ice_shotgun()
|
||||
return
|
||||
|
||||
var/easy_attack = prob(80 - enraged * 40)
|
||||
chosen_attack = rand(1, 3)
|
||||
switch(chosen_attack)
|
||||
if(1)
|
||||
if(easy_attack)
|
||||
frost_orbs(10, 8)
|
||||
else
|
||||
frost_orbs(5, 16)
|
||||
if(2)
|
||||
if(easy_attack)
|
||||
snowball_machine_gun()
|
||||
else
|
||||
INVOKE_ASYNC(src, .proc/ice_shotgun, 5, list(list(-180, -140, -100, -60, -20, 20, 60, 100, 140), list(-160, -120, -80, -40, 0, 40, 80, 120, 160)))
|
||||
snowball_machine_gun(5 * 8, 5)
|
||||
if(3)
|
||||
if(easy_attack)
|
||||
ice_shotgun()
|
||||
else
|
||||
ice_shotgun(5, list(list(0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330), list(-30, -15, 0, 15, 30)))
|
||||
|
||||
/obj/item/projectile/frost_orb
|
||||
name = "frost orb"
|
||||
icon_state = "ice_1"
|
||||
damage = 20
|
||||
armour_penetration = 100
|
||||
speed = 10
|
||||
homing_turn_speed = 30
|
||||
damage_type = BURN
|
||||
|
||||
/obj/item/projectile/frost_orb/on_hit(atom/target, blocked = FALSE)
|
||||
. = ..()
|
||||
if(isturf(target) || isobj(target))
|
||||
target.ex_act(EXPLODE_HEAVY)
|
||||
|
||||
/obj/item/projectile/snowball
|
||||
name = "machine-gun snowball"
|
||||
icon_state = "nuclear_particle"
|
||||
damage = 5
|
||||
armour_penetration = 100
|
||||
speed = 4
|
||||
damage_type = BRUTE
|
||||
|
||||
/obj/item/projectile/ice_blast
|
||||
name = "ice blast"
|
||||
icon_state = "ice_2"
|
||||
damage = 15
|
||||
armour_penetration = 100
|
||||
speed = 4
|
||||
damage_type = BRUTE
|
||||
|
||||
/obj/item/projectile/ice_blast/on_hit(atom/target, blocked = FALSE)
|
||||
. = ..()
|
||||
if(isturf(target) || isobj(target))
|
||||
target.ex_act(EXPLODE_HEAVY)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/ex_act(severity, target)
|
||||
adjustBruteLoss(30 * severity - 120)
|
||||
visible_message("<span class='danger'>[src] absorbs the explosion!</span>", "<span class='userdanger'>You absorb the explosion!</span>")
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/Goto(target, delay, minimum_distance)
|
||||
if(enraging)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/MoveToTarget(list/possible_targets)
|
||||
if(enraging)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/Move()
|
||||
if(enraging)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/// Shoots out homing frost orbs that explode into ice blast projectiles after a couple seconds
|
||||
/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/proc/frost_orbs(added_delay = 10, shoot_times = 8)
|
||||
for(var/i in 1 to shoot_times)
|
||||
var/turf/startloc = get_turf(src)
|
||||
var/turf/endloc = get_turf(target)
|
||||
if(!endloc)
|
||||
break
|
||||
var/obj/item/projectile/frost_orb/P = new(startloc)
|
||||
P.preparePixelProjectile(endloc, startloc)
|
||||
P.firer = src
|
||||
if(target)
|
||||
P.original = target
|
||||
P.set_homing_target(target)
|
||||
P.fire(rand(0, 360))
|
||||
addtimer(CALLBACK(P, /obj/item/projectile/frost_orb/proc/orb_explosion, projectile_speed_multiplier), 20) // make the orbs home in after a second
|
||||
SLEEP_CHECK_DEATH(added_delay)
|
||||
SetRecoveryTime(40, 60)
|
||||
|
||||
/// Called when the orb is exploding, shoots out projectiles
|
||||
/obj/item/projectile/frost_orb/proc/orb_explosion(projectile_speed_multiplier)
|
||||
for(var/i in 0 to 5)
|
||||
var/angle = i * 60
|
||||
var/turf/startloc = get_turf(src)
|
||||
var/turf/endloc = get_turf(original)
|
||||
if(!startloc || !endloc)
|
||||
break
|
||||
var/obj/item/projectile/ice_blast/P = new(startloc)
|
||||
P.speed *= projectile_speed_multiplier
|
||||
P.preparePixelProjectile(endloc, startloc, null, angle + rand(-10, 10))
|
||||
P.firer = firer
|
||||
if(original)
|
||||
P.original = original
|
||||
P.fire()
|
||||
qdel(src)
|
||||
|
||||
/// Shoots out snowballs with a random spread
|
||||
/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/proc/snowball_machine_gun(shots = 60, spread = 45)
|
||||
for(var/i in 1 to shots)
|
||||
var/turf/startloc = get_turf(src)
|
||||
var/turf/endloc = get_turf(target)
|
||||
if(!endloc)
|
||||
break
|
||||
var/obj/item/projectile/P = new /obj/item/projectile/snowball(startloc)
|
||||
P.speed *= projectile_speed_multiplier
|
||||
P.preparePixelProjectile(endloc, startloc, null, rand(-spread, spread))
|
||||
P.firer = src
|
||||
if(target)
|
||||
P.original = target
|
||||
P.fire()
|
||||
SLEEP_CHECK_DEATH(1)
|
||||
SetRecoveryTime(15, 15)
|
||||
|
||||
/// Shoots out ice blasts in a shotgun like pattern
|
||||
/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/proc/ice_shotgun(shots = 5, list/patterns = list(list(-40, -20, 0, 20, 40), list(-30, -10, 10, 30)))
|
||||
for(var/i in 1 to shots)
|
||||
var/list/pattern = patterns[i % length(patterns) + 1] // alternating patterns
|
||||
for(var/spread in pattern)
|
||||
var/turf/startloc = get_turf(src)
|
||||
var/turf/endloc = get_turf(target)
|
||||
if(!endloc)
|
||||
break
|
||||
var/obj/item/projectile/P = new /obj/item/projectile/ice_blast(startloc)
|
||||
P.speed *= projectile_speed_multiplier
|
||||
P.preparePixelProjectile(endloc, startloc, null, spread)
|
||||
P.firer = src
|
||||
if(target)
|
||||
P.original = target
|
||||
P.fire()
|
||||
SLEEP_CHECK_DEATH(8)
|
||||
SetRecoveryTime(15, 20)
|
||||
|
||||
/// Checks if the demonic frost miner is ready to be enraged
|
||||
/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/proc/check_enraged()
|
||||
if(enraged)
|
||||
return
|
||||
if(health > maxHealth*0.25)
|
||||
return
|
||||
SetRecoveryTime(80, 80)
|
||||
adjustHealth(-maxHealth)
|
||||
enraged = TRUE
|
||||
enraging = TRUE
|
||||
animate(src, pixel_y = pixel_y + 96, time = 100, easing = ELASTIC_EASING)
|
||||
spin(100, 10)
|
||||
SLEEP_CHECK_DEATH(60)
|
||||
playsound(src, 'sound/effects/explosion3.ogg', 100, TRUE)
|
||||
icon_state = "demonic_miner_phase2"
|
||||
animate(src, pixel_y = pixel_y - 96, time = 8, flags = ANIMATION_END_NOW)
|
||||
spin(8, 2)
|
||||
SLEEP_CHECK_DEATH(8)
|
||||
for(var/mob/living/L in viewers(src))
|
||||
shake_camera(L, 3, 2)
|
||||
playsound(src, 'sound/effects/meteorimpact.ogg', 100, TRUE)
|
||||
setMovetype(movement_type | FLYING)
|
||||
enraging = FALSE
|
||||
adjustHealth(-maxHealth)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/death(gibbed, list/force_grant)
|
||||
if(health > 0)
|
||||
return
|
||||
var/turf/T = get_turf(src)
|
||||
var/loot = rand(1, 3)
|
||||
switch(loot)
|
||||
if(1)
|
||||
new /obj/item/resurrection_crystal(T)
|
||||
if(2)
|
||||
new /obj/item/clothing/shoes/winterboots/ice_boots/speedy(T)
|
||||
if(3)
|
||||
new /obj/item/pickaxe/drill/jackhammer/demonic(T)
|
||||
return ..()
|
||||
|
||||
/obj/item/resurrection_crystal
|
||||
name = "resurrection crystal"
|
||||
desc = "When used by anything holding it, this crystal gives them a second chance at life if they die."
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "demonic_crystal"
|
||||
|
||||
/obj/item/resurrection_crystal/attack_self(mob/living/user)
|
||||
if(!iscarbon(user))
|
||||
to_chat(user, "<span class='notice'>A dark presence stops you from absorbing the crystal.</span>")
|
||||
return
|
||||
forceMove(user)
|
||||
to_chat(user, "<span class='notice'>You feel a bit safer... but a demonic presence lurks in the back of your head...</span>")
|
||||
RegisterSignal(user, COMSIG_MOB_DEATH, .proc/resurrect)
|
||||
|
||||
/// Resurrects the target when they die by cloning them into a new duplicate body and transferring their mind to the clone on a safe station turf
|
||||
/obj/item/resurrection_crystal/proc/resurrect(mob/living/carbon/user, gibbed)
|
||||
user.visible_message("<span class='notice'>You see [user]'s soul dragged out of their body!</span>", "<span class='notice'>You feel your soul dragged away to a fresh body!</span>")
|
||||
var/typepath = user.type
|
||||
var/turf/T = find_safe_turf()
|
||||
var/mob/living/carbon/clone = new typepath(T)
|
||||
clone.real_name = user.real_name
|
||||
user.dna.transfer_identity(clone)
|
||||
clone.updateappearance(mutcolor_update=1)
|
||||
user.mind.transfer_to(clone) // second life
|
||||
to_chat(clone, "<span class='notice'>You blink and find yourself in [get_area_name(T)].</span>")
|
||||
user.gib()
|
||||
qdel(src)
|
||||
|
||||
/obj/item/clothing/shoes/winterboots/ice_boots/speedy
|
||||
name = "cursed ice hiking boots"
|
||||
desc = "A pair of winter boots contractually made by a devil, they cannot be taken off once put on."
|
||||
slowdown = SHOES_SPEED_SLIGHT
|
||||
|
||||
/obj/item/clothing/shoes/winterboots/ice_boots/speedy/Initialize()
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_NODROP, CURSED_ITEM_TRAIT)
|
||||
|
||||
/obj/item/pickaxe/drill/jackhammer/demonic
|
||||
name = "demonic jackhammer"
|
||||
desc = "Cracks rocks at an inhuman speed, as well as being enhanced for combat purposes."
|
||||
toolspeed = 0
|
||||
|
||||
/obj/item/pickaxe/drill/jackhammer/demonic/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/knockback, 4, FALSE, TRUE)
|
||||
AddComponent(/datum/component/lifesteal, 5)
|
||||
|
||||
/obj/item/crusher_trophy/ice_block_talisman
|
||||
name = "ice block talisman"
|
||||
desc = "A glowing trinket that a demonic miner had on him, it seems he couldn't utilize it for whatever reason."
|
||||
icon_state = "ice_trap_talisman"
|
||||
denied_type = /obj/item/crusher_trophy/ice_block_talisman
|
||||
|
||||
/obj/item/crusher_trophy/ice_block_talisman/effect_desc()
|
||||
return "mark detonation to freeze a creature in a block of ice for a period, preventing them from moving"
|
||||
|
||||
/obj/item/crusher_trophy/ice_block_talisman/on_mark_detonation(mob/living/target, mob/living/user)
|
||||
target.apply_status_effect(/datum/status_effect/ice_block_talisman)
|
||||
|
||||
/datum/status_effect/ice_block_talisman
|
||||
id = "ice_block_talisman"
|
||||
duration = 25
|
||||
status_type = STATUS_EFFECT_REFRESH
|
||||
alert_type = /obj/screen/alert/status_effect/ice_block_talisman
|
||||
/// Stored icon overlay for the hit mob, removed when effect is removed
|
||||
var/icon/cube
|
||||
|
||||
/obj/screen/alert/status_effect/ice_block_talisman
|
||||
name = "Frozen Solid"
|
||||
desc = "You're frozen inside an ice cube, and cannot move!"
|
||||
icon_state = "frozen"
|
||||
|
||||
/datum/status_effect/ice_block_talisman/on_apply()
|
||||
RegisterSignal(owner, COMSIG_MOVABLE_PRE_MOVE, .proc/owner_moved)
|
||||
if(!owner.stat)
|
||||
to_chat(owner, "<span class='userdanger'>You become frozen in a cube!</span>")
|
||||
cube = icon('icons/effects/freeze.dmi', "ice_cube")
|
||||
var/icon/size_check = icon(owner.icon, owner.icon_state)
|
||||
cube.Scale(size_check.Width(), size_check.Height())
|
||||
owner.add_overlay(cube)
|
||||
return ..()
|
||||
|
||||
/// Blocks movement from the status effect owner
|
||||
/datum/status_effect/ice_block_talisman/proc/owner_moved()
|
||||
return COMPONENT_MOVABLE_BLOCK_PRE_MOVE
|
||||
|
||||
/datum/status_effect/ice_block_talisman/on_remove()
|
||||
. = ..()
|
||||
if(!owner.stat)
|
||||
to_chat(owner, "<span class='notice'>The cube melts!</span>")
|
||||
owner.cut_overlay(cube)
|
||||
UnregisterSignal(owner, COMSIG_MOVABLE_PRE_MOVE)
|
||||
@@ -394,3 +394,26 @@ Difficulty: Medium
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/lesser/grant_achievement(medaltype,scoretype)
|
||||
return
|
||||
|
||||
//fire line keeps going even if dragon is deleted
|
||||
/proc/dragon_fire_line(source, list/turfs)
|
||||
var/list/hit_list = list()
|
||||
for(var/turf/T in turfs)
|
||||
if(istype(T, /turf/closed))
|
||||
break
|
||||
new /obj/effect/hotspot(T)
|
||||
T.hotspot_expose(700,50,1)
|
||||
for(var/mob/living/L in T.contents)
|
||||
if(L in hit_list || L == source)
|
||||
continue
|
||||
hit_list += L
|
||||
L.adjustFireLoss(20)
|
||||
to_chat(L, "<span class='userdanger'>You're hit by [source]'s fire breath!</span>")
|
||||
|
||||
// deals damage to mechs
|
||||
for(var/obj/mecha/M in T.contents)
|
||||
if(M in hit_list)
|
||||
continue
|
||||
hit_list += M
|
||||
M.take_damage(45, BRUTE, "melee", 1)
|
||||
sleep(1.5)
|
||||
|
||||
@@ -27,23 +27,51 @@
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
layer = LARGE_MOB_LAYER //Looks weird with them slipping under mineral walls and cameras and shit otherwise
|
||||
flags_1 = PREVENT_CONTENTS_EXPLOSION_1 | HEAR_1
|
||||
/// Crusher loot dropped when fauna killed with a crusher
|
||||
var/list/crusher_loot
|
||||
var/medal_type
|
||||
/// Score given to players when the fauna is killed
|
||||
var/score_type = BOSS_SCORE
|
||||
/// If the megafauna is actually killed (vs entering another phase)
|
||||
var/elimination = 0
|
||||
/// Modifies attacks when at lower health
|
||||
var/anger_modifier = 0
|
||||
/// Internal tracking GPS inside fauna
|
||||
var/obj/item/gps/internal
|
||||
/// Next time fauna can use a melee attack
|
||||
var/recovery_time = 0
|
||||
|
||||
var/true_spawn = TRUE // if this is a megafauna that should grant achievements, or have a gps signal
|
||||
var/nest_range = 10
|
||||
var/chosen_attack = 1 // chosen attack num
|
||||
var/list/attack_action_types = list()
|
||||
var/small_sprite_type
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/Initialize(mapload)
|
||||
. = ..()
|
||||
apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
|
||||
ADD_TRAIT(src, TRAIT_NO_TELEPORT, MEGAFAUNA_TRAIT)
|
||||
for(var/action_type in attack_action_types)
|
||||
var/datum/action/innate/megafauna_attack/attack_action = new action_type()
|
||||
attack_action.Grant(src)
|
||||
if(small_sprite_type)
|
||||
var/datum/action/small_sprite/small_action = new small_sprite_type()
|
||||
small_action.Grant(src)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/Destroy()
|
||||
QDEL_NULL(internal)
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/Moved()
|
||||
if(nest && nest.parent && get_dist(nest.parent, src) > nest_range)
|
||||
var/turf/closest = get_turf(nest.parent)
|
||||
for(var/i = 1 to nest_range)
|
||||
closest = get_step(closest, get_dir(closest, src))
|
||||
forceMove(closest) // someone teleported out probably and the megafauna kept chasing them
|
||||
target = null
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/death(gibbed)
|
||||
if(health > 0)
|
||||
return
|
||||
@@ -134,3 +162,21 @@
|
||||
SSmedals.SetScore(BOSS_SCORE, C, 1)
|
||||
SSmedals.SetScore(score_type, C, 1)
|
||||
return TRUE
|
||||
|
||||
/datum/action/innate/megafauna_attack
|
||||
name = "Megafauna Attack"
|
||||
icon_icon = 'icons/mob/actions/actions_animal.dmi'
|
||||
button_icon_state = ""
|
||||
var/mob/living/simple_animal/hostile/megafauna/M
|
||||
var/chosen_message
|
||||
var/chosen_attack_num = 0
|
||||
|
||||
/datum/action/innate/megafauna_attack/Grant(mob/living/L)
|
||||
if(istype(L, /mob/living/simple_animal/hostile/megafauna))
|
||||
M = L
|
||||
return ..()
|
||||
return FALSE
|
||||
|
||||
/datum/action/innate/megafauna_attack/Activate()
|
||||
M.chosen_attack = chosen_attack_num
|
||||
to_chat(M, chosen_message)
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
Difficulty: Hard
|
||||
*/
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/wendigo
|
||||
name = "wendigo"
|
||||
desc = "A mythological man-eating legendary creature, you probably aren't going to survive this."
|
||||
health = 2500
|
||||
maxHealth = 2500
|
||||
icon_state = "wendigo"
|
||||
icon_living = "wendigo"
|
||||
icon_dead = "wendigo_dead"
|
||||
icon = 'icons/mob/icemoon/64x64megafauna.dmi'
|
||||
attacktext = "claws"
|
||||
attack_sound = 'sound/magic/demon_attack1.ogg'
|
||||
weather_immunities = list("snow")
|
||||
speak_emote = list("roars")
|
||||
armour_penetration = 40
|
||||
melee_damage_lower = 40
|
||||
melee_damage_upper = 40
|
||||
vision_range = 9
|
||||
aggro_vision_range = 18 // man-eating for a reason
|
||||
speed = 8
|
||||
move_to_delay = 8
|
||||
rapid_melee = 16 // every 1/8 second
|
||||
melee_queue_distance = 20 // as far as possible really, need this because of charging and teleports
|
||||
ranged = TRUE
|
||||
pixel_x = -16
|
||||
loot = list(/obj/item/wendigo_blood)
|
||||
crusher_loot = list(/obj/item/wendigo_blood, /obj/item/crusher_trophy/demon_claws)
|
||||
wander = FALSE
|
||||
del_on_death = TRUE
|
||||
blood_volume = BLOOD_VOLUME_NORMAL
|
||||
deathmessage = "falls, shaking the ground around it"
|
||||
deathsound = 'sound/effects/gravhit.ogg'
|
||||
attack_action_types = list(/datum/action/innate/megafauna_attack/heavy_stomp,
|
||||
/datum/action/innate/megafauna_attack/teleport,
|
||||
/datum/action/innate/megafauna_attack/disorienting_scream)
|
||||
/// Saves the turf the megafauna was created at (spawns exit portal here)
|
||||
var/turf/starting
|
||||
/// Range for wendigo stomping when it moves
|
||||
var/stomp_range = 1
|
||||
/// Stores directions the mob is moving, then calls that a move has fully ended when these directions are removed in moved
|
||||
var/stored_move_dirs = 0
|
||||
/// If the wendigo is allowed to move
|
||||
var/can_move = TRUE
|
||||
|
||||
/datum/action/innate/megafauna_attack/heavy_stomp
|
||||
name = "Heavy Stomp"
|
||||
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
||||
button_icon_state = "sniper_zoom"
|
||||
chosen_message = "<span class='colossus'>You are now stomping the ground around you.</span>"
|
||||
chosen_attack_num = 1
|
||||
|
||||
/datum/action/innate/megafauna_attack/teleport
|
||||
name = "Teleport"
|
||||
icon_icon = 'icons/effects/bubblegum.dmi'
|
||||
button_icon_state = "smack ya one"
|
||||
chosen_message = "<span class='colossus'>You are now teleporting at the target you click on.</span>"
|
||||
chosen_attack_num = 2
|
||||
|
||||
/datum/action/innate/megafauna_attack/disorienting_scream
|
||||
name = "Disorienting Scream"
|
||||
icon_icon = 'icons/turf/walls/wall.dmi'
|
||||
button_icon_state = "wall"
|
||||
chosen_message = "<span class='colossus'>You are now screeching, disorienting targets around you.</span>"
|
||||
chosen_attack_num = 3
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/wendigo/Initialize()
|
||||
. = ..()
|
||||
starting = get_turf(src)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/wendigo/OpenFire()
|
||||
SetRecoveryTime(0, 100)
|
||||
if(health <= maxHealth*0.5)
|
||||
stomp_range = 2
|
||||
speed = 6
|
||||
move_to_delay = 6
|
||||
else
|
||||
stomp_range = initial(stomp_range)
|
||||
speed = initial(speed)
|
||||
move_to_delay = initial(move_to_delay)
|
||||
|
||||
if(client)
|
||||
switch(chosen_attack)
|
||||
if(1)
|
||||
heavy_stomp()
|
||||
if(2)
|
||||
teleport()
|
||||
if(3)
|
||||
disorienting_scream()
|
||||
return
|
||||
|
||||
chosen_attack = rand(1, 3)
|
||||
switch(chosen_attack)
|
||||
if(1)
|
||||
heavy_stomp()
|
||||
if(2)
|
||||
teleport()
|
||||
if(3)
|
||||
disorienting_scream()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/wendigo/Move(atom/newloc, direct)
|
||||
if(!can_move)
|
||||
return
|
||||
stored_move_dirs |= direct
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/wendigo/Moved(atom/oldloc, direct)
|
||||
. = ..()
|
||||
stored_move_dirs &= ~direct
|
||||
if(!stored_move_dirs)
|
||||
INVOKE_ASYNC(src, .proc/ground_slam, stomp_range, 1)
|
||||
|
||||
/// Slams the ground around the wendigo throwing back enemies caught nearby
|
||||
/mob/living/simple_animal/hostile/megafauna/wendigo/proc/ground_slam(range, delay)
|
||||
var/turf/orgin = get_turf(src)
|
||||
var/list/all_turfs = RANGE_TURFS(range, orgin)
|
||||
for(var/i = 0 to range)
|
||||
for(var/turf/T in all_turfs)
|
||||
if(get_dist(orgin, T) > i)
|
||||
continue
|
||||
playsound(T,'sound/effects/bamf.ogg', 600, TRUE, 10)
|
||||
new /obj/effect/temp_visual/small_smoke/halfsecond(T)
|
||||
for(var/mob/living/L in T)
|
||||
if(L == src || L.throwing)
|
||||
continue
|
||||
to_chat(L, "<span class='userdanger'>[src]'s ground slam shockwave sends you flying!</span>")
|
||||
var/turf/thrownat = get_ranged_target_turf_direct(src, L, 8, rand(-10, 10))
|
||||
L.throw_at(thrownat, 8, 2, src, TRUE) //, force = MOVE_FORCE_OVERPOWERING, gentle = TRUE)
|
||||
L.apply_damage(20, BRUTE)
|
||||
shake_camera(L, 2, 1)
|
||||
all_turfs -= T
|
||||
sleep(delay)
|
||||
|
||||
/// Larger but slower ground stomp
|
||||
/mob/living/simple_animal/hostile/megafauna/wendigo/proc/heavy_stomp()
|
||||
can_move = FALSE
|
||||
ground_slam(5, 2)
|
||||
SetRecoveryTime(0, 0)
|
||||
can_move = TRUE
|
||||
|
||||
/// Teleports to a location 4 turfs away from the enemy in view
|
||||
/mob/living/simple_animal/hostile/megafauna/wendigo/proc/teleport()
|
||||
var/list/possible_ends = list()
|
||||
for(var/turf/T in view(4, target.loc) - view(3, target.loc))
|
||||
if(isclosedturf(T))
|
||||
continue
|
||||
possible_ends |= T
|
||||
var/turf/end = pick(possible_ends)
|
||||
do_teleport(src, end, 0, channel=TELEPORT_CHANNEL_BLUESPACE, forced = TRUE)
|
||||
SetRecoveryTime(20, 0)
|
||||
|
||||
/// Shakes all nearby enemies screens and animates the wendigo shaking up and down
|
||||
/mob/living/simple_animal/hostile/megafauna/wendigo/proc/disorienting_scream()
|
||||
can_move = FALSE
|
||||
playsound(src, 'sound/magic/demon_dies.ogg', 600, FALSE, 10)
|
||||
animate(src, pixel_z = rand(5, 15), time = 1, loop = 6)
|
||||
animate(pixel_z = 0, time = 1)
|
||||
for(var/mob/living/L in get_hearers_in_view(7, src) - src)
|
||||
shake_camera(L, 30, 1)
|
||||
to_chat(L, "<span class='danger'>The wendigo screams loudly!</span>")
|
||||
SetRecoveryTime(30, 0)
|
||||
SLEEP_CHECK_DEATH(12)
|
||||
can_move = TRUE
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/wendigo/death(gibbed, list/force_grant)
|
||||
if(health > 0)
|
||||
return
|
||||
var/obj/effect/portal/permanent/one_way/exit = new /obj/effect/portal/permanent/one_way(starting)
|
||||
exit.id = "wendigo arena exit"
|
||||
exit.add_atom_colour(COLOR_RED_LIGHT, ADMIN_COLOUR_PRIORITY)
|
||||
exit.set_light(20, 1, LIGHT_COLOR_RED)
|
||||
return ..()
|
||||
|
||||
/obj/item/wendigo_blood
|
||||
name = "bottle of wendigo blood"
|
||||
desc = "You're not actually going to drink this, are you?"
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "vial"
|
||||
|
||||
/obj/item/wendigo_blood/attack_self(mob/living/user)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(!H.mind)
|
||||
return
|
||||
to_chat(H, "<span class='danger'>Power courses through you! You can now shift your form at will.</span>")
|
||||
var/obj/effect/proc_holder/spell/targeted/shapeshift/polar_bear/P = new
|
||||
H.mind.AddSpell(P)
|
||||
playsound(H.loc,'sound/items/drink.ogg', rand(10,50), TRUE)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/shapeshift/polar_bear
|
||||
name = "Polar Bear Form"
|
||||
desc = "Take on the shape of a polar bear."
|
||||
invocation = "RAAAAAAAAWR!"
|
||||
convert_damage = FALSE
|
||||
|
||||
shapeshift_type = /mob/living/simple_animal/hostile/asteroid/polarbear
|
||||
@@ -424,3 +424,29 @@
|
||||
l_pocket = /obj/item/reagent_containers/food/drinks/soda_cans/buzz_fuzz
|
||||
mask = /obj/item/clothing/mask/rat/bee
|
||||
. = ..()
|
||||
|
||||
// Snow Legion
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow
|
||||
name = "snow legion"
|
||||
desc = "You can still see what was once a human under the shifting snowy mass, clearly decorated by a clown."
|
||||
icon = 'icons/mob/icemoon/icemoon_monsters.dmi'
|
||||
icon_state = "snowlegion"
|
||||
icon_living = "snowlegion"
|
||||
icon_aggro = "snowlegion_alive"
|
||||
icon_dead = "snowlegion"
|
||||
crusher_loot = /obj/item/crusher_trophy/legion_skull
|
||||
loot = list(/obj/item/organ/regenerative_core/legion)
|
||||
brood_type = /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/snow
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow/tendril
|
||||
fromtendril = TRUE
|
||||
|
||||
// Snow Legion skull
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/snow
|
||||
name = "snow legion"
|
||||
desc = "One of many."
|
||||
icon = 'icons/mob/icemoon/icemoon_monsters.dmi'
|
||||
icon_state = "snowlegion_head"
|
||||
icon_living = "snowlegion_head"
|
||||
icon_aggro = "snowlegion_head"
|
||||
icon_dead = "snowlegion_head"
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/mob/living/simple_animal/hostile/asteroid/ice_demon
|
||||
name = "demonic watcher"
|
||||
desc = "A creature formed entirely out of ice, bluespace energy emanates from inside of it."
|
||||
icon = 'icons/mob/icemoon/icemoon_monsters.dmi'
|
||||
icon_state = "ice_demon"
|
||||
icon_living = "ice_demon"
|
||||
icon_dead = "ice_demon_dead"
|
||||
icon_gib = "syndicate_gib"
|
||||
mob_biotypes = MOB_ORGANIC|MOB_BEAST
|
||||
mouse_opacity = MOUSE_OPACITY_ICON
|
||||
speak_emote = list("telepathically cries")
|
||||
speed = 2
|
||||
move_to_delay = 2
|
||||
projectiletype = /obj/item/projectile/temp/basilisk/ice
|
||||
projectilesound = 'sound/weapons/pierce.ogg'
|
||||
ranged = TRUE
|
||||
ranged_message = "manifests ice"
|
||||
ranged_cooldown_time = 30
|
||||
minimum_distance = 3
|
||||
retreat_distance = 3
|
||||
maxHealth = 150
|
||||
health = 150
|
||||
obj_damage = 40
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 15
|
||||
attacktext = "slices"
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
vision_range = 9
|
||||
aggro_vision_range = 9
|
||||
move_force = MOVE_FORCE_VERY_STRONG
|
||||
move_resist = MOVE_FORCE_VERY_STRONG
|
||||
pull_force = MOVE_FORCE_VERY_STRONG
|
||||
del_on_death = TRUE
|
||||
loot = list(/obj/item/stack/ore/bluespace_crystal = 3)
|
||||
crusher_loot = /obj/item/crusher_trophy/watcher_wing/ice_wing
|
||||
deathmessage = "fades as the energies that tied it to this world dissipate."
|
||||
deathsound = 'sound/magic/demon_dies.ogg'
|
||||
stat_attack = UNCONSCIOUS
|
||||
movement_type = FLYING
|
||||
robust_searching = TRUE
|
||||
/// Distance the demon will teleport from the target
|
||||
var/teleport_distance = 3
|
||||
|
||||
/obj/item/projectile/temp/basilisk/ice
|
||||
name = "ice blast"
|
||||
damage = 5
|
||||
nodamage = FALSE
|
||||
temperature = -75
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/ice_demon/OpenFire()
|
||||
if(teleport_distance <= 0)
|
||||
return ..()
|
||||
var/list/possible_ends = list()
|
||||
for(var/turf/T in view(teleport_distance, target.loc) - view(teleport_distance - 1, target.loc))
|
||||
if(isclosedturf(T))
|
||||
continue
|
||||
possible_ends |= T
|
||||
var/turf/end = pick(possible_ends)
|
||||
do_teleport(src, end, 0, channel=TELEPORT_CHANNEL_BLUESPACE, forced = TRUE)
|
||||
SLEEP_CHECK_DEATH(8)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/ice_demon/Life()
|
||||
. = ..()
|
||||
if(!. || target)
|
||||
return
|
||||
adjustHealth(-maxHealth*0.025)
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/ice_demon/death(gibbed)
|
||||
move_force = MOVE_FORCE_DEFAULT
|
||||
move_resist = MOVE_RESIST_DEFAULT
|
||||
pull_force = PULL_FORCE_DEFAULT
|
||||
var/turf/T = get_turf(src)
|
||||
if(T && prob(5))
|
||||
new /obj/item/assembly/signaler/anomaly/bluespace(T)
|
||||
return ..()
|
||||
@@ -0,0 +1,54 @@
|
||||
/mob/living/simple_animal/hostile/asteroid/ice_whelp
|
||||
name = "ice whelp"
|
||||
desc = "The offspring of an ice drake, weak in comparison but still terrifying."
|
||||
icon = 'icons/mob/icemoon/icemoon_monsters.dmi'
|
||||
icon_state = "ice_whelp"
|
||||
icon_living = "ice_whelp"
|
||||
icon_dead = "ice_whelp_dead"
|
||||
mob_biotypes = MOB_ORGANIC|MOB_BEAST
|
||||
mouse_opacity = MOUSE_OPACITY_ICON
|
||||
friendly = "stares down"
|
||||
speak_emote = list("roars")
|
||||
speed = 30
|
||||
move_to_delay = 30
|
||||
ranged = TRUE
|
||||
ranged_cooldown_time = 40
|
||||
maxHealth = 350
|
||||
health = 350
|
||||
obj_damage = 40
|
||||
armour_penetration = 20
|
||||
melee_damage_lower = 20
|
||||
melee_damage_upper = 20
|
||||
attacktext = "chomps"
|
||||
attack_sound = 'sound/magic/demon_attack1.ogg'
|
||||
vision_range = 9
|
||||
aggro_vision_range = 9
|
||||
move_force = MOVE_FORCE_VERY_STRONG
|
||||
move_resist = MOVE_FORCE_VERY_STRONG
|
||||
pull_force = MOVE_FORCE_VERY_STRONG
|
||||
butcher_results = list(/obj/item/stack/ore/diamond = 3, /obj/item/stack/sheet/sinew = 2, /obj/item/stack/sheet/bone = 10, /obj/item/stack/sheet/animalhide/ashdrake = 1)
|
||||
loot = list()
|
||||
crusher_loot = /obj/item/crusher_trophy/tail_spike
|
||||
deathmessage = "collapses on it's side."
|
||||
deathsound = 'sound/magic/demon_dies.ogg'
|
||||
stat_attack = UNCONSCIOUS
|
||||
robust_searching = TRUE
|
||||
/// How far the whelps fire can go
|
||||
var/fire_range = 4
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/ice_whelp/OpenFire()
|
||||
var/turf/T = get_ranged_target_turf_direct(src, target, fire_range)
|
||||
var/list/burn_turfs = getline(src, T) - get_turf(src)
|
||||
dragon_fire_line(src, burn_turfs)
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/ice_whelp/Life()
|
||||
. = ..()
|
||||
if(!. || target)
|
||||
return
|
||||
adjustHealth(-maxHealth*0.025)
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/ice_whelp/death(gibbed)
|
||||
move_force = MOVE_FORCE_DEFAULT
|
||||
move_resist = MOVE_RESIST_DEFAULT
|
||||
pull_force = PULL_FORCE_DEFAULT
|
||||
return ..()
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/Aggro()
|
||||
..()
|
||||
if(vision_range != aggro_vision_range)
|
||||
if(vision_range == aggro_vision_range && icon_aggro)
|
||||
icon_state = icon_aggro
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/LoseAggro()
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/mob/living/simple_animal/hostile/asteroid/polarbear
|
||||
name = "polar bear"
|
||||
desc = "An aggressive animal that defends it's territory with incredible power. These beasts don't run from their enemies."
|
||||
icon = 'icons/mob/icemoon/icemoon_monsters.dmi'
|
||||
icon_state = "polarbear"
|
||||
icon_living = "polarbear"
|
||||
icon_dead = "polarbear_dead"
|
||||
mob_biotypes = MOB_ORGANIC|MOB_BEAST
|
||||
mouse_opacity = MOUSE_OPACITY_ICON
|
||||
friendly = "growls at"
|
||||
speak_emote = list("growls")
|
||||
speed = 12
|
||||
move_to_delay = 12
|
||||
maxHealth = 300
|
||||
health = 300
|
||||
obj_damage = 40
|
||||
melee_damage_lower = 25
|
||||
melee_damage_upper = 25
|
||||
attacktext = "claws"
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
vision_range = 2 // don't aggro unless you basically antagonize it, though they will kill you worse than a goliath will
|
||||
aggro_vision_range = 9
|
||||
move_force = MOVE_FORCE_VERY_STRONG
|
||||
move_resist = MOVE_FORCE_VERY_STRONG
|
||||
pull_force = MOVE_FORCE_VERY_STRONG
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/bear = 3, /obj/item/stack/sheet/bone = 2)
|
||||
guaranteed_butcher_results = list(/obj/item/stack/sheet/animalhide/goliath_hide/polar_bear_hide = 1)
|
||||
loot = list()
|
||||
crusher_loot = /obj/item/crusher_trophy/goliath_tentacle
|
||||
stat_attack = UNCONSCIOUS
|
||||
robust_searching = TRUE
|
||||
/// Message for when the polar bear starts to attack faster
|
||||
var/aggressive_message_said = FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/polarbear/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
|
||||
. = ..()
|
||||
if(health > maxHealth*0.5)
|
||||
rapid_melee = initial(rapid_melee)
|
||||
return
|
||||
if(!aggressive_message_said && target)
|
||||
visible_message("<span class='danger'>The [name] gets an enraged look at [target]!</span>")
|
||||
aggressive_message_said = TRUE
|
||||
rapid_melee = 2
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/polarbear/Life()
|
||||
. = ..()
|
||||
if(!. || target)
|
||||
return
|
||||
adjustHealth(-maxHealth*0.025)
|
||||
aggressive_message_said = FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/polarbear/death(gibbed)
|
||||
move_force = MOVE_FORCE_DEFAULT
|
||||
move_resist = MOVE_RESIST_DEFAULT
|
||||
pull_force = PULL_FORCE_DEFAULT
|
||||
return ..()
|
||||
@@ -0,0 +1,57 @@
|
||||
/mob/living/simple_animal/hostile/asteroid/wolf
|
||||
name = "white wolf"
|
||||
desc = "A beast that survives by feasting on weaker opponents, they're much stronger with numbers."
|
||||
icon = 'icons/mob/icemoon/icemoon_monsters.dmi'
|
||||
icon_state = "whitewolf"
|
||||
icon_living = "whitewolf"
|
||||
icon_dead = "whitewolf_dead"
|
||||
mob_biotypes = MOB_ORGANIC|MOB_BEAST
|
||||
mouse_opacity = MOUSE_OPACITY_ICON
|
||||
friendly = "howls at"
|
||||
speak_emote = list("howls")
|
||||
speed = 5
|
||||
move_to_delay = 5
|
||||
maxHealth = 130
|
||||
health = 130
|
||||
obj_damage = 15
|
||||
melee_damage_lower = 7.5
|
||||
melee_damage_upper = 7.5
|
||||
rapid_melee = 2 // every second attack
|
||||
dodging = TRUE
|
||||
dodge_prob = 50
|
||||
attacktext = "bites"
|
||||
attack_sound = 'sound/weapons/bite.ogg'
|
||||
vision_range = 7
|
||||
aggro_vision_range = 7
|
||||
move_force = MOVE_FORCE_WEAK
|
||||
move_resist = MOVE_FORCE_WEAK
|
||||
pull_force = MOVE_FORCE_WEAK
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 2, /obj/item/stack/sheet/sinew/wolf = 2, /obj/item/stack/sheet/bone = 2)
|
||||
loot = list()
|
||||
crusher_loot = /obj/item/crusher_trophy/watcher_wing
|
||||
stat_attack = UNCONSCIOUS
|
||||
robust_searching = TRUE
|
||||
/// Message for when the wolf decides to start running away
|
||||
var/retreat_message_said = FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/wolf/Move(atom/newloc)
|
||||
if(newloc && newloc.z == z && (islava(newloc) || ischasm(newloc)))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/wolf/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
|
||||
. = ..()
|
||||
if(stat == DEAD || health > maxHealth*0.1)
|
||||
retreat_distance = initial(retreat_distance)
|
||||
return
|
||||
if(!retreat_message_said && target)
|
||||
visible_message("<span class='danger'>The [name] tries to flee from [target]!</span>")
|
||||
retreat_message_said = TRUE
|
||||
retreat_distance = 30
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/wolf/Life()
|
||||
. = ..()
|
||||
if(!. || target)
|
||||
return
|
||||
adjustHealth(-maxHealth*0.025)
|
||||
retreat_message_said = FALSE
|
||||
@@ -1,14 +1,13 @@
|
||||
/mob/living/simple_animal/hostile/retaliate/clown
|
||||
name = "Clown"
|
||||
desc = "A denizen of clown planet."
|
||||
icon = 'icons/mob/simple_human.dmi'
|
||||
icon = 'icons/mob/clown_mobs.dmi'
|
||||
icon_state = "clown"
|
||||
icon_living = "clown"
|
||||
icon_dead = "clown_dead"
|
||||
icon_gib = "clown_gib"
|
||||
mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
|
||||
turns_per_move = 5
|
||||
response_help = "pokes"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "robusts"
|
||||
speak = list("HONK", "Honk!", "Welcome to clown planet!")
|
||||
@@ -21,7 +20,6 @@
|
||||
harm_intent_damage = 8
|
||||
melee_damage_lower = 10
|
||||
melee_damage_upper = 10
|
||||
attacktext = "attacks"
|
||||
attack_sound = 'sound/items/bikehorn.ogg'
|
||||
obj_damage = 0
|
||||
environment_smash = ENVIRONMENT_SMASH_NONE
|
||||
@@ -32,15 +30,245 @@
|
||||
minbodytemp = 270
|
||||
maxbodytemp = 370
|
||||
unsuitable_atmos_damage = 10
|
||||
|
||||
do_footstep = TRUE
|
||||
var/banana_time = 0 // If there's no time set it won't spawn.
|
||||
var/banana_type = /obj/item/grown/bananapeel
|
||||
var/attack_reagent
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/handle_temperature_damage()
|
||||
if(bodytemperature < minbodytemp)
|
||||
adjustBruteLoss(10)
|
||||
throw_alert("temp", /obj/screen/alert/cold, 2)
|
||||
else if(bodytemperature > maxbodytemp)
|
||||
adjustBruteLoss(15)
|
||||
throw_alert("temp", /obj/screen/alert/hot, 3)
|
||||
else
|
||||
clear_alert("temp")
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/attack_hand(mob/living/carbon/human/M)
|
||||
..()
|
||||
playsound(src.loc, 'sound/items/bikehorn.ogg', 50, 1)
|
||||
playsound(src.loc, 'sound/items/bikehorn.ogg', 50, TRUE)
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/Life()
|
||||
. = ..()
|
||||
if(banana_time && banana_time < world.time)
|
||||
var/turf/T = get_turf(src)
|
||||
var/list/adjacent = T.GetAtmosAdjacentTurfs(1)
|
||||
new banana_type(pick(adjacent))
|
||||
banana_time = world.time + rand(30,60)
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/AttackingTarget()
|
||||
. = ..()
|
||||
if(attack_reagent && . && isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(L.reagents)
|
||||
L.reagents.add_reagent(attack_reagent, rand(1,5))
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/lube
|
||||
name = "Living Lube"
|
||||
desc = "A puddle of lube brought to life by the honkmother."
|
||||
icon_state = "lube"
|
||||
icon_living = "lube"
|
||||
turns_per_move = 1
|
||||
response_help = "dips a finger into"
|
||||
response_disarm = "gently scoops and pours aside"
|
||||
emote_see = list("bubbles", "oozes")
|
||||
loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/particle_effect/foam)
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/lube/Initialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/snailcrawl)
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/banana
|
||||
name = "Clownana"
|
||||
desc = "A fusion of clown and banana DNA birthed from a botany experiment gone wrong."
|
||||
icon_state = "banana tree"
|
||||
icon_living = "banana tree"
|
||||
response_disarm = "peels"
|
||||
response_harm = "peels"
|
||||
turns_per_move = 1
|
||||
speak = list("HONK", "Honk!", "YA-HONK!!!")
|
||||
emote_see = list("honks", "bites into the banana", "plucks a banana off its head", "photosynthesizes")
|
||||
maxHealth = 120
|
||||
health = 120
|
||||
speed = -10
|
||||
loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/human, /obj/item/soap, /obj/item/seeds/banana)
|
||||
banana_time = 20
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/honkling
|
||||
name = "Honkling"
|
||||
desc = "A divine being sent by the Honkmother to spread joy. It's not dangerous, but it's a bit of a nuisance."
|
||||
icon_state = "honkling"
|
||||
icon_living = "honkling"
|
||||
turns_per_move = 1
|
||||
speed = -10
|
||||
harm_intent_damage = 1
|
||||
melee_damage_lower = 1
|
||||
melee_damage_upper = 1
|
||||
attacktext = "cheers up"
|
||||
loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/human, /obj/item/soap, /obj/item/seeds/banana/bluespace)
|
||||
banana_type = /obj/item/grown/bananapeel
|
||||
attack_reagent = /datum/reagent/consumable/laughter
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/fleshclown
|
||||
name = "Fleshclown"
|
||||
desc = "A being forged out of the pure essence of pranking, cursed into existence by a cruel maker."
|
||||
icon_state = "fleshclown"
|
||||
icon_living = "fleshclown"
|
||||
response_help = "reluctantly pokes"
|
||||
response_disarm = "sinks his hands into the spongy flesh of"
|
||||
response_harm = "cleanses the world of"
|
||||
speak = list("HONK", "Honk!", "I didn't ask for this", "I feel constant and horrible pain", "YA-HONK!!!", "this body is a merciless and unforgiving prison", "I was born out of mirthful pranking but I live in suffering")
|
||||
emote_see = list("honks", "sweats", "jiggles", "contemplates its existence")
|
||||
speak_chance = 5
|
||||
dextrous = TRUE
|
||||
ventcrawler = VENTCRAWLER_ALWAYS
|
||||
maxHealth = 140
|
||||
health = 140
|
||||
speed = -5
|
||||
melee_damage_upper = 15
|
||||
attacktext = "limply slaps"
|
||||
obj_damage = 5
|
||||
loot = list(/obj/item/clothing/suit/hooded/bloated_human, /obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/human, /obj/item/soap)
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/longface
|
||||
name = "Longface"
|
||||
desc = "Often found walking into the bar."
|
||||
icon_state = "long face"
|
||||
icon_living = "long face"
|
||||
move_resist = INFINITY
|
||||
turns_per_move = 10
|
||||
response_help = "tries to awkwardly hug"
|
||||
response_disarm = "pushes the unwieldy frame of"
|
||||
response_harm = "tries to shut up"
|
||||
speak = list("YA-HONK!!!")
|
||||
emote_see = list("honks", "squeaks")
|
||||
speak_chance = 60
|
||||
maxHealth = 150
|
||||
health = 150
|
||||
pixel_x = -16
|
||||
speed = 10
|
||||
harm_intent_damage = 5
|
||||
melee_damage_lower = 5
|
||||
attacktext = "YA-HONKs"
|
||||
loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/human, /obj/item/soap)
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/clownhulk
|
||||
name = "Honk Hulk"
|
||||
desc = "A cruel and fearsome clown. Don't make him angry."
|
||||
icon_state = "honkhulk"
|
||||
icon_living = "honkhulk"
|
||||
move_resist = INFINITY
|
||||
response_help = "tries desperately to appease"
|
||||
response_disarm = "foolishly pushes"
|
||||
response_harm = "angers"
|
||||
speak = list("HONK", "Honk!", "HAUAUANK!!!", "GUUURRRRAAAHHH!!!")
|
||||
emote_see = list("honks", "sweats", "grunts")
|
||||
speak_chance = 5
|
||||
maxHealth = 400
|
||||
health = 400
|
||||
pixel_x = -16
|
||||
speed = 2
|
||||
harm_intent_damage = 15
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 20
|
||||
attacktext = "pummels"
|
||||
obj_damage = 30
|
||||
environment_smash = ENVIRONMENT_SMASH_WALLS
|
||||
loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/human, /obj/item/soap)
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/clownhulk/chlown
|
||||
name = "Chlown"
|
||||
desc = "A real lunkhead who somehow gets all the girls."
|
||||
icon_state = "chlown"
|
||||
icon_living = "chlown"
|
||||
response_help = "submits to"
|
||||
response_disarm = "tries to assert dominance over"
|
||||
response_harm = "makes a weak beta attack at"
|
||||
speak = list("HONK", "Honk!", "Bruh", "cheeaaaahhh?")
|
||||
emote_see = list("asserts his dominance", "emasculates everyone implicitly")
|
||||
maxHealth = 500
|
||||
health = 500
|
||||
speed = -2
|
||||
armour_penetration = 20
|
||||
attacktext = "steals the girlfriend of"
|
||||
attack_sound = 'sound/items/airhorn2.ogg'
|
||||
loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/human, /obj/effect/particle_effect/foam, /obj/item/soap)
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/clownhulk/honcmunculus
|
||||
name = "Honkmunculus"
|
||||
desc = "A slender wiry figure of alchemical origin."
|
||||
icon_state = "honkmunculus"
|
||||
icon_living = "honkmunculus"
|
||||
response_help = "skeptically pokes"
|
||||
response_disarm = "pushes the unwieldy frame of"
|
||||
speak = list("honk")
|
||||
emote_see = list("squirms", "writhes")
|
||||
speak_chance = 1
|
||||
maxHealth = 200
|
||||
health = 200
|
||||
speed = -5
|
||||
harm_intent_damage = 5
|
||||
melee_damage_lower = 5
|
||||
melee_damage_upper = 10
|
||||
attacktext = "ferociously mauls"
|
||||
environment_smash = ENVIRONMENT_SMASH_NONE
|
||||
loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/xeno/bodypartless, /obj/effect/particle_effect/foam, /obj/item/soap)
|
||||
attack_reagent = /datum/reagent/peaceborg_confuse
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/clownhulk/destroyer
|
||||
name = "The Destroyer"
|
||||
desc = "An ancient being born of arcane honking."
|
||||
icon_state = "destroyer"
|
||||
icon_living = "destroyer"
|
||||
response_disarm = "bounces off of"
|
||||
response_harm = "bounces off of"
|
||||
speak = list("HONK!!!", "The Honkmother is merciful, so I must act out her wrath.", "parce mihi ad beatus honkmother placet mihi ut peccata committere,", "DIE!!!")
|
||||
maxHealth = 400
|
||||
health = 400
|
||||
speed = 5
|
||||
harm_intent_damage = 30
|
||||
melee_damage_lower = 20
|
||||
melee_damage_upper = 40
|
||||
armour_penetration = 30
|
||||
stat_attack = UNCONSCIOUS
|
||||
attacktext = "acts out divine vengeance on"
|
||||
obj_damage = 50
|
||||
environment_smash = ENVIRONMENT_SMASH_RWALLS
|
||||
loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/human, /obj/effect/particle_effect/foam, /obj/item/soap)
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/mutant
|
||||
name = "Unknown"
|
||||
desc = "Kill it for its own sake."
|
||||
icon_state = "mutant"
|
||||
icon_living = "mutant"
|
||||
move_resist = INFINITY
|
||||
turns_per_move = 10
|
||||
response_help = "reluctantly sinks a finger into"
|
||||
response_disarm = "squishes into"
|
||||
response_harm = "squishes into"
|
||||
speak = list("aaaaaahhhhuuhhhuhhhaaaaa", "AAAaaauuuaaAAAaauuhhh", "huuuuuh... hhhhuuuooooonnnnkk", "HuaUAAAnKKKK")
|
||||
emote_see = list("squirms", "writhes", "pulsates", "froths", "oozes")
|
||||
speak_chance = 10
|
||||
maxHealth = 130
|
||||
health = 130
|
||||
pixel_x = -16
|
||||
speed = -5
|
||||
harm_intent_damage = 10
|
||||
melee_damage_lower = 10
|
||||
melee_damage_upper = 20
|
||||
attacktext = "awkwardly flails at"
|
||||
loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/xeno/bodypartless, /obj/item/soap, /obj/effect/gibspawner/generic, /obj/effect/gibspawner/generic/animal, /obj/effect/gibspawner/human/bodypartless, /obj/effect/gibspawner/human)
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/mutant/blob
|
||||
name = "Something that was once a clown"
|
||||
desc = "A grotesque bulging figure far mutated from it's original state."
|
||||
icon_state = "blob"
|
||||
icon_living = "blob"
|
||||
speak = list("hey, buddy", "HONK!!!", "H-h-h-H-HOOOOONK!!!!", "HONKHONKHONK!!!", "HEY, BUCKO, GET BACK HERE!!!", "HOOOOOOOONK!!!")
|
||||
emote_see = list("jiggles", "wobbles")
|
||||
health = 130
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
speed = 20
|
||||
attacktext = "bounces off of"
|
||||
loot = list(/obj/item/clothing/mask/gas/clown_hat, /obj/effect/gibspawner/xeno/bodypartless, /obj/effect/particle_effect/foam, /obj/item/soap, /obj/effect/gibspawner/generic, /obj/effect/gibspawner/generic/animal, /obj/effect/gibspawner/human/bodypartless, /obj/effect/gibspawner/human)
|
||||
attack_reagent = /datum/reagent/toxin/mindbreaker
|
||||
|
||||
@@ -41,6 +41,9 @@ Contents:
|
||||
for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list)
|
||||
if(isturf(L.loc))
|
||||
spawn_locs += L.loc
|
||||
for(var/obj/effect/landmark/loneopspawn/L in GLOB.landmarks_list)
|
||||
if(isturf(L.loc))
|
||||
spawn_locs += L.loc
|
||||
if(!spawn_locs.len)
|
||||
return kill()
|
||||
spawn_loc = pick(spawn_locs)
|
||||
|
||||
@@ -182,18 +182,14 @@
|
||||
var/path = pick(/mob/living/simple_animal/hostile/carp,
|
||||
/mob/living/simple_animal/hostile/bear,
|
||||
/mob/living/simple_animal/hostile/mushroom,
|
||||
/mob/living/simple_animal/hostile/statue,
|
||||
/mob/living/simple_animal/hostile/retaliate/bat,
|
||||
/mob/living/simple_animal/hostile/retaliate/goat,
|
||||
/mob/living/simple_animal/hostile/killertomato,
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider,
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/hunter,
|
||||
/mob/living/simple_animal/hostile/blob/blobbernaut/independent,
|
||||
/mob/living/simple_animal/hostile/carp/ranged,
|
||||
/mob/living/simple_animal/hostile/carp/ranged/chaos,
|
||||
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher,
|
||||
/mob/living/simple_animal/hostile/asteroid/goliath/beast,
|
||||
/mob/living/simple_animal/hostile/headcrab,
|
||||
/mob/living/simple_animal/hostile/morph,
|
||||
/mob/living/simple_animal/hostile/stickman,
|
||||
/mob/living/simple_animal/hostile/stickman/dog,
|
||||
|
||||
37
code/modules/ruins/icemoonruin_code/hotsprings.dm
Normal file
37
code/modules/ruins/icemoonruin_code/hotsprings.dm
Normal file
@@ -0,0 +1,37 @@
|
||||
GLOBAL_LIST_EMPTY(cursed_minds)
|
||||
|
||||
/**
|
||||
* Turns whoever enters into a mob
|
||||
*
|
||||
* If mob is chosen, turns the person into a random animal type
|
||||
* Once the spring is used, it cannot be used by the same mind ever again
|
||||
* After usage, teleports the user back to a random safe turf (so mobs are not killed by ice moon atmosphere)
|
||||
*
|
||||
*/
|
||||
|
||||
/turf/open/water/cursed_spring
|
||||
baseturfs = /turf/open/water/cursed_spring
|
||||
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
|
||||
|
||||
/turf/open/water/cursed_spring/Entered(atom/movable/thing, atom/oldLoc)
|
||||
. = ..()
|
||||
if(!isliving(thing))
|
||||
return
|
||||
var/mob/living/L = thing
|
||||
if(!L.client)
|
||||
return
|
||||
if(GLOB.cursed_minds[L.mind])
|
||||
return
|
||||
GLOB.cursed_minds[L.mind] = TRUE
|
||||
RegisterSignal(L.mind, COMSIG_PARENT_QDELETING, .proc/remove_from_cursed)
|
||||
L = wabbajack(L, "animal") // Appearance randomization removed so citadel players don't get randomized into some ungodly ugly creature and complain
|
||||
var/turf/T = find_safe_turf()
|
||||
L.forceMove(T)
|
||||
to_chat(L, "<span class='notice'>You blink and find yourself in [get_area_name(T)].</span>")
|
||||
|
||||
/**
|
||||
* Deletes minds from the cursed minds list after their deletion
|
||||
*
|
||||
*/
|
||||
/turf/open/water/cursed_spring/proc/remove_from_cursed(datum/mind/M)
|
||||
GLOB.cursed_minds -= M
|
||||
33
code/modules/ruins/icemoonruin_code/library.dm
Normal file
33
code/modules/ruins/icemoonruin_code/library.dm
Normal file
@@ -0,0 +1,33 @@
|
||||
/obj/machinery/door/keycard/library
|
||||
name = "wooden door"
|
||||
desc = "A dusty, scratched door with a thick lock attached."
|
||||
icon = 'icons/obj/doors/puzzledoor/wood.dmi'
|
||||
puzzle_id = "library"
|
||||
open_message = "The door opens with a loud creak."
|
||||
|
||||
/obj/item/keycard/library
|
||||
name = "golden key"
|
||||
desc = "A dull, golden key."
|
||||
icon_state = "golden_key"
|
||||
puzzle_id = "library"
|
||||
|
||||
/obj/item/paper/crumpled/bloody/fluff/stations/lavaland/library/warning
|
||||
name = "ancient note"
|
||||
info = "<b>Here lies the vast collection of He Who Knows Ten Thousand Things. May all who pursue this knowledge for power be cursed a thousand times.</b>"
|
||||
|
||||
/obj/item/paper/crumpled/fluff/stations/lavaland/library/diary
|
||||
name = "diary entry 13"
|
||||
info = "It has been a week since the library was buried. I am so hungry that I can barely muster the energy to think, let alone write. The owl is gone."
|
||||
|
||||
/obj/item/paper/crumpled/fluff/stations/lavaland/library/diary2
|
||||
name = "diary entry 18"
|
||||
info = "I've lost track of time. I lack the strength to even pick up books off the shelves. To think, after all this time spent searching for the library, I will die before I can so much as graze the depth of its knowledge."
|
||||
|
||||
/obj/item/feather
|
||||
name = "feather"
|
||||
desc = "A dark, wilting feather. It seems as old as time."
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "feather"
|
||||
force = 0
|
||||
throwforce = 0
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
@@ -557,7 +557,7 @@
|
||||
dwidth = 1
|
||||
width = 3
|
||||
height = 4
|
||||
var/target_area = /area/lavaland/surface/outdoors
|
||||
var/target_area = list(/area/lavaland/surface/outdoors, /area/icemoon/underground/unexplored/rivers)
|
||||
var/edge_distance = 16
|
||||
// Minimal distance from the map edge, setting this too low can result in shuttle landing on the edge and getting "sliced"
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
var/view_range = 7
|
||||
var/x_offset = 0
|
||||
var/y_offset = 0
|
||||
var/list/whitelist_turfs = list(/turf/open/space, /turf/open/floor/plating, /turf/open/lava)
|
||||
var/space_turfs_only = TRUE
|
||||
var/see_hidden = FALSE
|
||||
var/designate_time = 0
|
||||
@@ -22,6 +23,7 @@
|
||||
/obj/machinery/computer/camera_advanced/shuttle_docker/Initialize()
|
||||
. = ..()
|
||||
GLOB.navigation_computers += src
|
||||
whitelist_turfs = typecacheof(whitelist_turfs)
|
||||
|
||||
/obj/machinery/computer/camera_advanced/shuttle_docker/Destroy()
|
||||
. = ..()
|
||||
@@ -226,6 +228,11 @@
|
||||
if(!ispath(turf_type, /turf/open/space))
|
||||
return SHUTTLE_DOCKER_BLOCKED
|
||||
|
||||
if(length(whitelist_turfs))
|
||||
var/turf_type = hidden_turf_info ? hidden_turf_info[2] : T.type
|
||||
if(!is_type_in_typecache(turf_type, whitelist_turfs))
|
||||
return SHUTTLE_DOCKER_BLOCKED
|
||||
|
||||
// Checking for overlapping dock boundaries
|
||||
for(var/i in 1 to overlappers.len)
|
||||
var/obj/docking_port/port = overlappers[i]
|
||||
|
||||
@@ -62,6 +62,8 @@
|
||||
view_range = 13
|
||||
x_offset = -7
|
||||
y_offset = -1
|
||||
space_turfs_only = FALSE
|
||||
whitelist_turfs = list(/turf/open/space, /turf/open/floor/plating, /turf/open/lava, /turf/closed/mineral)
|
||||
see_hidden = TRUE
|
||||
|
||||
#undef SYNDICATE_CHALLENGE_TIMER
|
||||
#undef SYNDICATE_CHALLENGE_TIMER
|
||||
|
||||
Reference in New Issue
Block a user