Merge branch 'master' into upstream-merge-27344

This commit is contained in:
Poojawa
2017-05-20 23:26:28 -05:00
committed by GitHub
95 changed files with 3681 additions and 1609 deletions
File diff suppressed because it is too large Load Diff
@@ -63624,6 +63624,7 @@
dir = 8
},
/obj/effect/turf_decal/bot,
/obj/machinery/portable_atmospherics/canister/freon,
/turf/open/floor/plasteel,
/area/engine/engineering)
"cqt" = (
+9
View File
@@ -0,0 +1,9 @@
//rune colors, for easy reference
#define RUNE_COLOR_TALISMAN "#0000FF"
#define RUNE_COLOR_TELEPORT "#551A8B"
#define RUNE_COLOR_OFFER "#FFFFFF"
#define RUNE_COLOR_DARKRED "#7D1717"
#define RUNE_COLOR_MEDIUMRED "#C80000"
#define RUNE_COLOR_RED "#FF0000"
#define RUNE_COLOR_EMP "#4D94FF"
#define RUNE_COLOR_SUMMON "#00FF00"
+1
View File
@@ -27,6 +27,7 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define BLOCK_GAS_SMOKE_EFFECT 4096 // blocks the effect that chemical clouds would have on a mob --glasses, mask and helmets ONLY!
#define THICKMATERIAL 8192 //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 DROPDEL 16384 // When dropped, it calls qdel on itself
#define PREVENT_CLICK_UNDER 32768 //Prevent clicking things below it on the same turf eg. doors/ fulltile windows
/* Secondary atom flags, access using the SECONDARY_FLAG macros */
+4
View File
@@ -407,3 +407,7 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
//Error handler defines
#define ERROR_USEFUL_LEN 2
#define NO_FIELD 0
#define FIELD_TURF 1
#define FIELD_EDGE 2
+14
View File
@@ -340,6 +340,20 @@ Proc for attack log creation, because really why not
qdel(progbar)
//some additional checks as a callback for for do_afters that want to break on losing health or on the mob taking action
/mob/proc/break_do_after_checks(list/checked_health, check_clicks)
if(check_clicks && next_move > world.time)
return FALSE
return TRUE
//pass a list in the format list("health" = mob's health var) to check health during this
/mob/living/break_do_after_checks(list/checked_health, check_clicks)
if(islist(checked_health))
if(health < checked_health["health"])
return FALSE
checked_health["health"] = health
return ..()
/proc/do_after(mob/user, delay, needhand = 1, atom/target = null, progress = 1, datum/callback/extra_checks = null)
if(!user)
return 0
+2 -1
View File
@@ -13,4 +13,5 @@ GLOBAL_VAR_INIT(sac_image, null)
GLOBAL_VAR_INIT(cult_vote_called, FALSE)
GLOBAL_VAR_INIT(cult_mastered, FALSE)
GLOBAL_VAR_INIT(reckoning_complete, FALSE)
GLOBAL_VAR_INIT(sac_complete, FALSE)
GLOBAL_VAR_INIT(sac_complete, FALSE)
GLOBAL_DATUM(cult_narsie, /obj/singularity/narsie/large/cult)
+21
View File
@@ -92,6 +92,9 @@
if(next_move > world.time) // in the year 2000...
return
if(A.IsObscured())
return
if(istype(loc,/obj/mecha))
var/obj/mecha/M = loc
return M.click_action(A,src,params)
@@ -141,6 +144,24 @@
else
RangedAttack(A,params)
//Is the atom obscured by a PREVENT_CLICK_UNDER object above it
/atom/proc/IsObscured()
if(!isturf(loc)) //This only makes sense for things directly on turfs for now
return FALSE
var/turf/T = get_turf_pixel(src)
if(!T)
return FALSE
for(var/atom/movable/AM in T)
if(AM.flags & PREVENT_CLICK_UNDER && AM.density && AM.layer > layer)
return TRUE
return FALSE
/turf/IsObscured()
for(var/atom/movable/AM in src)
if(AM.flags & PREVENT_CLICK_UNDER && AM.density)
return TRUE
return FALSE
/atom/movable/proc/CanReach(atom/target,obj/item/tool,view_only = FALSE)
if(isturf(target) || isturf(target.loc) || DirectAccess(target)) //Directly accessible atoms
if(Adjacent(target) || (tool && CheckToolReach(src, target, tool.reach))) //Adjacent or reaching attacks
+6 -7
View File
@@ -287,9 +287,9 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
GLOB.blood_target = null
else
blood_target = GLOB.blood_target
if(Cviewer)
if(Cviewer.seeking && Cviewer.master)
blood_target = Cviewer.master
if(Cviewer && Cviewer.seeking && Cviewer.master)
blood_target = Cviewer.master
desc = "Your blood sense is leading you to [Cviewer.master]"
if(!blood_target)
if(!GLOB.sac_complete)
if(icon_state == "runed_sense0")
@@ -301,22 +301,21 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
desc = "Nar-Sie demands that [GLOB.sac_mind] be sacrificed before the summoning ritual can begin."
add_overlay(GLOB.sac_image)
else
if(SSticker.mode.eldergod)
desc = "The sacrifice is complete, prepare to summon Nar-Sie!"
else
desc = "The summoning is complete, glory to Nar-Sie!"
if(icon_state == "runed_sense1")
return
animate(src, transform = null, time = 1, loop = 0)
angle = 0
cut_overlays()
icon_state = "runed_sense1"
desc = "The sacrifice is complete, bring the wrath of Nar-Sie upon the crew!"
add_overlay(narnar)
return
var/turf/P = get_turf(blood_target)
var/turf/Q = get_turf(mob_viewer)
var/area/A = get_area(P)
if(P.z != Q.z) //The target is on a different Z level, we cannot sense that far.
icon_state = "runed_sense2"
desc = "[blood_target] is no longer in your sector, you cannot sense its presence here."
return
desc = "You are currently tracking [blood_target] in [A.name]."
var/target_angle = Get_Angle(Q, P)
+27
View File
@@ -0,0 +1,27 @@
SUBSYSTEM_DEF(fields)
name = "Fields"
wait = 2
priority = 40
flags = SS_KEEP_TIMING
var/list/datum/proximity_monitor/advanced/running = list()
var/list/datum/proximity_monitor/advanced/currentrun = list()
/datum/controller/subsystem/fields/fire(resumed = 0)
if(!resumed)
src.currentrun = running.Copy()
var/list/currentrun = src.currentrun
while(currentrun.len)
var/datum/proximity_monitor/advanced/F = currentrun[currentrun.len]
currentrun.len--
if(!F.requires_processing)
continue
F.process()
if(MC_TICK_CHECK)
return
/datum/controller/subsystem/fields/proc/register_new_field(datum/proximity_monitor/advanced/F)
running += F
/datum/controller/subsystem/fields/proc/unregister_field(datum/proximity_monitor/advanced/F)
running -= F
+19 -1
View File
@@ -284,7 +284,7 @@ SUBSYSTEM_DEF(ticker)
//Now animate the cinematic
switch(station_missed)
if(NUKE_NEAR_MISS) //nuke was nearby but (mostly) missed
if( mode && !override )
if(mode && !override )
override = mode.name
switch( override )
if("nuclear emergency") //Nuke wasn't on station when it blew up
@@ -294,6 +294,17 @@ SUBSYSTEM_DEF(ticker)
station_explosion_detonation(bomb)
flick("station_intact_fade_red",cinematic)
cinematic.icon_state = "summary_nukefail"
if("cult")
cinematic.icon_state = null
flick("intro_cult",cinematic)
sleep(25)
world << sound('sound/magic/enter_blood.ogg')
sleep(28)
world << sound('sound/machines/terminal_off.ogg')
sleep(20)
flick("station_corrupted",cinematic)
world << sound('sound/effects/ghost.ogg')
actually_blew_up = FALSE
if("gang war") //Gang Domination (just show the override screen)
cinematic.icon_state = "intro_malf_still"
flick("intro_malf",cinematic)
@@ -342,6 +353,13 @@ SUBSYSTEM_DEF(ticker)
world << sound('sound/effects/explosionfar.ogg')
station_explosion_detonation(bomb) //TODO: no idea what this case could be
cinematic.icon_state = "summary_selfdes"
if("cult") //Station nuked (nuke,explosion,summary)
flick("intro_nuke",cinematic)
sleep(35)
flick("station_explode_fade_red",cinematic)
world << sound('sound/effects/explosionfar.ogg')
station_explosion_detonation(bomb) //TODO: no idea what this case could be
cinematic.icon_state = "summary_cult"
if("no_core") //Nuke failed to detonate as it had no core
flick("intro_nuke",cinematic)
sleep(35)
+8 -3
View File
@@ -31,6 +31,7 @@
var/obj/machinery/holopad/H = I
if(!QDELETED(H) && H.is_operational())
dialed_holopads += H
H.say("Incoming call.")
LAZYADD(H.holo_calls, src)
if(!dialed_holopads.len)
@@ -42,12 +43,16 @@
//cleans up ALL references :)
/datum/holocall/Destroy()
QDEL_NULL(eye)
user.reset_perspective()
if(user.client)
for(var/datum/camerachunk/chunk in eye.visibleCameraChunks)
user.client.images -= chunk.obscured
user.remote_control = null
QDEL_NULL(eye)
user = null
hologram.HC = null
if(hologram)
hologram.HC = null
hologram = null
calling_holopad.outgoing_call = null
+1 -1
View File
@@ -1330,7 +1330,7 @@
obj_count++
/datum/mind/proc/find_syndicate_uplink()
var/list/L = current.get_contents()
var/list/L = current.GetAllContents()
for (var/obj/item/I in L)
if (I.hidden_uplink)
return I.hidden_uplink
@@ -387,4 +387,4 @@
return list("operation_time" = 0, "new_obj_type" = /obj/effect/temp_visual/ratvar/beam/itemconsume, "power_cost" = -(CLOCKCULT_POWER_UNIT*0.04), "spawn_dir" = SOUTH)
/obj/item/clockwork/alloy_shards/small/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
return list("operation_time" = 0, "new_obj_type" = /obj/effect/temp_visual/ratvar/beam/itemconsume, "power_cost" = -(CLOCKCULT_POWER_UNIT*0.02), "spawn_dir" = SOUTH)
return list("operation_time" = 0, "new_obj_type" = /obj/effect/temp_visual/ratvar/beam/itemconsume, "power_cost" = -(CLOCKCULT_POWER_UNIT*0.02), "spawn_dir" = SOUTH)
@@ -162,14 +162,15 @@
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
var/randomsinglesprite = FALSE
var/randomspritemax = 2
var/sprite_shift = 9
/obj/item/clockwork/alloy_shards/Initialize()
. = ..()
if(randomsinglesprite)
replace_name_desc()
icon_state = "[icon_state][rand(1, randomspritemax)]"
pixel_x = rand(-9, 9)
pixel_y = rand(-9, 9)
pixel_x = rand(-sprite_shift, sprite_shift)
pixel_y = rand(-sprite_shift, sprite_shift)
/obj/item/clockwork/alloy_shards/proc/replace_name_desc()
name = "replicant alloy shard"
@@ -177,16 +178,21 @@
clockwork_desc = "A broken shard of replicant alloy. Can be proselytized for additional power."
/obj/item/clockwork/alloy_shards/large
w_class = WEIGHT_CLASS_TINY
randomsinglesprite = TRUE
icon_state = "shard_large"
sprite_shift = 9
/obj/item/clockwork/alloy_shards/medium
w_class = WEIGHT_CLASS_TINY
randomsinglesprite = TRUE
icon_state = "shard_medium"
sprite_shift = 10
/obj/item/clockwork/alloy_shards/medium/gear_bit
randomspritemax = 4
icon_state = "gear_bit"
sprite_shift = 12
/obj/item/clockwork/alloy_shards/medium/gear_bit/replace_name_desc()
name = "gear bit"
@@ -200,9 +206,11 @@
name = "complex gear bit"
/obj/item/clockwork/alloy_shards/small
w_class = WEIGHT_CLASS_TINY
randomsinglesprite = TRUE
randomspritemax = 3
icon_state = "shard_small"
sprite_shift = 12
/obj/item/clockwork/alloy_shards/pinion_lock
name = "pinion lock"
@@ -178,21 +178,24 @@
return TRUE
//A note here; return values are for if we CAN BE PUT ON A TABLE, not IF WE ARE SUCCESSFUL, unless no_table_check is TRUE
/obj/item/clockwork/clockwork_proselytizer/proc/proselytize(atom/target, mob/living/user, no_table_check)
/obj/item/clockwork/clockwork_proselytizer/proc/proselytize(atom/target, mob/living/user, silent, no_table_check)
if(!target || !user)
return FALSE
if(repairing)
to_chat(user, "<span class='warning'>You are currently repairing [repairing] with [src]!</span>")
if(!silent)
to_chat(user, "<span class='warning'>You are currently repairing [repairing] with [src]!</span>")
return FALSE
if(recharging)
to_chat(user, "<span class='warning'>You are currently recharging [src] from the [recharging.sigil_name]!</span>")
if(!silent)
to_chat(user, "<span class='warning'>You are currently recharging [src] from the [recharging.sigil_name]!</span>")
return FALSE
var/list/proselytize_values = target.proselytize_vals(user, src) //relevant values for proselytizing stuff, given as an associated list
var/list/proselytize_values = target.proselytize_vals(user, src, silent) //relevant values for proselytizing stuff, given as an associated list
if(!islist(proselytize_values))
if(proselytize_values != TRUE) //if we get true, fail, but don't send a message for whatever reason
if(!isturf(target)) //otherwise, if we didn't get TRUE and the original target wasn't a turf, try to proselytize the turf
return proselytize(get_turf(target), user, no_table_check)
to_chat(user, "<span class='warning'>[target] cannot be proselytized!</span>")
if(!silent)
to_chat(user, "<span class='warning'>[target] cannot be proselytized!</span>")
if(!no_table_check)
return TRUE
return FALSE
@@ -207,19 +210,22 @@
var/target_type = target.type
if(!proselytize_checks(proselytize_values, target, target_type, user))
if(!proselytize_checks(proselytize_values, target, target_type, user, silent))
return FALSE
proselytize_values["operation_time"] *= speed_multiplier
playsound(target, 'sound/machines/click.ogg', 50, 1)
if(proselytize_values["operation_time"])
user.visible_message("<span class='warning'>[user]'s [name] begins tearing apart [target]!</span>", "<span class='brass'>You begin proselytizing [target]...</span>")
if(!silent)
user.visible_message("<span class='warning'>[user]'s [name] begins tearing apart [target]!</span>", "<span class='brass'>You begin proselytizing [target]...</span>")
if(!do_after(user, proselytize_values["operation_time"], target = target, extra_checks = CALLBACK(src, .proc/proselytize_checks, proselytize_values, target, target_type, user, TRUE)))
return FALSE
user.visible_message("<span class='warning'>[user]'s [name] covers [target] in golden energy!</span>", "<span class='brass'>You proselytize [target].</span>")
if(!silent)
user.visible_message("<span class='warning'>[user]'s [name] covers [target] in golden energy!</span>", "<span class='brass'>You proselytize [target].</span>")
else
user.visible_message("<span class='warning'>[user]'s [name] tears apart [target], covering it in golden energy!</span>", "<span class='brass'>You proselytize [target].</span>")
if(!silent)
user.visible_message("<span class='warning'>[user]'s [name] tears apart [target], covering it in golden energy!</span>", "<span class='brass'>You proselytize [target].</span>")
playsound(target, 'sound/items/Deconstruct.ogg', 50, 1)
var/new_thing_type = proselytize_values["new_obj_type"]
@@ -227,11 +233,12 @@
var/turf/T = target
T.ChangeTurf(new_thing_type)
else
if(proselytize_values["dir_in_new"])
new new_thing_type(get_turf(target), proselytize_values["spawn_dir"]) //please verify that your new object actually wants to get a dir in New()
else
var/atom/A = new new_thing_type(get_turf(target))
A.setDir(proselytize_values["spawn_dir"])
if(new_thing_type)
if(proselytize_values["dir_in_new"])
new new_thing_type(get_turf(target), proselytize_values["spawn_dir"]) //please verify that your new object actually wants to get a dir in New()
else
var/atom/A = new new_thing_type(get_turf(target))
A.setDir(proselytize_values["spawn_dir"])
if(!proselytize_values["no_target_deletion"]) //for some cases where proselytize_vals() modifies the object but doesn't want it deleted
qdel(target)
modify_stored_power(-proselytize_values["power_cost"])
@@ -239,8 +246,13 @@
return TRUE
return FALSE
//The following three procs are heavy wizardry.
//What these procs do is they take an existing list of values, which they then modify.
//This(modifying an existing object, in this case the list) is the only way to get information OUT of a do_after callback, which this is used as.
//The proselytize check proc.
/obj/item/clockwork/clockwork_proselytizer/proc/proselytize_checks(list/proselytize_values, atom/target, expected_type, mob/user, silent) //checked constantly while proselytizing
if(!islist(proselytize_values) || !target || QDELETED(target) || !user)
if(!islist(proselytize_values) || QDELETED(target) || QDELETED(user))
return FALSE
if(repairing || recharging)
return FALSE
@@ -259,11 +271,8 @@
return TRUE
//The repair check proc.
//Is dark magic. Can probably kill you.
//What this proc does is it takes an existing list of values, which it modifies.
//This(modifying an existing object) is the only way to get information OUT of a do_after callback, which this is used as.
/obj/item/clockwork/clockwork_proselytizer/proc/proselytizer_repair_checks(list/repair_values, atom/target, mob/user, silent) //Exists entirely to avoid an otherwise unreadable series of checks.
if(!islist(repair_values) || !target || QDELETED(target) || !user)
if(!islist(repair_values) || QDELETED(target) || QDELETED(user))
return FALSE
if(isliving(target)) //standard checks for if we can affect the target
var/mob/living/L = target
@@ -302,9 +311,9 @@
return FALSE
return TRUE
//checked constantly while charging from a sigil
//The sigil charge check proc.
/obj/item/clockwork/clockwork_proselytizer/proc/sigil_charge_checks(list/charge_values, obj/effect/clockwork/sigil/transmission/sigil, mob/user, silent)
if(!islist(charge_values) || !sigil || QDELETED(sigil) || !user)
if(!islist(charge_values) || QDELETED(sigil) || QDELETED(user))
return FALSE
if(can_use_power(RATVAR_POWER_CHECK))
return FALSE
@@ -28,7 +28,7 @@
var/mutable_appearance/alert_overlay = mutable_appearance('icons/effects/clockwork_effects.dmi', "ratvar_alert")
var/area/A = get_area(src)
notify_ghosts("The Justiciar's light calls to you! Reach out to Ratvar in [A.name] to be granted a shell to spread his glory!", null, source = src, alert_overlay = alert_overlay)
INVOKE_ASYNC(SSshuttle.emergency, /obj/docking_port/mobile/emergency..proc/request, null, 0, 0)
INVOKE_ASYNC(SSshuttle.emergency, /obj/docking_port/mobile/emergency.proc/request, null, 0, null, FALSE, 0)
/obj/structure/destructible/clockwork/massive/ratvar/Destroy()
GLOB.ratvar_awakens--
+1 -1
View File
@@ -152,7 +152,7 @@
return TRUE
/datum/action/innate/cult/master/IsAvailable()
if(!owner.mind || !owner.mind.has_antag_datum(ANTAG_DATUM_CULT_MASTER))
if(!owner.mind || !owner.mind.has_antag_datum(ANTAG_DATUM_CULT_MASTER) || GLOB.cult_narsie)
return 0
return ..()
+1 -1
View File
@@ -214,7 +214,7 @@
/obj/item/clothing/suit/hooded/cultrobes/cult_shield/worn_overlays(isinhands)
. = list()
if(!isinhands && current_charges)
. += mutable_appearance('icons/effects/effects.dmi', "shield-cult", MOB_LAYER + 0.01)
. += mutable_appearance('icons/effects/cult_effects.dmi', "shield-cult", MOB_LAYER + 0.01)
/obj/item/clothing/suit/hooded/cultrobes/berserker
name = "flagellant's robes"
@@ -0,0 +1,70 @@
//after a delay, creates a rune below you. for constructs creating runes.
/datum/action/innate/cult/create_rune
background_icon_state = "bg_cult"
var/obj/effect/rune/rune_type
var/cooldown = 0
var/base_cooldown = 900
var/scribe_time = 100
var/damage_interrupt = TRUE
var/action_interrupt = TRUE
var/obj/effect/overlay/temp/cult/rune_spawn/rune_word_type
var/obj/effect/overlay/temp/cult/rune_spawn/rune_innerring_type
var/obj/effect/overlay/temp/cult/rune_spawn/rune_center_type
var/rune_color
/datum/action/innate/cult/create_rune/IsAvailable()
if(!rune_type || cooldown > world.time)
return FALSE
return ..()
/datum/action/innate/cult/create_rune/Activate()
var/chosen_keyword
if(!isturf(owner.loc))
to_chat(owner, "<span class='warning>You need more space to scribe a rune!</span>")
return
if(initial(rune_type.req_keyword))
chosen_keyword = stripped_input(owner, "Enter a keyword for the new rune.", "Words of Power")
if(!chosen_keyword)
return
//the outer ring is always the same across all runes
var/obj/effect/overlay/temp/cult/rune_spawn/R1 = new(owner.loc, scribe_time, rune_color)
//the rest are not always the same, so we need types for em
var/obj/effect/overlay/temp/cult/rune_spawn/R2
if(rune_word_type)
R2 = new rune_word_type(owner.loc, scribe_time, rune_color)
var/obj/effect/overlay/temp/cult/rune_spawn/R3
if(rune_innerring_type)
R3 = new rune_innerring_type(owner.loc, scribe_time, rune_color)
var/obj/effect/overlay/temp/cult/rune_spawn/R4
if(rune_center_type)
R4 = new rune_center_type(owner.loc, scribe_time, rune_color)
cooldown = base_cooldown + world.time
owner.update_action_buttons_icon()
addtimer(CALLBACK(owner, /mob.proc/update_action_buttons_icon), base_cooldown)
var/list/health
if(damage_interrupt && isliving(owner))
var/mob/living/L = owner
health = list("health" = L.health)
if(do_after(owner, scribe_time, target = owner, extra_checks = CALLBACK(owner, /mob.proc/break_do_after_checks, health, action_interrupt)))
var/obj/effect/rune/new_rune = new rune_type(owner.loc)
new_rune.keyword = chosen_keyword
else
qdel(R1)
if(R2)
qdel(R2)
if(R3)
qdel(R3)
if(R4)
qdel(R4)
cooldown = 0
owner.update_action_buttons_icon()
//teleport rune
/datum/action/innate/cult/create_rune/tele
button_icon_state = "telerune"
rune_type = /obj/effect/rune/teleport
rune_word_type = /obj/effect/overlay/temp/cult/rune_spawn/rune2
rune_innerring_type = /obj/effect/overlay/temp/cult/rune_spawn/rune2/inner
rune_center_type = /obj/effect/overlay/temp/cult/rune_spawn/rune2/center
rune_color = RUNE_COLOR_TELEPORT
+30 -30
View File
@@ -24,7 +24,7 @@ To draw a rune, use an arcane tome.
icon_state = "1"
resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF
layer = LOW_OBJ_LAYER
color = "#FF0000"
color = RUNE_COLOR_RED
var/invocation = "Aiy ele-mayo!" //This is said by cultists when the rune is invoked.
var/req_cultists = 1 //The amount of cultists required around the rune to invoke it. If only 1, any cultist can invoke it.
@@ -148,8 +148,7 @@ structure_check() searches for nearby cultist structures required for the invoca
/obj/effect/rune/proc/fail_invoke()
//This proc contains the effects of a rune if it is not invoked correctly, through either invalid wording or not enough cultists. By default, it's just a basic fizzle.
visible_message("<span class='warning'>The markings pulse with a \
small flash of red light, then fall dark.</span>")
visible_message("<span class='warning'>The markings pulse with a small flash of red light, then fall dark.</span>")
var/oldcolor = color
color = rgb(255, 0, 0)
animate(src, color = oldcolor, time = 5)
@@ -192,7 +191,7 @@ structure_check() searches for nearby cultist structures required for the invoca
cultist_desc = "transforms paper into powerful magic talismans."
invocation = "H'drak v'loso, mir'kanas verbot!"
icon_state = "3"
color = "#0000FF"
color = RUNE_COLOR_TALISMAN
/obj/effect/rune/imbue/invoke(var/list/invokers)
var/mob/living/user = invokers[1] //the first invoker is always the user
@@ -247,7 +246,7 @@ structure_check() searches for nearby cultist structures required for the invoca
cultist_desc = "warps everything above it to another chosen teleport rune."
invocation = "Sas'so c'arta forbici!"
icon_state = "2"
color = "#551A8B"
color = RUNE_COLOR_TELEPORT
req_keyword = TRUE
var/listkey
@@ -307,10 +306,11 @@ structure_check() searches for nearby cultist structures required for the invoca
A.forceMove(target)
if(movedsomething)
..()
visible_message("<span class='warning'>There is a sharp crack of inrushing air, and everything above the rune disappears!</span>")
visible_message("<span class='warning'>There is a sharp crack of inrushing air, and everything above the rune disappears!</span>", null, "<i>You hear a sharp crack.</i>")
to_chat(user, "<span class='cult'>You[moveuserlater ? "r vision blurs, and you suddenly appear somewhere else":" send everything above the rune away"].</span>")
if(moveuserlater)
user.forceMove(target)
target.visible_message("<span class='warning'>There is a boom of outrushing air as something appears above the rune!</span>", null, "<i>You hear a boom.</i>")
else
fail_invoke()
@@ -322,7 +322,7 @@ structure_check() searches for nearby cultist structures required for the invoca
req_cultists_text = "2 for conversion, 3 for living sacrifices and sacrifice targets."
invocation = "Mah'weyh pleggh at e'ntrath!"
icon_state = "3"
color = "#FFFFFF"
color = RUNE_COLOR_OFFER
req_cultists = 1
allow_excess_invokers = TRUE
rune_in_use = FALSE
@@ -345,7 +345,7 @@ structure_check() searches for nearby cultist structures required for the invoca
rune_in_use = TRUE
visible_message("<span class='warning'>[src] pulses blood red!</span>")
var/oldcolor = color
color = "#7D1717"
color = RUNE_COLOR_DARKRED
var/mob/living/L = pick(myriad_targets)
var/is_clock = is_servant_of_ratvar(L)
var/is_convertable = is_convertable_to_cult(L)
@@ -442,7 +442,7 @@ structure_check() searches for nearby cultist structures required for the invoca
invocation = "TOK-LYR RQA-NAP G'OLT-ULOFT!!"
req_cultists = 9
icon = 'icons/effects/96x96.dmi'
color = "#7D1717"
color = RUNE_COLOR_DARKRED
icon_state = "rune_large"
pixel_x = -32 //So the big ol' 96x96 sprite shows up right
pixel_y = -32
@@ -479,9 +479,9 @@ structure_check() searches for nearby cultist structures required for the invoca
var/turf/T = get_turf(src)
sleep(40)
if(src)
color = "#FF0000"
color = RUNE_COLOR_RED
SSticker.mode.eldergod = FALSE
new /obj/singularity/narsie/large(T) //Causes Nar-Sie to spawn even if the rune has been removed
new /obj/singularity/narsie/large/cult(T) //Causes Nar-Sie to spawn even if the rune has been removed
/obj/effect/rune/narsie/attackby(obj/I, mob/user, params) //Since the narsie rune takes a long time to make, add logging to removal.
if((istype(I, /obj/item/weapon/tome) && iscultist(user)))
@@ -502,7 +502,7 @@ structure_check() searches for nearby cultist structures required for the invoca
cultist_desc = "requires the corpse of a cultist placed upon the rune. Provided there have been sufficient sacrifices, they will be revived."
invocation = "Pasnar val'keriam usinar. Savrae ines amutan. Yam'toth remium il'tarat!" //Depends on the name of the user - see below
icon_state = "1"
color = "#C80000"
color = RUNE_COLOR_MEDIUMRED
var/static/revives_used = 0
/obj/effect/rune/raise_dead/examine(mob/user)
@@ -593,7 +593,7 @@ structure_check() searches for nearby cultist structures required for the invoca
invocation = "Ta'gh fara'qha fel d'amar det!"
icon_state = "5"
allow_excess_invokers = 1
color = "#4D94FF"
color = RUNE_COLOR_EMP
/obj/effect/rune/emp/invoke(var/list/invokers)
var/turf/E = get_turf(src)
@@ -623,7 +623,7 @@ structure_check() searches for nearby cultist structures required for the invoca
cultist_desc = "severs the link between one's spirit and body. This effect is taxing and one's physical body will take damage while this is active."
invocation = "Fwe'sh mah erl nyag r'ya!"
icon_state = "7"
color = "#7D1717"
color = RUNE_COLOR_DARKRED
rune_in_use = 0 //One at a time, please!
construct_invoke = 0
var/mob/living/affecting = null
@@ -649,9 +649,9 @@ structure_check() searches for nearby cultist structures required for the invoca
var/mob/living/user = invokers[1]
..()
var/turf/T = get_turf(src)
rune_in_use = 1
rune_in_use = TRUE
affecting = user
user.color = "#7D1717"
user.add_atom_colour(RUNE_COLOR_DARKRED, ADMIN_COLOUR_PRIORITY)
user.visible_message("<span class='warning'>[user] freezes statue-still, glowing an unearthly red.</span>", \
"<span class='cult'>You see what lies beyond. All is revealed. While this is a wondrous experience, your physical form will waste away in this state. Hurry...</span>")
user.ghostize(1)
@@ -659,7 +659,7 @@ structure_check() searches for nearby cultist structures required for the invoca
if(!affecting)
visible_message("<span class='warning'>[src] pulses gently before falling dark.</span>")
affecting = null //In case it's assigned to a number or something
rune_in_use = 0
rune_in_use = FALSE
return
affecting.apply_damage(0.1, BRUTE)
if(!(user in T))
@@ -669,9 +669,9 @@ structure_check() searches for nearby cultist structures required for the invoca
if(user.key)
user.visible_message("<span class='warning'>[user] slowly relaxes, the glow around [user.p_them()] dimming.</span>", \
"<span class='danger'>You are re-united with your physical form. [src] releases its hold over you.</span>")
user.color = initial(user.color)
user.remove_atom_colour(ADMIN_COLOUR_PRIORITY, RUNE_COLOR_DARKRED)
user.Weaken(3)
rune_in_use = 0
rune_in_use = FALSE
affecting = null
return
if(user.stat == UNCONSCIOUS)
@@ -679,14 +679,14 @@ structure_check() searches for nearby cultist structures required for the invoca
var/mob/dead/observer/G = user.get_ghost()
to_chat(G, "<span class='cultitalic'>You feel the link between you and your body weakening... you must hurry!</span>")
if(user.stat == DEAD)
user.color = initial(user.color)
rune_in_use = 0
user.remove_atom_colour(ADMIN_COLOUR_PRIORITY, RUNE_COLOR_DARKRED)
rune_in_use = FALSE
affecting = null
var/mob/dead/observer/G = user.get_ghost()
to_chat(G, "<span class='cultitalic'><b>You suddenly feel your physical form pass on. [src]'s exertion has killed you!</b></span>")
return
sleep(1)
rune_in_use = 0
rune_in_use = FALSE
//Rite of the Corporeal Shield: When invoked, becomes solid and cannot be passed. Invoke again to undo.
/obj/effect/rune/wall
@@ -694,7 +694,7 @@ structure_check() searches for nearby cultist structures required for the invoca
cultist_desc = "when invoked, makes a temporary invisible wall to block passage. Can be invoked again to reverse this."
invocation = "Khari'd! Eske'te tannin!"
icon_state = "1"
color = "#C80000"
color = RUNE_COLOR_MEDIUMRED
CanAtmosPass = ATMOS_PASS_DENSITY
var/density_timer
var/recharging = FALSE
@@ -753,7 +753,7 @@ structure_check() searches for nearby cultist structures required for the invoca
/obj/effect/rune/wall/proc/recharge()
recharging = FALSE
add_atom_colour("#C80000", FIXED_COLOUR_PRIORITY)
add_atom_colour(RUNE_COLOR_MEDIUMRED, FIXED_COLOUR_PRIORITY)
/obj/effect/rune/wall/proc/update_state()
deltimer(density_timer)
@@ -764,10 +764,10 @@ structure_check() searches for nearby cultist structures required for the invoca
shimmer.alpha = 60
shimmer.color = "#701414"
add_overlay(shimmer)
add_atom_colour("#FF0000", FIXED_COLOUR_PRIORITY)
add_atom_colour(RUNE_COLOR_RED, FIXED_COLOUR_PRIORITY)
else
cut_overlays()
add_atom_colour("#C80000", FIXED_COLOUR_PRIORITY)
add_atom_colour(RUNE_COLOR_MEDIUMRED, FIXED_COLOUR_PRIORITY)
//Rite of Joined Souls: Summons a single cultist.
/obj/effect/rune/summon
@@ -777,7 +777,7 @@ structure_check() searches for nearby cultist structures required for the invoca
req_cultists = 2
allow_excess_invokers = 1
icon_state = "5"
color = "#00FF00"
color = RUNE_COLOR_SUMMON
/obj/effect/rune/summon/invoke(var/list/invokers)
var/mob/living/user = invokers[1]
@@ -822,7 +822,7 @@ structure_check() searches for nearby cultist structures required for the invoca
cultist_desc = "boils the blood of non-believers who can see the rune, rapidly dealing extreme amounts of damage. Requires 3 invokers."
invocation = "Dedo ol'btoh!"
icon_state = "4"
color = "#C80000"
color = RUNE_COLOR_MEDIUMRED
light_color = LIGHT_COLOR_LAVA
req_cultists = 3
construct_invoke = 0
@@ -889,7 +889,7 @@ structure_check() searches for nearby cultist structures required for the invoca
invocation = "Gal'h'rfikk harfrandid mud'gib!" //how the fuck do you pronounce this
icon_state = "6"
construct_invoke = 0
color = "#C80000"
color = RUNE_COLOR_MEDIUMRED
var/ghost_limit = 5
var/ghosts = 0
@@ -962,4 +962,4 @@ structure_check() searches for nearby cultist structures required for the invoca
"<span class='cultlarge'>Your link to the world fades. Your form breaks apart.</span>")
for(var/obj/I in new_human)
new_human.dropItemToGround(I, TRUE)
new_human.dust()
new_human.dust()
+1 -1
View File
@@ -49,7 +49,7 @@
/obj/item/weapon/paper/talisman/teleport
cultist_name = "Talisman of Teleportation"
cultist_desc = "A single-use talisman that will teleport a user to a random rune of the same keyword."
color = "#551A8B" // purple
color = RUNE_COLOR_TELEPORT
invocation = "Sas'so c'arta forbici!"
health_cost = 5
creation_time = 80
+4 -1
View File
@@ -210,13 +210,16 @@
var/datum/action/innate/seek_master/SM = new()
SM.Grant(newstruct)
newstruct.key = target.key
var/obj/screen/alert/bloodsense/BS
if(newstruct.mind && ((stoner && iscultist(stoner)) || cultoverride) && SSticker && SSticker.mode)
SSticker.mode.add_cultist(newstruct.mind, 0)
BS = newstruct.alerts.Find("bloodsense")
if(iscultist(stoner) || cultoverride)
to_chat(newstruct, "<b>You are still bound to serve the cult[stoner ? " and [stoner]":""], follow their orders and help them complete their goals at all costs.</b>")
else if(stoner)
to_chat(newstruct, "<b>You are still bound to serve your creator, [stoner], follow their orders and help them complete their goals at all costs.</b>")
var/obj/screen/alert/bloodsense/BS = newstruct.throw_alert("bloodsense", /obj/screen/alert/bloodsense)
BS = newstruct.throw_alert("bloodsense", /obj/screen/alert/bloodsense)
if(BS)
BS.Cviewer = newstruct
newstruct.cancel_camera()
-3
View File
@@ -25,9 +25,6 @@
if(istype(I, /obj/item/stack/spacecash))
var/obj/item/stack/spacecash/C = I
value = C.value * C.amount
if(istype(I, /obj/item/weapon/coin))
var/obj/item/weapon/coin/C = I
value = C.value
if(value)
SSshuttle.points += value
to_chat(user, "<span class='notice'>You deposit [I]. The station now has [SSshuttle.points] credits.</span>")
+2 -1
View File
@@ -43,7 +43,8 @@
/obj/item/weapon/grenade/chem_grenade/glitter/pink = 1,
/obj/item/weapon/grenade/chem_grenade/glitter/blue = 1,
/obj/item/weapon/grenade/chem_grenade/glitter/white = 1,
/obj/item/toy/eightball = 2)
/obj/item/toy/eightball = 2,
/obj/item/toy/windupToolbox = 2)
light_color = LIGHT_COLOR_GREEN
+1
View File
@@ -12,6 +12,7 @@
max_integrity = 350
armor = list(melee = 30, bullet = 30, laser = 20, energy = 20, bomb = 10, bio = 100, rad = 100, fire = 80, acid = 70)
CanAtmosPass = ATMOS_PASS_DENSITY
flags = PREVENT_CLICK_UNDER
var/secondsElectrified = 0
var/shockedby = list()
+1 -3
View File
@@ -26,8 +26,6 @@ Possible to do for anyone motivated enough:
#define HOLOPAD_PASSIVE_POWER_USAGE 1
#define HOLOGRAM_POWER_USAGE 2
GLOBAL_LIST_EMPTY(holopads)
#define HOLOPAD_MODE RANGE_BASED
/obj/machinery/holopad
@@ -295,7 +293,7 @@ GLOBAL_LIST_EMPTY(holopads)
Hologram.Impersonation = user
Hologram.language_holder = user.get_language_holder()
Hologram.copy_known_languages_from(user,replace = TRUE)
Hologram.mouse_opacity = 0//So you can't click on it.
Hologram.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them.
+23 -5
View File
@@ -48,6 +48,7 @@
var/icon_deny //Icon_state when vending!
var/seconds_electrified = 0 //Shock customers like an airlock.
var/shoot_inventory = 0 //Fire items at customers! We're broken!
var/shoot_inventory_chance = 2
var/shut_up = 0 //Stop spouting those godawful pitches!
var/extended_inventory = 0 //can we access the hidden inventory?
var/scan_id = 1
@@ -561,7 +562,7 @@
speak(slogan)
last_slogan = world.time
if(shoot_inventory && prob(2))
if(shoot_inventory && prob(shoot_inventory_chance))
throw_item()
@@ -592,7 +593,7 @@
if(!target)
return 0
for(var/datum/data/vending_product/R in product_records)
for(var/datum/data/vending_product/R in shuffle(product_records))
if(R.amount <= 0) //Try to use a record that actually has something to dump.
continue
var/dump_path = R.product_path
@@ -605,19 +606,22 @@
if(!throw_item)
return 0
pre_throw(throw_item)
throw_item.throw_at(target, 16, 3)
visible_message("<span class='danger'>[src] launches [throw_item] at [target]!</span>")
return 1
/obj/machinery/vending/proc/pre_throw(obj/item/I)
return
/obj/machinery/vending/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()
do_sparks(5, TRUE, src)
var/tmp/check_range = TRUE
if(electrocute_mob(user, get_area(src), src, 0.7, check_range))
return TRUE
@@ -864,6 +868,11 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
/obj/item/weapon/storage/fancy/cigarettes/cigars = 1, /obj/item/weapon/storage/fancy/cigarettes/cigars/havana = 1, /obj/item/weapon/storage/fancy/cigarettes/cigars/cohiba = 1)
refill_canister = /obj/item/weapon/vending_refill/cigarette
/obj/machinery/vending/cigarette/pre_throw(obj/item/I)
if(istype(I, /obj/item/weapon/lighter))
var/obj/item/weapon/lighter/L = I
L.set_lit(TRUE)
/obj/machinery/vending/medical
name = "\improper NanoMed Plus"
desc = "Medical drug dispenser."
@@ -919,6 +928,15 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
armor = list(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 50)
resistance_flags = FIRE_PROOF
/obj/machinery/vending/security/pre_throw(obj/item/I)
if(istype(I, /obj/item/weapon/grenade))
var/obj/item/weapon/grenade/G = I
G.preprime()
else if(istype(I, /obj/item/device/flashlight))
var/obj/item/device/flashlight/F = I
F.on = TRUE
F.update_brightness()
/obj/machinery/vending/hydronutrients
name = "\improper NutriMax"
desc = "A plant nutrients vendor."
-614
View File
@@ -18,620 +18,6 @@
..()
QDEL_IN(src, 10)
/obj/effect/overlay/temp
icon_state = "nothing"
anchored = 1
layer = ABOVE_MOB_LAYER
mouse_opacity = 0
var/duration = 10 //in deciseconds
var/randomdir = TRUE
var/timerid
/obj/effect/overlay/temp/Destroy()
. = ..()
deltimer(timerid)
/obj/effect/overlay/temp/Initialize()
. = ..()
if(randomdir)
setDir(pick(GLOB.cardinal))
timerid = QDEL_IN(src, duration)
/obj/effect/overlay/temp/ex_act()
return
/obj/effect/overlay/temp/dir_setting
randomdir = FALSE
/obj/effect/overlay/temp/dir_setting/Initialize(mapload, set_dir)
if(set_dir)
setDir(set_dir)
. = ..()
/obj/effect/overlay/temp/dir_setting/bloodsplatter
icon = 'icons/effects/blood.dmi'
duration = 5
randomdir = FALSE
layer = BELOW_MOB_LAYER
var/splatter_type = "splatter"
/obj/effect/overlay/temp/dir_setting/bloodsplatter/Initialize(mapload, set_dir)
if(set_dir in GLOB.diagonals)
icon_state = "[splatter_type][pick(1, 2, 6)]"
else
icon_state = "[splatter_type][pick(3, 4, 5)]"
. = ..()
var/target_pixel_x = 0
var/target_pixel_y = 0
switch(set_dir)
if(NORTH)
target_pixel_y = 16
if(SOUTH)
target_pixel_y = -16
layer = ABOVE_MOB_LAYER
if(EAST)
target_pixel_x = 16
if(WEST)
target_pixel_x = -16
if(NORTHEAST)
target_pixel_x = 16
target_pixel_y = 16
if(NORTHWEST)
target_pixel_x = -16
target_pixel_y = 16
if(SOUTHEAST)
target_pixel_x = 16
target_pixel_y = -16
layer = ABOVE_MOB_LAYER
if(SOUTHWEST)
target_pixel_x = -16
target_pixel_y = -16
layer = ABOVE_MOB_LAYER
animate(src, pixel_x = target_pixel_x, pixel_y = target_pixel_y, alpha = 0, time = duration)
/obj/effect/overlay/temp/dir_setting/bloodsplatter/xenosplatter
splatter_type = "xsplatter"
/obj/effect/overlay/temp/dir_setting/speedbike_trail
name = "speedbike trails"
icon_state = "ion_fade"
layer = BELOW_MOB_LAYER
duration = 10
randomdir = 0
/obj/effect/overlay/temp/dir_setting/firing_effect
icon = 'icons/effects/effects.dmi'
icon_state = "firing_effect"
duration = 2
/obj/effect/overlay/temp/dir_setting/firing_effect/setDir(newdir)
switch(newdir)
if(NORTH)
layer = BELOW_MOB_LAYER
pixel_x = rand(-3,3)
pixel_y = rand(4,6)
if(SOUTH)
pixel_x = rand(-3,3)
pixel_y = rand(-1,1)
else
pixel_x = rand(-1,1)
pixel_y = rand(-1,1)
..()
/obj/effect/overlay/temp/dir_setting/firing_effect/energy
icon_state = "firing_effect_energy"
duration = 3
/obj/effect/overlay/temp/dir_setting/firing_effect/magic
icon_state = "shieldsparkles"
duration = 3
/obj/effect/overlay/temp/dir_setting/ninja
name = "ninja shadow"
icon = 'icons/mob/mob.dmi'
icon_state = "uncloak"
duration = 9
/obj/effect/overlay/temp/dir_setting/ninja/cloak
icon_state = "cloak"
/obj/effect/overlay/temp/dir_setting/ninja/shadow
icon_state = "shadow"
/obj/effect/overlay/temp/dir_setting/ninja/phase
name = "ninja energy"
icon_state = "phasein"
/obj/effect/overlay/temp/dir_setting/ninja/phase/out
icon_state = "phaseout"
/obj/effect/overlay/temp/dir_setting/wraith
name = "blood"
icon = 'icons/mob/mob.dmi'
icon_state = "phase_shift2"
duration = 12
/obj/effect/overlay/temp/dir_setting/wraith/out
icon_state = "phase_shift"
/obj/effect/overlay/temp/dir_setting/tailsweep
icon_state = "tailsweep"
duration = 4
/obj/effect/overlay/temp/wizard
name = "water"
icon = 'icons/mob/mob.dmi'
icon_state = "reappear"
duration = 5
/obj/effect/overlay/temp/wizard/out
icon_state = "liquify"
duration = 12
/obj/effect/overlay/temp/monkeyify
icon = 'icons/mob/mob.dmi'
icon_state = "h2monkey"
duration = 22
/obj/effect/overlay/temp/monkeyify/humanify
icon_state = "monkey2h"
/obj/effect/overlay/temp/borgflash
icon = 'icons/mob/mob.dmi'
icon_state = "blspell"
duration = 5
/obj/effect/overlay/temp/guardian
randomdir = 0
/obj/effect/overlay/temp/guardian/phase
duration = 5
icon_state = "phasein"
/obj/effect/overlay/temp/guardian/phase/out
icon_state = "phaseout"
/obj/effect/overlay/temp/decoy
desc = "It's a decoy!"
duration = 15
/obj/effect/overlay/temp/decoy/Initialize(mapload, atom/mimiced_atom)
. = ..()
alpha = initial(alpha)
if(mimiced_atom)
name = mimiced_atom.name
appearance = mimiced_atom.appearance
setDir(mimiced_atom.dir)
mouse_opacity = 0
/obj/effect/overlay/temp/decoy/fading/Initialize(mapload, atom/mimiced_atom)
. = ..()
animate(src, alpha = 0, time = duration)
/obj/effect/overlay/temp/decoy/fading/fivesecond
duration = 50
/obj/effect/overlay/temp/small_smoke
icon_state = "smoke"
duration = 50
/obj/effect/overlay/temp/fire
icon = 'icons/effects/fire.dmi'
icon_state = "3"
duration = 20
/obj/effect/overlay/temp/cult
randomdir = 0
duration = 10
/obj/effect/overlay/temp/cult/sparks
randomdir = 1
name = "blood sparks"
icon_state = "bloodsparkles"
/obj/effect/overlay/temp/cult/blood // The traditional teleport
name = "blood jaunt"
duration = 12
icon_state = "bloodin"
/obj/effect/overlay/temp/cult/blood/out
icon_state = "bloodout"
/obj/effect/overlay/temp/dir_setting/cult/phase // The veil shifter teleport
name = "phase glow"
duration = 7
icon_state = "cultin"
/obj/effect/overlay/temp/dir_setting/cult/phase/out
icon_state = "cultout"
/obj/effect/overlay/temp/cult/sac
name = "maw of Nar-Sie"
icon_state = "sacconsume"
/obj/effect/overlay/temp/cult/door
name = "unholy glow"
icon_state = "doorglow"
layer = CLOSED_FIREDOOR_LAYER //above closed doors
/obj/effect/overlay/temp/cult/door/unruned
icon_state = "unruneddoorglow"
/obj/effect/overlay/temp/cult/turf
name = "unholy glow"
icon_state = "wallglow"
layer = ABOVE_NORMAL_TURF_LAYER
/obj/effect/overlay/temp/cult/turf/floor
icon_state = "floorglow"
duration = 5
/obj/effect/overlay/temp/ratvar
name = "ratvar's light"
icon = 'icons/effects/clockwork_effects.dmi'
duration = 8
randomdir = 0
layer = ABOVE_NORMAL_TURF_LAYER
/obj/effect/overlay/temp/ratvar/door
icon_state = "ratvardoorglow"
layer = CLOSED_DOOR_LAYER //above closed doors
/obj/effect/overlay/temp/ratvar/door/window
icon_state = "ratvarwindoorglow"
layer = ABOVE_WINDOW_LAYER
/obj/effect/overlay/temp/ratvar/beam
icon_state = "ratvarbeamglow"
/obj/effect/overlay/temp/ratvar/beam/door
layer = CLOSED_DOOR_LAYER
/obj/effect/overlay/temp/ratvar/beam/grille
layer = BELOW_OBJ_LAYER
/obj/effect/overlay/temp/ratvar/beam/itemconsume
layer = HIGH_OBJ_LAYER
/obj/effect/overlay/temp/ratvar/beam/falsewall
layer = OBJ_LAYER
/obj/effect/overlay/temp/ratvar/beam/catwalk
layer = LATTICE_LAYER
/obj/effect/overlay/temp/ratvar/wall
icon_state = "ratvarwallglow"
/obj/effect/overlay/temp/ratvar/wall/false
layer = OBJ_LAYER
/obj/effect/overlay/temp/ratvar/floor
icon_state = "ratvarfloorglow"
/obj/effect/overlay/temp/ratvar/floor/catwalk
layer = LATTICE_LAYER
/obj/effect/overlay/temp/ratvar/window
icon_state = "ratvarwindowglow"
layer = ABOVE_OBJ_LAYER
/obj/effect/overlay/temp/ratvar/window/single
icon_state = "ratvarwindowglow_s"
/obj/effect/overlay/temp/ratvar/gear
icon_state = "ratvargearglow"
layer = BELOW_OBJ_LAYER
/obj/effect/overlay/temp/ratvar/grille
icon_state = "ratvargrilleglow"
layer = BELOW_OBJ_LAYER
/obj/effect/overlay/temp/ratvar/grille/broken
icon_state = "ratvarbrokengrilleglow"
/obj/effect/overlay/temp/ratvar/mending_mantra
layer = ABOVE_MOB_LAYER
duration = 20
alpha = 200
icon_state = "mending_mantra"
light_range = 1.5
light_color = "#1E8CE1"
/obj/effect/overlay/temp/ratvar/mending_mantra/Initialize(mapload)
. = ..()
transform = matrix()*2
var/matrix/M = transform
M.Turn(90)
animate(src, alpha = 20, time = duration, easing = BOUNCE_EASING, flags = ANIMATION_PARALLEL)
animate(src, transform = M, time = duration, flags = ANIMATION_PARALLEL)
/obj/effect/overlay/temp/ratvar/volt_hit
name = "volt blast"
layer = ABOVE_MOB_LAYER
duration = 5
icon_state = "volt_hit"
light_range = 1.5
light_power = 2
light_color = LIGHT_COLOR_ORANGE
var/mob/user
var/damage = 20
/obj/effect/overlay/temp/ratvar/volt_hit/Initialize(mapload, caster, multiplier)
if(multiplier)
damage *= multiplier
duration = max(round(damage * 0.2), 1)
. = ..()
/obj/effect/overlay/temp/ratvar/volt_hit/true/Initialize(mapload, caster, multiplier)
. = ..()
user = caster
if(user)
var/matrix/M = new
M.Turn(Get_Angle(src, user))
transform = M
INVOKE_ASYNC(src, .proc/volthit)
/obj/effect/overlay/temp/ratvar/volt_hit/proc/volthit()
if(user)
Beam(get_turf(user), "volt_ray", time=duration, maxdistance=8, beam_type=/obj/effect/ebeam/volt_ray)
var/hit_amount = 0
var/turf/T = get_turf(src)
for(var/mob/living/L in T)
if(is_servant_of_ratvar(L))
continue
var/obj/item/I = L.null_rod_check()
if(I)
L.visible_message("<span class='warning'>Strange energy flows into [L]'s [I.name]!</span>", \
"<span class='userdanger'>Your [I.name] shields you from [src]!</span>")
continue
L.visible_message("<span class='warning'>[L] is struck by a [name]!</span>", "<span class='userdanger'>You're struck by a [name]!</span>")
L.apply_damage(damage, BURN, "chest", L.run_armor_check("chest", "laser", "Your armor absorbs [src]!", "Your armor blocks part of [src]!", 0, "Your armor was penetrated by [src]!"))
add_logs(user, L, "struck with a volt blast")
hit_amount++
for(var/obj/mecha/M in T)
if(M.occupant)
if(is_servant_of_ratvar(M.occupant))
continue
to_chat(M.occupant, "<span class='userdanger'>Your [M.name] is struck by a [name]!</span>")
M.visible_message("<span class='warning'>[M] is struck by a [name]!</span>")
M.take_damage(damage, BURN, 0, 0)
hit_amount++
if(hit_amount)
playsound(src, 'sound/machines/defib_zap.ogg', damage*hit_amount, 1, -1)
else
playsound(src, "sparks", 50, 1)
/obj/effect/overlay/temp/ratvar/ocular_warden
name = "warden's gaze"
layer = ABOVE_MOB_LAYER
icon_state = "warden_gaze"
duration = 3
/obj/effect/overlay/temp/ratvar/ocular_warden/Initialize()
. = ..()
pixel_x = rand(-8, 8)
pixel_y = rand(-10, 10)
animate(src, alpha = 0, time = 3, easing = EASE_OUT)
/obj/effect/overlay/temp/ratvar/spearbreak
icon = 'icons/effects/64x64.dmi'
icon_state = "ratvarspearbreak"
layer = BELOW_MOB_LAYER
pixel_y = -16
pixel_x = -16
/obj/effect/overlay/temp/ratvar/geis_binding
icon_state = "geisbinding"
/obj/effect/overlay/temp/ratvar/geis_binding/top
icon_state = "geisbinding_top"
/obj/effect/overlay/temp/ratvar/component
icon = 'icons/obj/clockwork_objects.dmi'
icon_state = "belligerent_eye"
layer = ABOVE_MOB_LAYER
duration = 10
/obj/effect/overlay/temp/ratvar/component/Initialize()
. = ..()
transform = matrix()*0.75
pixel_x = rand(-10, 10)
pixel_y = rand(-10, -2)
animate(src, pixel_y = pixel_y + 10, alpha = 50, time = 10, easing = EASE_OUT)
/obj/effect/overlay/temp/ratvar/component/cogwheel
icon_state = "vanguard_cogwheel"
/obj/effect/overlay/temp/ratvar/component/capacitor
icon_state = "geis_capacitor"
/obj/effect/overlay/temp/ratvar/component/alloy
icon_state = "replicant_alloy"
/obj/effect/overlay/temp/ratvar/component/ansible
icon_state = "hierophant_ansible"
/obj/effect/overlay/temp/ratvar/sigil
name = "glowing circle"
icon_state = "sigildull"
/obj/effect/overlay/temp/ratvar/sigil/transgression
color = "#FAE48C"
layer = ABOVE_MOB_LAYER
duration = 70
light_range = 5
light_power = 2
light_color = "#FAE48C"
/obj/effect/overlay/temp/ratvar/sigil/transgression/Initialize()
. = ..()
var/oldtransform = transform
animate(src, transform = matrix()*2, time = 5)
animate(transform = oldtransform, alpha = 0, time = 65)
/obj/effect/overlay/temp/ratvar/sigil/vitality
color = "#1E8CE1"
icon_state = "sigilactivepulse"
layer = ABOVE_MOB_LAYER
light_range = 1.4
light_power = 0.5
light_color = "#1E8CE1"
/obj/effect/overlay/temp/ratvar/sigil/accession
color = "#AF0AAF"
layer = ABOVE_MOB_LAYER
duration = 70
icon_state = "sigilactiveoverlay"
alpha = 0
/obj/effect/overlay/temp/revenant
name = "spooky lights"
icon_state = "purplesparkles"
/obj/effect/overlay/temp/revenant/cracks
name = "glowing cracks"
icon_state = "purplecrack"
duration = 6
/obj/effect/overlay/temp/gravpush
name = "gravity wave"
icon_state = "shieldsparkles"
duration = 5
/obj/effect/overlay/temp/telekinesis
name = "telekinetic force"
icon_state = "empdisable"
duration = 5
/obj/effect/overlay/temp/emp
name = "emp sparks"
icon_state = "empdisable"
/obj/effect/overlay/temp/emp/pulse
name = "emp pulse"
icon_state = "emppulse"
duration = 8
randomdir = 0
/obj/effect/overlay/temp/gib_animation
icon = 'icons/mob/mob.dmi'
duration = 15
/obj/effect/overlay/temp/gib_animation/Initialize(mapload, gib_icon)
icon_state = gib_icon // Needs to be before ..() so icon is correct
. = ..()
/obj/effect/overlay/temp/gib_animation/ex_act(severity)
return //so the overlay isn't deleted by the explosion that gibbed the mob.
/obj/effect/overlay/temp/gib_animation/animal
icon = 'icons/mob/animal.dmi'
/obj/effect/overlay/temp/dust_animation
icon = 'icons/mob/mob.dmi'
duration = 15
/obj/effect/overlay/temp/dust_animation/Initialize(mapload, dust_icon)
icon_state = dust_icon // Before ..() so the correct icon is flick()'d
. = ..()
/obj/effect/overlay/temp/mummy_animation
icon = 'icons/mob/mob.dmi'
icon_state = "mummy_revive"
duration = 20
/obj/effect/overlay/temp/heal //color is white by default, set to whatever is needed
name = "healing glow"
icon_state = "heal"
duration = 15
/obj/effect/overlay/temp/heal/Initialize(mapload, colour)
if(colour)
color = colour
. = ..()
pixel_x = rand(-12, 12)
pixel_y = rand(-9, 0)
/obj/effect/overlay/temp/kinetic_blast
name = "kinetic explosion"
icon = 'icons/obj/projectiles.dmi'
icon_state = "kinetic_blast"
layer = ABOVE_ALL_MOB_LAYER
duration = 4
/obj/effect/overlay/temp/explosion
name = "explosion"
icon = 'icons/effects/96x96.dmi'
icon_state = "explosion"
pixel_x = -32
pixel_y = -32
duration = 8
/obj/effect/overlay/temp/explosion/fast
icon_state = "explosionfast"
duration = 4
/obj/effect/overlay/temp/blob
name = "blob"
icon_state = "blob_attack"
alpha = 140
randomdir = 0
duration = 6
/obj/effect/overlay/temp/impact_effect
icon_state = "impact_bullet"
duration = 5
/obj/effect/overlay/temp/impact_effect/Initialize(mapload, atom/target, obj/item/projectile/P)
if(target == P.original) //the projectile hit the target originally clicked
pixel_x = P.p_x + target.pixel_x - 16 + rand(-4,4)
pixel_y = P.p_y + target.pixel_y - 16 + rand(-4,4)
else
pixel_x = target.pixel_x + rand(-4,4)
pixel_y = target.pixel_y + rand(-4,4)
. = ..()
/obj/effect/overlay/temp/impact_effect/red_laser
icon_state = "impact_laser"
duration = 4
/obj/effect/overlay/temp/impact_effect/red_laser/wall
icon_state = "impact_laser_wall"
duration = 10
/obj/effect/overlay/temp/impact_effect/blue_laser
icon_state = "impact_laser_blue"
duration = 4
/obj/effect/overlay/temp/impact_effect/green_laser
icon_state = "impact_laser_green"
duration = 4
/obj/effect/overlay/temp/impact_effect/purple_laser
icon_state = "impact_laser_purple"
duration = 4
/obj/effect/overlay/temp/impact_effect/ion
icon_state = "shieldsparkles"
duration = 6
/obj/effect/overlay/temp/heart
name = "heart"
icon = 'icons/mob/animal.dmi'
icon_state = "heart"
duration = 25
/obj/effect/overlay/temp/heart/Initialize(mapload)
. = ..()
pixel_x = rand(-4,4)
pixel_y = rand(-4,4)
animate(src, pixel_y = pixel_y + 32, alpha = 0, time = 25)
/obj/effect/overlay/palmtree_r
name = "Palm tree"
icon = 'icons/misc/beach2.dmi'
@@ -0,0 +1,218 @@
//temporary visual effects(/obj/effect/overlay/temp) used by clockcult stuff
/obj/effect/overlay/temp/ratvar
name = "ratvar's light"
icon = 'icons/effects/clockwork_effects.dmi'
duration = 8
randomdir = 0
layer = ABOVE_NORMAL_TURF_LAYER
/obj/effect/overlay/temp/ratvar/door
icon_state = "ratvardoorglow"
layer = CLOSED_DOOR_LAYER //above closed doors
/obj/effect/overlay/temp/ratvar/door/window
icon_state = "ratvarwindoorglow"
layer = ABOVE_WINDOW_LAYER
/obj/effect/overlay/temp/ratvar/beam
icon_state = "ratvarbeamglow"
/obj/effect/overlay/temp/ratvar/beam/door
layer = CLOSED_DOOR_LAYER
/obj/effect/overlay/temp/ratvar/beam/grille
layer = BELOW_OBJ_LAYER
/obj/effect/overlay/temp/ratvar/beam/itemconsume
layer = HIGH_OBJ_LAYER
/obj/effect/overlay/temp/ratvar/beam/falsewall
layer = OBJ_LAYER
/obj/effect/overlay/temp/ratvar/beam/catwalk
layer = LATTICE_LAYER
/obj/effect/overlay/temp/ratvar/wall
icon_state = "ratvarwallglow"
/obj/effect/overlay/temp/ratvar/wall/false
layer = OBJ_LAYER
/obj/effect/overlay/temp/ratvar/floor
icon_state = "ratvarfloorglow"
/obj/effect/overlay/temp/ratvar/floor/catwalk
layer = LATTICE_LAYER
/obj/effect/overlay/temp/ratvar/window
icon_state = "ratvarwindowglow"
layer = ABOVE_OBJ_LAYER
/obj/effect/overlay/temp/ratvar/window/single
icon_state = "ratvarwindowglow_s"
/obj/effect/overlay/temp/ratvar/gear
icon_state = "ratvargearglow"
layer = BELOW_OBJ_LAYER
/obj/effect/overlay/temp/ratvar/grille
icon_state = "ratvargrilleglow"
layer = BELOW_OBJ_LAYER
/obj/effect/overlay/temp/ratvar/grille/broken
icon_state = "ratvarbrokengrilleglow"
/obj/effect/overlay/temp/ratvar/mending_mantra
layer = ABOVE_MOB_LAYER
duration = 20
alpha = 200
icon_state = "mending_mantra"
light_range = 1.5
light_color = "#1E8CE1"
/obj/effect/overlay/temp/ratvar/mending_mantra/Initialize(mapload)
. = ..()
transform = matrix()*2
var/matrix/M = transform
M.Turn(90)
animate(src, alpha = 20, time = duration, easing = BOUNCE_EASING, flags = ANIMATION_PARALLEL)
animate(src, transform = M, time = duration, flags = ANIMATION_PARALLEL)
/obj/effect/overlay/temp/ratvar/volt_hit
name = "volt blast"
layer = ABOVE_MOB_LAYER
duration = 5
icon_state = "volt_hit"
light_range = 1.5
light_power = 2
light_color = LIGHT_COLOR_ORANGE
var/mob/user
var/damage = 20
/obj/effect/overlay/temp/ratvar/volt_hit/Initialize(mapload, caster, multiplier)
if(multiplier)
damage *= multiplier
duration = max(round(damage * 0.2), 1)
. = ..()
/obj/effect/overlay/temp/ratvar/volt_hit/true/Initialize(mapload, caster, multiplier)
. = ..()
user = caster
if(user)
var/matrix/M = new
M.Turn(Get_Angle(src, user))
transform = M
INVOKE_ASYNC(src, .proc/volthit)
/obj/effect/overlay/temp/ratvar/volt_hit/proc/volthit()
if(user)
Beam(get_turf(user), "volt_ray", time=duration, maxdistance=8, beam_type=/obj/effect/ebeam/volt_ray)
var/hit_amount = 0
var/turf/T = get_turf(src)
for(var/mob/living/L in T)
if(is_servant_of_ratvar(L))
continue
var/obj/item/I = L.null_rod_check()
if(I)
L.visible_message("<span class='warning'>Strange energy flows into [L]'s [I.name]!</span>", \
"<span class='userdanger'>Your [I.name] shields you from [src]!</span>")
continue
L.visible_message("<span class='warning'>[L] is struck by a [name]!</span>", "<span class='userdanger'>You're struck by a [name]!</span>")
L.apply_damage(damage, BURN, "chest", L.run_armor_check("chest", "laser", "Your armor absorbs [src]!", "Your armor blocks part of [src]!", 0, "Your armor was penetrated by [src]!"))
add_logs(user, L, "struck with a volt blast")
hit_amount++
for(var/obj/mecha/M in T)
if(M.occupant)
if(is_servant_of_ratvar(M.occupant))
continue
to_chat(M.occupant, "<span class='userdanger'>Your [M.name] is struck by a [name]!</span>")
M.visible_message("<span class='warning'>[M] is struck by a [name]!</span>")
M.take_damage(damage, BURN, 0, 0)
hit_amount++
if(hit_amount)
playsound(src, 'sound/machines/defib_zap.ogg', damage*hit_amount, 1, -1)
else
playsound(src, "sparks", 50, 1)
/obj/effect/overlay/temp/ratvar/ocular_warden
name = "warden's gaze"
layer = ABOVE_MOB_LAYER
icon_state = "warden_gaze"
duration = 3
/obj/effect/overlay/temp/ratvar/ocular_warden/Initialize()
. = ..()
pixel_x = rand(-8, 8)
pixel_y = rand(-10, 10)
animate(src, alpha = 0, time = 3, easing = EASE_OUT)
/obj/effect/overlay/temp/ratvar/spearbreak
icon = 'icons/effects/64x64.dmi'
icon_state = "ratvarspearbreak"
layer = BELOW_MOB_LAYER
pixel_y = -16
pixel_x = -16
/obj/effect/overlay/temp/ratvar/geis_binding
icon_state = "geisbinding"
/obj/effect/overlay/temp/ratvar/geis_binding/top
icon_state = "geisbinding_top"
/obj/effect/overlay/temp/ratvar/component
icon = 'icons/obj/clockwork_objects.dmi'
icon_state = "belligerent_eye"
layer = ABOVE_MOB_LAYER
duration = 10
/obj/effect/overlay/temp/ratvar/component/Initialize()
. = ..()
transform = matrix()*0.75
pixel_x = rand(-10, 10)
pixel_y = rand(-10, -2)
animate(src, pixel_y = pixel_y + 10, alpha = 50, time = 10, easing = EASE_OUT)
/obj/effect/overlay/temp/ratvar/component/cogwheel
icon_state = "vanguard_cogwheel"
/obj/effect/overlay/temp/ratvar/component/capacitor
icon_state = "geis_capacitor"
/obj/effect/overlay/temp/ratvar/component/alloy
icon_state = "replicant_alloy"
/obj/effect/overlay/temp/ratvar/component/ansible
icon_state = "hierophant_ansible"
/obj/effect/overlay/temp/ratvar/sigil
name = "glowing circle"
icon_state = "sigildull"
/obj/effect/overlay/temp/ratvar/sigil/transgression
color = "#FAE48C"
layer = ABOVE_MOB_LAYER
duration = 70
light_range = 5
light_power = 2
light_color = "#FAE48C"
/obj/effect/overlay/temp/ratvar/sigil/transgression/Initialize()
. = ..()
var/oldtransform = transform
animate(src, transform = matrix()*2, time = 5)
animate(transform = oldtransform, alpha = 0, time = 65)
/obj/effect/overlay/temp/ratvar/sigil/vitality
color = "#1E8CE1"
icon_state = "sigilactivepulse"
layer = ABOVE_MOB_LAYER
light_range = 1.4
light_power = 0.5
light_color = "#1E8CE1"
/obj/effect/overlay/temp/ratvar/sigil/accession
color = "#AF0AAF"
layer = ABOVE_MOB_LAYER
duration = 70
icon_state = "sigilactiveoverlay"
alpha = 0
@@ -0,0 +1,144 @@
//temporary visual effects(/obj/effect/overlay/temp) used by cult stuff
/obj/effect/overlay/temp/cult
icon = 'icons/effects/cult_effects.dmi'
randomdir = 0
duration = 10
/obj/effect/overlay/temp/cult/sparks
randomdir = 1
name = "blood sparks"
icon_state = "bloodsparkles"
/obj/effect/overlay/temp/cult/blood // The traditional teleport
name = "blood jaunt"
duration = 12
icon_state = "bloodin"
/obj/effect/overlay/temp/cult/blood/out
icon_state = "bloodout"
/obj/effect/overlay/temp/dir_setting/cult/phase // The veil shifter teleport
name = "phase glow"
duration = 7
icon_state = "cultin"
/obj/effect/overlay/temp/dir_setting/cult/phase/out
icon_state = "cultout"
/obj/effect/overlay/temp/cult/sac
name = "maw of Nar-Sie"
icon_state = "sacconsume"
/obj/effect/overlay/temp/cult/door
name = "unholy glow"
icon_state = "doorglow"
layer = CLOSED_FIREDOOR_LAYER //above closed doors
/obj/effect/overlay/temp/cult/door/unruned
icon_state = "unruneddoorglow"
/obj/effect/overlay/temp/cult/turf
name = "unholy glow"
icon_state = "wallglow"
layer = ABOVE_NORMAL_TURF_LAYER
/obj/effect/overlay/temp/cult/turf/floor
icon_state = "floorglow"
duration = 5
//visuals for runes being magically created
/obj/effect/overlay/temp/cult/rune_spawn
icon_state = "runeouter"
alpha = 0
var/turnedness = 179 //179 turns counterclockwise, 181 turns clockwise
/obj/effect/overlay/temp/cult/rune_spawn/Initialize(mapload, set_duration, set_color)
if(isnum(set_duration))
duration = set_duration
if(set_color)
add_atom_colour(set_color, FIXED_COLOUR_PRIORITY)
. = ..()
var/oldtransform = transform
transform = matrix()*2
var/matrix/M = transform
M.Turn(turnedness)
transform = M
animate(src, alpha = 255, time = duration, easing = BOUNCE_EASING, flags = ANIMATION_PARALLEL)
animate(src, transform = oldtransform, time = duration, flags = ANIMATION_PARALLEL)
/obj/effect/overlay/temp/cult/rune_spawn/rune1
icon_state = "rune1words"
turnedness = 181
/obj/effect/overlay/temp/cult/rune_spawn/rune1/inner
icon_state = "rune1inner"
turnedness = 179
/obj/effect/overlay/temp/cult/rune_spawn/rune1/center
icon_state = "rune1center"
/obj/effect/overlay/temp/cult/rune_spawn/rune2
icon_state = "rune2words"
turnedness = 181
/obj/effect/overlay/temp/cult/rune_spawn/rune2/inner
icon_state = "rune2inner"
turnedness = 179
/obj/effect/overlay/temp/cult/rune_spawn/rune2/center
icon_state = "rune2center"
/obj/effect/overlay/temp/cult/rune_spawn/rune3
icon_state = "rune3words"
turnedness = 181
/obj/effect/overlay/temp/cult/rune_spawn/rune3/inner
icon_state = "rune3inner"
turnedness = 179
/obj/effect/overlay/temp/cult/rune_spawn/rune3/center
icon_state = "rune3center"
/obj/effect/overlay/temp/cult/rune_spawn/rune4
icon_state = "rune4words"
turnedness = 181
/obj/effect/overlay/temp/cult/rune_spawn/rune4/inner
icon_state = "rune4inner"
turnedness = 179
/obj/effect/overlay/temp/cult/rune_spawn/rune4/center
icon_state = "rune4center"
/obj/effect/overlay/temp/cult/rune_spawn/rune5
icon_state = "rune5words"
turnedness = 181
/obj/effect/overlay/temp/cult/rune_spawn/rune5/inner
icon_state = "rune5inner"
turnedness = 179
/obj/effect/overlay/temp/cult/rune_spawn/rune5/center
icon_state = "rune5center"
/obj/effect/overlay/temp/cult/rune_spawn/rune6
icon_state = "rune6words"
turnedness = 181
/obj/effect/overlay/temp/cult/rune_spawn/rune6/inner
icon_state = "rune6inner"
turnedness = 179
/obj/effect/overlay/temp/cult/rune_spawn/rune6/center
icon_state = "rune6center"
/obj/effect/overlay/temp/cult/rune_spawn/rune7
icon_state = "rune7words"
turnedness = 181
/obj/effect/overlay/temp/cult/rune_spawn/rune7/inner
icon_state = "rune7inner"
turnedness = 179
/obj/effect/overlay/temp/cult/rune_spawn/rune7/center
icon_state = "rune7center"
@@ -0,0 +1,312 @@
//unsorted miscellaneous temporary visuals
/obj/effect/overlay/temp/dir_setting/bloodsplatter
icon = 'icons/effects/blood.dmi'
duration = 5
randomdir = FALSE
layer = BELOW_MOB_LAYER
var/splatter_type = "splatter"
/obj/effect/overlay/temp/dir_setting/bloodsplatter/Initialize(mapload, set_dir)
if(set_dir in GLOB.diagonals)
icon_state = "[splatter_type][pick(1, 2, 6)]"
else
icon_state = "[splatter_type][pick(3, 4, 5)]"
. = ..()
var/target_pixel_x = 0
var/target_pixel_y = 0
switch(set_dir)
if(NORTH)
target_pixel_y = 16
if(SOUTH)
target_pixel_y = -16
layer = ABOVE_MOB_LAYER
if(EAST)
target_pixel_x = 16
if(WEST)
target_pixel_x = -16
if(NORTHEAST)
target_pixel_x = 16
target_pixel_y = 16
if(NORTHWEST)
target_pixel_x = -16
target_pixel_y = 16
if(SOUTHEAST)
target_pixel_x = 16
target_pixel_y = -16
layer = ABOVE_MOB_LAYER
if(SOUTHWEST)
target_pixel_x = -16
target_pixel_y = -16
layer = ABOVE_MOB_LAYER
animate(src, pixel_x = target_pixel_x, pixel_y = target_pixel_y, alpha = 0, time = duration)
/obj/effect/overlay/temp/dir_setting/bloodsplatter/xenosplatter
splatter_type = "xsplatter"
/obj/effect/overlay/temp/dir_setting/speedbike_trail
name = "speedbike trails"
icon_state = "ion_fade"
layer = BELOW_MOB_LAYER
duration = 10
randomdir = 0
/obj/effect/overlay/temp/dir_setting/firing_effect
icon = 'icons/effects/effects.dmi'
icon_state = "firing_effect"
duration = 2
/obj/effect/overlay/temp/dir_setting/firing_effect/setDir(newdir)
switch(newdir)
if(NORTH)
layer = BELOW_MOB_LAYER
pixel_x = rand(-3,3)
pixel_y = rand(4,6)
if(SOUTH)
pixel_x = rand(-3,3)
pixel_y = rand(-1,1)
else
pixel_x = rand(-1,1)
pixel_y = rand(-1,1)
..()
/obj/effect/overlay/temp/dir_setting/firing_effect/energy
icon_state = "firing_effect_energy"
duration = 3
/obj/effect/overlay/temp/dir_setting/firing_effect/magic
icon_state = "shieldsparkles"
duration = 3
/obj/effect/overlay/temp/dir_setting/ninja
name = "ninja shadow"
icon = 'icons/mob/mob.dmi'
icon_state = "uncloak"
duration = 9
/obj/effect/overlay/temp/dir_setting/ninja/cloak
icon_state = "cloak"
/obj/effect/overlay/temp/dir_setting/ninja/shadow
icon_state = "shadow"
/obj/effect/overlay/temp/dir_setting/ninja/phase
name = "ninja energy"
icon_state = "phasein"
/obj/effect/overlay/temp/dir_setting/ninja/phase/out
icon_state = "phaseout"
/obj/effect/overlay/temp/dir_setting/wraith
name = "blood"
icon = 'icons/mob/mob.dmi'
icon_state = "phase_shift2"
duration = 12
/obj/effect/overlay/temp/dir_setting/wraith/out
icon_state = "phase_shift"
/obj/effect/overlay/temp/dir_setting/tailsweep
icon_state = "tailsweep"
duration = 4
/obj/effect/overlay/temp/wizard
name = "water"
icon = 'icons/mob/mob.dmi'
icon_state = "reappear"
duration = 5
/obj/effect/overlay/temp/wizard/out
icon_state = "liquify"
duration = 12
/obj/effect/overlay/temp/monkeyify
icon = 'icons/mob/mob.dmi'
icon_state = "h2monkey"
duration = 22
/obj/effect/overlay/temp/monkeyify/humanify
icon_state = "monkey2h"
/obj/effect/overlay/temp/borgflash
icon = 'icons/mob/mob.dmi'
icon_state = "blspell"
duration = 5
/obj/effect/overlay/temp/guardian
randomdir = 0
/obj/effect/overlay/temp/guardian/phase
duration = 5
icon_state = "phasein"
/obj/effect/overlay/temp/guardian/phase/out
icon_state = "phaseout"
/obj/effect/overlay/temp/decoy
desc = "It's a decoy!"
duration = 15
/obj/effect/overlay/temp/decoy/Initialize(mapload, atom/mimiced_atom)
. = ..()
alpha = initial(alpha)
if(mimiced_atom)
name = mimiced_atom.name
appearance = mimiced_atom.appearance
setDir(mimiced_atom.dir)
mouse_opacity = 0
/obj/effect/overlay/temp/decoy/fading/Initialize(mapload, atom/mimiced_atom)
. = ..()
animate(src, alpha = 0, time = duration)
/obj/effect/overlay/temp/decoy/fading/fivesecond
duration = 50
/obj/effect/overlay/temp/small_smoke
icon_state = "smoke"
duration = 50
/obj/effect/overlay/temp/fire
icon = 'icons/effects/fire.dmi'
icon_state = "3"
duration = 20
/obj/effect/overlay/temp/revenant
name = "spooky lights"
icon_state = "purplesparkles"
/obj/effect/overlay/temp/revenant/cracks
name = "glowing cracks"
icon_state = "purplecrack"
duration = 6
/obj/effect/overlay/temp/gravpush
name = "gravity wave"
icon_state = "shieldsparkles"
duration = 5
/obj/effect/overlay/temp/telekinesis
name = "telekinetic force"
icon_state = "empdisable"
duration = 5
/obj/effect/overlay/temp/emp
name = "emp sparks"
icon_state = "empdisable"
/obj/effect/overlay/temp/emp/pulse
name = "emp pulse"
icon_state = "emppulse"
duration = 8
randomdir = 0
/obj/effect/overlay/temp/gib_animation
icon = 'icons/mob/mob.dmi'
duration = 15
/obj/effect/overlay/temp/gib_animation/Initialize(mapload, gib_icon)
icon_state = gib_icon // Needs to be before ..() so icon is correct
. = ..()
/obj/effect/overlay/temp/gib_animation/animal
icon = 'icons/mob/animal.dmi'
/obj/effect/overlay/temp/dust_animation
icon = 'icons/mob/mob.dmi'
duration = 15
/obj/effect/overlay/temp/dust_animation/Initialize(mapload, dust_icon)
icon_state = dust_icon // Before ..() so the correct icon is flick()'d
. = ..()
/obj/effect/overlay/temp/mummy_animation
icon = 'icons/mob/mob.dmi'
icon_state = "mummy_revive"
duration = 20
/obj/effect/overlay/temp/heal //color is white by default, set to whatever is needed
name = "healing glow"
icon_state = "heal"
duration = 15
/obj/effect/overlay/temp/heal/Initialize(mapload, set_color)
if(set_color)
add_atom_colour(set_color, FIXED_COLOUR_PRIORITY)
. = ..()
pixel_x = rand(-12, 12)
pixel_y = rand(-9, 0)
/obj/effect/overlay/temp/kinetic_blast
name = "kinetic explosion"
icon = 'icons/obj/projectiles.dmi'
icon_state = "kinetic_blast"
layer = ABOVE_ALL_MOB_LAYER
duration = 4
/obj/effect/overlay/temp/explosion
name = "explosion"
icon = 'icons/effects/96x96.dmi'
icon_state = "explosion"
pixel_x = -32
pixel_y = -32
duration = 8
/obj/effect/overlay/temp/explosion/fast
icon_state = "explosionfast"
duration = 4
/obj/effect/overlay/temp/blob
name = "blob"
icon_state = "blob_attack"
alpha = 140
randomdir = 0
duration = 6
/obj/effect/overlay/temp/impact_effect
icon_state = "impact_bullet"
duration = 5
/obj/effect/overlay/temp/impact_effect/Initialize(mapload, atom/target, obj/item/projectile/P)
if(target == P.original) //the projectile hit the target originally clicked
pixel_x = P.p_x + target.pixel_x - 16 + rand(-4,4)
pixel_y = P.p_y + target.pixel_y - 16 + rand(-4,4)
else
pixel_x = target.pixel_x + rand(-4,4)
pixel_y = target.pixel_y + rand(-4,4)
. = ..()
/obj/effect/overlay/temp/impact_effect/red_laser
icon_state = "impact_laser"
duration = 4
/obj/effect/overlay/temp/impact_effect/red_laser/wall
icon_state = "impact_laser_wall"
duration = 10
/obj/effect/overlay/temp/impact_effect/blue_laser
icon_state = "impact_laser_blue"
duration = 4
/obj/effect/overlay/temp/impact_effect/green_laser
icon_state = "impact_laser_green"
duration = 4
/obj/effect/overlay/temp/impact_effect/purple_laser
icon_state = "impact_laser_purple"
duration = 4
/obj/effect/overlay/temp/impact_effect/ion
icon_state = "shieldsparkles"
duration = 6
/obj/effect/overlay/temp/heart
name = "heart"
icon = 'icons/mob/animal.dmi'
icon_state = "heart"
duration = 25
/obj/effect/overlay/temp/heart/Initialize(mapload)
. = ..()
pixel_x = rand(-4,4)
pixel_y = rand(-4,4)
animate(src, pixel_y = pixel_y + 32, alpha = 0, time = 25)
@@ -0,0 +1,37 @@
//temporary visual effects
/obj/effect/overlay/temp
icon_state = "nothing"
anchored = 1
layer = ABOVE_MOB_LAYER
mouse_opacity = 0
var/duration = 10 //in deciseconds
var/randomdir = TRUE
var/timerid
/obj/effect/overlay/temp/Initialize()
. = ..()
if(randomdir)
setDir(pick(GLOB.cardinal))
timerid = QDEL_IN(src, duration)
/obj/effect/overlay/temp/Destroy()
. = ..()
deltimer(timerid)
/obj/effect/overlay/temp/singularity_act()
return
/obj/effect/overlay/temp/singularity_pull()
return
/obj/effect/overlay/temp/ex_act()
return
/obj/effect/overlay/temp/dir_setting
randomdir = FALSE
/obj/effect/overlay/temp/dir_setting/Initialize(mapload, set_dir)
if(set_dir)
setDir(set_dir)
. = ..()
+3
View File
@@ -528,6 +528,9 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
/obj/item/throw_impact(atom/A)
if(A && !QDELETED(A))
if(is_hot() && isliving(A))
var/mob/living/L = A
L.IgniteMob()
var/itempush = 1
if(w_class < 4)
itempush = 0 //too light to push anything
@@ -504,6 +504,113 @@
S.change_head_color(color2)
dropped = TRUE
//Peacekeeper Cyborg Projectile Dampenening Field
/obj/item/borg/projectile_dampen
name = "Hyperkinetic Dampening projector"
desc = "A device that projects a dampening field that weakens kinetic energy above a certain threshold. <span class='boldnotice'>Projects a field that drains power per second \
while active, that will weaken and slow damaging projectiles inside its field.</span> Still being a prototype, it tends to induce a charge on ungrounded metallic surfaces."
icon = 'icons/obj/device.dmi'
icon_state = "shield"
var/maxenergy = 1500
var/energy = 1500
var/energy_recharge = 7.5
var/energy_recharge_cyborg_drain_coefficient = 0.4
var/cyborg_cell_critical_percentage = 0.05
var/mob/living/silicon/robot/host = null
var/datum/proximity_monitor/advanced/dampening_field
var/projectile_damage_coefficient = 0.5
var/projectile_damage_tick_ecost_coefficient = 2 //Lasers get half their damage chopped off, drains 50 power/tick. Note that fields are processed 5 times per second.
var/projectile_speed_coefficient = 1.5 //Higher the coefficient slower the projectile.
var/projectile_tick_speed_ecost = 15
var/current_damage_dampening = 0
var/list/obj/item/projectile/tracked
var/image/projectile_effect
var/field_radius = 3
/obj/item/borg/projectile_dampen/debug
maxenergy = 50000
energy = 50000
energy_recharge = 5000
/obj/item/borg/projectile_dampen/Initialize()
. = ..()
projectile_effect = image('icons/effects/fields.dmi', "projectile_dampen_effect")
tracked = list()
icon_state = "shield0"
START_PROCESSING(SSfastprocess, src)
/obj/item/borg/projectile_dampen/Destroy()
STOP_PROCESSING(SSfastprocess, src)
return ..()
/obj/item/borg/projectile_dampen/attack_self(mob/user)
var/active = FALSE
if(!istype(dampening_field))
activate_field()
active = TRUE
else
deactivate_field()
active = FALSE
to_chat(user, "<span class='boldnotice'>You [active? "activate":"deactivate"] the [src].</span>")
icon_state = "[initial(icon_state)][active]"
/obj/item/borg/projectile_dampen/proc/activate_field()
if(!istype(dampening_field))
dampening_field = make_field(/datum/proximity_monitor/advanced/peaceborg_dampener, list("current_range" = field_radius, "host" = src, "projector" = src))
/obj/item/borg/projectile_dampen/proc/deactivate_field()
QDEL_NULL(dampening_field)
visible_message("<span class='warning'>The [src] shuts off!</span>")
for(var/obj/item/projectile/P in tracked)
restore_projectile(P)
/obj/item/borg/projectile_dampen/process()
process_recharge()
process_usage()
update_location()
/obj/item/borg/projectile_dampen/proc/update_location()
if(dampening_field)
dampening_field.HandleMove()
/obj/item/borg/projectile_dampen/proc/process_usage()
var/usage = 0
for(var/I in tracked)
if(!tracked[I]) //No damage
continue
usage += projectile_tick_speed_ecost
usage += (current_damage_dampening * projectile_damage_tick_ecost_coefficient)
energy = Clamp(energy - usage, 0, maxenergy)
if(energy <= 0)
deactivate_field()
visible_message("<span class='warning'>The [src] blinks \"ENERGY DEPLETED\"</span>")
/obj/item/borg/projectile_dampen/proc/process_recharge()
if(!istype(host))
energy = Clamp(energy + energy_recharge, 0, maxenergy)
return
if((host.cell.charge >= (host.cell.maxcharge * cyborg_cell_critical_percentage)) && (energy < maxenergy))
host.cell.use(energy_recharge*energy_recharge_cyborg_drain_coefficient)
energy += energy_recharge
/obj/item/borg/projectile_dampen/proc/dampen_projectile(obj/item/projectile/P, track_projectile = TRUE)
if(tracked[P])
return
if(track_projectile)
tracked[P] = P.damage
current_damage_dampening += P.damage
P.damage *= projectile_damage_coefficient
P.speed *= projectile_speed_coefficient
P.add_overlay(projectile_effect)
/obj/item/borg/projectile_dampen/proc/restore_projectile(obj/item/projectile/P)
tracked -= P
P.damage *= (1/projectile_damage_coefficient)
P.speed *= (1/projectile_speed_coefficient)
P.cut_overlay(projectile_effect)
current_damage_dampening -= P.damage
/**********************************************************************
HUD/SIGHT things
***********************************************************************/
+22
View File
@@ -279,6 +279,28 @@
resistance_flags = FLAMMABLE
/obj/item/toy/windupToolbox
name = "windup toolbox"
desc = "A replica toolbox that rumbles when you turn the key"
icon_state = "his_grace"
item_state = "artistic_toolbox"
var/active = FALSE
icon = 'icons/obj/weapons.dmi'
attack_verb = list("robusted")
/obj/item/toy/windupToolbox/attack_self(mob/user)
if(!active)
icon_state = "his_grace_awakened"
to_chat(user, "<span class='warning'>You wind up [src], it begins to rumble.</span>")
active = TRUE
addtimer(CALLBACK(src, .proc/stopRumble), 600)
else
to_chat(user, "[src] is already active.")
/obj/item/toy/windupToolbox/proc/stopRumble()
icon_state = initial(icon_state)
active = FALSE
/*
* Subtype of Double-Bladed Energy Swords
*/
@@ -472,8 +472,10 @@ CIGARETTE PACKETS ARE IN FANCY.DM
flags = CONDUCT
slot_flags = SLOT_BELT
var/lit = 0
var/fancy = TRUE
heat = 1500
resistance_flags = FIRE_PROOF
light_color = LIGHT_COLOR_FIRE
/obj/item/weapon/lighter/update_icon()
if(lit)
@@ -484,37 +486,28 @@ CIGARETTE PACKETS ARE IN FANCY.DM
/obj/item/weapon/lighter/ignition_effect(atom/A, mob/user)
. = "<span class='rose'>With a single flick of their wrist, [user] smoothly lights [A] with [src]. Damn [user.p_theyre()] cool.</span>"
/obj/item/weapon/lighter/greyscale
name = "cheap lighter"
desc = "A cheap-as-free lighter."
icon_state = "lighter"
/obj/item/weapon/lighter/greyscale/Initialize()
. = ..()
add_atom_colour(color2hex(randomColor(1)), FIXED_COLOUR_PRIORITY)
update_icon()
/obj/item/weapon/lighter/greyscale/update_icon()
cut_overlays()
var/mutable_appearance/base_overlay = mutable_appearance(icon,"[initial(icon_state)]_base")
base_overlay.appearance_flags = RESET_COLOR //the edging doesn't change color
/obj/item/weapon/lighter/proc/set_lit(new_lit)
lit = new_lit
if(lit)
base_overlay.icon_state = "[initial(icon_state)]_on"
add_overlay(base_overlay)
/obj/item/weapon/lighter/greyscale/ignition_effect(atom/A, mob/user)
. = "<span class='notice'>After some fiddling, [user] manages to light [A] with [src].</span>"
force = 5
damtype = "fire"
hitsound = 'sound/items/welder.ogg'
attack_verb = list("burnt", "singed")
set_light(1)
START_PROCESSING(SSobj, src)
else
hitsound = "swing_hit"
force = 0
attack_verb = null //human_defense.dm takes care of it
set_light(0)
STOP_PROCESSING(SSobj, src)
update_icon()
/obj/item/weapon/lighter/attack_self(mob/living/user)
if(user.is_holding(src))
if(!lit)
lit = 1
update_icon()
force = 5
damtype = "fire"
hitsound = 'sound/items/welder.ogg'
attack_verb = list("burnt", "singed")
if(!istype(src, /obj/item/weapon/lighter/greyscale))
set_lit(TRUE)
if(fancy)
user.visible_message("Without even breaking stride, [user] flips open and lights [src] in one smooth movement.", "<span class='notice'>Without even breaking stride, you flip open and lights [src] in one smooth movement.</span>")
else
var/prot = FALSE
@@ -534,20 +527,12 @@ CIGARETTE PACKETS ARE IN FANCY.DM
user.apply_damage(5, BURN, hitzone)
user.visible_message("<span class='warning'>After a few attempts, [user] manages to light [src] - however, [user.p_they()] burn their finger in the process.</span>", "<span class='warning'>You burn yourself while lighting the lighter!</span>")
set_light(1)
START_PROCESSING(SSobj, src)
else
lit = 0
update_icon()
hitsound = "swing_hit"
force = 0
attack_verb = null //human_defense.dm takes care of it
if(!istype(src, /obj/item/weapon/lighter/greyscale))
set_lit(FALSE)
if(fancy)
user.visible_message("You hear a quiet click, as [user] shuts off [src] without even looking at what [user.p_theyre()] doing. Wow.", "<span class='notice'>You quietly shut off [src] without even looking at what you're doing. Wow.</span>")
else
user.visible_message("[user] quietly shuts off [src].", "<span class='notice'>You quietly shut off [src].")
set_light(0)
STOP_PROCESSING(SSobj, src)
else
. = ..()
@@ -562,7 +547,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
if(M == user)
cig.attackby(src, user)
else
if(!istype(src, /obj/item/weapon/lighter/greyscale))
if(fancy)
cig.light("<span class='rose'>[user] whips the [name] out and holds it for [M]. [user.p_their(TRUE)] arm is as steady as the unflickering flame they light \the [cig] with.</span>")
else
cig.light("<span class='notice'>[user] holds the [name] out for [M], and lights the [cig.name].</span>")
@@ -575,6 +560,30 @@ CIGARETTE PACKETS ARE IN FANCY.DM
/obj/item/weapon/lighter/is_hot()
return lit * heat
/obj/item/weapon/lighter/greyscale
name = "cheap lighter"
desc = "A cheap-as-free lighter."
icon_state = "lighter"
fancy = FALSE
/obj/item/weapon/lighter/greyscale/Initialize()
. = ..()
add_atom_colour(color2hex(randomColor(1)), FIXED_COLOUR_PRIORITY)
update_icon()
/obj/item/weapon/lighter/greyscale/update_icon()
cut_overlays()
var/mutable_appearance/base_overlay = mutable_appearance(icon,"[initial(icon_state)]_base")
base_overlay.appearance_flags = RESET_COLOR //the edging doesn't change color
if(lit)
base_overlay.icon_state = "[initial(icon_state)]_on"
add_overlay(base_overlay)
/obj/item/weapon/lighter/greyscale/ignition_effect(atom/A, mob/user)
. = "<span class='notice'>After some fiddling, [user] manages to light [A] with [src].</span>"
///////////
//ROLLING//
///////////
@@ -50,9 +50,7 @@
M.dna.uni_identity = merge_text(M.dna.uni_identity, fields["UI"])
M.updateappearance(mutations_overlay_update=1)
log_attack(log_msg)
else
to_chat(user, "<span class='notice'>It appears that [M] does not have compatible DNA.</span>")
return
return TRUE
/obj/item/weapon/dnainjector/attack(mob/target, mob/user)
if(!user.IsAdvancedToolUser())
@@ -79,7 +77,9 @@
add_logs(user, target, "injected", src)
inject(target, user) //Now we actually do the heavy lifting.
if(!inject(target, user)) //Now we actually do the heavy lifting.
to_chat(user, "<span class='notice'>It appears that [target] does not have compatible DNA.</span>")
used = 1
icon_state = "dnainjector0"
desc += " This one is used up."
@@ -48,23 +48,27 @@
/obj/item/weapon/grenade/attack_self(mob/user)
if(!active)
if(clown_check(user))
to_chat(user, "<span class='warning'>You prime the [name]! [det_time/10] seconds!</span>")
playsound(user.loc, 'sound/weapons/armbomb.ogg', 60, 1)
active = 1
icon_state = initial(icon_state) + "_active"
add_fingerprint(user)
var/turf/bombturf = get_turf(src)
var/area/A = get_area(bombturf)
var/message = "[ADMIN_LOOKUPFLW(user)]) has primed a [name] for detonation at [ADMIN_COORDJMP(bombturf)]"
GLOB.bombers += message
message_admins(message)
log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] [COORD(bombturf)].")
preprime(user)
if(iscarbon(user))
var/mob/living/carbon/C = user
C.throw_mode_on()
spawn(det_time)
prime()
/obj/item/weapon/grenade/proc/preprime(mob/user)
if(user)
to_chat(user, "<span class='warning'>You prime the [name]! [det_time/10] seconds!</span>")
playsound(loc, 'sound/weapons/armbomb.ogg', 60, 1)
active = TRUE
icon_state = initial(icon_state) + "_active"
add_fingerprint(user)
var/turf/bombturf = get_turf(src)
var/area/A = get_area(bombturf)
if(user)
var/message = "[ADMIN_LOOKUPFLW(user)]) has primed a [name] for detonation at [ADMIN_COORDJMP(bombturf)]"
GLOB.bombers += message
message_admins(message)
log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] [COORD(bombturf)].")
addtimer(CALLBACK(src, .proc/prime), det_time)
/obj/item/weapon/grenade/proc/prime()
@@ -104,4 +108,4 @@
if(damage && attack_type == PROJECTILE_ATTACK && prob(15))
owner.visible_message("<span class='danger'>[attack_text] hits [owner]'s [src], setting it off! What a shot!</span>")
prime()
return 1 //It hit the grenade, not them
return 1 //It hit the grenade, not them
@@ -18,6 +18,10 @@
plastic_overlay = mutable_appearance(icon, "[item_state]2")
..()
/obj/item/weapon/grenade/plastic/Initialize(mapload)
. = ..()
SET_SECONDARY_FLAG(src, NO_EMP_WIRES)
/obj/item/weapon/grenade/plastic/Destroy()
qdel(nadeassembly)
nadeassembly = null
@@ -244,7 +244,7 @@
range_multiplier = 3
fire_mode = PCANNON_FIFO
throw_amount = 1
maxWeightClass = 100 //50 pies. :^)
maxWeightClass = 150 //50 pies. :^)
clumsyCheck = FALSE
/obj/item/weapon/pneumatic_cannon/pie/can_load_item(obj/item/I, mob/user)
@@ -252,3 +252,22 @@
return ..()
to_chat(user, "<span class='warning'>[src] only accepts pies!</span>")
return FALSE
/obj/item/weapon/pneumatic_cannon/pie/selfcharge
automatic = TRUE
var/charge_amount = 1
var/charge_ticks = 1
var/charge_tick = 0
maxWeightClass = 60 //20 pies.
/obj/item/weapon/pneumatic_cannon/pie/selfcharge/Initialize()
. = ..()
START_PROCESSING(SSobj, src)
/obj/item/weapon/pneumatic_cannon/pie/selfcharge/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/weapon/pneumatic_cannon/pie/selfcharge/process()
if(++charge_tick >= charge_ticks)
fill_with_type(/obj/item/weapon/reagent_containers/food/snacks/pie, charge_amount)
+2
View File
@@ -140,6 +140,8 @@
item_state = "plasmaman_tank_belt"
slot_flags = SLOT_BELT
force = 5
volume = 3
w_class = WEIGHT_CLASS_SMALL //thanks i forgot this
/obj/item/weapon/tank/internals/plasmaman/belt/full/New()
..()
@@ -149,8 +149,8 @@
/obj/effect/mob_spawn/human/golem/attack_hand(mob/user)
if(isgolem(user) && can_transfer)
var/transfer = alert("Transfer your soul to [src]? (Warning, your old body will die!)",,"Yes","No")
if(!transfer)
var/transfer_choice = alert("Transfer your soul to [src]? (Warning, your old body will die!)",,"Yes","No")
if(transfer_choice != "Yes")
return
log_game("[user.ckey] golem-swapped into [src]")
user.visible_message("<span class='notice'>A faint light leaves [user], moving to [src] and animating it!</span>","<span class='notice'>You leave your old body behind, and transfer into [src]!</span>")
+6 -6
View File
@@ -440,7 +440,7 @@
dir = FULLTILE_WINDOW_DIR
max_integrity = 50
fulltile = 1
flags = NONE
flags = PREVENT_CLICK_UNDER
smooth = SMOOTH_TRUE
canSmoothWith = list(/obj/structure/window/fulltile, /obj/structure/window/reinforced/fulltile,/obj/structure/window/reinforced/highpressure/fulltile, /obj/structure/window/reinforced/tinted/fulltile)
glass_amount = 2
@@ -454,7 +454,7 @@
dir = FULLTILE_WINDOW_DIR
max_integrity = 100
fulltile = 1
flags = NONE
flags = PREVENT_CLICK_UNDER
smooth = SMOOTH_TRUE
canSmoothWith = list(/obj/structure/window/fulltile, /obj/structure/window/reinforced/fulltile,/obj/structure/window/reinforced/highpressure/fulltile, /obj/structure/window/reinforced/tinted/fulltile)
@@ -467,7 +467,7 @@
dir = FULLTILE_WINDOW_DIR
max_integrity = 1000
fulltile = 1
flags = NONE
flags = PREVENT_CLICK_UNDER
smooth = SMOOTH_TRUE
canSmoothWith = list(/obj/structure/window/fulltile, /obj/structure/window/reinforced/fulltile,/obj/structure/window/reinforced/highpressure/fulltile, /obj/structure/window/reinforced/tinted/fulltile)
level = 3
@@ -481,7 +481,7 @@
icon_state = "tinted_window"
dir = FULLTILE_WINDOW_DIR
fulltile = 1
flags = NONE
flags = PREVENT_CLICK_UNDER
smooth = SMOOTH_TRUE
canSmoothWith = list(/obj/structure/window/fulltile, /obj/structure/window/reinforced/fulltile,/obj/structure/window/reinforced/highpressure/fulltile, /obj/structure/window/reinforced/tinted/fulltile/)
level = 3
@@ -504,7 +504,7 @@
max_integrity = 100
wtype = "shuttle"
fulltile = 1
flags = NONE
flags = PREVENT_CLICK_UNDER
reinf = 1
heat_resistance = 1600
armor = list(melee = 50, bullet = 0, laser = 0, energy = 0, bomb = 25, bio = 100, rad = 100, fire = 80, acid = 100)
@@ -583,7 +583,7 @@
smooth = SMOOTH_TRUE
canSmoothWith = null
fulltile = 1
flags = NONE
flags = PREVENT_CLICK_UNDER
dir = FULLTILE_WINDOW_DIR
max_integrity = 120
level = 3
+3 -3
View File
@@ -42,7 +42,7 @@
if (opacity)
has_opaque_atom = TRUE
return INITIALIZE_HINT_NORMAL
/turf/open/space/attack_ghost(mob/dead/observer/user)
@@ -177,7 +177,7 @@
ChangeTurf(/turf/open/floor/plating)
return TRUE
return FALSE
/turf/open/space/ReplaceWithLattice()
var/dest_x = destination_x
var/dest_y = destination_y
@@ -186,4 +186,4 @@
destination_x = dest_x
destination_y = dest_y
destination_z = dest_z
+19 -18
View File
@@ -92,39 +92,39 @@
LC.attackby(C,user)
return
coil.place_turf(src, user)
return 1
return TRUE
return 0
return FALSE
/turf/CanPass(atom/movable/mover, turf/target, height=1.5)
if(!target) return 0
if(!target) return FALSE
if(istype(mover)) // turf/Enter(...) will perform more advanced checks
return !density
else // Now, doing more detailed checks for air movement and air group formation
if(target.blocks_air||blocks_air)
return 0
return FALSE
for(var/obj/obstacle in src)
if(!obstacle.CanPass(mover, target, height))
return 0
return FALSE
for(var/obj/obstacle in target)
if(!obstacle.CanPass(mover, src, height))
return 0
return FALSE
return 1
return TRUE
/turf/Enter(atom/movable/mover as mob|obj, atom/forget as mob|obj|turf|area)
if (!mover)
return 1
return TRUE
// First, make sure it can leave its square
if(isturf(mover.loc))
// Nothing but border objects stop you from leaving a tile, only one loop is needed
for(var/obj/obstacle in mover.loc)
if(!obstacle.CheckExit(mover, src) && obstacle != mover && obstacle != forget)
mover.Bump(obstacle, 1)
return 0
return FALSE
var/list/large_dense = list()
//Next, check objects to block entry that are on the border
@@ -132,14 +132,14 @@
if(border_obstacle.flags & ON_BORDER)
if(!border_obstacle.CanPass(mover, mover.loc, 1) && (forget != border_obstacle))
mover.Bump(border_obstacle, 1)
return 0
return FALSE
else
large_dense += border_obstacle
//Then, check the turf itself
if (!src.CanPass(mover, src))
mover.Bump(src, 1)
return 0
return FALSE
//Finally, check objects/mobs to block entry that are not on the border
var/atom/movable/tompost_bump
@@ -151,8 +151,9 @@
top_layer = obstacle.layer
if(tompost_bump)
mover.Bump(tompost_bump,1)
return 0
return 1 //Nothing found to block so return success!
return FALSE
return TRUE //Nothing found to block so return success!
/turf/Entered(atom/movable/AM)
if(explosion_level && AM.ex_check(explosion_id))
@@ -185,7 +186,7 @@
O.make_unfrozen()
/turf/proc/is_plasteel_floor()
return 0
return FALSE
/turf/proc/levelupdate()
for(var/obj/O in src)
@@ -303,7 +304,7 @@
if(src_object.contents.len)
to_chat(usr, "<span class='notice'>You start dumping out the contents...</span>")
if(!do_after(usr,20,target=src_object))
return 0
return FALSE
var/list/things = src_object.contents.Copy()
var/datum/progressbar/progress = new(user, things.len, src)
@@ -311,7 +312,7 @@
sleep(1)
qdel(progress)
return 1
return TRUE
//////////////////////////////
//Distance procs
@@ -325,7 +326,7 @@
// possible. It results in more efficient (CPU-wise) pathing
// for bots and anything else that only moves in cardinal dirs.
/turf/proc/Distance_cardinal(turf/T)
if(!src || !T) return 0
if(!src || !T) return FALSE
return abs(x - T.x) + abs(y - T.y)
////////////////////////////////////////////////////
@@ -341,7 +342,7 @@
return(2)
/turf/proc/can_have_cabling()
return 1
return TRUE
/turf/proc/can_lay_cable()
return can_have_cabling() & !intact
+4
View File
@@ -108,7 +108,11 @@ GLOBAL_PROTECT(AdminProcCallCount)
return call(target, procname)(arglist(arguments))
/proc/IsAdminAdvancedProcCall()
#ifdef TESTING
return FALSE
#else
return usr && usr.client && GLOB.AdminProcCaller == usr.client.ckey
#endif
/client/proc/callproc_datum(datum/A as null|area|mob|obj|turf)
set category = "Debug"
@@ -153,8 +153,8 @@
return
var/datum/gas_mixture/air1 = AIR1
var/turf/T = get_turf(src)
if(isliving(occupant))
var/mob/living/mob_occupant
if(occupant)
var/mob/living/mob_occupant = occupant
if(mob_occupant.health >= 100) // Don't bother with fully healed people.
on = FALSE
update_icon()
@@ -176,8 +176,8 @@
if(beaker)
if(reagent_transfer == 0) // Magically transfer reagents. Because cryo magic.
beaker.reagents.trans_to(mob_occupant, 1, 10 * efficiency) // Transfer reagents, multiplied because cryo magic.
beaker.reagents.reaction(mob_occupant, VAPOR)
beaker.reagents.trans_to(occupant, 1, 10 * efficiency) // Transfer reagents, multiplied because cryo magic.
beaker.reagents.reaction(occupant, VAPOR)
air1.gases["o2"][MOLES] -= 2 / efficiency // Lets use gas for this.
if(++reagent_transfer >= 10 * efficiency) // Throttle reagent transfer (higher efficiency will transfer the same amount but consume less from the beaker).
reagent_transfer = 0
@@ -192,7 +192,7 @@
on = FALSE
update_icon()
return
if(isliving(occupant))
if(occupant)
var/mob/living/mob_occupant = occupant
var/cold_protection = 0
var/mob/living/carbon/human/H = occupant
@@ -244,7 +244,7 @@
..()
if(occupant)
if(on)
to_chat(user, "[occupant] is inside [src]!")
to_chat(user, "Someone's inside [src]!")
else
to_chat(user, "You can barely make out a form floating in [src].")
else
@@ -299,7 +299,7 @@
data["autoEject"] = autoeject
var/list/occupantData = list()
if(isliving(occupant))
if(occupant)
var/mob/living/mob_occupant = occupant
occupantData["name"] = mob_occupant.name
occupantData["stat"] = mob_occupant.stat
+309
View File
@@ -0,0 +1,309 @@
//Movable and easily code-modified fields! Allows for custom AOE effects that affect movement and anything inside of them, and can do custom turf effects!
//Supports automatic recalculation/reset on movement.
//If there's any way to make this less CPU intensive than I've managed, gimme a call or do it yourself! - kevinz000
//Field shapes
#define FIELD_NO_SHAPE 0 //Does not update turfs automatically
#define FIELD_SHAPE_RADIUS_SQUARE 1 //Uses current_range and square_depth_up/down
#define FIELD_SHAPE_CUSTOM_SQUARE 2 //Uses square_height and square_width and square_depth_up/down
//Proc to make fields. make_field(field_type, field_params_in_associative_list)
/proc/make_field(field_type, list/field_params, override_checks = FALSE, start_field = TRUE)
var/datum/proximity_monitor/advanced/F = new field_type()
if(!F.assume_params(field_params) && !override_checks)
QDEL_NULL(F)
if(!F.check_variables() && !override_checks)
QDEL_NULL(F)
if(start_field && (F || override_checks))
F.Initialize()
return F
/datum/proximity_monitor/advanced
var/name = "\improper Energy Field"
//Field setup specifications
var/field_shape = FIELD_NO_SHAPE
var/square_height = 0
var/square_width = 0
var/square_depth_up = 0
var/square_depth_down = 0
//Processing
var/requires_processing = FALSE
var/process_inner_turfs = FALSE //Don't do this unless it's absolutely necessary
var/process_edge_turfs = FALSE //Don't do this either unless it's absolutely necessary, you can just track what things are inside manually or on the initial setup.
var/setup_edge_turfs = FALSE //Setup edge turfs/all field turfs. Set either or both to ON when you need it, it's defaulting to off unless you do to save CPU.
var/setup_field_turfs = FALSE
var/list/turf/field_turfs = list()
var/list/turf/edge_turfs = list()
var/list/turf/field_turfs_new = list()
var/list/turf/edge_turfs_new = list()
/datum/proximity_monitor/advanced/New()
SSfields.register_new_field(src)
/datum/proximity_monitor/advanced/Destroy()
SSfields.unregister_field(src)
full_cleanup()
return ..()
/datum/proximity_monitor/advanced/proc/assume_params(list/field_params)
var/pass_check = TRUE
for(var/param in field_params)
if(vars[param] || isnull(vars[param]) || (param in vars))
vars[param] = field_params[param]
else
pass_check = FALSE
return pass_check
/datum/proximity_monitor/advanced/proc/check_variables()
var/pass = TRUE
if(field_shape == FIELD_NO_SHAPE) //If you're going to make a manually updated field you shouldn't be using automatic checks so don't.
pass = FALSE
if(current_range < 0 || square_height < 0 || square_width < 0 || square_depth_up < 0 || square_depth_down < 0)
pass = FALSE
if(!istype(host))
pass = FALSE
return pass
/datum/proximity_monitor/advanced/process()
if(process_inner_turfs)
for(var/turf/T in field_turfs)
process_inner_turf(T)
CHECK_TICK //Really crappy lagchecks, needs improvement once someone starts using processed fields.
if(process_edge_turfs)
for(var/turf/T in edge_turfs)
process_edge_turf(T)
CHECK_TICK //Same here.
/datum/proximity_monitor/advanced/proc/process_inner_turf(turf/T)
/datum/proximity_monitor/advanced/proc/process_edge_turf(turf/T)
/datum/proximity_monitor/advanced/proc/Initialize()
setup_field()
post_setup_field()
/datum/proximity_monitor/advanced/proc/full_cleanup() //Full cleanup for when you change something that would require complete resetting.
for(var/turf/T in edge_turfs)
cleanup_edge_turf(T)
for(var/turf/T in field_turfs)
cleanup_field_turf(T)
/datum/proximity_monitor/advanced/proc/recalculate_field(ignore_movement_check = FALSE) //Call every time the field moves (done automatically if you use update_center) or a setup specification is changed.
if(!(ignore_movement_check || ((host.loc != last_host_loc) && (field_shape != FIELD_NO_SHAPE))))
return
update_new_turfs()
var/list/turf/needs_setup = field_turfs_new.Copy()
if(setup_field_turfs)
for(var/turf/T in field_turfs)
if(!(T in needs_setup))
cleanup_field_turf(T)
else
needs_setup -= T
CHECK_TICK
for(var/turf/T in needs_setup)
setup_field_turf(T)
CHECK_TICK
if(setup_edge_turfs)
for(var/turf/T in edge_turfs)
cleanup_edge_turf(T)
CHECK_TICK
for(var/turf/T in edge_turfs_new)
setup_edge_turf(T)
CHECK_TICK
/datum/proximity_monitor/advanced/proc/field_turf_canpass(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_turf/F, turf/entering)
return TRUE
/datum/proximity_monitor/advanced/proc/field_turf_uncross(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_turf/F)
return TRUE
/datum/proximity_monitor/advanced/proc/field_turf_crossed(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_turf/F)
return TRUE
/datum/proximity_monitor/advanced/proc/field_turf_uncrossed(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_turf/F)
return TRUE
/datum/proximity_monitor/advanced/proc/field_edge_canpass(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_edge/F, turf/entering)
return TRUE
/datum/proximity_monitor/advanced/proc/field_edge_uncross(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_edge/F)
return TRUE
/datum/proximity_monitor/advanced/proc/field_edge_crossed(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_edge/F)
return TRUE
/datum/proximity_monitor/advanced/proc/field_edge_uncrossed(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_edge/F)
return TRUE
/datum/proximity_monitor/advanced/HandleMove()
var/atom/_host = host
var/atom/new_host_loc = _host.loc
if(last_host_loc != new_host_loc)
recalculate_field()
/datum/proximity_monitor/advanced/proc/post_setup_field()
/datum/proximity_monitor/advanced/proc/setup_field()
update_new_turfs()
if(setup_field_turfs)
for(var/turf/T in field_turfs_new)
setup_field_turf(T)
CHECK_TICK
if(setup_edge_turfs)
for(var/turf/T in edge_turfs_new)
setup_edge_turf(T)
CHECK_TICK
/datum/proximity_monitor/advanced/proc/cleanup_field_turf(turf/T)
qdel(field_turfs[T])
field_turfs -= T
/datum/proximity_monitor/advanced/proc/cleanup_edge_turf(turf/T)
qdel(edge_turfs[T])
edge_turfs -= T
/datum/proximity_monitor/advanced/proc/setup_field_turf(turf/T)
field_turfs[T] = new /obj/effect/abstract/proximity_checker/advanced/field_turf(T, src)
/datum/proximity_monitor/advanced/proc/setup_edge_turf(turf/T)
edge_turfs[T] = new /obj/effect/abstract/proximity_checker/advanced/field_edge(T, src)
/datum/proximity_monitor/advanced/proc/update_new_turfs()
if(!istype(host))
return FALSE
last_host_loc = host.loc
var/turf/center = get_turf(host)
field_turfs_new = list()
edge_turfs_new = list()
switch(field_shape)
if(FIELD_NO_SHAPE)
return FALSE
if(FIELD_SHAPE_RADIUS_SQUARE)
for(var/turf/T in block(locate(center.x-current_range,center.y-current_range,center.z-square_depth_down),locate(center.x+current_range, center.y+current_range,center.z+square_depth_up)))
field_turfs_new += T
edge_turfs_new = field_turfs_new.Copy()
if(current_range >= 1)
var/list/turf/center_turfs = list()
for(var/turf/T in block(locate(center.x-current_range+1,center.y-current_range+1,center.z-square_depth_down),locate(center.x+current_range-1, center.y+current_range-1,center.z+square_depth_up)))
center_turfs += T
for(var/turf/T in center_turfs)
edge_turfs_new -= T
if(FIELD_SHAPE_CUSTOM_SQUARE)
for(var/turf/T in block(locate(center.x-square_width,center.y-square_height,center.z-square_depth_down),locate(center.x+square_width, center.y+square_height,center.z+square_depth_up)))
field_turfs_new += T
edge_turfs_new = field_turfs_new.Copy()
if(square_height >= 1 && square_width >= 1)
var/list/turf/center_turfs = list()
for(var/turf/T in block(locate(center.x-square_width+1,center.y-square_height+1,center.z-square_depth_down),locate(center.x+square_width-1, center.y+square_height-1,center.z+square_depth_up)))
center_turfs += T
for(var/turf/T in center_turfs)
edge_turfs_new -= T
//Gets edge direction/corner, only works with square radius/WDH fields!
/datum/proximity_monitor/advanced/proc/get_edgeturf_direction(turf/T, turf/center_override = null)
var/turf/checking_from = get_turf(host)
if(istype(center_override))
checking_from = center_override
if(field_shape != FIELD_SHAPE_RADIUS_SQUARE && field_shape != FIELD_SHAPE_CUSTOM_SQUARE)
return
if(!(T in edge_turfs))
return
switch(field_shape)
if(FIELD_SHAPE_RADIUS_SQUARE)
if(((T.x == (checking_from.x + current_range)) || (T.x == (checking_from.x - current_range))) && ((T.y == (checking_from.y + current_range)) || (T.y == (checking_from.y - current_range))))
return get_dir(checking_from, T)
if(T.x == (checking_from.x + current_range))
return EAST
if(T.x == (checking_from.x - current_range))
return WEST
if(T.y == (checking_from.y - current_range))
return SOUTH
if(T.y == (checking_from.y + current_range))
return NORTH
if(FIELD_SHAPE_CUSTOM_SQUARE)
if(((T.x == (checking_from.x + square_width)) || (T.x == (checking_from.x - square_width))) && ((T.y == (checking_from.y + square_height)) || (T.y == (checking_from.y - square_height))))
return get_dir(checking_from, T)
if(T.x == (checking_from.x + square_width))
return EAST
if(T.x == (checking_from.x - square_width))
return WEST
if(T.y == (checking_from.y - square_height))
return SOUTH
if(T.y == (checking_from.y + square_height))
return NORTH
//DEBUG FIELDS
/datum/proximity_monitor/advanced/debug
name = "\improper Color Matrix Field"
field_shape = FIELD_SHAPE_RADIUS_SQUARE
current_range = 5
var/set_fieldturf_color = "#aaffff"
var/set_edgeturf_color = "#ffaaff"
setup_field_turfs = TRUE
setup_edge_turfs = TRUE
/datum/proximity_monitor/advanced/debug/recalculate_field()
..()
/datum/proximity_monitor/advanced/debug/post_setup_field()
..()
/datum/proximity_monitor/advanced/debug/setup_edge_turf(turf/T)
T.color = set_edgeturf_color
..()
/datum/proximity_monitor/advanced/debug/cleanup_edge_turf(turf/T)
T.color = initial(T.color)
..()
if(T in field_turfs)
T.color = set_fieldturf_color
/datum/proximity_monitor/advanced/debug/setup_field_turf(turf/T)
T.color = set_fieldturf_color
..()
/datum/proximity_monitor/advanced/debug/cleanup_field_turf(turf/T)
T.color = initial(T.color)
..()
//DEBUG FIELD ITEM
/obj/item/device/multitool/field_debug
name = "strange multitool"
desc = "Seems to project a colored field!"
var/list/field_params = list("field_shape" = FIELD_SHAPE_RADIUS_SQUARE, "current_range" = 5, "set_fieldturf_color" = "#aaffff", "set_edgeturf_color" = "#ffaaff")
var/field_type = /datum/proximity_monitor/advanced/debug
var/operating = FALSE
var/datum/proximity_monitor/advanced/current = null
/obj/item/device/multitool/field_debug/New()
START_PROCESSING(SSobj, src)
..()
/obj/item/device/multitool/field_debug/Destroy()
STOP_PROCESSING(SSobj, src)
QDEL_NULL(current)
..()
/obj/item/device/multitool/field_debug/proc/setup_debug_field()
var/list/new_params = field_params.Copy()
new_params["host"] = src
current = make_field(field_type, new_params)
/obj/item/device/multitool/field_debug/attack_self(mob/user)
operating = !operating
to_chat(user, "You turn the [src] [operating? "on":"off"].")
if(!istype(current) && operating)
setup_debug_field()
else if(!operating)
QDEL_NULL(current)
/obj/item/device/multitool/field_debug/on_mob_move()
check_turf(get_turf(src))
/obj/item/device/multitool/field_debug/process()
check_turf(get_turf(src))
/obj/item/device/multitool/field_debug/proc/check_turf(turf/T)
current.HandleMove()
+106
View File
@@ -0,0 +1,106 @@
//Projectile dampening field that slows projectiles and lowers their damage for an energy cost deducted every 1/5 second.
//Only use square radius for this!
/datum/proximity_monitor/advanced/peaceborg_dampener
name = "\improper Hyperkinetic Dampener Field"
requires_processing = TRUE
setup_edge_turfs = TRUE
setup_field_turfs = TRUE
field_shape = FIELD_SHAPE_RADIUS_SQUARE
var/static/image/edgeturf_south = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_south")
var/static/image/edgeturf_north = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_north")
var/static/image/edgeturf_west = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_west")
var/static/image/edgeturf_east = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_east")
var/static/image/northwest_corner = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_northwest")
var/static/image/southwest_corner = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_southwest")
var/static/image/northeast_corner = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_northeast")
var/static/image/southeast_corner = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_southeast")
var/obj/item/borg/projectile_dampen/projector = null
var/list/obj/item/projectile/tracked
var/list/obj/item/projectile/staging
/datum/proximity_monitor/advanced/peaceborg_dampener/New()
tracked = list()
staging = list()
..()
/datum/proximity_monitor/advanced/peaceborg_dampener/process()
if(!istype(projector))
qdel(src)
var/list/ranged = list()
for(var/obj/item/projectile/P in range(current_range, get_turf(host)))
ranged += P
for(var/obj/item/projectile/P in tracked)
if(!(P in ranged) || !P.loc)
release_projectile(P)
for(var/mob/living/silicon/robot/R in range(current_range, get_turf(host)))
if(R.has_buckled_mobs())
for(var/mob/living/L in R.buckled_mobs)
L.visible_message("<span class='warning'>[L] is knocked off of [R] by the charge in [R]'s chassis induced by [name]!</span>") //I know it's bad.
L.Weaken(3)
R.unbuckle_mob(L)
do_sparks(5, 0, L)
..()
/datum/proximity_monitor/advanced/peaceborg_dampener/setup_edge_turf(turf/T)
..()
var/image/I = get_edgeturf_overlay(get_edgeturf_direction(T))
var/obj/effect/abstract/proximity_checker/advanced/F = edge_turfs[T]
F.appearance = I.appearance
F.invisibility = 0
F.layer = 5
/datum/proximity_monitor/advanced/peaceborg_dampener/cleanup_edge_turf(turf/T)
..()
/datum/proximity_monitor/advanced/peaceborg_dampener/proc/get_edgeturf_overlay(direction)
switch(direction)
if(NORTH)
return edgeturf_north
if(SOUTH)
return edgeturf_south
if(EAST)
return edgeturf_east
if(WEST)
return edgeturf_west
if(NORTHEAST)
return northeast_corner
if(NORTHWEST)
return northwest_corner
if(SOUTHEAST)
return southeast_corner
if(SOUTHWEST)
return southwest_corner
/datum/proximity_monitor/advanced/peaceborg_dampener/proc/capture_projectile(obj/item/projectile/P, track_projectile = TRUE)
if(P in tracked)
return
projector.dampen_projectile(P, track_projectile)
if(track_projectile)
tracked += P
/datum/proximity_monitor/advanced/peaceborg_dampener/proc/release_projectile(obj/item/projectile/P)
projector.restore_projectile(P)
tracked -= P
/datum/proximity_monitor/advanced/peaceborg_dampener/field_edge_uncrossed(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_edge/F)
if(!is_turf_in_field(get_turf(AM), src))
if(istype(AM, /obj/item/projectile))
if(AM in tracked)
release_projectile(AM)
else
capture_projectile(AM, FALSE)
return ..()
/datum/proximity_monitor/advanced/peaceborg_dampener/field_edge_crossed(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_edge/F)
if(istype(AM, /obj/item/projectile) && !(AM in tracked) && staging[AM] && !is_turf_in_field(staging[AM], src))
capture_projectile(AM)
staging -= AM
return ..()
/datum/proximity_monitor/advanced/peaceborg_dampener/field_edge_canpass(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_edge/F, turf/entering)
if(istype(AM, /obj/item/projectile))
staging[AM] = get_turf(AM)
. = ..()
if(!.)
staging -= AM //This one ain't goin' through.
+76
View File
@@ -0,0 +1,76 @@
/obj/effect/abstract/proximity_checker/advanced
name = "field"
desc = "Why can you see energy fields?!"
icon = null
icon_state = null
alpha = 0
invisibility = INVISIBILITY_ABSTRACT
flags = ABSTRACT|ON_BORDER
var/datum/proximity_monitor/advanced/parent = null
/obj/effect/abstract/proximity_checker/advanced/Initialize(mapload, _monitor)
if(_monitor)
parent = _monitor
return ..()
/obj/effect/abstract/proximity_checker/advanced/center
name = "field anchor"
desc = "No."
/obj/effect/abstract/proximity_checker/advanced/field_turf
name = "energy field"
desc = "Get off my turf!"
/obj/effect/abstract/proximity_checker/advanced/field_turf/CanPass(atom/movable/AM, turf/target, height)
if(parent)
return parent.field_turf_canpass(AM, src, target)
return TRUE
/obj/effect/abstract/proximity_checker/advanced/field_turf/Crossed(atom/movable/AM)
if(parent)
return parent.field_turf_crossed(AM, src)
return TRUE
/obj/effect/abstract/proximity_checker/advanced/field_turf/Uncross(atom/movable/AM)
if(parent)
return parent.field_turf_uncross(AM, src)
return TRUE
/obj/effect/abstract/proximity_checker/advanced/field_turf/Uncrossed(atom/movable/AM)
if(parent)
return parent.field_turf_uncrossed(AM, src)
return TRUE
/obj/effect/abstract/proximity_checker/advanced/field_edge
name = "energy field edge"
desc = "Edgy description here."
/obj/effect/abstract/proximity_checker/advanced/field_edge/CanPass(atom/movable/AM, turf/target, height)
if(parent)
return parent.field_edge_canpass(AM, src, target)
return TRUE
/obj/effect/abstract/proximity_checker/advanced/field_edge/Crossed(atom/movable/AM)
if(parent)
return parent.field_edge_crossed(AM, src)
return TRUE
/obj/effect/abstract/proximity_checker/advanced/field_edge/Uncross(atom/movable/AM)
if(parent)
return parent.field_edge_uncross(AM, src)
return TRUE
/obj/effect/abstract/proximity_checker/advanced/field_edge/Uncrossed(atom/movable/AM)
if(parent)
return parent.field_edge_uncrossed(AM, src)
return TRUE
/proc/is_turf_in_field(turf/T, datum/proximity_monitor/advanced/F) //Looking for ways to optimize this!
for(var/obj/effect/abstract/proximity_checker/advanced/O in T)
if(istype(O, /obj/effect/abstract/proximity_checker/advanced/field_edge))
if(O.parent == F)
return FIELD_EDGE
if(O.parent == F)
return FIELD_TURF
return NO_FIELD
@@ -135,7 +135,6 @@
/obj/item/weapon/reagent_containers/food/snacks/customizable/initialize_slice(obj/item/weapon/reagent_containers/food/snacks/slice, reagents_per_slice)
..()
slice.name = "[customname] [initial(slice.name)]"
slice.filling_color = filling_color
slice.update_overlays(src)
+3 -2
View File
@@ -215,8 +215,9 @@
/obj/item/weapon/reagent_containers/food/snacks/proc/initialize_slice(obj/item/weapon/reagent_containers/food/snacks/slice, reagents_per_slice)
slice.create_reagents(slice.volume)
reagents.trans_to(slice,reagents_per_slice)
if( name != initial(name) || desc != initial(desc) )
slice.name = "slice of [src]"
if(name != initial(name))
slice.name = "slice of [name]"
if(desc != initial(desc))
slice.desc = "[desc]"
/obj/item/weapon/reagent_containers/food/snacks/proc/generate_trash(atom/location)
@@ -174,7 +174,6 @@
var/mob/living/carbon/human/gibee = occupant
sourcejob = gibee.job
var/sourcenutriment = mob_occupant.nutrition / 15
var/sourcetotalreagents = mob_occupant.reagents.total_volume
var/gibtype = /obj/effect/decal/cleanable/blood/gibs
var/typeofmeat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human
var/typeofskin = /obj/item/stack/sheet/animalhide/human
@@ -207,7 +206,6 @@
newmeat.reagents.add_reagent ("nutriment", sourcenutriment / meat_produced) // Thehehe. Fat guys go first
if(sourcejob)
newmeat.subjectjob = sourcejob
src.occupant.reagents.trans_to (newmeat, round (sourcetotalreagents / meat_produced, 1)) // Transfer all the reagents from the
allmeat[i] = newmeat
allskin = newskin
+9 -1
View File
@@ -2,7 +2,8 @@
#define BAD_ZLEVEL 1
#define BAD_AREA 2
#define ZONE_SET 3
#define BAD_COORDS 3
#define ZONE_SET 4
/area/shuttle/auxillary_base
name = "Auxillary Base"
@@ -149,6 +150,9 @@ interface with the mining shuttle at the landing site if a mobile beacon is also
if(T.z != ZLEVEL_MINING)
return BAD_ZLEVEL
var/colony_radius = max(base_dock.width, base_dock.height)*0.5
if(T.x - colony_radius < 1 || T.x + colony_radius >= world.maxx || T.y - colony_radius < 1 || T.y + colony_radius >= world.maxx)
return BAD_COORDS //Avoid dropping the base too close to map boundaries, as it results in parts of it being left in space
var/list/area_counter = get_areas_in_range(colony_radius, T)
if(area_counter.len > 1) //Avoid smashing ruins unless you are inside a really big one
return BAD_AREA
@@ -195,6 +199,7 @@ interface with the mining shuttle at the landing site if a mobile beacon is also
if(!do_after(user, 50, target = user)) //You get a few seconds to cancel if you do not want to drop there.
setting = FALSE
return
setting = FALSE
var/turf/T = get_turf(user)
var/obj/machinery/computer/auxillary_base/AB
@@ -212,6 +217,8 @@ interface with the mining shuttle at the landing site if a mobile beacon is also
to_chat(user, "<span class='warning'>This uplink can only be used in a designed mining zone.</span>")
if(BAD_AREA)
to_chat(user, "<span class='warning'>Unable to acquire a targeting lock. Find an area clear of stuctures or entirely within one.</span>")
if(BAD_COORDS)
to_chat(user, "<span class='warning'>Location is too close to the edge of the station's scanning range. Move several paces away and try again.</span>")
if(ZONE_SET)
qdel(src)
@@ -347,4 +354,5 @@ obj/docking_port/stationary/public_mining_dock/onShuttleMove()
#undef BAD_ZLEVEL
#undef BAD_AREA
#undef BAD_COORDS
#undef ZONE_SET
@@ -1,5 +1,6 @@
//The chests dropped by mob spawner tendrils. Also contains associated loot.
/obj/structure/closet/crate/necropolis
name = "necropolis chest"
desc = "It's watching you closely."
@@ -821,6 +822,8 @@
if(isliving(target) && chaser_timer <= world.time) //living and chasers off cooldown? fire one!
chaser_timer = world.time + chaser_cooldown
new /obj/effect/temp_visual/hierophant/chaser(get_turf(user), user, target, chaser_speed, friendly_fire_check)
C.damage = 30
C.monster_damage_boost = FALSE
add_logs(user, target, "fired a chaser at", src)
else
INVOKE_ASYNC(src, .proc/cardinal_blasts, T, user) //otherwise, just do cardinal blast
@@ -1005,6 +1008,8 @@
if(!J)
return
new /obj/effect/temp_visual/hierophant/blast(J, user, friendly_fire_check)
B.damage = 30
B.monster_damage_boost = FALSE
previousturf = J
J = get_step(previousturf, dir)
@@ -1016,3 +1021,4 @@
sleep(2)
for(var/t in RANGE_TURFS(1, T))
new /obj/effect/temp_visual/hierophant/blast(t, user, friendly_fire_check)
B.damage = 15 //keeps monster damage boost due to lower damage
@@ -17,4 +17,4 @@
/mob/living/carbon/alien/AdjustStunned(amount, updating = 1, ignore_canstun = 0)
. = ..()
if(!.)
move_delay_add = min(move_delay_add + round(amount / 2), 10)
move_delay_add = Clamp(move_delay_add + round(amount/2), 0, 10)
+1 -1
View File
@@ -823,7 +823,7 @@
/mob/living/proc/has_bane(banetype)
var/datum/antagonist/devil/devilInfo = is_devil(src)
return (banetype == devilInfo.bane)
return devilInfo && banetype == devilInfo.bane
/mob/living/proc/check_weakness(obj/item/weapon, mob/living/attacker)
if(mind && mind.has_antag_datum(ANTAG_DATUM_DEVIL))
+366 -357
View File
@@ -1,361 +1,370 @@
/mob/living/proc/run_armor_check(def_zone = null, attack_flag = "melee", absorb_text = null, soften_text = null, armour_penetration, penetrated_text)
var/armor = getarmor(def_zone, attack_flag)
//the if "armor" check is because this is used for everything on /living, including humans
if(armor && armour_penetration)
armor = max(0, armor - armour_penetration)
if(penetrated_text)
to_chat(src, "<span class='userdanger'>[penetrated_text]</span>")
else
to_chat(src, "<span class='userdanger'>Your armor was penetrated!</span>")
else if(armor >= 100)
if(absorb_text)
to_chat(src, "<span class='userdanger'>[absorb_text]</span>")
else
to_chat(src, "<span class='userdanger'>Your armor absorbs the blow!</span>")
else if(armor > 0)
if(soften_text)
to_chat(src, "<span class='userdanger'>[soften_text]</span>")
else
to_chat(src, "<span class='userdanger'>Your armor softens the blow!</span>")
return armor
/mob/living/proc/getarmor(def_zone, type)
return 0
//this returns the mob's protection against eye damage (number between -1 and 2)
/mob/living/proc/get_eye_protection()
return 0
//this returns the mob's protection against ear damage (0:no protection; 1: some ear protection; 2: has no ears)
/mob/living/proc/get_ear_protection()
return 0
/mob/living/proc/on_hit(obj/item/projectile/P)
return
/mob/living/bullet_act(obj/item/projectile/P, def_zone)
var/armor = run_armor_check(def_zone, P.flag, "","",P.armour_penetration)
if(!P.nodamage)
apply_damage(P.damage, P.damage_type, def_zone, armor)
if(P.dismemberment)
check_projectile_dismemberment(P, def_zone)
return P.on_hit(src, armor)
/mob/living/proc/check_projectile_dismemberment(obj/item/projectile/P, def_zone)
return 0
/obj/item/proc/get_volume_by_throwforce_and_or_w_class()
if(throwforce && w_class)
return Clamp((throwforce + w_class) * 5, 30, 100)// Add the item's throwforce to its weight class and multiply by 5, then clamp the value between 30 and 100
else if(w_class)
return Clamp(w_class * 8, 20, 100) // Multiply the item's weight class by 8, then clamp the value between 20 and 100
else
return 0
/mob/living/hitby(atom/movable/AM, skipcatch, hitpush = 1, blocked = 0)
if(istype(AM, /obj/item))
var/obj/item/I = AM
var/zone = ran_zone("chest", 65)//Hits a random part of the body, geared towards the chest
var/dtype = BRUTE
var/volume = I.get_volume_by_throwforce_and_or_w_class()
if(istype(I,/obj/item/weapon)) //If the item is a weapon...
var/obj/item/weapon/W = I
dtype = W.damtype
if (W.throwforce > 0) //If the weapon's throwforce is greater than zero...
if (W.throwhitsound) //...and throwhitsound is defined...
playsound(loc, W.throwhitsound, volume, 1, -1) //...play the weapon's throwhitsound.
else if(W.hitsound) //Otherwise, if the weapon's hitsound is defined...
playsound(loc, W.hitsound, volume, 1, -1) //...play the weapon's hitsound.
else if(!W.throwhitsound) //Otherwise, if throwhitsound isn't defined...
playsound(loc, 'sound/weapons/genhit.ogg',volume, 1, -1) //...play genhit.ogg.
else if(!I.throwhitsound && I.throwforce > 0) //Otherwise, if the item doesn't have a throwhitsound and has a throwforce greater than zero...
playsound(loc, 'sound/weapons/genhit.ogg', volume, 1, -1)//...play genhit.ogg
if(!I.throwforce)// Otherwise, if the item's throwforce is 0...
playsound(loc, 'sound/weapons/throwtap.ogg', 1, volume, -1)//...play throwtap.ogg.
if(!blocked)
visible_message("<span class='danger'>[src] has been hit by [I].</span>", \
"<span class='userdanger'>[src] has been hit by [I].</span>")
var/armor = run_armor_check(zone, "melee", "Your armor has protected your [parse_zone(zone)].", "Your armor has softened hit to your [parse_zone(zone)].",I.armour_penetration)
apply_damage(I.throwforce, dtype, zone, armor)
if(I.thrownby)
add_logs(I.thrownby, src, "hit", I)
else
return 1
else
playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1)
..()
/mob/living/mech_melee_attack(obj/mecha/M)
if(M.occupant.a_intent == INTENT_HARM)
M.do_attack_animation(src)
if(M.damtype == "brute")
step_away(src,M,15)
switch(M.damtype)
if(BRUTE)
Paralyse(1)
take_overall_damage(rand(M.force/2, M.force))
playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
if(BURN)
take_overall_damage(0, rand(M.force/2, M.force))
playsound(src, 'sound/items/Welder.ogg', 50, 1)
if(TOX)
M.mech_toxin_damage(src)
else
return
updatehealth()
visible_message("<span class='danger'>[M.name] has hit [src]!</span>", \
"<span class='userdanger'>[M.name] has hit [src]!</span>", null, COMBAT_MESSAGE_RANGE)
add_logs(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])")
else
step_away(src,M)
add_logs(M.occupant, src, "pushed", M)
visible_message("<span class='warning'>[M] pushes [src] out of the way.</span>", null, null, 5)
/mob/living/fire_act()
adjust_fire_stacks(3)
IgniteMob()
/mob/living/proc/grabbedby(mob/living/carbon/user, supress_message = 0)
if(user == src || anchored || !isturf(user.loc))
return 0
if(!user.pulling || user.pulling != src)
user.start_pulling(src, supress_message)
return
if(!(status_flags & CANPUSH))
to_chat(user, "<span class='warning'>[src] can't be grabbed more aggressively!</span>")
return 0
grippedby(user)
//proc to upgrade a simple pull into a more aggressive grab.
/mob/living/proc/grippedby(mob/living/carbon/user)
if(user.grab_state < GRAB_KILL)
user.changeNext_move(CLICK_CD_GRABBING)
playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
if(user.grab_state) //only the first upgrade is instantaneous
var/old_grab_state = user.grab_state
var/grab_upgrade_time = 30
visible_message("<span class='danger'>[user] starts to tighten [user.p_their()] grip on [src]!</span>", \
"<span class='userdanger'>[user] starts to tighten [user.p_their()] grip on you!</span>")
if(!do_mob(user, src, grab_upgrade_time))
return 0
if(!user.pulling || user.pulling != src || user.grab_state != old_grab_state || user.a_intent != INTENT_GRAB)
return 0
user.grab_state++
switch(user.grab_state)
if(GRAB_AGGRESSIVE)
add_logs(user, src, "grabbed", addition="aggressively")
visible_message("<span class='danger'>[user] has grabbed [src] aggressively!</span>", \
"<span class='userdanger'>[user] has grabbed [src] aggressively!</span>")
drop_all_held_items()
stop_pulling()
if(GRAB_NECK)
visible_message("<span class='danger'>[user] has grabbed [src] by the neck!</span>",\
"<span class='userdanger'>[user] has grabbed you by the neck!</span>")
update_canmove() //we fall down
if(!buckled && !density)
Move(user.loc)
if(GRAB_KILL)
visible_message("<span class='danger'>[user] is strangling [src]!</span>", \
"<span class='userdanger'>[user] is strangling you!</span>")
update_canmove() //we fall down
if(!buckled && !density)
Move(user.loc)
return 1
/mob/living/attack_slime(mob/living/simple_animal/slime/M)
/mob/living/proc/run_armor_check(def_zone = null, attack_flag = "melee", absorb_text = null, soften_text = null, armour_penetration, penetrated_text)
var/armor = getarmor(def_zone, attack_flag)
//the if "armor" check is because this is used for everything on /living, including humans
if(armor && armour_penetration)
armor = max(0, armor - armour_penetration)
if(penetrated_text)
to_chat(src, "<span class='userdanger'>[penetrated_text]</span>")
else
to_chat(src, "<span class='userdanger'>Your armor was penetrated!</span>")
else if(armor >= 100)
if(absorb_text)
to_chat(src, "<span class='userdanger'>[absorb_text]</span>")
else
to_chat(src, "<span class='userdanger'>Your armor absorbs the blow!</span>")
else if(armor > 0)
if(soften_text)
to_chat(src, "<span class='userdanger'>[soften_text]</span>")
else
to_chat(src, "<span class='userdanger'>Your armor softens the blow!</span>")
return armor
/mob/living/proc/getarmor(def_zone, type)
return 0
//this returns the mob's protection against eye damage (number between -1 and 2)
/mob/living/proc/get_eye_protection()
return 0
//this returns the mob's protection against ear damage (0:no protection; 1: some ear protection; 2: has no ears)
/mob/living/proc/get_ear_protection()
return 0
/mob/living/proc/on_hit(obj/item/projectile/P)
return
/mob/living/bullet_act(obj/item/projectile/P, def_zone)
var/armor = run_armor_check(def_zone, P.flag, "","",P.armour_penetration)
if(!P.nodamage)
apply_damage(P.damage, P.damage_type, def_zone, armor)
if(P.dismemberment)
check_projectile_dismemberment(P, def_zone)
return P.on_hit(src, armor)
/mob/living/proc/check_projectile_dismemberment(obj/item/projectile/P, def_zone)
return 0
/obj/item/proc/get_volume_by_throwforce_and_or_w_class()
if(throwforce && w_class)
return Clamp((throwforce + w_class) * 5, 30, 100)// Add the item's throwforce to its weight class and multiply by 5, then clamp the value between 30 and 100
else if(w_class)
return Clamp(w_class * 8, 20, 100) // Multiply the item's weight class by 8, then clamp the value between 20 and 100
else
return 0
/mob/living/hitby(atom/movable/AM, skipcatch, hitpush = 1, blocked = 0)
if(istype(AM, /obj/item))
var/obj/item/I = AM
var/zone = ran_zone("chest", 65)//Hits a random part of the body, geared towards the chest
var/dtype = BRUTE
var/volume = I.get_volume_by_throwforce_and_or_w_class()
if(istype(I,/obj/item/weapon)) //If the item is a weapon...
var/obj/item/weapon/W = I
dtype = W.damtype
if (W.throwforce > 0) //If the weapon's throwforce is greater than zero...
if (W.throwhitsound) //...and throwhitsound is defined...
playsound(loc, W.throwhitsound, volume, 1, -1) //...play the weapon's throwhitsound.
else if(W.hitsound) //Otherwise, if the weapon's hitsound is defined...
playsound(loc, W.hitsound, volume, 1, -1) //...play the weapon's hitsound.
else if(!W.throwhitsound) //Otherwise, if throwhitsound isn't defined...
playsound(loc, 'sound/weapons/genhit.ogg',volume, 1, -1) //...play genhit.ogg.
else if(!I.throwhitsound && I.throwforce > 0) //Otherwise, if the item doesn't have a throwhitsound and has a throwforce greater than zero...
playsound(loc, 'sound/weapons/genhit.ogg', volume, 1, -1)//...play genhit.ogg
if(!I.throwforce)// Otherwise, if the item's throwforce is 0...
playsound(loc, 'sound/weapons/throwtap.ogg', 1, volume, -1)//...play throwtap.ogg.
if(!blocked)
visible_message("<span class='danger'>[src] has been hit by [I].</span>", \
"<span class='userdanger'>[src] has been hit by [I].</span>")
var/armor = run_armor_check(zone, "melee", "Your armor has protected your [parse_zone(zone)].", "Your armor has softened hit to your [parse_zone(zone)].",I.armour_penetration)
apply_damage(I.throwforce, dtype, zone, armor)
if(I.thrownby)
add_logs(I.thrownby, src, "hit", I)
else
return 1
else
playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1)
..()
/mob/living/mech_melee_attack(obj/mecha/M)
if(M.occupant.a_intent == INTENT_HARM)
M.do_attack_animation(src)
if(M.damtype == "brute")
step_away(src,M,15)
switch(M.damtype)
if(BRUTE)
Paralyse(1)
take_overall_damage(rand(M.force/2, M.force))
playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
if(BURN)
take_overall_damage(0, rand(M.force/2, M.force))
playsound(src, 'sound/items/Welder.ogg', 50, 1)
if(TOX)
M.mech_toxin_damage(src)
else
return
updatehealth()
visible_message("<span class='danger'>[M.name] has hit [src]!</span>", \
"<span class='userdanger'>[M.name] has hit [src]!</span>", null, COMBAT_MESSAGE_RANGE)
add_logs(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])")
else
step_away(src,M)
add_logs(M.occupant, src, "pushed", M)
visible_message("<span class='warning'>[M] pushes [src] out of the way.</span>", null, null, 5)
/mob/living/fire_act()
adjust_fire_stacks(3)
IgniteMob()
/mob/living/proc/grabbedby(mob/living/carbon/user, supress_message = 0)
if(user == src || anchored || !isturf(user.loc))
return 0
if(!user.pulling || user.pulling != src)
user.start_pulling(src, supress_message)
return
if(!(status_flags & CANPUSH))
to_chat(user, "<span class='warning'>[src] can't be grabbed more aggressively!</span>")
return 0
grippedby(user)
//proc to upgrade a simple pull into a more aggressive grab.
/mob/living/proc/grippedby(mob/living/carbon/user)
if(user.grab_state < GRAB_KILL)
user.changeNext_move(CLICK_CD_GRABBING)
playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
if(user.grab_state) //only the first upgrade is instantaneous
var/old_grab_state = user.grab_state
var/grab_upgrade_time = 30
visible_message("<span class='danger'>[user] starts to tighten [user.p_their()] grip on [src]!</span>", \
"<span class='userdanger'>[user] starts to tighten [user.p_their()] grip on you!</span>")
if(!do_mob(user, src, grab_upgrade_time))
return 0
if(!user.pulling || user.pulling != src || user.grab_state != old_grab_state || user.a_intent != INTENT_GRAB)
return 0
user.grab_state++
switch(user.grab_state)
if(GRAB_AGGRESSIVE)
add_logs(user, src, "grabbed", addition="aggressively")
visible_message("<span class='danger'>[user] has grabbed [src] aggressively!</span>", \
"<span class='userdanger'>[user] has grabbed [src] aggressively!</span>")
drop_all_held_items()
stop_pulling()
if(GRAB_NECK)
visible_message("<span class='danger'>[user] has grabbed [src] by the neck!</span>",\
"<span class='userdanger'>[user] has grabbed you by the neck!</span>")
update_canmove() //we fall down
if(!buckled && !density)
Move(user.loc)
if(GRAB_KILL)
visible_message("<span class='danger'>[user] is strangling [src]!</span>", \
"<span class='userdanger'>[user] is strangling you!</span>")
update_canmove() //we fall down
if(!buckled && !density)
Move(user.loc)
return 1
/mob/living/attack_slime(mob/living/simple_animal/slime/M)
if(!SSticker.HasRoundStarted())
to_chat(M, "You cannot attack people before the game has started.")
return
if(M.buckled)
if(M in buckled_mobs)
M.Feedstop()
return // can't attack while eating!
if (stat != DEAD)
add_logs(M, src, "attacked")
M.do_attack_animation(src)
visible_message("<span class='danger'>The [M.name] glomps [src]!</span>", \
"<span class='userdanger'>The [M.name] glomps [src]!</span>", null, COMBAT_MESSAGE_RANGE)
return 1
/mob/living/attack_animal(mob/living/simple_animal/M)
M.face_atom(src)
if(M.melee_damage_upper == 0)
M.visible_message("<span class='notice'>\The [M] [M.friendly] [src]!</span>")
return 0
else
if(M.attack_sound)
playsound(loc, M.attack_sound, 50, 1, 1)
M.do_attack_animation(src)
visible_message("<span class='danger'>\The [M] [M.attacktext] [src]!</span>", \
"<span class='userdanger'>\The [M] [M.attacktext] [src]!</span>", null, COMBAT_MESSAGE_RANGE)
add_logs(M, src, "attacked")
return 1
/mob/living/attack_paw(mob/living/carbon/monkey/M)
if(isturf(loc) && istype(loc.loc, /area/start))
to_chat(M, "No attacking people at spawn, you jackass.")
return 0
if (M.a_intent == INTENT_HARM)
if(M.is_muzzled() || (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSMOUTH))
to_chat(M, "<span class='warning'>You can't bite with your mouth covered!</span>")
return 0
M.do_attack_animation(src, ATTACK_EFFECT_BITE)
if (prob(75))
add_logs(M, src, "attacked")
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
visible_message("<span class='danger'>[M.name] bites [src]!</span>", \
"<span class='userdanger'>[M.name] bites [src]!</span>", null, COMBAT_MESSAGE_RANGE)
return 1
else
visible_message("<span class='danger'>[M.name] has attempted to bite [src]!</span>", \
"<span class='userdanger'>[M.name] has attempted to bite [src]!</span>", null, COMBAT_MESSAGE_RANGE)
return 0
/mob/living/attack_larva(mob/living/carbon/alien/larva/L)
switch(L.a_intent)
if("help")
visible_message("<span class='notice'>[L.name] rubs its head against [src].</span>")
return 0
else
L.do_attack_animation(src)
if(prob(90))
add_logs(L, src, "attacked")
visible_message("<span class='danger'>[L.name] bites [src]!</span>", \
"<span class='userdanger'>[L.name] bites [src]!</span>", null, COMBAT_MESSAGE_RANGE)
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
return 1
else
visible_message("<span class='danger'>[L.name] has attempted to bite [src]!</span>", \
"<span class='userdanger'>[L.name] has attempted to bite [src]!</span>", null, COMBAT_MESSAGE_RANGE)
return 0
/mob/living/attack_alien(mob/living/carbon/alien/humanoid/M)
switch(M.a_intent)
if ("help")
visible_message("<span class='notice'>[M] caresses [src] with its scythe like arm.</span>")
return 0
if ("grab")
grabbedby(M)
return 0
if("harm")
M.do_attack_animation(src)
return 1
if("disarm")
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
return 1
/mob/living/ex_act(severity, target, origin)
if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src))
return
..()
//Looking for irradiate()? It's been moved to radiation.dm under the rad_act() for mobs.
/mob/living/acid_act(acidpwr, acid_volume)
take_bodypart_damage(acidpwr * min(1, acid_volume * 0.1))
return 1
/mob/living/proc/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
to_chat(M, "You cannot attack people before the game has started.")
return
if(M.buckled)
if(M in buckled_mobs)
M.Feedstop()
return // can't attack while eating!
if (stat != DEAD)
add_logs(M, src, "attacked")
M.do_attack_animation(src)
visible_message("<span class='danger'>The [M.name] glomps [src]!</span>", \
"<span class='userdanger'>The [M.name] glomps [src]!</span>", null, COMBAT_MESSAGE_RANGE)
return 1
/mob/living/attack_animal(mob/living/simple_animal/M)
M.face_atom(src)
if(M.melee_damage_upper == 0)
M.visible_message("<span class='notice'>\The [M] [M.friendly] [src]!</span>")
return 0
else
if(M.attack_sound)
playsound(loc, M.attack_sound, 50, 1, 1)
M.do_attack_animation(src)
visible_message("<span class='danger'>\The [M] [M.attacktext] [src]!</span>", \
"<span class='userdanger'>\The [M] [M.attacktext] [src]!</span>", null, COMBAT_MESSAGE_RANGE)
add_logs(M, src, "attacked")
return 1
/mob/living/attack_paw(mob/living/carbon/monkey/M)
if(isturf(loc) && istype(loc.loc, /area/start))
to_chat(M, "No attacking people at spawn, you jackass.")
return 0
if (M.a_intent == INTENT_HARM)
if(M.is_muzzled() || (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSMOUTH))
to_chat(M, "<span class='warning'>You can't bite with your mouth covered!</span>")
return 0
M.do_attack_animation(src, ATTACK_EFFECT_BITE)
if (prob(75))
add_logs(M, src, "attacked")
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
visible_message("<span class='danger'>[M.name] bites [src]!</span>", \
"<span class='userdanger'>[M.name] bites [src]!</span>", null, COMBAT_MESSAGE_RANGE)
return 1
else
visible_message("<span class='danger'>[M.name] has attempted to bite [src]!</span>", \
"<span class='userdanger'>[M.name] has attempted to bite [src]!</span>", null, COMBAT_MESSAGE_RANGE)
return 0
/mob/living/attack_larva(mob/living/carbon/alien/larva/L)
switch(L.a_intent)
if("help")
visible_message("<span class='notice'>[L.name] rubs its head against [src].</span>")
return 0
else
L.do_attack_animation(src)
if(prob(90))
add_logs(L, src, "attacked")
visible_message("<span class='danger'>[L.name] bites [src]!</span>", \
"<span class='userdanger'>[L.name] bites [src]!</span>", null, COMBAT_MESSAGE_RANGE)
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
return 1
else
visible_message("<span class='danger'>[L.name] has attempted to bite [src]!</span>", \
"<span class='userdanger'>[L.name] has attempted to bite [src]!</span>", null, COMBAT_MESSAGE_RANGE)
return 0
/mob/living/attack_alien(mob/living/carbon/alien/humanoid/M)
switch(M.a_intent)
if ("help")
visible_message("<span class='notice'>[M] caresses [src] with its scythe like arm.</span>")
return 0
if ("grab")
grabbedby(M)
return 0
if("harm")
M.do_attack_animation(src)
return 1
if("disarm")
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
return 1
/mob/living/ex_act(severity, target, origin)
if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src))
return
..()
//Looking for irradiate()? It's been moved to radiation.dm under the rad_act() for mobs.
/mob/living/acid_act(acidpwr, acid_volume)
take_bodypart_damage(acidpwr * min(1, acid_volume * 0.1))
return 1
/mob/living/proc/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
if(tesla_shock && HAS_SECONDARY_FLAG(src, TESLA_IGNORE))
return FALSE
if(shock_damage > 0)
if(!illusion)
adjustFireLoss(shock_damage)
visible_message(
"<span class='danger'>[src] was shocked by \the [source]!</span>", \
"<span class='userdanger'>You feel a powerful shock coursing through your body!</span>", \
"<span class='italics'>You hear a heavy electrical crack.</span>" \
)
return shock_damage
/mob/living/emp_act(severity)
var/list/L = src.get_contents()
for(var/obj/O in L)
O.emp_act(severity)
..()
/mob/living/singularity_act()
var/gain = 20
investigate_log("([key_name(src)]) has been consumed by the singularity.","singulo") //Oh that's where the clown ended up!
gib()
return(gain)
/mob/living/narsie_act()
if(status_flags & GODMODE)
return
if(is_servant_of_ratvar(src) && !stat)
to_chat(src, "<span class='userdanger'>You resist Nar-Sie's influence... but not all of it. <i>Run!</i></span>")
adjustBruteLoss(35)
if(src && reagents)
reagents.add_reagent("heparin", 5)
return FALSE
if(client)
return FALSE
if(shock_damage > 0)
if(!illusion)
adjustFireLoss(shock_damage)
visible_message(
"<span class='danger'>[src] was shocked by \the [source]!</span>", \
"<span class='userdanger'>You feel a powerful shock coursing through your body!</span>", \
"<span class='italics'>You hear a heavy electrical crack.</span>" \
)
return shock_damage
/mob/living/emp_act(severity)
var/list/L = src.get_contents()
for(var/obj/O in L)
O.emp_act(severity)
..()
/mob/living/singularity_act()
var/gain = 20
investigate_log("([key_name(src)]) has been consumed by the singularity.","singulo") //Oh that's where the clown ended up!
gib()
return(gain)
/mob/living/narsie_act()
if(status_flags & GODMODE)
return
if(is_servant_of_ratvar(src) && !stat)
to_chat(src, "<span class='userdanger'>You resist Nar-Sie's influence... but not all of it. <i>Run!</i></span>")
adjustBruteLoss(35)
if(src && reagents)
reagents.add_reagent("heparin", 5)
return FALSE
if(GLOB.cult_narsie && GLOB.cult_narsie.souls_needed[src])
GLOB.cult_narsie.resize(1.1)
GLOB.cult_narsie.souls_needed -= src
GLOB.cult_narsie.souls += 1
if((GLOB.cult_narsie.souls == GLOB.cult_narsie.soul_goal) && (GLOB.cult_narsie.resolved == FALSE))
GLOB.cult_narsie.resolved = TRUE
world << sound('sound/machines/Alarm.ogg')
addtimer(CALLBACK(GLOBAL_PROC, .proc/cult_ending_helper, 1), 120)
addtimer(CALLBACK(GLOBAL_PROC, .proc/ending_helper), 270)
if(client)
makeNewConstruct(/mob/living/simple_animal/hostile/construct/harvester, src, cultoverride = TRUE)
else
else
switch(rand(1, 6))
if(1)
new /mob/living/simple_animal/hostile/construct/armored/hostile(get_turf(src))
if(2)
new /mob/living/simple_animal/hostile/construct/wraith/hostile(get_turf(src))
if(3 to 6)
new /mob/living/simple_animal/hostile/construct/builder/hostile(get_turf(src))
spawn_dust()
gib()
return TRUE
/mob/living/ratvar_act()
if(status_flags & GODMODE)
return
if(stat != DEAD && !is_servant_of_ratvar(src))
for(var/obj/item/weapon/implant/mindshield/M in implants)
qdel(M)
if(!add_servant_of_ratvar(src))
to_chat(src, "<span class='userdanger'>A blinding light boils you alive! <i>Run!</i></span>")
adjustFireLoss(35)
if(src)
adjust_fire_stacks(1)
IgniteMob()
return FALSE
return TRUE
//called when the mob receives a bright flash
/mob/living/proc/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /obj/screen/fullscreen/flash)
if(get_eye_protection() < intensity && (override_blindness_check || !(disabilities & BLIND)))
overlay_fullscreen("flash", type)
addtimer(CALLBACK(src, .proc/clear_fullscreen, "flash", 25), 25)
return 1
//called when the mob receives a loud bang
/mob/living/proc/soundbang_act()
return 0
//to damage the clothes worn by a mob
/mob/living/proc/damage_clothes(damage_amount, damage_type = BRUTE, damage_flag = 0, def_zone)
return
/mob/living/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y)
if(A != src)
end_pixel_y = get_standard_pixel_y_offset(lying)
used_item = get_active_held_item()
..()
floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement.
if(1)
new /mob/living/simple_animal/hostile/construct/armored/hostile(get_turf(src))
if(2)
new /mob/living/simple_animal/hostile/construct/wraith/hostile(get_turf(src))
if(3 to 6)
new /mob/living/simple_animal/hostile/construct/builder/hostile(get_turf(src))
spawn_dust()
gib()
return TRUE
/mob/living/ratvar_act()
if(status_flags & GODMODE)
return
if(stat != DEAD && !is_servant_of_ratvar(src))
for(var/obj/item/weapon/implant/mindshield/M in implants)
qdel(M)
if(!add_servant_of_ratvar(src))
to_chat(src, "<span class='userdanger'>A blinding light boils you alive! <i>Run!</i></span>")
adjustFireLoss(35)
if(src)
adjust_fire_stacks(1)
IgniteMob()
return FALSE
return TRUE
//called when the mob receives a bright flash
/mob/living/proc/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /obj/screen/fullscreen/flash)
if(get_eye_protection() < intensity && (override_blindness_check || !(disabilities & BLIND)))
overlay_fullscreen("flash", type)
addtimer(CALLBACK(src, .proc/clear_fullscreen, "flash", 25), 25)
return 1
//called when the mob receives a loud bang
/mob/living/proc/soundbang_act()
return 0
//to damage the clothes worn by a mob
/mob/living/proc/damage_clothes(damage_amount, damage_type = BRUTE, damage_flag = 0, def_zone)
return
/mob/living/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y)
if(A != src)
end_pixel_y = get_standard_pixel_y_offset(lying)
used_item = get_active_held_item()
..()
floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement.
@@ -407,7 +407,8 @@
/obj/item/weapon/reagent_containers/borghypo/peace,
/obj/item/weapon/holosign_creator/cyborg,
/obj/item/borg/cyborghug/peacekeeper,
/obj/item/weapon/extinguisher)
/obj/item/weapon/extinguisher,
/obj/item/borg/projectile_dampen)
emag_modules = list(/obj/item/weapon/reagent_containers/borghypo/peace/hacked)
ratvar_modules = list(
/obj/item/clockwork/slab/cyborg/peacekeeper,
@@ -171,7 +171,30 @@
attacktext = "slashes"
attack_sound = 'sound/weapons/bladeslice.ogg'
construct_spells = list(/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift)
playstyle_string = "<b>You are a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls.</b>"
playstyle_string = "<b>You are a Wraith. Though relatively fragile, you are fast, deadly, can phase through walls, and your attacks will lower the cooldown on phasing.</b>"
var/attack_refund = 10 //1 second per attack
var/crit_refund = 50 //5 seconds when putting a target into critical
var/kill_refund = 250 //full refund on kills
/mob/living/simple_animal/hostile/construct/wraith/AttackingTarget() //refund jaunt cooldown when attacking living targets
var/prev_stat
if(isliving(target) && !iscultist(target))
var/mob/living/L = target
prev_stat = L.stat
. = ..()
if(. && isnum(prev_stat))
var/mob/living/L = target
var/refund = 0
if(QDELETED(L) || (L.stat == DEAD && prev_stat != DEAD)) //they're dead, you killed them
refund += kill_refund
else if(L.InCritical() && prev_stat == CONSCIOUS) //you knocked them into critical
refund += crit_refund
if(L.stat != DEAD && prev_stat != DEAD)
refund += attack_refund
for(var/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift/S in mob_spell_list)
S.charge_counter = min(S.charge_counter + refund, S.charge_max)
/mob/living/simple_animal/hostile/construct/wraith/hostile //actually hostile, will move around, hit things
AIStatus = AI_ON
@@ -265,8 +288,8 @@
name = "Harvester"
real_name = "Harvester"
desc = "A long, thin construct built to herald Nar-Sie's rise. It'll be all over soon."
icon_state = "harvester"
icon_living = "harvester"
icon_state = "chosen"
icon_living = "chosen"
maxHealth = 60
health = 60
sight = SEE_MOBS
@@ -277,9 +300,10 @@
construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/area_conversion,
/obj/effect/proc_holder/spell/aoe_turf/conjure/lesserforcewall)
playstyle_string = "<B>You are a Harvester. You are incapable of directly killing humans, but your attacks will remove their limbs: \
Bring those who still cling to this world of illusion back to the Geometer so they may know Truth.</B>"
Bring those who still cling to this world of illusion back to the Geometer so they may know Truth. Your form and any you are pulling can pass through runed walls effortlessly.</B>"
can_repair_constructs = TRUE
/mob/living/simple_animal/hostile/construct/harvester/Bump(atom/AM)
. = ..()
if(istype(AM, /turf/closed/wall/mineral/cult) && AM != loc) //we can go through cult walls
@@ -306,6 +330,8 @@
if(!LAZYLEN(parts))
if(undismembermerable_limbs) //they have limbs we can't remove, and no parts we can, attack!
return ..()
C.Weaken(30)
visible_message("<span class='danger'>[src] paralyzes [C]!</span>")
to_chat(src, "<span class='cultlarge'>\"Bring [C.p_them()] to me.\"</span>")
return FALSE
do_attack_animation(C)
@@ -314,6 +340,11 @@
return FALSE
. = ..()
/mob/living/simple_animal/hostile/construct/harvester/Initialize()
. = ..()
var/datum/action/innate/seek_prey/seek = new()
seek.Grant(src)
seek.Activate()
///////////////////////Master-Tracker///////////////////////
@@ -326,11 +357,14 @@
var/tracking = FALSE
var/mob/living/simple_animal/hostile/construct/the_construct
/datum/action/innate/seek_master/Grant(var/mob/living/C)
the_construct = C
..()
/datum/action/innate/seek_master/Activate()
if(!SSticker.mode.eldergod)
the_construct.master = GLOB.blood_target
if(!the_construct.master)
to_chat(the_construct, "<span class='cultitalic'>You have no master to seek!</span>")
the_construct.seeking = FALSE
@@ -346,6 +380,43 @@
to_chat(the_construct, "<span class='cultitalic'>You are now tracking your master.</span>")
/datum/action/innate/seek_prey
name = "Seek the Harvest"
desc = "None can hide from Nar'Sie, activate to track a survivor attempting to flee the red harvest!"
background_icon_state = "bg_demon"
buttontooltipstyle = "cult"
button_icon_state = "cult_mark"
var/tracking = FALSE
var/mob/living/simple_animal/hostile/construct/harvester/the_construct
/datum/action/innate/seek_prey/Grant(var/mob/living/C)
the_construct = C
..()
/datum/action/innate/seek_prey/Activate()
if(GLOB.cult_narsie == null)
return
if(tracking)
desc = "None can hide from Nar'Sie, activate to track a survivor attempting to flee the red harvest!"
button_icon_state = "cult_mark"
tracking = FALSE
the_construct.seeking = FALSE
the_construct.master = GLOB.cult_narsie
to_chat(the_construct, "<span class='cultitalic'>You are now tracking Nar'Sie, return to reap the harvest!</span>")
return
else
if(LAZYLEN(GLOB.cult_narsie.souls_needed))
the_construct.master = pick(GLOB.cult_narsie.souls_needed)
to_chat(the_construct, "<span class='cultitalic'>You are now tracking your prey, [the_construct.master] - harvest them!</span>")
else
to_chat(the_construct, "<span class='cultitalic'>Nar'Sie has completed her harvest!</span>")
return
desc = "Activate to track Nar'Sie!"
button_icon_state = "sintouch"
tracking = TRUE
the_construct.seeking = TRUE
/////////////////////////////ui stuff/////////////////////////////
/mob/living/simple_animal/hostile/construct/update_health_hud()
@@ -467,6 +467,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
var/used_message = "<span class='holoparasite'>All the cards seem to be blank now.</span>"
var/failure_message = "<span class='holoparasitebold'>..And draw a card! It's...blank? Maybe you should try again later.</span>"
var/ling_failure = "<span class='holoparasitebold'>The deck refuses to respond to a souless creature such as you.</span>"
var/activation_message = "<span class='holoparasite'>The rest of the deck rapidly flashes to ash!</span>"
var/list/possible_guardians = list("Assassin", "Chaos", "Charger", "Explosive", "Lightning", "Protector", "Ranged", "Standard", "Support")
var/random = TRUE
var/allowmultiple = FALSE
@@ -495,6 +496,8 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
if(candidates.len)
theghost = pick(candidates)
spawn_guardian(user, theghost.key)
to_chat(user, "[activation_message]")
qdel(src)
else
to_chat(user, "[failure_message]")
used = FALSE
@@ -587,6 +590,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
used_message = "<span class='holoparasite'>The injector has already been used.</span>"
failure_message = "<span class='holoparasitebold'>...ERROR. BOOT SEQUENCE ABORTED. AI FAILED TO INTIALIZE. PLEASE CONTACT SUPPORT OR TRY AGAIN LATER.</span>"
ling_failure = "<span class='holoparasitebold'>The holoparasites recoil in horror. They want nothing to do with a creature like you.</span>"
activation_message = "<span class='holoparasite'>The injector self destructs after you inject yourself with it.</span>"
/obj/item/weapon/guardiancreator/tech/choose/traitor
possible_guardians = list("Assassin", "Chaos", "Charger", "Explosive", "Lightning", "Protector", "Ranged", "Standard", "Support")
@@ -599,7 +603,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
/obj/item/weapon/paper/guardian
name = "Holoparasite Guide"
icon_state = "paper_words"
icon_state = "alienpaper_words"
info = {"<b>A list of Holoparasite Types</b><br>
<br>
@@ -670,6 +674,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
used_message = "<span class='holoparasite'>Someone's already taken a bite out of these fishsticks! Ew.</span>"
failure_message = "<span class='holoparasitebold'>You couldn't catch any carp spirits from the seas of Lake Carp. Maybe there are none, maybe you fucked up.</span>"
ling_failure = "<span class='holoparasitebold'>Carp'sie is fine with changelings, so you shouldn't be seeing this message.</span>"
activation_message = "<span class='holoparasite'>You finish eating the fishsticks! Delicious!>"
allowmultiple = TRUE
allowling = TRUE
random = TRUE
@@ -478,6 +478,8 @@ Difficulty: Hard
var/speed = 3 //how many deciseconds between each step
var/currently_seeking = FALSE
var/friendly_fire_check = FALSE //if blasts produced apply friendly fire
var/monster_damage_boost = TRUE
var/damage = 10
/obj/effect/temp_visual/hierophant/chaser/Initialize(mapload, new_caster, new_target, new_speed, is_friendly_fire)
. = ..()
@@ -524,6 +526,8 @@ Difficulty: Hard
/obj/effect/temp_visual/hierophant/chaser/proc/make_blast()
new /obj/effect/temp_visual/hierophant/blast(loc, caster, friendly_fire_check)
B.damage = damage
B.monster_damage_boost = monster_damage_boost
/obj/effect/temp_visual/hierophant/telegraph
icon = 'icons/effects/96x96.dmi'
@@ -553,6 +557,7 @@ Difficulty: Hard
desc = "Get out of the way!"
duration = 9
var/damage = 10 //how much damage do we do?
var/monster_damage_boost = TRUE //do we deal extra damage to monsters? Used by the boss
var/list/hit_things = list() //we hit these already, ignore them
var/friendly_fire_check = FALSE
var/bursting = FALSE //if we're bursting and need to hit anyone crossing us
@@ -595,7 +600,7 @@ Difficulty: Hard
var/limb_to_hit = L.get_bodypart(pick("head", "chest", "r_arm", "l_arm", "r_leg", "l_leg"))
var/armor = L.run_armor_check(limb_to_hit, "melee", "Your armor absorbs [src]!", "Your armor blocks part of [src]!", 50, "Your armor was penetrated by [src]!")
L.apply_damage(damage, BURN, limb_to_hit, armor)
if(ismegafauna(L) || istype(L, /mob/living/simple_animal/hostile/asteroid))
if(monster_damage_boost && (ismegafauna(L) || istype(L, /mob/living/simple_animal/hostile/asteroid)))
L.adjustBruteLoss(damage)
add_logs(caster, L, "struck with a [name]")
for(var/obj/mecha/M in T.contents - hit_things) //and mechs.
+1 -2
View File
@@ -170,8 +170,7 @@
/obj/item/weapon/paper/proc/updateinfolinks()
info_links = info
var/i = 0
for(i=1,i<=fields,i++)
for(var/i in 1 to min(fields, 15))
addtofield(i, "<font face=\"[PEN_FONT]\"><A href='?src=\ref[src];write=[i]'>write</A></font>", 1)
info_links = info_links + "<font face=\"[PEN_FONT]\"><A href='?src=\ref[src];write=end'>write</A></font>"
+11 -10
View File
@@ -304,16 +304,17 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
// Sound the alert if gravity was just enabled or disabled.
var/alert = 0
var/area/A = get_area(src)
if(on && SSticker.IsRoundInProgress()) // If we turned on and the game is live.
if(gravity_in_level() == 0)
alert = 1
investigate_log("was brought online and is now producing gravity for this level.", "gravity")
message_admins("The gravity generator was brought online [A][ADMIN_COORDJMP(src)]")
else
if(gravity_in_level() == 1)
alert = 1
investigate_log("was brought offline and there is now no gravity for this level.", "gravity")
message_admins("The gravity generator was brought offline with no backup generator. [A][ADMIN_COORDJMP(src)]")
if(SSticker.IsRoundInProgress())
if(on) // If we turned on and the game is live.
if(gravity_in_level() == 0)
alert = 1
investigate_log("was brought online and is now producing gravity for this level.", "gravity")
message_admins("The gravity generator was brought online [A][ADMIN_COORDJMP(src)]")
else
if(gravity_in_level() == 1)
alert = 1
investigate_log("was brought offline and there is now no gravity for this level.", "gravity")
message_admins("The gravity generator was brought offline with no backup generator. [A][ADMIN_COORDJMP(src)]")
update_icon()
update_list()
+53 -5
View File
@@ -34,13 +34,61 @@
var/area/A = get_area(src)
if(A)
var/mutable_appearance/alert_overlay = mutable_appearance('icons/effects/effects.dmi', "ghostalertsie")
var/mutable_appearance/alert_overlay = mutable_appearance('icons/effects/cult_effects.dmi', "ghostalertsie")
notify_ghosts("Nar-Sie has risen in \the [A.name]. Reach out to the Geometer to be given a new shell for your soul.", source = src, alert_overlay = alert_overlay, action=NOTIFY_ATTACK)
INVOKE_ASYNC(src, .proc/narsie_spawn_animation)
narsie_spawn_animation()
/obj/singularity/narsie/large/cult // For the new cult ending, guaranteed to end the round within 3 minutes
var/list/souls_needed = list()
var/soul_goal = 0
var/souls = 0
var/resolved = FALSE
sleep(19)
SSshuttle.emergency.request(null, set_coefficient = 0) //instantly arrives
/obj/singularity/narsie/large/cult/proc/resize(var/ratio)
var/matrix/ntransform = matrix(transform) //aka transform.Copy()
ntransform.Scale(ratio)
animate(src, transform = ntransform, time = 40, easing = EASE_IN|EASE_OUT)
/obj/singularity/narsie/large/cult/Initialize()
. = ..()
GLOB.cult_narsie = src
GLOB.blood_target = src
resize(0.6)
for(var/datum/mind/cult_mind in SSticker.mode.cult)
if(isliving(cult_mind.current))
var/mob/living/L = cult_mind.current
L.narsie_act()
for(var/mob/living/player in GLOB.player_list)
if(player.stat != DEAD && player.loc.z == ZLEVEL_STATION && !iscultist(player) && isliving(player))
souls_needed[player] = TRUE
soul_goal = round(1 + LAZYLEN(souls_needed) * 0.6)
INVOKE_ASYNC(src, .proc/begin_the_end)
/obj/singularity/narsie/large/cult/proc/begin_the_end()
sleep(50)
priority_announce("An acausal dimensional event has been detected in your sector. Event has been flagged EXTINCTION-CLASS. Directing all available assets toward simulating solutions. SOLUTION ETA: 60 SECONDS.","Central Command Higher Dimensional Affairs", 'sound/misc/airraid.ogg')
sleep(550)
priority_announce("Simulations on acausal dimensional event complete. Deploying solution package now. Deployment ETA: TWO MINUTES. ","Central Command Higher Dimensional Affairs")
sleep(50)
set_security_level("delta")
SSshuttle.registerHostileEnvironment(src)
SSshuttle.lockdown = TRUE
sleep(1150)
if(resolved == FALSE)
resolved = TRUE
world << sound('sound/machines/Alarm.ogg')
addtimer(CALLBACK(GLOBAL_PROC, .proc/cult_ending_helper), 120)
addtimer(CALLBACK(GLOBAL_PROC, .proc/ending_helper), 220)
/obj/singularity/narsie/large/cult/Destroy()
GLOB.cult_narsie = null
return ..()
/proc/ending_helper()
SSticker.force_ending = 1
/proc/cult_ending_helper(var/no_explosion = 0)
SSticker.station_explosion_cinematic(no_explosion, "cult", null)
/obj/singularity/narsie/large/attack_ghost(mob/dead/observer/user as mob)
@@ -134,7 +182,7 @@
return
to_chat(target, "<span class='cultsmall'>NAR-SIE HAS LOST INTEREST IN YOU.</span>")
target = food
if(isliving(target))
if(ishuman(target))
to_chat(target, "<span class ='cult'>NAR-SIE HUNGERS FOR YOUR SOUL.</span>")
else
to_chat(target, "<span class ='cult'>NAR-SIE HAS CHOSEN YOU TO LEAD HER TO HER NEXT MEAL.</span>")
@@ -64,6 +64,25 @@
qdel(S)
..()
/obj/item/ammo_casing/dnainjector
name = "rigged syringe gun spring"
desc = "A high-power spring that throws DNA injectors."
projectile_type = /obj/item/projectile/bullet/dnainjector
firing_effect_type = null
/obj/item/ammo_casing/dnainjector/ready_proj(atom/target, mob/living/user, quiet, zone_override = "")
if(!BB)
return
if(istype(loc, /obj/item/weapon/gun/syringe/dna))
var/obj/item/weapon/gun/syringe/dna/SG = loc
if(!SG.syringes.len)
return
var/obj/item/weapon/dnainjector/S = popleft(SG.syringes)
var/obj/item/projectile/bullet/dnainjector/D = BB
S.forceMove(D)
D.injector = S
..()
/obj/item/ammo_casing/energy/c3dbullet
projectile_type = /obj/item/projectile/bullet/midbullet3
@@ -5,6 +5,7 @@
item_state = null
w_class = WEIGHT_CLASS_BULKY
force = 10
modifystate = TRUE
flags = CONDUCT
slot_flags = SLOT_BACK
ammo_type = list(/obj/item/ammo_casing/energy/laser/pulse, /obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser)
@@ -39,7 +40,7 @@
w_class = WEIGHT_CLASS_NORMAL
slot_flags = SLOT_BELT
icon_state = "pulse_carbine"
item_state = "pulse"
item_state = null
cell_type = "/obj/item/weapon/stock_parts/cell/pulse/carbine"
can_flashlight = 1
flight_x_offset = 18
+32 -6
View File
@@ -49,18 +49,18 @@
return 1
/obj/item/weapon/gun/syringe/attackby(obj/item/A, mob/user, params, show_msg = 1)
/obj/item/weapon/gun/syringe/attackby(obj/item/A, mob/user, params, show_msg = TRUE)
if(istype(A, /obj/item/weapon/reagent_containers/syringe))
if(syringes.len < max_syringes)
if(!user.transferItemToLoc(A, src))
return
return FALSE
to_chat(user, "<span class='notice'>You load [A] into \the [src].</span>")
syringes.Add(A)
syringes += A
recharge_newshot()
return 1
return TRUE
else
to_chat(usr, "<span class='warning'>[src] cannot hold more syringes!</span>")
return 0
to_chat(user, "<span class='warning'>[src] cannot hold more syringes!</span>")
return FALSE
/obj/item/weapon/gun/syringe/rapidsyringe
name = "rapid syringe gun"
@@ -78,3 +78,29 @@
force = 2 //Also very weak because it's smaller
suppressed = 1 //Softer fire sound
can_unsuppress = 0 //Permanently silenced
/obj/item/weapon/gun/syringe/dna
name = "modified syringe gun"
desc = "A syringe gun that has been modified to fit DNA injectors instead of normal syringes."
origin_tech = "combat=2;syndicate=2;biotech=3"
/obj/item/weapon/gun/syringe/dna/Initialize()
. = ..()
chambered = new /obj/item/ammo_casing/dnainjector(src)
/obj/item/weapon/gun/syringe/dna/attackby(obj/item/A, mob/user, params, show_msg = TRUE)
if(istype(A, /obj/item/weapon/dnainjector))
var/obj/item/weapon/dnainjector/D = A
if(D.used)
to_chat(user, "<span class='warning'>This injector is used up!</span>")
return
if(syringes.len < max_syringes)
if(!user.transferItemToLoc(D, src))
return FALSE
to_chat(user, "<span class='notice'>You load \the [D] into \the [src].</span>")
syringes += D
recharge_newshot()
return TRUE
else
to_chat(user, "<span class='warning'>[src] cannot hold more syringes!</span>")
return FALSE
+27 -6
View File
@@ -190,7 +190,7 @@
name = "dart"
icon_state = "cbbolt"
damage = 6
var/piercing = 0
var/piercing = FALSE
/obj/item/projectile/bullet/dart/New()
..()
@@ -201,15 +201,15 @@
if(iscarbon(target))
var/mob/living/carbon/M = target
if(blocked != 100) // not completely blocked
if(M.can_inject(null, 0, def_zone, piercing)) // Pass the hit zone to see if it can inject by whether it hit the head or the body.
if(M.can_inject(null, FALSE, def_zone, piercing)) // Pass the hit zone to see if it can inject by whether it hit the head or the body.
..()
reagents.reaction(M, INJECT)
reagents.trans_to(M, reagents.total_volume)
return 1
return TRUE
else
blocked = 100
target.visible_message("<span class='danger'>The [name] was deflected!</span>", \
"<span class='userdanger'>You were protected against the [name]!</span>")
target.visible_message("<span class='danger'>\The [src] was deflected!</span>", \
"<span class='userdanger'>You were protected against \the [src]!</span>")
..(target, blocked)
reagents.set_reacting(TRUE)
@@ -240,7 +240,28 @@
nodamage = 1
. = ..() // Execute the rest of the code.
/obj/item/projectile/bullet/dnainjector
name = "\improper DNA injector"
icon_state = "syringeproj"
var/obj/item/weapon/dnainjector/injector
/obj/item/projectile/bullet/dnainjector/on_hit(atom/target, blocked = 0)
if(iscarbon(target))
var/mob/living/carbon/M = target
if(blocked != 100)
if(M.can_inject(null, FALSE, def_zone, FALSE))
if(injector.inject(M, firer))
QDEL_NULL(injector)
return TRUE
else
blocked = 100
target.visible_message("<span class='danger'>\The [src] was deflected!</span>", \
"<span class='userdanger'>You were protected against \the [src]!</span>")
return ..()
/obj/item/projectile/bullet/dnainjector/Destroy()
QDEL_NULL(injector)
return ..()
//// SNIPER BULLETS
+1
View File
@@ -143,6 +143,7 @@
has_id = 1
flavour_text = "<font size=3>You are a syndicate agent, employed in a top secret research facility developing biological weapons. Unfortunately, your hated enemy, Nanotrasen, has begun mining in this sector. <b>Continue your research as best you can, and try to keep a low profile. Do not abandon the base without good cause.</b> The base is rigged with explosives should the worst happen, do not let the base fall into enemy hands!</b>"
id_access_list = list(GLOB.access_syndicate)
faction = list("syndicate")
/obj/effect/mob_spawn/human/lavaland_syndicate/comms
name = "Syndicate Comms Agent"
+1
View File
@@ -24,6 +24,7 @@
if(charge_type == "recharge")
var/refund_percent = current_amount/projectile_amount
charge_counter = charge_max * refund_percent
start_recharge()
remove_ranged_ability(msg)
else
msg = "<span class='notice'>[active_msg]<B>Left-click to shoot it at a target!</B></span>"
+15
View File
@@ -1276,6 +1276,14 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
restricted_roles = list("Chaplain")
surplus = 5 //Very low chance to get it in a surplus crate even without being the chaplain
/datum/uplink_item/role_restricted/pie_cannon
name = "Banana Cream Pie Cannon"
desc = "A special pie cannon for a special clown, this gadget can hold up to 20 pies and automatically fabricates one every two seconds!"
cost = 10
item = /obj/item/weapon/pneumatic_cannon/pie/selfcharge
restricted_roles = list("Clown")
surplus = 0 //No fun unless you're the clown!
/datum/uplink_item/role_restricted/ancient_jumpsuit
name = "Ancient Jumpsuit"
desc = "A tattered old jumpsuit that will provide absolutely no benefit to you. It fills the wearer with a strange compulsion to blurt out 'glorf'."
@@ -1291,6 +1299,13 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
cost = 2
restricted_roles = list("Curator")
limited_stock = 1 // please don't spam deadchat
/datum/uplink_item/role_restricted/modified_syringe_gun
name = "Modified Syringe Gun"
desc = "A syringe gun that fires DNA injectors instead of normal syringes."
item = /obj/item/weapon/gun/syringe/dna
cost = 14
restricted_roles = list("Geneticist", "Chief Medical Officer")
// Pointless
/datum/uplink_item/badass
+3 -2
View File
@@ -16,6 +16,7 @@
It requires an organic host as a home base and source of fuel." //This is the description of the actual injector. Feel free to change this for uplink purposes//
item = /obj/item/weapon/storage/box/syndie_kit/holoparasite
refundable = TRUE
cost = 10 //I'm working off the borer. Price subject to change
cost = 15 //I'm working off the borer. Price subject to change
surplus = 20 //Nobody needs a ton of parasites
exclude_modes = list(/datum/game_mode/nuclear)
exclude_modes = list(/datum/game_mode/nuclear)
refund_path = /obj/item/weapon/guardiancreator/tech/choose/traitor
@@ -0,0 +1,4 @@
author: "Lordpidey"
delete-after: True
changes:
- rscadd: "Toy toolboxes with realistic rumbling action have been added to arcade prizes."
@@ -0,0 +1,4 @@
author: "Tacolizard Forever: Plasmaman Powercreep"
delete-after: True
changes:
- tweak: "Plasmaman tanks are the same size as emergency oxygen tanks."
@@ -0,0 +1,4 @@
author: "CitadelStationBot"
delete-after: True
changes:
- rscadd: "Peacekeeper cyborgs now have projectile dampening fields."
@@ -0,0 +1,8 @@
author: "coiax"
delete-after: True
changes:
- rscadd: "Various vending machines, when shooting their inventory at nearby
people, will \"demonstrate their products features\". This means that if a
cigarette vending machine throws a lighter at you, it will be on.
Vending machines also choose random products when throwing, rather than
the first available one."
@@ -0,0 +1,4 @@
author: "Joan"
delete-after: True
changes:
- rscadd: "Proselytizing alloy shards will now proselytize all the shards in the tile, instead of requiring you to proselytize each one at a time."
@@ -0,0 +1,4 @@
author: "CitadelStationBot"
delete-after: True
changes:
- bugfix: "Golems touching a shell can now choose to stay in their own body."
@@ -0,0 +1,4 @@
author: "Swindly"
delete-after: True
changes:
- rscadd: "Added modified syringe guns. They fire DNA injectors. Geneticists and CMOs can buy them from the traitor uplink for 14 TC."
@@ -0,0 +1,4 @@
author: "Steelpoint"
delete-after: True
changes:
- rscadd: "All Pulse weapons now accurately show, by their sprites, what fire mode they are in."
@@ -0,0 +1,4 @@
author: "LetterJay"
delete-after: True
changes:
- bugfix: "Cryo should now properly utilize chems as well as freeze the occupant."
@@ -0,0 +1,4 @@
author: "Gun Hog"
delete-after: True
changes:
- bugfix: "The Auxiliary Base can no longer land outside the lavaland map's boundaries."
+6
View File
@@ -0,0 +1,6 @@
author: "Robustin"
delete-after: True
changes:
- rscadd: "Summoning Nar'Sie now triggers a different ending. No shuttle is coming! Survivors must escape on a pod or survive the Red Harvest for 3 minutes. If Nar'Sie acquires enough souls, the round ends immediately with a **special ending**."
- rscadd: "New Harvester Sprite"
- rscadd: "Harvesters can now track a random survivor on the station, then switch back to tracking Nar'Sie, via a new action button."
Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 526 KiB

After

Width:  |  Height:  |  Size: 494 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

After

Width:  |  Height:  |  Size: 5.2 MiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 249 KiB

After

Width:  |  Height:  |  Size: 258 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

+14 -4
View File
@@ -33,6 +33,7 @@
#include "code\__DEFINES\combat.dm"
#include "code\__DEFINES\construction.dm"
#include "code\__DEFINES\contracts.dm"
#include "code\__DEFINES\cult.dm"
#include "code\__DEFINES\DNA.dm"
#include "code\__DEFINES\events.dm"
#include "code\__DEFINES\flags.dm"
@@ -196,6 +197,7 @@
#include "code\controllers\subsystem\dbcore.dm"
#include "code\controllers\subsystem\disease.dm"
#include "code\controllers\subsystem\events.dm"
#include "code\controllers\subsystem\fields.dm"
#include "code\controllers\subsystem\fire_burning.dm"
#include "code\controllers\subsystem\garbage.dm"
#include "code\controllers\subsystem\icon_smooth.dm"
@@ -468,6 +470,7 @@
#include "code\game\gamemodes\cult\cult_items.dm"
#include "code\game\gamemodes\cult\cult_structures.dm"
#include "code\game\gamemodes\cult\ritual.dm"
#include "code\game\gamemodes\cult\rune_spawn_action.dm"
#include "code\game\gamemodes\cult\runes.dm"
#include "code\game\gamemodes\cult\supply.dm"
#include "code\game\gamemodes\cult\talisman.dm"
@@ -709,10 +712,10 @@
#include "code\game\objects\effects\decals\decal.dm"
#include "code\game\objects\effects\decals\misc.dm"
#include "code\game\objects\effects\decals\remains.dm"
#include "code\game\objects\effects\decals\cleanable\aliens.dm"
#include "code\game\objects\effects\decals\cleanable\humans.dm"
#include "code\game\objects\effects\decals\cleanable\misc.dm"
#include "code\game\objects\effects\decals\cleanable\robots.dm"
#include "code\game\objects\effects\decals\Cleanable\aliens.dm"
#include "code\game\objects\effects\decals\Cleanable\humans.dm"
#include "code\game\objects\effects\decals\Cleanable\misc.dm"
#include "code\game\objects\effects\decals\Cleanable\robots.dm"
#include "code\game\objects\effects\effect_system\effect_system.dm"
#include "code\game\objects\effects\effect_system\effects_explosion.dm"
#include "code\game\objects\effects\effect_system\effects_foam.dm"
@@ -727,6 +730,10 @@
#include "code\game\objects\effects\spawners\structure.dm"
#include "code\game\objects\effects\spawners\vaultspawner.dm"
#include "code\game\objects\effects\spawners\xeno_egg_delivery.dm"
#include "code\game\objects\effects\temporary_visuals\clockcult.dm"
#include "code\game\objects\effects\temporary_visuals\cult.dm"
#include "code\game\objects\effects\temporary_visuals\miscellaneous.dm"
#include "code\game\objects\effects\temporary_visuals\temporary_visual.dm"
#include "code\game\objects\items\apc_frame.dm"
#include "code\game\objects\items\blueprints.dm"
#include "code\game\objects\items\body_egg.dm"
@@ -1304,6 +1311,9 @@
#include "code\modules\events\wizard\rpgloot.dm"
#include "code\modules\events\wizard\shuffle.dm"
#include "code\modules\events\wizard\summons.dm"
#include "code\modules\fields\fields.dm"
#include "code\modules\fields\peaceborg_dampener.dm"
#include "code\modules\fields\turf_objects.dm"
#include "code\modules\flufftext\Dreaming.dm"
#include "code\modules\flufftext\Hallucination.dm"
#include "code\modules\flufftext\TextFilters.dm"
-16
View File
@@ -1,16 +0,0 @@
diff a/tgstation.dme b/tgstation.dme (rejected hunks)
@@ -677,10 +677,10 @@
#include "code\game\objects\effects\decals\decal.dm"
#include "code\game\objects\effects\decals\misc.dm"
#include "code\game\objects\effects\decals\remains.dm"
-#include "code\game\objects\effects\decals\Cleanable\aliens.dm"
-#include "code\game\objects\effects\decals\Cleanable\humans.dm"
-#include "code\game\objects\effects\decals\Cleanable\misc.dm"
-#include "code\game\objects\effects\decals\Cleanable\robots.dm"
+#include "code\game\objects\effects\decals\cleanable\aliens.dm"
+#include "code\game\objects\effects\decals\cleanable\humans.dm"
+#include "code\game\objects\effects\decals\cleanable\misc.dm"
+#include "code\game\objects\effects\decals\cleanable\robots.dm"
#include "code\game\objects\effects\effect_system\effect_system.dm"
#include "code\game\objects\effects\effect_system\effects_explosion.dm"
#include "code\game\objects\effects\effect_system\effects_foam.dm"