Attack Chain Migration: /turf (#27530)

* Attack Chain Migration: /turf

* don't clobber component/signal vars when copying holodeck turfs

* Attack Chain Migration: /turf

* don't clobber component/signal vars when copying holodeck turfs

* Fixes from first round of testing

* rename signals, add afterattack skip

* Update code/game/turfs/simulated/minerals.dm

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: warriorstar-orion <orion@snowfrost.garden>

* Add some tests.

* Update code/game/turfs/simulated/minerals.dm

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: warriorstar-orion <orion@snowfrost.garden>

* fix TM issues

* make soap instantaneous and remove hardcoded sleep

* add sentinel value for obj placement direction choice

* fix tests

---------

Signed-off-by: warriorstar-orion <orion@snowfrost.garden>
Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
This commit is contained in:
warriorstar-orion
2025-01-10 16:15:19 -05:00
committed by GitHub
parent 27db7ad209
commit 3db86c80ac
23 changed files with 349 additions and 235 deletions
+22 -1
View File
@@ -1013,7 +1013,28 @@ Returns 1 if the chain up to the area contains the given typepath
copied_objects += newmobs
for(var/V in T.vars)
if(!(V in list("type", "loc", "locs", "vars", "parent", "parent_type", "verbs", "ckey", "key", "x", "y", "z", "destination_z", "destination_x", "destination_y", "contents", "luminosity", "group")))
if(!(V in list(
"ckey",
"comp_lookup",
"contents",
"destination_x",
"destination_y",
"destination_z",
"group",
"key",
"loc",
"locs",
"luminosity",
"parent_type",
"parent",
"signal_procs",
"type",
"vars",
"verbs",
"x",
"y",
"z",
)))
X.vars[V] = T.vars[V]
to_update += X
@@ -228,6 +228,10 @@
thermal_conductivity = 0
icon_state = "plating"
/turf/simulated/floor/holofloor/Initialize(mapload)
. = ..()
RegisterSignal(src, COMSIG_ATTACK_BY, TYPE_PROC_REF(/datum, signal_cancel_attack_by))
/turf/simulated/floor/holofloor/carpet
name = "carpet"
icon = 'icons/turf/floors/carpet.dmi'
@@ -266,10 +270,6 @@
pixel_y = -9
layer = ABOVE_OPEN_TURF_LAYER
/turf/simulated/floor/holofloor/attackby__legacy__attackchain(obj/item/W as obj, mob/user as mob, params)
return
// HOLOFLOOR DOES NOT GIVE A FUCK
/turf/simulated/floor/holofloor/space
name = "\proper space"
icon = 'icons/turf/space.dmi'
+2 -1
View File
@@ -38,8 +38,9 @@
to_chat(user, "<span class='notice'>Slicing [name] joints...</span>")
deconstruct()
else
// hand this off to the turf instead (for building plating, catwalks, etc)
var/turf/T = get_turf(src)
return T.attackby__legacy__attackchain(C, user) //hand this off to the turf instead (for building plating, catwalks, etc)
return T.attack_by(C, user, params)
/obj/structure/lattice/deconstruct(disassembled = TRUE)
if(!(flags & NODECONSTRUCT))
+10 -14
View File
@@ -156,19 +156,16 @@ GLOBAL_LIST_INIT(icons_to_ignore_at_floor_init, list("damaged1","damaged2","dama
W.update_icon()
return W
/turf/simulated/floor/attackby__legacy__attackchain(obj/item/C as obj, mob/user as mob, params)
if(!C || !user)
return TRUE
/turf/simulated/floor/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if(..() || QDELETED(used) || QDELETED(user))
return ITEM_INTERACT_COMPLETE
if(..())
return TRUE
if((intact || transparent_floor) && istype(used, /obj/item/stack/tile))
try_replace_tile(used, user, modifiers)
return ITEM_INTERACT_COMPLETE
if((intact || transparent_floor) && istype(C, /obj/item/stack/tile))
try_replace_tile(C, user, params)
return TRUE
if(istype(C, /obj/item/pipe))
var/obj/item/pipe/P = C
if(istype(used, /obj/item/pipe))
var/obj/item/pipe/P = used
if(P.pipe_type != -1) // ANY PIPE
user.visible_message( \
"[user] starts sliding [P] along \the [src].", \
@@ -191,8 +188,7 @@ GLOBAL_LIST_INIT(icons_to_ignore_at_floor_init, list("damaged1","damaged2","dama
P.y = src.y
P.z = src.z
P.forceMove(src)
return TRUE
return FALSE
return ITEM_INTERACT_COMPLETE
/turf/simulated/floor/crowbar_act(mob/user, obj/item/I)
if(!intact)
@@ -211,7 +207,7 @@ GLOBAL_LIST_INIT(icons_to_ignore_at_floor_init, list("damaged1","damaged2","dama
var/turf/simulated/floor/plating/P = pry_tile(thing, user, TRUE)
if(!istype(P))
return
P.attackby__legacy__attackchain(T, user, params)
P.item_interaction(user, T, params)
/turf/simulated/floor/proc/pry_tile(obj/item/C, mob/user, silent = FALSE)
if(!silent)
@@ -57,7 +57,7 @@
if(1)
getDug()
/turf/simulated/floor/plating/asteroid/proc/attempt_ore_pickup(obj/item/storage/bag/ore/S, mob/user, params)
/turf/simulated/floor/plating/asteroid/proc/attempt_ore_pickup(obj/item/storage/bag/ore/S, mob/user)
if(!istype(S))
return
@@ -66,12 +66,11 @@
O.attackby__legacy__attackchain(S, user)
return
/turf/simulated/floor/plating/asteroid/attackby__legacy__attackchain(obj/item/I, mob/user, params)
//note that this proc does not call ..()
if(!I|| !user)
return FALSE
/turf/simulated/floor/plating/asteroid/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if(QDELETED(user)|| QDELETED(used))
return ITEM_INTERACT_COMPLETE
if((istype(I, /obj/item/shovel) || istype(I, /obj/item/pickaxe)))
if((istype(used, /obj/item/shovel) || istype(used, /obj/item/pickaxe)))
if(!can_dig(user))
return TRUE
@@ -81,19 +80,19 @@
to_chat(user, "<span class='notice'>You start digging...</span>")
playsound(src, I.usesound, 50, TRUE)
if(do_after(user, 40 * I.toolspeed, target = src))
playsound(src, used.usesound, 50, TRUE)
if(do_after(user, 40 * used.toolspeed, target = src))
if(!can_dig(user))
return TRUE
to_chat(user, "<span class='notice'>You dig a hole.</span>")
getDug()
return TRUE
else if(istype(I, /obj/item/storage/bag/ore))
attempt_ore_pickup(I, user, params)
else if(istype(used, /obj/item/storage/bag/ore))
attempt_ore_pickup(used, user)
else if(istype(I, /obj/item/stack/tile))
var/obj/item/stack/tile/Z = I
else if(istype(used, /obj/item/stack/tile))
var/obj/item/stack/tile/Z = used
if(!Z.use(1))
return
if(istype(Z, /obj/item/stack/tile/plasteel)) // Turn asteroid floors into plating by default
+14 -8
View File
@@ -62,9 +62,11 @@
underlay_appearance.icon_state = "basalt"
return TRUE
/turf/simulated/floor/chasm/attackby__legacy__attackchain(obj/item/C, mob/user, params, area/area_restriction)
..()
if(istype(C, /obj/item/stack/rods))
/turf/simulated/floor/chasm/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if(..())
return ITEM_INTERACT_COMPLETE
if(istype(used, /obj/item/stack/rods))
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
if(!L)
var/obj/item/inactive = user.get_inactive_hand()
@@ -77,19 +79,21 @@
if(!inactive || inactive.tool_behaviour != TOOL_SCREWDRIVER)
to_chat(user, "<span class='warning'>You need to hold a screwdriver in your other hand to secure this lattice.</span>")
return
var/obj/item/stack/rods/R = C
return ITEM_INTERACT_COMPLETE
var/obj/item/stack/rods/R = used
if(R.use(1))
to_chat(user, "<span class='notice'>You construct a lattice.</span>")
playsound(src, 'sound/weapons/genhit.ogg', 50, TRUE)
ReplaceWithLattice()
else
to_chat(user, "<span class='warning'>You need one rod to build a lattice.</span>")
return
if(istype(C, /obj/item/stack/tile/plasteel))
return ITEM_INTERACT_COMPLETE
if(istype(used, /obj/item/stack/tile/plasteel))
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
if(L)
var/obj/item/stack/tile/plasteel/S = C
var/obj/item/stack/tile/plasteel/S = used
if(S.use(1))
qdel(L)
playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
@@ -100,6 +104,8 @@
else
to_chat(user, "<span class='warning'>The plating is going to need some support! Place metal rods first.</span>")
return ITEM_INTERACT_COMPLETE
/turf/simulated/floor/chasm/is_safe()
if(find_safeties() && ..())
return TRUE
@@ -83,13 +83,12 @@
/turf/simulated/floor/grass/get_broken_states()
return list("damaged")
/turf/simulated/floor/grass/attackby__legacy__attackchain(obj/item/C, mob/user, params)
if(..())
return
if(istype(C, /obj/item/shovel))
/turf/simulated/floor/grass/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if(istype(used, /obj/item/shovel))
to_chat(user, "<span class='notice'>You shovel the grass.</span>")
playsound(src, 'sound/effects/shovel_dig.ogg', 50, 1)
remove_tile()
return ITEM_INTERACT_COMPLETE
/turf/simulated/floor/grass/jungle
name = "jungle grass"
@@ -1,5 +1,9 @@
/turf/simulated/floor/indestructible
/turf/simulated/floor/indestructible/Initialize(mapload)
. = ..()
RegisterSignal(src, COMSIG_ATTACK_BY, TYPE_PROC_REF(/datum, signal_cancel_attack_by))
/turf/simulated/floor/indestructible/ex_act(severity)
return
@@ -18,9 +22,6 @@
/turf/simulated/floor/indestructible/burn_down()
return
/turf/simulated/floor/indestructible/attackby__legacy__attackchain(obj/item/I, mob/user, params)
return
/turf/simulated/floor/indestructible/attack_hand(mob/user)
return
+21 -15
View File
@@ -118,34 +118,38 @@
L.adjust_fire_stacks(20)
L.IgniteMob()
/turf/simulated/floor/lava/attackby__legacy__attackchain(obj/item/C, mob/user, params) //Lava isn't a good foundation to build on
if(istype(C, /obj/item/stack/rods/lava))
var/obj/item/stack/rods/lava/R = C
/// Lava isn't a good foundation to build on.
/turf/simulated/floor/lava/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if(istype(used, /obj/item/stack/rods/lava))
var/obj/item/stack/rods/lava/R = used
var/obj/structure/lattice/lava/H = locate(/obj/structure/lattice/lava, src)
if(H)
to_chat(user, "<span class='warning'>There is already a lattice here!</span>")
return
return ITEM_INTERACT_COMPLETE
if(R.use(1))
to_chat(user, "<span class='warning'>You construct a lattice.</span>")
playsound(src, 'sound/weapons/genhit.ogg', 50, TRUE)
new /obj/structure/lattice/lava(locate(x, y, z))
return ITEM_INTERACT_COMPLETE
else
to_chat(user, "<span class='warning'>You need one rod to build a heatproof lattice.</span>")
return
if(istype(C, /obj/item/stack/tile/plasteel))
return ITEM_INTERACT_COMPLETE
if(istype(used, /obj/item/stack/tile/plasteel))
var/obj/structure/lattice/L = locate(/obj/structure/lattice/lava, src)
if(!L)
to_chat(user, "<span class='warning'>The plating is going to need some support! Place metal rods first.</span>")
return
var/obj/item/stack/tile/plasteel/S = C
return ITEM_INTERACT_COMPLETE
var/obj/item/stack/tile/plasteel/S = used
if(S.use(1))
qdel(L)
playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
to_chat(user, "<span class='notice'>You build a floor.</span>")
ChangeTurf(/turf/simulated/floor/plating, keep_icon = FALSE)
return ITEM_INTERACT_COMPLETE
else
to_chat(user, "<span class='warning'>You need one floor tile to build a floor!</span>")
return ITEM_INTERACT_COMPLETE
/turf/simulated/floor/lava/screwdriver_act()
return
@@ -183,13 +187,15 @@
. = ..()
. += "<span class='notice'>Some <b>liquid plasma<b> could probably be scooped up with a <b>container</b>.</span>"
/turf/simulated/floor/lava/lava_land_surface/plasma/attackby__legacy__attackchain(obj/item/I, mob/user, params)
if(!I.is_open_container())
/turf/simulated/floor/lava/lava_land_surface/plasma/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if(!used.is_open_container())
return ..()
if(!I.reagents.add_reagent("plasma", 10))
to_chat(user, "<span class='warning'>[I] is full.</span>")
return
to_chat(user, "<span class='notice'>You scoop out some plasma from the [src] using [I].</span>")
if(!used.reagents.add_reagent("plasma", 10))
to_chat(user, "<span class='warning'>[used] is full.</span>")
return ITEM_INTERACT_COMPLETE
to_chat(user, "<span class='notice'>You scoop out some plasma from the [src] using [used].</span>")
return ITEM_INTERACT_COMPLETE
/turf/simulated/floor/lava/lava_land_surface/plasma/burn_stuff(AM)
. = FALSE
@@ -34,14 +34,16 @@
if(exposed_temperature > 300)
PlasmaBurn()
/turf/simulated/floor/mineral/plasma/attackby__legacy__attackchain(obj/item/W, mob/user, params)
if(W.get_heat() > 300)//If the temperature of the object is over 300, then ignite
/turf/simulated/floor/mineral/plasma/attack_by(obj/item/attacking, mob/user, params)
if(..())
return FINISH_ATTACK
if(attacking.get_heat() > 300)//If the temperature of the object is over 300, then ignite
message_admins("Plasma flooring was ignited by [key_name_admin(user)]([ADMIN_QUE(user,"?")]) ([ADMIN_FLW(user,"FLW")]) in ([x],[y],[z] - <a href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)",0,1)
log_game("Plasma flooring was <b>ignited by [key_name(user)] in ([x],[y],[z])")
investigate_log("was <font color='red'><b>ignited</b></font> by [key_name(user)]","atmos")
ignite(W.get_heat())
return
..()
ignite(attacking.get_heat())
return FINISH_ATTACK
/turf/simulated/floor/mineral/plasma/welder_act(mob/user, obj/item/I)
if(I.use_tool(src, user, volume = I.tool_volume))
@@ -174,10 +176,11 @@
if(istype(M))
squeek()
/turf/simulated/floor/mineral/bananium/attackby__legacy__attackchain(obj/item/W, mob/user, params)
.=..()
if(!.)
honk()
/turf/simulated/floor/mineral/bananium/attack_by(obj/item/attacking, mob/user, params)
if(..())
return FINISH_ATTACK
honk()
/turf/simulated/floor/mineral/bananium/attack_hand(mob/user)
.=..()
@@ -250,10 +253,11 @@
if(istype(AM))
radiate()
/turf/simulated/floor/mineral/uranium/attackby__legacy__attackchain(obj/item/W, mob/user, params)
.=..()
if(!.)
radiate()
/turf/simulated/floor/mineral/uranium/attack_by(obj/item/attacking, mob/user, params)
if(..())
return FINISH_ATTACK
radiate()
/turf/simulated/floor/mineral/uranium/attack_hand(mob/user)
.=..()
+40 -41
View File
@@ -48,73 +48,70 @@
if(unfastened)
. += "<span class='warning'>It has been unfastened.</span>"
/turf/simulated/floor/plating/attackby__legacy__attackchain(obj/item/C, mob/user, params)
if(..())
return TRUE
if(istype(C, /obj/item/stack/rods))
/turf/simulated/floor/plating/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if(istype(used, /obj/item/stack/rods))
if(broken || burnt)
to_chat(user, "<span class='warning'>Repair the plating first!</span>")
return TRUE
var/obj/item/stack/rods/R = C
return ITEM_INTERACT_COMPLETE
var/obj/item/stack/rods/R = used
if(R.get_amount() < 2)
to_chat(user, "<span class='warning'>You need two rods to make a reinforced floor!</span>")
return TRUE
return ITEM_INTERACT_COMPLETE
else
to_chat(user, "<span class='notice'>You begin reinforcing the floor...</span>")
if(do_after(user, 30 * C.toolspeed, target = src))
if(do_after(user, 30 * used.toolspeed, target = src))
if(R.get_amount() >= 2 && !istype(src, /turf/simulated/floor/engine))
ChangeTurf(/turf/simulated/floor/engine)
playsound(src, C.usesound, 80, 1)
playsound(src, used.usesound, 80, 1)
R.use(2)
to_chat(user, "<span class='notice'>You reinforce the floor.</span>")
return TRUE
return ITEM_INTERACT_COMPLETE
else if(istype(C, /obj/item/stack/tile))
else if(istype(used, /obj/item/stack/tile))
if(!broken && !burnt)
var/obj/item/stack/tile/W = C
var/obj/item/stack/tile/W = used
if(!W.use(1))
return
return ITEM_INTERACT_COMPLETE
ChangeTurf(W.turf_type)
playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
return ITEM_INTERACT_COMPLETE
else
to_chat(user, "<span class='warning'>This section is too damaged to support a tile! Use a welder to fix the damage.</span>")
return TRUE
else if(is_glass_sheet(C))
return ITEM_INTERACT_COMPLETE
else if(is_glass_sheet(used))
if(broken || burnt)
to_chat(user, "<span class='warning'>Repair the plating first!</span>")
return TRUE
var/obj/item/stack/sheet/R = C
return ITEM_INTERACT_COMPLETE
var/obj/item/stack/sheet/R = used
if(R.get_amount() < 2)
to_chat(user, "<span class='warning'>You need two sheets to build a [C.name] floor!</span>")
return TRUE
to_chat(user, "<span class='notice'>You begin swapping the plating for [C]...</span>")
if(do_after(user, 3 SECONDS * C.toolspeed, target = src))
to_chat(user, "<span class='warning'>You need two sheets to build a [used.name] floor!</span>")
return ITEM_INTERACT_COMPLETE
to_chat(user, "<span class='notice'>You begin swapping the plating for [used]...</span>")
if(do_after(user, 3 SECONDS * used.toolspeed, target = src))
if(R.get_amount() >= 2 && !transparent_floor)
if(istype(C, /obj/item/stack/sheet/plasmaglass)) //So, what type of glass floor do we want today?
if(istype(used, /obj/item/stack/sheet/plasmaglass)) //So, what type of glass floor do we want today?
ChangeTurf(/turf/simulated/floor/transparent/glass/plasma)
else if(istype(C, /obj/item/stack/sheet/plasmarglass))
else if(istype(used, /obj/item/stack/sheet/plasmarglass))
ChangeTurf(/turf/simulated/floor/transparent/glass/reinforced/plasma)
else if(istype(C, /obj/item/stack/sheet/glass))
else if(istype(used, /obj/item/stack/sheet/glass))
ChangeTurf(/turf/simulated/floor/transparent/glass)
else if(istype(C, /obj/item/stack/sheet/rglass))
else if(istype(used, /obj/item/stack/sheet/rglass))
ChangeTurf(/turf/simulated/floor/transparent/glass/reinforced)
else if(istype(C, /obj/item/stack/sheet/titaniumglass))
else if(istype(used, /obj/item/stack/sheet/titaniumglass))
ChangeTurf(/turf/simulated/floor/transparent/glass/titanium)
else if(istype(C, /obj/item/stack/sheet/plastitaniumglass))
else if(istype(used, /obj/item/stack/sheet/plastitaniumglass))
ChangeTurf(/turf/simulated/floor/transparent/glass/titanium/plasma)
playsound(src, C.usesound, 80, TRUE)
playsound(src, used.usesound, 80, TRUE)
R.use(2)
to_chat(user, "<span class='notice'>You swap the plating for [C].</span>")
to_chat(user, "<span class='notice'>You swap the plating for [used].</span>")
new /obj/item/stack/sheet/metal(src, 2)
return TRUE
return ITEM_INTERACT_COMPLETE
else if(istype(C, /obj/item/storage/backpack/satchel_flat)) //if you click plating with a smuggler satchel, place it on the plating please
else if(istype(used, /obj/item/storage/backpack/satchel_flat)) //if you click plating with a smuggler satchel, place it on the plating please
if(user.drop_item())
C.forceMove(src)
used.forceMove(src)
return TRUE
return ITEM_INTERACT_COMPLETE
/turf/simulated/floor/plating/screwdriver_act(mob/user, obj/item/I)
if(!I.tool_use_check(user, 0))
@@ -393,20 +390,22 @@
if(METAL_FOAM_IRON)
icon_state = "ironfoam"
/turf/simulated/floor/plating/metalfoam/attackby__legacy__attackchain(obj/item/C, mob/user, params)
/turf/simulated/floor/plating/metalfoam/attack_by(obj/item/attacking, mob/user, params)
if(..())
return TRUE
return FINISH_ATTACK
if(istype(C) && C.force)
if(istype(attacking) && attacking.force)
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src)
var/smash_prob = max(0, C.force * 17 - metal_kind * 25) // A crowbar will have a 60% chance of a breakthrough on alum, 35% on iron
var/smash_prob = max(0, attacking.force * 17 - metal_kind * 25) // A crowbar will have a 60% chance of a breakthrough on alum, 35% on iron
if(prob(smash_prob))
// YAR BE CAUSIN A HULL BREACH
visible_message("<span class='danger'>[user] smashes through \the [src] with \the [C]!</span>")
visible_message("<span class='danger'>[user] smashes through \the [src] with \the [attacking]!</span>")
smash()
return FINISH_ATTACK
else
visible_message("<span class='warning'>[user]'s [C.name] bounces against \the [src]!</span>")
visible_message("<span class='warning'>[user]'s [attacking.name] bounces against \the [src]!</span>")
return FINISH_ATTACK
/turf/simulated/floor/plating/metalfoam/attack_animal(mob/living/simple_animal/M)
M.do_attack_animation(src)
+37 -48
View File
@@ -62,24 +62,32 @@
/turf/simulated/mineral/shuttleRotate(rotation)
QUEUE_SMOOTH(src)
/turf/simulated/mineral/attackby__legacy__attackchain(obj/item/I, mob/user, params)
// TODO: Just sticking this here for now because attack chain refactor is coming later
// No point in threading this through everything right now
if(SEND_SIGNAL(src, COMSIG_ATTACK_BY, I, user, params) & COMPONENT_SKIP_AFTERATTACK)
return
/turf/simulated/mineral/proc/invalid_tool(mob/user, obj/item/pickaxe/axe)
if(!istype(axe))
return TRUE
return FALSE
/turf/simulated/mineral/attack_by(obj/item/attacking, mob/user, params)
if(..())
return FINISH_ATTACK
if(!user.IsAdvancedToolUser())
to_chat(usr, "<span class='warning'>You don't have the dexterity to do this!</span>")
return
return FINISH_ATTACK
if(istype(attacking, /obj/item/pickaxe))
var/obj/item/pickaxe/P = attacking
if(invalid_tool(user, P))
return FINISH_ATTACK
if(istype(I, /obj/item/pickaxe))
var/obj/item/pickaxe/P = I
var/turf/T = user.loc
if(!isturf(T))
return
return FINISH_ATTACK
if(last_act + (mine_time * P.toolspeed) > world.time) // Prevents message spam
return
return FINISH_ATTACK
last_act = world.time
to_chat(user, "<span class='notice'>You start picking...</span>")
P.playDigSound()
@@ -89,6 +97,8 @@
to_chat(user, "<span class='notice'>You finish cutting into the rock.</span>")
gets_drilled(user)
SSblackbox.record_feedback("tally", "pick_used_mining", 1, P.name)
return FINISH_ATTACK
else
return attack_hand(user)
@@ -126,15 +136,15 @@
if(ishuman(AM))
var/mob/living/carbon/human/H = AM
if((istype(H.l_hand,/obj/item/pickaxe)) && (!H.hand))
attackby__legacy__attackchain(H.l_hand,H)
attack_by(H.l_hand, H)
else if((istype(H.r_hand,/obj/item/pickaxe)) && H.hand)
attackby__legacy__attackchain(H.r_hand,H)
attack_by(H.r_hand, H)
return
else if(isrobot(AM))
var/mob/living/silicon/robot/R = AM
if(istype(R.module_active, /obj/item/pickaxe))
attackby__legacy__attackchain(R.module_active, R)
attack_by(R.module_active, R)
else if(ismecha(AM))
var/obj/mecha/M = AM
@@ -192,31 +202,6 @@
should_reset_color = FALSE
baseturf = /turf/simulated/floor/plating/asteroid/ancient
/turf/simulated/mineral/ancient/attackby__legacy__attackchain(obj/item/I, mob/user, params)
if(!user.IsAdvancedToolUser())
to_chat(usr, "<span class='warning'>You don't have the dexterity to do this!</span>")
return
if(istype(I, /obj/item/pickaxe))
var/obj/item/pickaxe/P = I
var/turf/T = user.loc
if(!isturf(T))
return
if(last_act + (mine_time * P.toolspeed) > world.time) // Prevents message spam
return
last_act = world.time
to_chat(user, "<span class='notice'>You start picking...</span>")
P.playDigSound()
if(do_after(user, mine_time * P.toolspeed, target = src))
if(ismineralturf(src)) //sanity check against turf being deleted during digspeed delay
to_chat(user, "<span class='notice'>You finish cutting into the rock.</span>")
gets_drilled(user)
SSblackbox.record_feedback("tally", "pick_used_mining", 1, P.name)
else
return attack_hand(user)
/turf/simulated/mineral/ancient/blob_act(obj/structure/blob/B)
if(prob(50))
blob_destruction()
@@ -250,11 +235,13 @@
/obj/item/pickaxe/drill/diamonddrill,
))
/turf/simulated/mineral/ancient/outer/attackby__legacy__attackchain(obj/item/I, mob/user, params)
if(istype(I, /obj/item/pickaxe) && !(is_type_in_typecache(I, allowed_picks_typecache)))
to_chat(user, "<span class='notice'>Only a diamond tools or a sonic jackhammer can break this rock.</span>")
return
return ..()
/turf/simulated/mineral/ancient/outer/invalid_tool(mob/user, obj/item/pickaxe/axe)
if(..())
return TRUE
if(!(is_type_in_typecache(axe, allowed_picks_typecache)))
to_chat(user, "<span class='notice'>Only diamond tools or a sonic jackhammer can break this rock.</span>")
return TRUE
/turf/simulated/mineral/ancient/lava_land_surface_hard
name = "hardened volcanic rock"
@@ -278,11 +265,13 @@
/obj/item/pickaxe/drill/diamonddrill,
))
/turf/simulated/mineral/ancient/lava_land_surface_hard/attackby__legacy__attackchain(obj/item/I, mob/user, params)
if(istype(I, /obj/item/pickaxe) && !(is_type_in_typecache(I, allowed_picks_typecache)))
to_chat(user, "<span class='notice'>Only a diamond tools or a sonic jackhammer can break this rock.</span>")
return
return ..()
/turf/simulated/mineral/ancient/lava_land_surface_hard/invalid_tool(mob/user, obj/item/pickaxe/axe)
if(..())
return TRUE
if(!(is_type_in_typecache(axe, allowed_picks_typecache)))
to_chat(user, "<span class='notice'>Only diamond tools or a sonic jackhammer can break this rock.</span>")
return TRUE
/turf/simulated/mineral/random/high_chance
color = COLOR_YELLOW
+16 -14
View File
@@ -342,28 +342,30 @@
add_fingerprint(user)
return ..()
/turf/simulated/wall/attackby__legacy__attackchain(obj/item/I, mob/user, params)
/turf/simulated/wall/attack_by(obj/item/attacking, mob/user, params)
if(..())
return FINISH_ATTACK
user.changeNext_move(CLICK_CD_MELEE)
if(!isturf(user.loc))
return // No touching walls unless you're on a turf (pretty sure attackby can't be called anyways but whatever)
return FINISH_ATTACK // No touching walls unless you're on a turf (pretty sure attackby can't be called anyways but whatever)
if(rotting && try_rot(I, user, params))
return
if(rotting && try_rot(attacking, user, params))
return FINISH_ATTACK
if(try_decon(I, user, params))
return
if(try_decon(attacking, user, params))
return FINISH_ATTACK
if(try_destroy(I, user, params))
return
if(try_destroy(attacking, user, params))
return FINISH_ATTACK
if(try_wallmount(attacking, user, params))
return CONTINUE_ATTACK
if(try_wallmount(I, user, params))
return
// The cyborg gripper does a separate attackby, so bail from this one
if(istype(I, /obj/item/gripper))
return
return ..()
if(istype(attacking, /obj/item/gripper))
return CONTINUE_ATTACK
/turf/simulated/wall/welder_act(mob/user, obj/item/I)
. = TRUE
@@ -3,6 +3,10 @@
desc = "Effectively impervious to conventional methods of destruction."
explosion_block = 50
/turf/simulated/wall/indestructible/Initialize(mapload)
. = ..()
RegisterSignal(src, COMSIG_ATTACK_BY, TYPE_PROC_REF(/datum, signal_cancel_attack_by))
/turf/simulated/wall/indestructible/dismantle_wall(devastated = 0, explode = 0)
return
@@ -34,9 +38,6 @@
/turf/simulated/wall/indestructible/burn_down()
return
/turf/simulated/wall/indestructible/attackby__legacy__attackchain(obj/item/I, mob/user, params)
return
/turf/simulated/wall/indestructible/attack_hand(mob/user)
return
+21 -13
View File
@@ -87,9 +87,11 @@
radiate()
..()
/turf/simulated/wall/mineral/uranium/attackby__legacy__attackchain(obj/item/W as obj, mob/user as mob, params)
/turf/simulated/wall/mineral/uranium/attack_by(obj/item/attacking, mob/user, params)
if(..())
return FINISH_ATTACK
radiate()
..()
/turf/simulated/wall/mineral/uranium/Bumped(AM as mob|obj)
radiate()
@@ -106,14 +108,17 @@
smoothing_groups = list(SMOOTH_GROUP_SIMULATED_TURFS, SMOOTH_GROUP_WALLS, SMOOTH_GROUP_PLASMA_WALLS)
canSmoothWith = list(SMOOTH_GROUP_PLASMA_WALLS)
/turf/simulated/wall/mineral/plasma/attackby__legacy__attackchain(obj/item/W, mob/user)
if(W.get_heat() > 300)//If the temperature of the object is over 300, then ignite
/turf/simulated/wall/mineral/plasma/attack_by(obj/item/attacking, mob/user, params)
if(..())
return FINISH_ATTACK
if(attacking.get_heat() > 300)//If the temperature of the object is over 300, then ignite
message_admins("Plasma wall ignited by [key_name_admin(user)] in ([x], [y], [z] - <a href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)",0,1)
log_game("Plasma wall ignited by [key_name(user)] in ([x], [y], [z])")
investigate_log("was <font color='red'><b>ignited</b></font> by [key_name(user)]","atmos")
ignite(W.get_heat())
return
..()
ignite(attacking.get_heat())
return FINISH_ATTACK
/turf/simulated/wall/mineral/plasma/welder_act(mob/user, obj/item/I)
if(I.tool_enabled)
@@ -171,15 +176,18 @@
smoothing_groups = list(SMOOTH_GROUP_SIMULATED_TURFS, SMOOTH_GROUP_WALLS, SMOOTH_GROUP_WOOD_WALLS)
canSmoothWith = list(SMOOTH_GROUP_WOOD_WALLS)
/turf/simulated/wall/mineral/wood/attackby__legacy__attackchain(obj/item/W, mob/user)
if(W.sharp && W.force)
var/duration = (48 / W.force) * 2 //In seconds, for now.
if(istype(W, /obj/item/hatchet) || istype(W, /obj/item/fireaxe))
/turf/simulated/wall/mineral/wood/attack_by(obj/item/attacking, mob/user, params)
if(..())
return FINISH_ATTACK
if(attacking.sharp && attacking.force)
var/duration = (48 / attacking.force) * 2 //In seconds, for now.
if(istype(attacking, /obj/item/hatchet) || istype(attacking, /obj/item/fireaxe))
duration /= 4 //Much better with hatchets and axes.
if(do_after(user, duration * 10, target = src)) //Into deciseconds.
dismantle_wall(FALSE, FALSE)
return
return ..()
return FINISH_ATTACK
/turf/simulated/wall/mineral/wood/nonmetal
desc = "A solidly wooden wall. It's a bit weaker than a wall made with metal."
+14 -13
View File
@@ -40,37 +40,38 @@
if(RWALL_SHEATH)
. += "<span class='notice'>The support rods have been <i>sliced through</i>, and the outer sheath is <b>connected loosely</b> to the girder.</span>"
/turf/simulated/wall/r_wall/attackby__legacy__attackchain(obj/item/I, mob/user, params)
if(d_state == RWALL_COVER && istype(I, /obj/item/gun/energy/plasmacutter))
/turf/simulated/wall/r_wall/attack_by(obj/item/attacking, mob/user, params)
if(..())
return FINISH_ATTACK
if(d_state == RWALL_COVER && istype(attacking, /obj/item/gun/energy/plasmacutter))
to_chat(user, "<span class='notice'>You begin slicing through the metal cover...</span>")
if(I.use_tool(src, user, 40, volume = I.tool_volume) && d_state == RWALL_COVER)
if(attacking.use_tool(src, user, 40, volume = attacking.tool_volume) && d_state == RWALL_COVER)
d_state = RWALL_CUT_COVER
update_icon()
to_chat(user, "<span class='notice'>You press firmly on the cover, dislodging it.</span>")
return
else if(d_state == RWALL_SUPPORT_RODS && istype(I, /obj/item/gun/energy/plasmacutter))
return FINISH_ATTACK
else if(d_state == RWALL_SUPPORT_RODS && istype(attacking, /obj/item/gun/energy/plasmacutter))
to_chat(user, "<span class='notice'>You begin slicing through the support rods...</span>")
if(I.use_tool(src, user, 70, volume = I.tool_volume) && d_state == RWALL_SUPPORT_RODS)
if(attacking.use_tool(src, user, 70, volume = attacking.tool_volume) && d_state == RWALL_SUPPORT_RODS)
d_state = RWALL_SHEATH
update_icon()
return
return FINISH_ATTACK
else if(d_state)
// Repairing
if(istype(I, /obj/item/stack/sheet/metal))
var/obj/item/stack/sheet/metal/MS = I
if(istype(attacking, /obj/item/stack/sheet/metal))
var/obj/item/stack/sheet/metal/MS = attacking
to_chat(user, "<span class='notice'>You begin patching-up the wall with [MS]...</span>")
if(do_after(user, max(20 * d_state, 100) * MS.toolspeed, target = src) && d_state)
if(!MS.use(1))
to_chat(user, "<span class='warning'>You don't have enough [MS.name] for that!</span>")
return
return FINISH_ATTACK
d_state = RWALL_INTACT
update_icon()
QUEUE_SMOOTH_NEIGHBORS(src)
to_chat(user, "<span class='notice'>You repair the last of the damage.</span>")
return
else
return ..()
return FINISH_ATTACK
/turf/simulated/wall/r_wall/welder_act(mob/user, obj/item/I)
if(reagents?.get_reagent_amount("thermite") && I.use_tool(src, user, volume = I.tool_volume))
+13 -9
View File
@@ -74,44 +74,48 @@
return
set_light(0)
/turf/space/attackby__legacy__attackchain(obj/item/C as obj, mob/user as mob, params)
..()
if(istype(C, /obj/item/stack/rods))
var/obj/item/stack/rods/R = C
/turf/space/item_interaction(mob/living/user, obj/item/used, list/modifiers)
if(istype(used, /obj/item/stack/rods))
var/obj/item/stack/rods/R = used
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
var/obj/structure/lattice/catwalk/W = locate(/obj/structure/lattice/catwalk, src)
if(W)
to_chat(user, "<span class='warning'>There is already a catwalk here!</span>")
return
return ITEM_INTERACT_COMPLETE
if(L)
if(R.use(1))
to_chat(user, "<span class='notice'>You construct a catwalk.</span>")
playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
new/obj/structure/lattice/catwalk(src)
return ITEM_INTERACT_COMPLETE
else
to_chat(user, "<span class='warning'>You need two rods to build a catwalk!</span>")
return
return ITEM_INTERACT_COMPLETE
if(R.use(1))
to_chat(user, "<span class='notice'>Constructing support lattice...</span>")
playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
ReplaceWithLattice()
return ITEM_INTERACT_COMPLETE
else
to_chat(user, "<span class='warning'>You need one rod to build a lattice.</span>")
return
return ITEM_INTERACT_COMPLETE
if(istype(C, /obj/item/stack/tile/plasteel))
if(istype(used, /obj/item/stack/tile/plasteel))
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
if(L)
var/obj/item/stack/tile/plasteel/S = C
var/obj/item/stack/tile/plasteel/S = used
if(S.use(1))
qdel(L)
playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
to_chat(user, "<span class='notice'>You build a floor.</span>")
ChangeTurf(/turf/simulated/floor/plating)
return ITEM_INTERACT_COMPLETE
else
to_chat(user, "<span class='warning'>You need one floor tile to build a floor!</span>")
return ITEM_INTERACT_COMPLETE
else
to_chat(user, "<span class='warning'>The plating is going to need some support! Place metal rods first.</span>")
return ITEM_INTERACT_COMPLETE
/turf/space/Entered(atom/movable/A as mob|obj, atom/OL, ignoreRest = 0)
..()
+4 -3
View File
@@ -4,9 +4,10 @@
icon_state = "black"
dir = SOUTH
//Overwrite because we dont want people building rods in space.
/turf/space/transit/attackby__legacy__attackchain(obj/O as obj, mob/user as mob, params)
return
/turf/space/transit/Initialize(mapload)
. = ..()
// We don't want people building rods in space.
RegisterSignal(src, COMSIG_ATTACK_BY, TYPE_PROC_REF(/datum, signal_cancel_attack_by))
/// moving to the north
/turf/space/transit/north
+12 -9
View File
@@ -93,6 +93,8 @@
OPEN_HEAT_TRANSFER_COEFFICIENT)
var/list/milla_data = list()
new_attack_chain = TRUE
/turf/Initialize(mapload)
SHOULD_CALL_PARENT(FALSE)
if(initialized)
@@ -482,28 +484,29 @@
if(SSticker)
GLOB.cameranet.updateVisibility(src)
/turf/attackby__legacy__attackchain(obj/item/I, mob/user, params)
/turf/attack_by(obj/item/attacking, mob/user, params)
if(..())
return TRUE
if(can_lay_cable())
if(istype(I, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/C = I
if(istype(attacking, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/C = attacking
for(var/obj/structure/cable/LC in src)
if(LC.d1 == 0 || LC.d2 == 0)
LC.attackby__legacy__attackchain(C, user)
return
return TRUE
C.place_turf(src, user)
return TRUE
else if(istype(I, /obj/item/rcl))
var/obj/item/rcl/R = I
else if(istype(attacking, /obj/item/rcl))
var/obj/item/rcl/R = attacking
if(R.loaded)
for(var/obj/structure/cable/LC in src)
if(LC.d1 == 0 || LC.d2 == 0)
LC.attackby__legacy__attackchain(R, user)
return
return TRUE
R.loaded.place_turf(src, user)
R.is_empty(user)
return FALSE
/turf/proc/can_have_cabling()
return TRUE
+4 -3
View File
@@ -82,14 +82,15 @@
color = "#aa77aa"
icon_state = "vinefloor"
/turf/simulated/floor/vines/Initialize(mapload)
. = ..()
RegisterSignal(src, COMSIG_ATTACK_BY, TYPE_PROC_REF(/datum, signal_cancel_attack_by))
/turf/simulated/floor/vines/get_broken_states()
return list()
//All of this shit is useless for vines
/turf/simulated/floor/vines/attackby__legacy__attackchain()
return
/turf/simulated/floor/vines/burn_tile()
return
+28 -4
View File
@@ -34,10 +34,17 @@
origin_test.Fail("could not spawn obj [obj_type] in hand of [puppet]")
/datum/test_puppeteer/proc/spawn_obj_nearby(obj_type)
for(var/turf/T in RANGE_TURFS(1, puppet.loc))
if(!is_blocked_turf(T, exclude_mobs = FALSE))
return origin_test.allocate(obj_type, T)
/datum/test_puppeteer/proc/spawn_obj_nearby(obj_type, direction = -1)
var/turf/T
if(direction >= 0)
T = get_step(puppet, direction)
else
for(var/turf/nearby in RANGE_TURFS(1, puppet.loc))
if(!is_blocked_turf(nearby, exclude_mobs = FALSE))
T = nearby
if(T)
return origin_test.allocate(obj_type, T)
origin_test.Fail("could not spawn obj [obj_type] near [src]")
@@ -56,6 +63,23 @@
var/mob/new_mob = origin_test.allocate(mob_type, T)
return new_mob
/datum/test_puppeteer/proc/change_turf_nearby(turf_type, direction = -1)
var/turf/T
if(direction >= 0)
T = get_step(puppet, direction)
else
// just check for any contents, not blocked_turf which includes turf density
// (which we don't really care about)
for(var/turf/nearby in RANGE_TURFS(1, puppet))
if(!length(nearby.contents))
T = nearby
if(T)
T.ChangeTurf(turf_type)
return T
origin_test.Fail("could not spawn turf [turf_type] near [src]")
/datum/test_puppeteer/proc/check_attack_log(snippet)
for(var/log_text in puppet.attack_log_old)
if(findtextEx(log_text, snippet))
@@ -0,0 +1,47 @@
/datum/game_test/attack_chain_turf/Run()
var/datum/test_puppeteer/player = new(src)
var/area/admin_area = get_area(player.puppet)
// So we can actually place a mounted frame here
admin_area.requires_power = TRUE
var/turf/wall = player.change_turf_nearby(/turf/simulated/wall, EAST)
player.spawn_obj_in_hand(/obj/item/mounted/frame/alarm_frame)
player.click_on(wall)
TEST_ASSERT(locate(/obj/machinery/alarm) in player.puppet.loc, "Did not find built air alarm frame")
admin_area.requires_power = FALSE
var/turf/plating = player.change_turf_nearby(/turf/simulated/floor/plating)
var/obj/item/stack/rods/rods = player.spawn_obj_in_hand(/obj/item/stack/rods/fifty)
rods.toolspeed = 0 // Don't want to try waiting this out in a test
player.click_on(plating)
var/turf/engine = get_turf(plating)
TEST_ASSERT(istype(engine, /turf/simulated/floor/engine), "Did not find plating converted to engine floor")
player.puppet.drop_item_to_ground(rods, force = TRUE)
var/obj/item/storage/bag/ore/ore_bag = player.spawn_obj_in_hand(/obj/item/storage/bag/ore)
var/obj/item/stack/ore/gold/gold = player.spawn_obj_nearby(/obj/item/stack/ore/gold, SOUTH)
var/turf/asteroid = player.change_turf_nearby(/turf/simulated/floor/plating/asteroid, SOUTH)
player.click_on(asteroid)
TEST_ASSERT(gold in ore_bag, "Did not find gold in ore bag")
qdel(ore_bag)
plating = player.change_turf_nearby(/turf/simulated/floor/plating)
var/obj/rpd = player.spawn_obj_in_hand(/obj/item/rpd)
player.click_on(plating)
TEST_ASSERT(locate(/obj/machinery/atmospherics/pipe) in plating, "Did not find pipe placed with RPD")
qdel(rpd)
var/obj/resonator = player.spawn_obj_in_hand(/obj/item/resonator)
var/turf/mineral_wall = player.change_turf_nearby(/turf/simulated/mineral/ancient)
player.click_on(mineral_wall)
sleep(3 SECONDS)
TEST_ASSERT(istype(get_turf(mineral_wall), /turf/simulated/floor/plating/asteroid), "Did not find mineral wall dug with resonator")
qdel(resonator)
var/obj/item/soap/soap = player.spawn_obj_in_hand(/obj/item/soap)
soap.cleanspeed = 0
var/turf/T = get_turf(player.puppet)
new/obj/effect/spawner/themed_mess/bloody(T)
TEST_ASSERT(locate(/obj/effect/decal/cleanable) in T, "Did not find any mess decal on turf")
player.click_on(T)
TEST_ASSERT_NOT(locate(/obj/effect/decal/cleanable) in T, "Mess decal remained on turf after soap use")
+1
View File
@@ -6,6 +6,7 @@
#include "_game_test.dm"
#include "atmos\test_ventcrawl.dm"
#include "attack_chain\test_attack_chain_cult_dagger.dm"
#include "attack_chain\test_attack_chain_turf.dm"
#include "attack_chain\test_attack_chain_vehicles.dm"
#include "games\test_cards.dm"
#include "jobs\test_job_globals.dm"