Merge pull request #10541 from Detective-Google/the-p-o-o-l

adds the POOL to box station
This commit is contained in:
Ghom
2020-02-21 02:43:04 +01:00
committed by GitHub
34 changed files with 2149 additions and 262 deletions
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -17,4 +17,4 @@
#define MOVE_FORCE_NORMAL MOVE_FORCE_DEFAULT
#define MOVE_FORCE_WEAK (MOVE_FORCE_DEFAULT / 2)
#define MOVE_FORCE_VERY_WEAK ((MOVE_FORCE_DEFAULT / MOVE_FORCE_CRUSH_RATIO) + 1)
#define MOVE_FORCE_EXTREMELY_WEAK (MOVE_FORCE_DEFAULT / (MOVE_FORCE_CRUSH_RATIO * 3))
#define MOVE_FORCE_EXTREMELY_WEAK (MOVE_FORCE_DEFAULT / (MOVE_FORCE_CRUSH_RATIO * 3))
+13
View File
@@ -0,0 +1,13 @@
//TODO: move these to their own file
#define POOL_FRIGID 1
#define POOL_COOL 2
#define POOL_NORMAL 3
#define POOL_WARM 4
#define POOL_SCALDING 5
GLOBAL_LIST_INIT(blacklisted_pool_reagents, list(
/datum/reagent/toxin/plasma, /datum/reagent/oxygen, /datum/reagent/nitrous_oxide, /datum/reagent/nitrogen, //gases
/datum/reagent/fermi, //blanket fermichem ban sorry. this also covers mkultra, genital enlargers, etc etc.
/datum/reagent/drug/aphrodisiac, /datum/reagent/drug/anaphrodisiac, /datum/reagent/drug/aphrodisiacplus, /datum/reagent/drug/anaphrodisiacplus, //literally asking for prefbreaks
/datum/reagent/consumable/femcum, /datum/reagent/consumable/semen //NO.
))
+1 -1
View File
@@ -137,7 +137,7 @@
#define TRAIT_NOMARROW "nomarrow" // You don't make blood, with chemicals or nanites.
#define TRAIT_NOPULSE "nopulse" // Your heart doesn't beat.
#define TRAIT_EXEMPT_HEALTH_EVENTS "exempt-health-events"
#define TRAIT_SWIMMING "swimming" //only applied by /datum/element/swimming, for checking
//non-mob traits
#define TRAIT_PARALYSIS "paralysis" //Used for limb-based paralysis, where replacing the limb will fix it
+21
View File
@@ -0,0 +1,21 @@
/// Just for marking when someone's swimming.
/datum/element/swimming
element_flags = ELEMENT_DETACH
/datum/element/swimming/Attach(datum/target)
if((. = ..()) == ELEMENT_INCOMPATIBLE)
return
if(!isliving(target))
return ELEMENT_INCOMPATIBLE
RegisterSignal(target, COMSIG_MOVABLE_MOVED, .proc/check_valid)
ADD_TRAIT(target, TRAIT_SWIMMING, TRAIT_SWIMMING) //seriously there's only one way to get this
/datum/element/swimming/Detach(datum/target)
. = ..()
UnregisterSignal(target, COMSIG_MOVABLE_MOVED)
REMOVE_TRAIT(target, TRAIT_SWIMMING, TRAIT_SWIMMING)
/datum/element/swimming/proc/check_valid(datum/source)
var/mob/living/L = source
if(!istype(L.loc, /turf/open/pool))
source.RemoveElement(/datum/element/swimming)
+4
View File
@@ -1367,3 +1367,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/tcommsat/lounge
name = "Telecommunications Satellite Lounge"
icon_state = "tcomsatlounge"
/area/crew_quarters/fitness/pool
name = "Pool Area"
icon_state = "pool"
+2
View File
@@ -184,6 +184,8 @@
soundin = pick('sound/items/bikehorn.ogg', 'sound/items/AirHorn2.ogg', 'sound/misc/sadtrombone.ogg', 'sound/items/AirHorn.ogg', 'sound/effects/reee.ogg', 'sound/items/WEEOO1.ogg', 'sound/voice/beepsky/iamthelaw.ogg', 'sound/voice/beepsky/creep.ogg','sound/magic/Fireball.ogg' ,'sound/effects/pray.ogg', 'sound/voice/hiss1.ogg','sound/machines/buzz-sigh.ogg', 'sound/machines/ping.ogg', 'sound/weapons/flashbang.ogg', 'sound/weapons/bladeslice.ogg')
if("goose")
soundin = pick('sound/creatures/goose1.ogg', 'sound/creatures/goose2.ogg', 'sound/creatures/goose3.ogg', 'sound/creatures/goose4.ogg')
if("water_wade")
soundin = pick('sound/effects/water_wade1.ogg', 'sound/effects/water_wade2.ogg', 'sound/effects/water_wade3.ogg', 'sound/effects/water_wade4.ogg')
//START OF CIT CHANGES - adds random vore sounds
if ("struggle_sound")
soundin = pick( 'sound/vore/pred/struggle_01.ogg','sound/vore/pred/struggle_02.ogg','sound/vore/pred/struggle_03.ogg',
@@ -0,0 +1,91 @@
//shameless copies of carps.
/mob/living/simple_animal/hostile/shark
name = "Space Shark"
desc = "The best terror of the seas, next to the kraken."
icon_state = "shark"
icon_living = "shark"
icon = 'icons/mob/sharks.dmi'
icon_dead = "shark_dead"
icon_gib = "carp_gib"
environment_smash = 0
speak_chance = 0
turns_per_move = 3
butcher_results = list(/obj/item/reagent_containers/food/snacks/carpmeat = 3)
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "hits"
speed = 0
maxHealth = 75
health = 75
harm_intent_damage = 18
melee_damage_lower = 18
melee_damage_upper = 18
attacktext = "maims"
attack_sound = 'sound/weapons/bite.ogg'
gold_core_spawnable = 1
//Space shark aren't affected by cold.
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
maxbodytemp = 1500
faction = list("shark")
/mob/living/simple_animal/hostile/shark/Process_Spacemove(var/movement_dir = 0)
return 1 //No drifting in space for space sharks....either!
/mob/living/simple_animal/hostile/shark/FindTarget()
. = ..()
if(.)
emote("me", 1, "growls at [.]!")
/mob/living/simple_animal/hostile/shark/AttackingTarget()
. =..()
var/mob/living/carbon/L = .
if(istype(L))
if(prob(25))
L.Knockdown(20)
L.visible_message("<span class='danger'>\the [src] knocks down \the [L]!</span>")
/mob/living/simple_animal/hostile/shark/laser
name = "Laser-Shark"
desc = "NOW we've jumped the shark."
icon_state = "lasershark"
icon_living = "lasershark"
icon_dead = "lasershark_dead"
icon_gib = "carp_gib"
ranged = 1
retreat_distance = 3
minimum_distance = 0 //Between shots they can and will close in to nash
projectiletype = /obj/item/projectile/beam/laser/heavylaser
projectilesound = 'sound/weapons/lasercannonfire.ogg'
maxHealth = 50
health = 50
/mob/living/simple_animal/hostile/shark/kawaii
name = "Kawaii Shark"
desc = "Senpai~ Notice me.."
icon_state = "kawaiishark"
icon_living = "kawaiishark"
icon_dead = "kawaiishark_dead"
speak = list("Oh Senpai","Notice me senpai!","Oh my...","Kawaii~")
speak_emote = list("lovingly says","says")
speak_chance = 2
turns_per_move = 3
butcher_results = list(/mob/living/simple_animal/butterfly = 3)
maxHealth = 50
health = 50
maxbodytemp = INFINITY
harm_intent_damage = 0
melee_damage_lower = 0
melee_damage_upper = 0
attacktext = "violently hugs"
vision_range = 0
/mob/living/simple_animal/hostile/shark/kawaii/death()
say("Senpai, you noticed~!")
LoseAggro()
..()
walk(src, 0)
+422
View File
@@ -0,0 +1,422 @@
#define POOL_NO_OVERDOSE_MEDICINE_MAX 5 //max units of no-overdose medicine to allow mobs to have through duplication
//Originally stolen from paradise. Credits to tigercat2000.
//Modified a lot by Kokojo and Tortellini Tony for hippiestation.
//Heavily refactored by tgstation
/obj/machinery/pool
icon = 'icons/obj/machines/pool.dmi'
anchored = TRUE
resistance_flags = INDESTRUCTIBLE
/obj/machinery/pool/controller
name = "\improper Pool Controller"
desc = "An advanced substance generation and fluid tank management system that can refill the contents of a pool to a completely different substance in minutes."
icon_state = "poolc_3"
density = TRUE
use_power = TRUE
idle_power_usage = 75
/// How far it scans for pool objects
var/scan_range = 6
/// Is pool mist currently on?
var/mist_state = FALSE
/// Linked mist effects
var/list/obj/effect/mist/linked_mist = list()
/// Pool turfs
var/list/turf/open/pool/linked_turfs = list()
/// All mobs in pool
var/list/mob/living/mobs_in_pool = list()
/// Is the pool bloody?
var/bloody = 0
/// Last time we process_reagents()'d
var/last_reagent_process = 0
/// Maximum amount we will take from a beaker
var/max_beaker_transfer = 100
/// Minimum amount of a reagent for it to work on us
var/min_reagent_amount = 10
/// ADMINBUS ONLY - WHETHER OR NOT WE HAVE NOREACT ;)
var/noreact_reagents = FALSE
/// how fast in deciseconds between reagent processes
var/reagent_tick_interval = 5
/// Can we use unsafe temperatures
var/temperature_unlocked = FALSE
/// See __DEFINES/pool.dm, temperature defines
var/temperature = POOL_NORMAL
/// Whether or not the pool can be drained
var/drainable = FALSE
// Whether or not the pool is drained
var/drained = FALSE
/// Pool drain
var/obj/machinery/pool/drain/linked_drain
/// Pool filter
var/obj/machinery/pool/filter/linked_filter
/// Next world.time you can interact with settings
var/interact_delay = 0
/// Airlock style shocks
var/shocked = FALSE
/// Old reagent color, used to determine if update_color needs to reset colors.
var/old_rcolor
/// Just to prevent spam
var/draining = FALSE
/// Reagent blacklisting
var/respect_reagent_blacklist = TRUE
/obj/machinery/pool/controller/examine(mob/user)
. = ..()
. += "<span class='boldnotice'>Alt click to drain reagents.</span>"
/obj/machinery/pool/controller/Initialize()
. = ..()
START_PROCESSING(SSfastprocess, src)
create_reagents(1000)
if(noreact_reagents)
reagents.reagents_holder_flags |= NO_REACT
wires = new /datum/wires/poolcontroller(src)
scan_things()
/obj/machinery/pool/controller/Destroy()
STOP_PROCESSING(SSprocessing, src)
linked_drain = null
linked_filter = null
linked_turfs.Cut()
mobs_in_pool.Cut()
return ..()
/obj/machinery/pool/controller/proc/scan_things()
var/list/cached = range(scan_range, src)
for(var/turf/open/pool/W in cached)
linked_turfs += W
W.controller = src
for(var/obj/machinery/pool/drain/pooldrain in cached)
linked_drain = pooldrain
linked_drain.controller = src
break
for(var/obj/machinery/pool/filter/F in cached)
linked_filter = F
linked_filter.controller = src
break
/obj/machinery/pool/controller/emag_act(mob/user)
. = ..()
if(!(obj_flags & EMAGGED)) //If it is not already emagged, emag it.
to_chat(user, "<span class='warning'>You disable the [src]'s safety features.</span>")
do_sparks(5, TRUE, src)
obj_flags |= EMAGGED
temperature_unlocked = TRUE
drainable = TRUE
log_game("[key_name(user)] emagged [src]")
message_admins("[key_name_admin(user)] emagged [src]")
else
to_chat(user, "<span class='warning'>The interface on [src] is already too damaged to short it again.</span>")
return
/obj/machinery/pool/controller/AltClick(mob/user)
. = ..()
if(!isliving(user) || !user.Adjacent(src) || !user.CanReach(src) || user.IsStun() || user.IsKnockdown() || user.incapacitated())
return FALSE
visible_message("<span class='boldwarning'>[user] starts to drain [src]!</span>")
draining = TRUE
if(!do_after(user, 50, target = src))
draining = FALSE
return TRUE
reagents.remove_all(INFINITY)
visible_message("<span class='boldnotice'>[user] drains [src].</span>")
say("Reagents cleared.")
update_color()
draining = FALSE
return TRUE
/obj/machinery/pool/controller/attackby(obj/item/W, mob/user)
if(shocked && !(stat & NOPOWER))
shock(user,50)
if(stat & (BROKEN))
return
if(istype(W,/obj/item/reagent_containers))
if(W.reagents.total_volume) //check if there's reagent
user.visible_message("<span class='boldwarning'>[user] is feeding [src] some chemicals from [W].</span>")
if(do_after(user, 50, target = src))
for(var/datum/reagent/R in W.reagents.reagent_list)
if(R.type in GLOB.blacklisted_pool_reagents)
to_chat(user, "[src] cannot accept [R.name].")
return
if(R.reagent_state == SOLID)
to_chat(user, "The pool cannot accept reagents in solid form!.")
return
reagents.clear_reagents()
// This also reacts them. No nitroglycerin deathpools, sorry gamers :(
W.reagents.trans_to(reagents, max_beaker_transfer)
user.visible_message("<span class='notice'>[src] makes a slurping noise.</span>", "<span class='notice'>All of the contents of [W] are quickly suctioned out by the machine!</span")
updateUsrDialog()
var/list/reagent_names = list()
var/list/rejected = list()
for(var/datum/reagent/R in reagents.reagent_list)
if((R.volume >= min_reagent_amount) && (!respect_reagent_blacklist || R.can_synth))
reagent_names += R.name
else
reagents.remove_reagent(R.type, INFINITY)
rejected += R.name
if(length(reagent_names))
reagent_names = english_list(reagent_names)
var/msg = "POOL: [key_name(user)] has changed [src]'s chems to [reagent_names]"
log_game(msg)
message_admins(msg)
if(length(rejected))
rejected = english_list(rejected)
to_chat(user, "<span class='warning'>[src] rejects the following chemicals as they do not have at least [min_reagent_amount] units of volume: [rejected]</span>")
update_color()
else
to_chat(user, "<span class='notice'>[src] beeps unpleasantly as it rejects the beaker. Why are you trying to feed it an empty beaker?</span>")
return
else if(panel_open && is_wire_tool(W))
wires.interact(user)
else
return ..()
/obj/machinery/pool/controller/screwdriver_act(mob/living/user, obj/item/W)
. = ..()
if(.)
return TRUE
cut_overlays()
panel_open = !panel_open
to_chat(user, "You [panel_open ? "open" : "close"] the maintenance panel.")
W.play_tool_sound(src)
if(panel_open)
add_overlay("wires")
return TRUE
//procs
/obj/machinery/pool/controller/proc/shock(mob/user, prb)
if(stat & (BROKEN|NOPOWER)) // unpowered, no shock
return FALSE
if(!prob(prb))
return FALSE
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(5, 1, src)
s.start()
if(electrocute_mob(user, get_area(src), src, 0.7))
return TRUE
else
return FALSE
/obj/machinery/pool/controller/proc/process_reagents()
if(last_reagent_process > world.time + reagent_tick_interval)
return
if(!length(reagents.reagent_list))
return
for(var/turf/open/pool/W in linked_turfs)
for(var/mob/living/carbon/human/swimee in W)
for(var/datum/reagent/R in reagents.reagent_list)
if(R.reagent_state == SOLID)
R.reagent_state = LIQUID
if(!swimee.reagents.has_reagent(POOL_NO_OVERDOSE_MEDICINE_MAX))
swimee.reagents.add_reagent(R.type, 0.5) //osmosis
reagents.reaction(swimee, VAPOR, 0.03) //3 percent. Need to find a way to prevent this from stacking chems at some point like the above.
for(var/obj/objects in W)
if(W.reagents)
W.reagents.reaction(objects, VAPOR, 1)
last_reagent_process = world.time
/obj/machinery/pool/controller/process()
updateUsrDialog()
if(stat & (NOPOWER|BROKEN))
return
if(drained)
return
process_pool()
process_reagents()
/obj/machinery/pool/controller/proc/process_pool()
if(drained)
return
for(var/mob/living/M in mobs_in_pool)
switch(temperature) //Apply different effects based on what the temperature is set to.
if(POOL_SCALDING) //Scalding
M.adjust_bodytemperature(50,0,500)
if(POOL_WARM) //Warm
M.adjust_bodytemperature(20,0,360) //Heats up mobs till the termometer shows up
//Normal temp does nothing, because it's just room temperature water.
if(POOL_COOL)
M.adjust_bodytemperature(-20,250) //Cools mobs till the termometer shows up
if(POOL_FRIGID) //Freezing
M.adjust_bodytemperature(-60) //cool mob at -35k per cycle, less would not affect the mob enough.
if(M.bodytemperature <= 50 && !M.stat)
M.apply_status_effect(/datum/status_effect/freon)
if(ishuman(M))
var/mob/living/carbon/human/drownee = M
if(!drownee || drownee.stat == DEAD)
return
if(drownee.resting && !drownee.internal)
if(drownee.stat != CONSCIOUS)
drownee.adjustOxyLoss(9)
else
drownee.adjustOxyLoss(4)
if(prob(35))
to_chat(drownee, "<span class='danger'>You're drowning!</span>")
/obj/machinery/pool/controller/proc/set_bloody(state)
if(bloody == state)
return
bloody = state
update_color()
/obj/machinery/pool/controller/proc/update_color()
if(drained)
return
var/rcolor
if(reagents.reagent_list.len)
rcolor = mix_color_from_reagents(reagents.reagent_list)
if(rcolor == old_rcolor)
return // small performance upgrade hopefully?
old_rcolor = rcolor
for(var/X in linked_turfs)
var/turf/open/pool/color1 = X
if(bloody)
if(rcolor)
var/thecolor = BlendRGB(rgb(150, 20, 20), rcolor, 0.5)
color1.watereffect.add_atom_colour(thecolor, FIXED_COLOUR_PRIORITY)
color1.watertop.add_atom_colour(thecolor, FIXED_COLOUR_PRIORITY)
else
var/thecolor = rgb(150, 20, 20)
color1.watereffect.add_atom_colour(thecolor, FIXED_COLOUR_PRIORITY)
color1.watertop.add_atom_colour(thecolor, FIXED_COLOUR_PRIORITY)
else if(!bloody && rcolor)
color1.watereffect.add_atom_colour(rcolor, FIXED_COLOUR_PRIORITY)
color1.watertop.add_atom_colour(rcolor, FIXED_COLOUR_PRIORITY)
else
color1.watereffect.remove_atom_colour(FIXED_COLOUR_PRIORITY)
color1.watertop.remove_atom_colour(FIXED_COLOUR_PRIORITY)
/obj/machinery/pool/controller/proc/update_temp()
if(mist_state)
if(temperature < POOL_SCALDING)
mist_off()
else
if(temperature == POOL_SCALDING)
mist_on()
update_icon()
/obj/machinery/pool/controller/update_icon()
. = ..()
icon_state = "poolc_[temperature]"
/obj/machinery/pool/controller/proc/CanUpTemp(mob/user)
if(temperature == POOL_WARM && (temperature_unlocked || issilicon(user) || IsAdminGhost(user)) || temperature < POOL_WARM)
return TRUE
return FALSE
/obj/machinery/pool/controller/proc/CanDownTemp(mob/user)
if(temperature == POOL_COOL && (temperature_unlocked || issilicon(user) || IsAdminGhost(user)) || temperature > POOL_COOL)
return TRUE
return FALSE
/obj/machinery/pool/controller/Topic(href, href_list)
if(..())
return
if(interact_delay > world.time)
return
if(href_list["IncreaseTemp"])
if(CanUpTemp(usr))
visible_message("<span class='warning'>[usr] presses a button on [src].</span>")
temperature++
update_temp()
var/msg = "POOL: [key_name(usr)] increased [src]'s pool temperature at [COORD(src)] to [temperature]"
log_game(msg)
message_admins(msg)
interact_delay = world.time + 15
if(href_list["DecreaseTemp"])
if(CanDownTemp(usr))
visible_message("<span class='warning'>[usr] presses a button on [src].</span>")
temperature--
update_temp()
var/msg = "POOL: [key_name(usr)] decreased [src]'s pool temperature at [COORD(src)] to [temperature]"
log_game(msg)
message_admins(msg)
interact_delay = world.time + 15
if(href_list["Activate Drain"])
if((drainable || issilicon(usr) || IsAdminGhost(usr)) && !linked_drain.active)
var/msg = "POOL: [key_name(usr)] activated [src]'s pool drain in [linked_drain.filling? "FILLING" : "DRAINING"] mode at [COORD(src)]"
log_game(msg)
message_admins(msg)
visible_message("<span class='warning'>[usr] presses a button on [src].</span>")
mist_off()
interact_delay = world.time + 60
linked_drain.active = TRUE
linked_drain.cycles_left = 75
if(!linked_drain.filling)
new /obj/effect/whirlpool(linked_drain.loc)
temperature = POOL_NORMAL
else
new /obj/effect/waterspout(linked_drain.loc)
temperature = POOL_NORMAL
update_temp()
bloody = FALSE
updateUsrDialog()
/obj/machinery/pool/controller/proc/temp2text()
switch(temperature)
if(POOL_FRIGID)
return "<span class='boldwarning'>Frigid</span>"
if(POOL_COOL)
return "<span class='boldnotice'>Cool</span>"
if(POOL_NORMAL)
return "<span class='notice'>Normal</span>"
if(POOL_WARM)
return "<span class='boldnotice'>Warm</span>"
if(POOL_SCALDING)
return "<span class='boldwarning'>Scalding</span>"
else
return "Outside of possible range."
/obj/machinery/pool/controller/ui_interact(mob/user)
. = ..()
if(.)
return
if(shocked && !(stat & NOPOWER))
shock(user,50)
if(panel_open && !isAI(user))
return wires.interact(user)
if(stat & (NOPOWER|BROKEN))
return
var/datum/browser/popup = new(user, "Pool Controller", name, 300, 450)
var/dat = ""
if(interact_delay > world.time)
dat += "<span class='notice'>[round((interact_delay - world.time)/10, 0.1)] seconds left until [src] can operate again.</span><BR>"
dat += text({"
<h3>Temperature</h3>
<div class='statusDisplay'>
<B>Current temperature:</B> [temp2text()]<BR>
[CanUpTemp(user) ? "<a href='?src=\ref[src];IncreaseTemp=1'>Increase Temperature</a><br>" : "<span class='linkOff'>Increase Temperature</span><br>"]
[CanDownTemp(user) ? "<a href='?src=\ref[src];DecreaseTemp=1'>Decrease Temperature</a><br>" : "<span class='linkOff'>Decrease Temperature</span><br>"]
</div>
<h3>Drain</h3>
<div class='statusDisplay'>
<B>Drain status:</B> [(issilicon(user) || IsAdminGhost(user) || drainable) ? "<span class='bad'>Enabled</span>" : "<span class='good'>Disabled</span>"]
<br><b>Pool status:</b> "})
if(!drained)
dat += "<span class='good'>Full</span><BR>"
else
dat += "<span class='bad'>Drained</span><BR>"
if((issilicon(user) || IsAdminGhost(user) || drainable) && !linked_drain.active)
dat += "<a href='?src=\ref[src];Activate Drain=1'>[drained ? "Fill" : "Drain"] Pool</a><br>"
popup.set_content(dat)
popup.open()
/obj/machinery/pool/controller/proc/reset(wire)
switch(wire)
if(WIRE_SHOCK)
if(!wires.is_cut(wire))
shocked = FALSE
/obj/machinery/pool/controller/proc/mist_on() //Spawn /obj/effect/mist (from the shower) on all linked pool tiles
if(mist_state)
return
mist_state = TRUE
for(var/X in linked_turfs)
var/turf/open/pool/W = X
if(W.filled)
var/M = new /obj/effect/mist(W)
linked_mist += M
/obj/machinery/pool/controller/proc/mist_off() //Delete all /obj/effect/mist from all linked pool tiles.
for(var/M in linked_mist)
qdel(M)
mist_state = FALSE
+160
View File
@@ -0,0 +1,160 @@
/obj/machinery/pool/drain
name = "drain"
icon_state = "drain"
desc = "A suction system to remove the contents of the pool, and sometimes small objects. Do not insert fingers."
anchored = TRUE
/// Active/on?
var/active = FALSE
/// Filling or draining
var/filling = FALSE
/// Drain item suction range
var/item_suction_range = 2
/// Fill mode knock away range
var/fill_push_range = 6
/// Drain mode suction range
var/drain_suck_range = 6
/// Parent controller
var/obj/machinery/pool/controller/controller
/// Cycles left for fill/drain while active
var/cycles_left = 0
/// Mobs we are swirling around
var/list/whirling_mobs
/// Suck in once per x ticks
var/suck_in_once_per = 3
var/cooldown
/obj/machinery/pool/drain/Initialize()
START_PROCESSING(SSfastprocess, src)
whirling_mobs = list()
return ..()
/obj/machinery/pool/drain/Destroy()
STOP_PROCESSING(SSfastprocess, src)
controller.linked_drain = null
controller = null
whirling_mobs = null
return ..()
/obj/machinery/pool/drain/proc/is_in_our_pool(atom/A)
. = FALSE
if(istype(A.loc, /turf/open/pool))
var/turf/open/pool/P = A.loc
if(P.controller == controller)
. = TRUE
// This should probably start using move force sometime in the future but I'm lazy.
/obj/machinery/pool/drain/process()
if(!filling)
for(var/obj/item/I in range(min(item_suction_range, 10), src))
if(!I.anchored && (I.w_class <= WEIGHT_CLASS_SMALL))
step_towards(I, src)
if((I.w_class <= WEIGHT_CLASS_TINY) && (get_dist(I, src) == 0))
I.forceMove(controller.linked_filter)
if(active)
if(filling)
if(cycles_left-- > 0)
playsound(src, 'sound/effects/fillingwatter.ogg', 100, TRUE)
for(var/obj/O in orange(min(fill_push_range, 10), src))
if(!O.anchored && is_in_our_pool(O))
step_away(O, src)
for(var/mob/M in orange(min(fill_push_range, 10), src)) //compiler fastpath apparently?
if(!M.anchored && isliving(M) && is_in_our_pool(M))
step_away(M, src)
else
for(var/turf/open/pool/P in controller.linked_turfs)
P.filled = TRUE
P.update_icon()
for(var/obj/effect/waterspout/S in range(1, src))
qdel(S)
controller.drained = FALSE
if(controller.bloody < 1000)
controller.bloody /= 2
else
controller.bloody /= 4
controller.update_color()
filling = FALSE
active = FALSE
else
if(cycles_left-- > 0)
playsound(src, 'sound/effects/pooldrain.ogg', 100, TRUE)
playsound(src, "water_wade", 60, TRUE)
for(var/obj/O in orange(min(drain_suck_range, 10), src))
if(!O.anchored && is_in_our_pool(O))
step_towards(O, src)
for(var/mob/M in orange(min(drain_suck_range, 10), src))
if(isliving(M) && !M.anchored && is_in_our_pool(M))
if(!(cycles_left % suck_in_once_per))
step_towards(M, src)
whirl_mob(M)
if(ishuman(M) && (get_dist(M, src) <= 1))
var/mob/living/carbon/human/H = M
playsound(src, pick('sound/misc/crack.ogg','sound/misc/crunch.ogg'), 50, TRUE)
if(H.lying) //down for any reason
H.adjustBruteLoss(2)
to_chat(H, "<span class='danger'>You're caught in the drain!</span>")
else
H.apply_damage(2.5, BRUTE, pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)) //drain should only target the legs
to_chat(H, "<span class='danger'>Your legs are caught in the drain!</span>")
else
for(var/turf/open/pool/P in controller.linked_turfs)
P.filled = FALSE
P.update_icon()
for(var/obj/effect/whirlpool/W in range(1, src))
qdel(W)
controller.drained = TRUE
controller.mist_off()
active = FALSE
filling = TRUE
/// dangerous proc don't fuck with, admins
/obj/machinery/pool/drain/proc/whirl_mob(mob/living/L, duration = 8, delay = 1)
set waitfor = FALSE
if(whirling_mobs[L])
return
whirling_mobs[L] = TRUE
for(var/i in 1 to min(duration, 100))
L.setDir(turn(L.dir, 90))
sleep(delay)
if(QDELETED(L))
break
if(QDELETED(src))
return
whirling_mobs -= L
/obj/machinery/pool/filter
name = "Filter"
icon_state = "filter"
desc = "The part of the pool where all the IDs, ATV keys, and pens, and other dangerous things get trapped."
var/obj/machinery/pool/controller/controller
/obj/machinery/pool/filter/Destroy()
controller.linked_filter = null
controller = null
return ..()
/obj/machinery/pool/filter/emag_act(mob/living/user)
. = ..()
if(!(obj_flags & EMAGGED))
to_chat(user, "<span class='warning'>You disable the [src]'s shark filter! Run!</span>")
obj_flags |= EMAGGED
do_sparks(5, TRUE, src)
icon_state = "filter_b"
addtimer(CALLBACK(src, /obj/machinery/pool/filter/proc/spawn_shark), 50)
var/msg = "[key_name(user)] emagged the pool filter and spawned a shark"
log_game(msg)
message_admins(msg)
/obj/machinery/pool/filter/proc/spawn_shark()
if(prob(50))
new /mob/living/simple_animal/hostile/shark(loc)
else
if(prob(50))
new /mob/living/simple_animal/hostile/shark/kawaii(loc)
else
new /mob/living/simple_animal/hostile/shark/laser(loc)
/obj/machinery/pool/filter/attack_hand(mob/user)
to_chat(user, "You search the filter.")
for(var/obj/O in contents)
O.forceMove(loc)
+29
View File
@@ -0,0 +1,29 @@
/obj/effect/splash
name = "splash"
desc = "Wataaa!."
icon = 'icons/turf/pool.dmi'
icon_state = "splash"
layer = ABOVE_ALL_MOB_LAYER
/obj/effect/whirlpool
name = "Whirlpool"
icon = 'icons/effects/96x96.dmi'
icon_state = "whirlpool"
layer = 5
anchored = TRUE
mouse_opacity = 0
pixel_x = -32
pixel_y = -32
alpha = 90
/obj/effect/waterspout
name = "Waterspout"
icon = 'icons/effects/96x96.dmi'
icon_state = "waterspout"
color = "#3399AA"
layer = 5
anchored = TRUE
mouse_opacity = 0
pixel_x = -32
pixel_y = -32
alpha = 120
+191
View File
@@ -0,0 +1,191 @@
/turf/open/pool
icon = 'icons/turf/pool.dmi'
name = "poolwater"
desc = "You're safer here than in the deep."
icon_state = "pool_tile"
heat_capacity = INFINITY
var/filled = TRUE
var/next_splash = 0
var/obj/machinery/pool/controller/controller
var/obj/effect/overlay/water/watereffect
var/obj/effect/overlay/water/top/watertop
/turf/open/pool/Initialize(mapload)
. = ..()
update_icon()
/turf/open/pool/Destroy()
if(controller)
controller.linked_turfs -= src
controller = null
QDEL_NULL(watereffect)
QDEL_NULL(watertop)
return ..()
/turf/open/pool/update_icon()
. = ..()
if(!filled)
name = "drained pool"
desc = "No diving!"
QDEL_NULL(watereffect)
QDEL_NULL(watertop)
else
name = "poolwater"
desc = "You're safer here than in the deep."
watereffect = new /obj/effect/overlay/water(src)
watertop = new /obj/effect/overlay/water/top(src)
/obj/effect/overlay/water
name = "water"
icon = 'icons/turf/pool.dmi'
icon_state = "bottom"
density = FALSE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
layer = ABOVE_MOB_LAYER
anchored = TRUE
resistance_flags = INDESTRUCTIBLE
/obj/effect/overlay/water/top
icon_state = "top"
layer = BELOW_MOB_LAYER
// Mousedrop hook to normal turfs to get out of pools.
/turf/open/MouseDrop_T(atom/from, mob/user)
// I could make this /open/floor and not have the !istype but ehh - kev
if(isliving(from) && HAS_TRAIT(from, TRAIT_SWIMMING) && isliving(user) && ((user == from) || user.CanReach(from)) && !user.IsStun() && !user.IsKnockdown() && !user.incapacitated() && !istype(src, /turf/open/pool))
var/mob/living/L = from
//The element only exists if you're on water and a living mob, so let's skip those checks.
var/pre_msg
var/post_msg
if(user == from)
pre_msg = "<span class='notice'>[L] is getting out of the pool.</span>"
post_msg = "<span class='notice'>[L] gets out of the pool.</span>"
else
pre_msg = "<span class='notice'>[L] is being pulled out of the pool by [user].</span>"
post_msg = "<span class='notice'>[user] pulls [L] out of the pool.</span>"
L.visible_message(pre_msg)
if(do_mob(user, L, 20))
L.visible_message(post_msg)
L.forceMove(src)
else
return ..()
// Exit check
/turf/open/pool/Exit(atom/movable/AM, atom/newloc)
if(!AM.has_gravity(src))
return ..()
if(isliving(AM) || isstructure(AM))
if(AM.throwing)
return ..() //WHEEEEEEEEEEE
if(istype(AM, /obj/structure) && isliving(AM.pulledby))
return ..() //people pulling stuff out of pool
if(!ishuman(AM))
return ..() //human weak, monkey (and anyone else) ook ook eek eek strong
if(isliving(AM) && (locate(/obj/structure/pool/ladder) in src))
return ..() //climbing out
return istype(newloc, /turf/open/pool)
return ..()
// Exited logic
/turf/open/pool/Exited(atom/A, atom/newLoc)
. = ..()
if(isliving(A))
var/turf/open/pool/P = newLoc
if(!istype(P) || (P.controller != controller))
controller?.mobs_in_pool -= A
// Entered logic
/turf/open/pool/Entered(atom/movable/AM, atom/oldloc)
if(istype(AM, /obj/effect/decal/cleanable))
var/obj/effect/decal/cleanable/C = AM
if(prob(C.bloodiness))
controller.set_bloody(TRUE)
QDEL_IN(AM, 25)
animate(AM, alpha = 10, time = 20)
return ..()
if(!AM.has_gravity(src))
return ..()
if(isliving(AM))
var/mob/living/victim = AM
if(!HAS_TRAIT(victim, TRAIT_SWIMMING)) //poor guy not swimming time to dunk them!
victim.AddElement(/datum/element/swimming)
controller.mobs_in_pool += victim
if(locate(/obj/structure/pool/ladder) in src) //safe climbing
return
if(iscarbon(AM)) //FUN TIME!
var/mob/living/carbon/H = victim
if(filled)
if (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSMOUTH)
H.visible_message("<span class='danger'>[H] falls in the water!</span>",
"<span class='userdanger'>You fall in the water!</span>")
playsound(src, 'sound/effects/splash.ogg', 60, TRUE, 1)
H.Knockdown(20)
return
else
H.Knockdown(60)
H.adjustOxyLoss(5)
H.emote("cough")
H.visible_message("<span class='danger'>[H] falls in and takes a drink!</span>",
"<span class='userdanger'>You fall in and swallow some water!</span>")
playsound(src, 'sound/effects/splash.ogg', 60, TRUE, 1)
else if(!H.head || !(H.head.armor.getRating("melee") > 20))
if(prob(75))
H.visible_message("<span class='danger'>[H] falls in the drained pool!</span>",
"<span class='userdanger'>You fall in the drained pool!</span>")
H.adjustBruteLoss(7)
H.Knockdown(80)
playsound(src, 'sound/effects/woodhit.ogg', 60, TRUE, 1)
else
H.visible_message("<span class='danger'>[H] falls in the drained pool, and cracks his skull!</span>",
"<span class='userdanger'>You fall in the drained pool, and crack your skull!</span>")
H.apply_damage(15, BRUTE, "head")
H.Knockdown(200) // This should hurt. And it does.
playsound(src, 'sound/effects/woodhit.ogg', 60, TRUE, 1)
playsound(src, 'sound/misc/crack.ogg', 100, TRUE)
else
H.visible_message("<span class='danger'>[H] falls in the drained pool, but had an helmet!</span>",
"<span class='userdanger'>You fall in the drained pool, but you had an helmet!</span>")
H.Knockdown(40)
playsound(src, 'sound/effects/woodhit.ogg', 60, TRUE, 1)
else if(filled)
victim.adjustStaminaLoss(1)
playsound(src, "water_wade", 20, TRUE)
return ..()
/turf/open/pool/MouseDrop_T(atom/from, mob/user)
. = ..()
if(!isliving(from))
return
var/mob/living/victim = from
if(user.stat || user.lying || !Adjacent(user) || !from.Adjacent(user) || !iscarbon(user) || !victim.has_gravity(src) || HAS_TRAIT(victim, TRAIT_SWIMMING))
return
var/victimname = victim == user? "themselves" : "[victim]"
var/starttext = victim == user? "[user] is descending into [src]." : "[user] is lowering [victim] into [src]."
user.visible_message("<span class='notice'>[starttext]</span>")
if(do_mob(user, victim, 20))
user.visible_message("<span class='notice'>[user] lowers [victimname] into [src].</span>")
victim.AddElement(/datum/element/swimming) //make sure they have it so they don't fall/whatever
victim.forceMove(src)
/turf/open/pool/attackby(obj/item/W, mob/living/user)
if(istype(W, /obj/item/mop) && filled)
W.reagents.add_reagent("water", 5)
to_chat(user, "<span class='notice'>You wet [W] in [src].</span>")
playsound(loc, 'sound/effects/slosh.ogg', 25, TRUE)
else
return ..()
/turf/open/pool/attack_hand(mob/living/user)
. = ..()
if(.)
return
if((user.loc != src) && !user.IsStun() && !user.IsKnockdown() && !user.incapacitated() && Adjacent(user) && HAS_TRAIT(user, TRAIT_SWIMMING) && filled && (next_splash < world.time))
playsound(src, 'sound/effects/watersplash.ogg', 8, TRUE, 1)
next_splash = world.time + 25
var/obj/effect/splash/S = new(src)
animate(S, alpha = 0, time = 8)
QDEL_IN(S, 10)
for(var/mob/living/carbon/human/H in src)
if(!H.wear_mask && (H.stat == CONSCIOUS))
H.emote("cough")
H.adjustStaminaLoss(4)
+32
View File
@@ -0,0 +1,32 @@
//Pool noodles
/obj/item/toy/poolnoodle
icon = 'icons/obj/toy.dmi'
icon_state = "noodle"
name = "pool noodle"
desc = "A strange, bulky, bendable toy that can annoy people."
force = 0
color = "#000000"
w_class = WEIGHT_CLASS_SMALL
throwforce = 1
throw_speed = 10 //weeee
hitsound = 'sound/weapons/tap.ogg'
attack_verb = list("flogged", "poked", "jabbed", "slapped", "annoyed")
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
/obj/item/toy/poolnoodle/attack(target as mob, mob/living/user as mob)
. = ..()
user.spin(prob(20)? 16 : 8, 1)
/obj/item/toy/poolnoodle/red
item_state = "noodlered"
color = "#ff4c4c"
/obj/item/toy/poolnoodle/blue
item_state = "noodleblue"
color = "#3232ff"
/obj/item/toy/poolnoodle/yellow
item_state = "noodleyellow"
color = "#ffff66"
+159
View File
@@ -0,0 +1,159 @@
/obj/structure/pool
name = "pool"
icon = 'icons/obj/machines/pool.dmi'
anchored = TRUE
resistance_flags = UNACIDABLE|INDESTRUCTIBLE
/obj/structure/pool/ladder
name = "Ladder"
icon_state = "ladder"
desc = "Are you getting in or are you getting out?."
layer = ABOVE_MOB_LAYER
dir = EAST
/obj/structure/pool/ladder/attack_hand(mob/living/user)
. = ..()
if(.)
return
if(!HAS_TRAIT(user, TRAIT_SWIMMING))
if(user.CanReach(src))
user.AddElement(/datum/element/swimming)
user.forceMove(get_step(src, dir))
else
if(user.loc == loc)
user.forceMove(get_step(src, turn(dir, 180))) //If this moves them out the element cleans up after itself.
/obj/structure/pool/Rboard
name = "JumpBoard"
density = FALSE
icon_state = "boardright"
desc = "The less-loved portion of the jumping board."
dir = EAST
/obj/structure/pool/Lboard
name = "JumpBoard"
icon_state = "boardleft"
desc = "Get on there to jump!"
layer = FLY_LAYER
dir = WEST
var/jumping = FALSE
var/timer
/obj/structure/pool/Lboard/proc/backswim()
if(jumping)
for(var/mob/living/jumpee in loc) //hackzors.
playsound(jumpee, 'sound/effects/splash.ogg', 60, TRUE, 1)
if(!HAS_TRAIT(jumpee, TRAIT_SWIMMING))
jumpee.AddElement(/datum/element/swimming)
jumpee.Stun(2)
/obj/structure/pool/Lboard/proc/reset_position(mob/user, initial_layer, initial_px, initial_py)
user.layer = initial_layer
user.pixel_x = initial_px
user.pixel_y = initial_py
/obj/structure/pool/Lboard/attack_hand(mob/living/user)
if(iscarbon(user))
var/mob/living/carbon/jumper = user
if(jumping)
to_chat(user, "<span class='notice'>Someone else is already making a jump!</span>")
return
var/turf/T = get_turf(src)
if(HAS_TRAIT(user, TRAIT_SWIMMING))
return
else
if(Adjacent(jumper))
jumper.visible_message("<span class='notice'>[user] climbs up \the [src]!</span>", \
"<span class='notice'>You climb up \the [src] and prepares to jump!</span>")
jumper.Stun(40)
jumping = TRUE
var/original_layer = jumper.layer
var/original_px = jumper.pixel_x
var/original_py = jumper.pixel_y
jumper.layer = RIPPLE_LAYER
jumper.pixel_x = 3
jumper.pixel_y = 7
jumper.dir = WEST
jumper.AddElement(/datum/element/swimming)
sleep(1)
jumper.forceMove(T)
addtimer(CALLBACK(src, .proc/dive, jumper, original_layer, original_px, original_py), 10)
/obj/structure/pool/Lboard/proc/dive(mob/living/carbon/jumper, original_layer, original_px, original_py)
switch(rand(1, 100))
if(1 to 20)
jumper.visible_message("<span class='notice'>[jumper] goes for a small dive!</span>", \
"<span class='notice'>You go for a small dive.</span>")
sleep(15)
backswim()
var/atom/throw_target = get_edge_target_turf(src, dir)
jumper.throw_at(throw_target, 1, 1, callback = CALLBACK(src, .proc/on_finish_jump, jumper))
if(21 to 40)
jumper.visible_message("<span class='notice'>[jumper] goes for a dive!</span>", \
"<span class='notice'>You're going for a dive!</span>")
sleep(20)
backswim()
var/atom/throw_target = get_edge_target_turf(src, dir)
jumper.throw_at(throw_target, 2, 1, callback = CALLBACK(src, .proc/on_finish_jump, jumper))
if(41 to 60)
jumper.visible_message("<span class='notice'>[jumper] goes for a long dive! Stay far away!</span>", \
"<span class='notice'>You're going for a long dive!!</span>")
sleep(25)
backswim()
var/atom/throw_target = get_edge_target_turf(src, dir)
jumper.throw_at(throw_target, 3, 1, callback = CALLBACK(src, .proc/on_finish_jump, jumper))
if(61 to 80)
jumper.visible_message("<span class='notice'>[jumper] goes for an awesome dive! Don't stand in [jumper.p_their()] way!</span>", \
"<span class='notice'>You feel like this dive will be awesome</span>")
sleep(30)
backswim()
var/atom/throw_target = get_edge_target_turf(src, dir)
jumper.throw_at(throw_target, 4, 1, callback = CALLBACK(src, .proc/on_finish_jump, jumper))
if(81 to 91)
sleep(20)
backswim()
jumper.visible_message("<span class='danger'>[jumper] misses [jumper.p_their()] step!</span>", \
"<span class='userdanger'>You misstep!</span>")
var/atom/throw_target = get_edge_target_turf(src, dir)
jumper.throw_at(throw_target, 0, 1, callback = CALLBACK(src, .proc/on_finish_jump, jumper))
jumper.Knockdown(100)
jumper.adjustBruteLoss(10)
if(91 to 100)
jumper.visible_message("<span class='notice'>[jumper] is preparing for the legendary dive! Can [jumper.p_they()] make it?</span>", \
"<span class='userdanger'>You start preparing for a legendary dive!</span>")
jumper.SpinAnimation(7,1)
sleep(30)
if(prob(75))
backswim()
jumper.visible_message("<span class='notice'>[jumper] fails!</span>", \
"<span class='userdanger'>You can't quite do it!</span>")
var/atom/throw_target = get_edge_target_turf(src, dir)
jumper.throw_at(throw_target, 1, 1, callback = CALLBACK(src, .proc/on_finish_jump, jumper))
else
jumper.fire_stacks = min(1,jumper.fire_stacks + 1)
jumper.IgniteMob()
sleep(5)
backswim()
jumper.visible_message("<span class='danger'>[jumper] bursts into flames of pure awesomness!</span>", \
"<span class='userdanger'>No one can stop you now!</span>")
var/atom/throw_target = get_edge_target_turf(src, dir)
jumper.throw_at(throw_target, 6, 1, callback = CALLBACK(src, .proc/on_finish_jump, jumper))
addtimer(CALLBACK(src, .proc/togglejumping), 35)
reset_position(jumper, original_layer, original_px, original_py)
/obj/structure/pool/Lboard/proc/togglejumping()
jumping = FALSE
/obj/structure/pool/Lboard/proc/on_finish_jump(mob/living/victim)
if(istype(victim.loc, /turf/open/pool))
var/turf/open/pool/P = victim.loc
if(!P.filled) //you dun fucked up now
to_chat(victim, "<span class='warning'>That was stupid of you..</span>")
victim.visible_message("<span class='danger'>[victim] smashes into the ground!</span>")
victim.apply_damage(50)
victim.Knockdown(200)
+59
View File
@@ -0,0 +1,59 @@
#define POOL_WIRE_DRAIN "drain"
#define POOL_WIRE_TEMP "temp"
/datum/wires/poolcontroller
holder_type = /obj/machinery/pool/controller
proper_name = "Pool"
/datum/wires/poolcontroller/New(atom/holder)
wires = list(
POOL_WIRE_DRAIN, WIRE_SHOCK, WIRE_ZAP, POOL_WIRE_TEMP
)
add_duds(3)
..()
/datum/wires/poolcontroller/interactable(mob/user)
var/obj/machinery/pool/controller/P = holder
if(P.panel_open)
return TRUE
/datum/wires/poolcontroller/get_status()
var/obj/machinery/pool/controller/P = holder
var/list/status = list()
status += "The blue light is [P.drainable ? "on" : "off"]."
status += "The red light is [P.temperature_unlocked ? "on" : "off"]."
status += "The yellow light is [P.shocked ? "on" : "off"]."
return status
/datum/wires/poolcontroller/on_pulse(wire)
var/obj/machinery/pool/controller/P = holder
switch(wire)
if(POOL_WIRE_DRAIN)
P.drainable = FALSE
if(POOL_WIRE_TEMP)
P.temperature_unlocked = FALSE
if(WIRE_SHOCK)
P.shocked = !P.shocked
addtimer(CALLBACK(P, /obj/machinery/autolathe.proc/reset, wire), 60)
/datum/wires/poolcontroller/on_cut(wire, mend)
var/obj/machinery/pool/controller/P = holder
switch(wire)
if(POOL_WIRE_DRAIN)
if(mend)
P.drainable = FALSE
else
P.drainable = TRUE
if(POOL_WIRE_TEMP)
if(mend)
P.temperature_unlocked = FALSE
else
P.temperature_unlocked = TRUE
if(WIRE_ZAP)
P.shock(usr, 50)
if(WIRE_SHOCK)
if(mend)
P.stat &= ~NOPOWER
else
P.stat |= NOPOWER
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Executable → Regular
+11
View File
@@ -1,3 +1,4 @@
// DM Environment file for tgstation.dme.
// All manual changes should be made outside the BEGIN_ and END_ blocks.
// New source code should be placed in .dm files: choose File/New --> Code File.
@@ -77,6 +78,7 @@
#include "code\__DEFINES\obj_flags.dm"
#include "code\__DEFINES\pinpointers.dm"
#include "code\__DEFINES\pipe_construction.dm"
#include "code\__DEFINES\pool.dm"
#include "code\__DEFINES\preferences.dm"
#include "code\__DEFINES\procpath.dm"
#include "code\__DEFINES\profile.dm"
@@ -491,6 +493,7 @@
#include "code\datums\elements\earhealing.dm"
#include "code\datums\elements\ghost_role_eligibility.dm"
#include "code\datums\elements\mob_holder.dm"
#include "code\datums\elements\swimming.dm"
#include "code\datums\elements\wuv.dm"
#include "code\datums\helper_datums\events.dm"
#include "code\datums\helper_datums\getrev.dm"
@@ -2371,6 +2374,7 @@
#include "code\modules\mob\living\simple_animal\hostile\netherworld.dm"
#include "code\modules\mob\living\simple_animal\hostile\pirate.dm"
#include "code\modules\mob\living\simple_animal\hostile\russian.dm"
#include "code\modules\mob\living\simple_animal\hostile\sharks.dm"
#include "code\modules\mob\living\simple_animal\hostile\skeleton.dm"
#include "code\modules\mob\living\simple_animal\hostile\statue.dm"
#include "code\modules\mob\living\simple_animal\hostile\stickman.dm"
@@ -2527,6 +2531,13 @@
#include "code\modules\photography\photos\album.dm"
#include "code\modules\photography\photos\frame.dm"
#include "code\modules\photography\photos\photo.dm"
#include "code\modules\pool\pool_controller.dm"
#include "code\modules\pool\pool_drain.dm"
#include "code\modules\pool\pool_effects.dm"
#include "code\modules\pool\pool_main.dm"
#include "code\modules\pool\pool_noodles.dm"
#include "code\modules\pool\pool_structures.dm"
#include "code\modules\pool\pool_wires.dm"
#include "code\modules\power\apc.dm"
#include "code\modules\power\cable.dm"
#include "code\modules\power\cell.dm"