[Testmerge ready] Ports tool behaviours; refactors all tools; adds functionality for self-filling reagent containers (#11700)

* Adds support for self-filling reagent containers

* Sets tool_behaviour on the default set of tools

* Fixing merge conflicts

* Refactors welder to use tool behaviour

* The refactor: part I

* The refactor: part II

* Tool Refactor Part III: Revenge of the Maint

* Tool Refactor Part IV: A New Hope

* Tool Refactor Part V: The Oldcoder Strikes Back

* Tool Refactor Part VI: Return of the Coder

* VII

* Holy shit, it compiles?!

* Nannek I completed your TODO, you owe me ice cream

* Tool helpers; telepad is compliant

* Bugtest, Round 1: Fight

Fuck refactoring disposals

* Buggfixing, Round 2: Electric Boogaloo

* Personal crafting uses tool behaviours now

* Construction datums use new tool behaviours; better way of handling fueltank refuelling; more bugfixing

* multitool_check_buffer change; removes some useless things in tool_helpers

* proc name change

* TRUE/FALSE changes

* Bugfixing, Round 3: A Good Day To Bugfix Hard

Fixes multiple issues raised by the testmerge

* Minor style changes
This commit is contained in:
Citinited
2020-02-15 13:31:08 -07:00
committed by GitHub
parent 5b1941e784
commit fddff1049b
238 changed files with 6681 additions and 5544 deletions
+16 -13
View File
@@ -90,25 +90,28 @@
return
// Maybe later add encryption key support, but that's a pain in the neck atm
if(isscrewdriver(O))
if(radio)
user.visible_message("<span class='warning'>[user] begins to uninstall the radio from [src]...</span>", \
"<span class='notice'>You start to uninstall the radio from [src]...</span>")
if(do_after(user, 40 * O.toolspeed, target = src))
uninstall_radio()
new /obj/item/mmi_radio_upgrade(get_turf(src))
user.visible_message("<span class='warning'>[user] uninstalls the radio from [src].</span>", \
"<span class='notice'>You uninstall the radio from [src].</span>")
else
to_chat(user, "<span class='warning'>There is no radio in [src]!</span>")
return
if(brainmob)
O.attack(brainmob, user)//Oh noooeeeee
// Brainmobs can take damage, but they can't actually die. Maybe should fix.
return
..()
return ..()
/obj/item/mmi/screwdriver_act(mob/user, obj/item/I)
. = TRUE
if(!I.tool_use_check(user, 0))
return
if(!radio)
to_chat(user, "<span class='warning'>There is no radio in [src]!</span>")
return
user.visible_message("<span class='warning'>[user] begins to uninstall the radio from [src]...</span>", \
"<span class='notice'>You start to uninstall the radio from [src]...</span>")
if(!I.use_tool(src, user, 40, volume = I.tool_volume) || !radio)
return
uninstall_radio()
new /obj/item/mmi_radio_upgrade(get_turf(src))
user.visible_message("<span class='warning'>[user] uninstalls the radio from [src].</span>", \
"<span class='notice'>You uninstall the radio from [src].</span>")
/obj/item/mmi/attack_self(mob/user as mob)
@@ -35,6 +35,73 @@ emp_act
return (..(P , def_zone))
/mob/living/carbon/human/screwdriver_act(mob/user, obj/item/I)
if(!can_operate(src)) //Checks if mob is lying down on table for surgery
return
if(!ismachine(src))
return
if(user.a_intent != INTENT_HELP)
return
if(attempt_initiate_surgery(I, src, user))
return TRUE
/mob/living/carbon/human/welder_act(mob/user, obj/item/I)
if(user.a_intent != INTENT_HELP)
return
if(!I.tool_use_check(user, 1))
return
var/obj/item/organ/external/S = bodyparts_by_name[user.zone_selected]
if(!S)
return
if(!S.is_robotic() || S.open == 2)
return
. = TRUE
if(S.brute_dam > ROBOLIMB_SELF_REPAIR_CAP)
to_chat(user, "<span class='danger'>The damage is far too severe to patch over externally.</span>")
return
if(!S.brute_dam)
to_chat(user, "<span class='notice'>Nothing to fix!</span>")
return
var/surgery_time = 0
if(user == src)
surgery_time = 10
if(!I.use_tool(src, user, surgery_time, amount = 1, volume = I.tool_volume))
return
var/rembrute = HEALPERWELD
var/nrembrute = 0
var/childlist
if(!isnull(S.children))
childlist = S.children.Copy()
var/parenthealed = FALSE
while(rembrute > 0)
var/obj/item/organ/external/E
if(S.brute_dam)
E = S
else if(LAZYLEN(childlist))
E = pick_n_take(childlist)
if(!E.brute_dam || !E.is_robotic())
continue
else if(S.parent && !parenthealed)
E = S.parent
parenthealed = TRUE
if(!E.brute_dam || !E.is_robotic())
break
else
break
nrembrute = max(rembrute - E.brute_dam, 0)
E.heal_damage(rembrute,0,0,1)
rembrute = nrembrute
user.visible_message("<span class='alert'>[user] patches some dents on [src]'s [E.name] with [I].</span>")
if(bleed_rate && isSynthetic())
bleed_rate = 0
user.visible_message("<span class='alert'>[user] patches some leaks on [src] with [I].</span>")
if(IgniteMob())
message_admins("[key_name_admin(user)] set [key_name_admin(src)] on fire with [I]")
log_game("[key_name(user)] set [key_name(src)] on fire with [I]")
/mob/living/carbon/human/check_projectile_dismemberment(obj/item/projectile/P, def_zone)
var/obj/item/organ/external/affecting = get_organ(check_zone(def_zone))
if(affecting && !affecting.cannot_amputate && affecting.get_damage() >= (affecting.max_damage - P.dismemberment))
+7
View File
@@ -270,6 +270,13 @@
take_organ_damage(acidpwr * min(1, acid_volume * 0.1))
return 1
/mob/living/welder_act(mob/user, obj/item/I)
if(!I.tool_use_check(null, 0)) //Don't need the message, just if it succeeded
return
if(IgniteMob())
message_admins("[key_name_admin(user)] set [key_name_admin(src)] on fire with [I]")
log_game("[key_name(user)] set [key_name(src)] on fire with [I]")
/mob/living/proc/updatehealth(reason = "none given")
if(status_flags & GODMODE)
health = maxHealth
+2
View File
@@ -1125,6 +1125,8 @@ var/list/ai_verbs_default = list(
else
return ..()
/mob/living/silicon/ai/welder_act()
return
/mob/living/silicon/ai/proc/control_integrated_radio()
set name = "Radio Settings"
@@ -19,6 +19,9 @@
else
return ..()
/mob/living/silicon/decoy/welder_act()
return
/mob/living/silicon/decoy/syndicate
faction = list("syndicate")
name = "R.O.D.G.E.R"
@@ -470,6 +470,9 @@
close_up()
return
/mob/living/silicon/pai/welder_act()
return
/mob/living/silicon/pai/attack_hand(mob/user as mob)
if(stat == DEAD)
return
+103 -93
View File
@@ -621,28 +621,7 @@ var/list/robot_verbs_default = list(
return
if(istype(W, /obj/item/weldingtool) && user.a_intent == INTENT_HELP)
if(W == module_active)
return
if(!getBruteLoss())
to_chat(user, "<span class='notice'>Nothing to fix!</span>")
return
else if(!getBruteLoss(TRUE))
to_chat(user, "<span class='warning'>The damaged components are beyond saving!</span>")
return
var/obj/item/weldingtool/WT = W
user.changeNext_move(CLICK_CD_MELEE)
if(WT.remove_fuel(0))
playsound(src.loc, W.usesound, 50, 1)
adjustBruteLoss(-30)
add_fingerprint(user)
user.visible_message("<span class='alert'>\The [user] patches some dents on \the [src] with \the [WT].</span>")
else
to_chat(user, "<span class='warning'>Need more welding fuel!</span>")
return
else if(istype(W, /obj/item/stack/cable_coil) && user.a_intent == INTENT_HELP && (wiresexposed || istype(src, /mob/living/silicon/robot/drone)))
if(istype(W, /obj/item/stack/cable_coil) && user.a_intent == INTENT_HELP && (wiresexposed || istype(src, /mob/living/silicon/robot/drone)))
user.changeNext_move(CLICK_CD_MELEE)
if(!getFireLoss())
to_chat(user, "<span class='notice'>Nothing to fix!</span>")
@@ -657,58 +636,6 @@ var/list/robot_verbs_default = list(
coil.use(1)
user.visible_message("<span class='alert'>\The [user] fixes some of the burnt wires on \the [src] with \the [coil].</span>")
else if(istype(W, /obj/item/crowbar)) // crowbar means open or close the cover
if(opened)
if(cell)
to_chat(user, "You close the cover.")
opened = 0
update_icons()
else if(wiresexposed && wires.IsAllCut())
//Cell is out, wires are exposed, remove MMI, produce damaged chassis, baleet original mob.
if(!mmi)
to_chat(user, "[src] has no brain to remove.")
return
to_chat(user, "You jam the crowbar into the robot and begin levering the securing bolts.")
if(do_after(user, 30 * W.toolspeed, target = src))
user.visible_message("[user] deconstructs [src]!", "<span class='notice'>You unfasten the securing bolts, and [src] falls to pieces!</span>")
deconstruct()
else
// Okay we're not removing the cell or an MMI, but maybe something else?
var/list/removable_components = list()
for(var/V in components)
if(V == "power cell") continue
var/datum/robot_component/C = components[V]
if(C.installed == 1 || C.installed == -1)
removable_components += V
if(module)
removable_components += module.custom_removals
var/remove = input(user, "Which component do you want to pry out?", "Remove Component") as null|anything in removable_components
if(!remove)
return
if(module && module.handle_custom_removal(remove, user, W, params))
return
var/datum/robot_component/C = components[remove]
var/obj/item/robot_parts/robot_component/I = C.wrapped
to_chat(user, "You remove \the [I].")
if(istype(I))
I.brute = C.brute_damage
I.burn = C.electronics_damage
I.loc = src.loc
var/was_installed = C.installed
C.installed = 0
if(was_installed == 1)
C.uninstall()
else
if(locked)
to_chat(user, "The cover is locked and cannot be opened.")
else
to_chat(user, "You open the cover.")
opened = 1
update_icons()
else if(istype(W, /obj/item/stock_parts/cell) && opened) // trying to put a cell inside
var/datum/robot_component/C = components["power cell"]
if(wiresexposed)
@@ -729,24 +656,6 @@ var/list/robot_verbs_default = list(
C.electronics_damage = 0
diag_hud_set_borgcell()
else if(istype(W, /obj/item/wirecutters) || istype(W, /obj/item/multitool))
if(wiresexposed)
wires.Interact(user)
else
to_chat(user, "You can't reach the wiring.")
else if(istype(W, /obj/item/screwdriver) && opened && !cell) // haxing
wiresexposed = !wiresexposed
to_chat(user, "The wires have been [wiresexposed ? "exposed" : "unexposed"]")
update_icons()
else if(istype(W, /obj/item/screwdriver) && opened && cell) // radio
if(radio)
radio.attackby(W,user)//Push it to the radio to let it handle everything
else
to_chat(user, "Unable to locate a radio.")
update_icons()
else if(istype(W, /obj/item/encryptionkey/) && opened)
if(radio)//sanityyyyyy
radio.attackby(W,user)//GTFO, you have your own procs
@@ -801,6 +710,108 @@ var/list/robot_verbs_default = list(
else
return ..()
/mob/living/silicon/robot/wirecutter_act(mob/user, obj/item/I)
if(!opened)
return
. = TRUE
if(!I.use_tool(src, user, 0, volume = 0))
return
if(wiresexposed)
wires.Interact(user)
/mob/living/silicon/robot/multitool_act(mob/user, obj/item/I)
if(!opened)
return
. = TRUE
if(!I.use_tool(src, user, 0, volume = 0))
return
if(wiresexposed)
wires.Interact(user)
/mob/living/silicon/robot/screwdriver_act(mob/user, obj/item/I)
if(!opened)
return
. = TRUE
if(!I.use_tool(src, user, 0, volume = 0))
return
if(!cell) // haxing
wiresexposed = !wiresexposed
to_chat(user, "<span class='notice'>The wires have been [wiresexposed ? "exposed" : "unexposed"]</span>")
update_icons()
I.play_tool_sound(user, I.tool_volume)
else //radio check
if(radio)
radio.screwdriver_act(user, I)//Push it to the radio to let it handle everything
else
to_chat(user, "Unable to locate a radio.")
update_icons()
/mob/living/silicon/robot/crowbar_act(mob/user, obj/item/I)
if(user.a_intent != INTENT_HELP)
return
. = TRUE
if(!I.tool_use_check(user, 0))
return
if(!opened)
if(locked)
to_chat(user, "The cover is locked and cannot be opened.")
return
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
to_chat(user, "You open the cover.")
opened = TRUE
update_icons()
return
else if(cell)
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
to_chat(user, "You close the cover.")
opened = FALSE
update_icons()
return
else if(wiresexposed && wires.IsAllCut())
//Cell is out, wires are exposed, remove MMI, produce damaged chassis, baleet original mob.
if(!mmi)
to_chat(user, "[src] has no brain to remove.")
return
to_chat(user, "You jam the crowbar into the robot and begin levering the securing bolts...")
if(I.use_tool(src, user, 30, volume = I.tool_volume))
user.visible_message("[user] deconstructs [src]!", "<span class='notice'>You unfasten the securing bolts, and [src] falls to pieces!</span>")
deconstruct()
return
// Okay we're not removing the cell or an MMI, but maybe something else?
var/list/removable_components = list()
for(var/V in components)
if(V == "power cell")
continue
var/datum/robot_component/C = components[V]
if(C.installed == 1 || C.installed == -1)
removable_components += V
if(module)
removable_components += module.custom_removals
var/remove = input(user, "Which component do you want to pry out?", "Remove Component") as null|anything in removable_components
if(!remove)
return
if(module && module.handle_custom_removal(remove, user, I))
return
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
var/datum/robot_component/C = components[remove]
var/obj/item/robot_parts/robot_component/thing = C.wrapped
to_chat(user, "You remove \the [thing].")
if(istype(thing))
thing.brute = C.brute_damage
thing.burn = C.electronics_damage
thing.loc = loc
var/was_installed = C.installed
C.installed = 0
if(was_installed == 1)
C.uninstall()
/mob/living/silicon/robot/attacked_by(obj/item/I, mob/living/user, def_zone)
if(I.force && I.damtype != STAMINA && stat != DEAD) //only sparks if real damage is dealt.
spark_system.start()
@@ -1457,4 +1468,3 @@ var/list/robot_verbs_default = list(
SEND_SIGNAL(src, COMSIG_MOB_UPDATE_SIGHT)
sync_lighting_plane_alpha()
@@ -106,7 +106,7 @@
R.module_actions.Cut()
// Return true in an overridden subtype to prevent normal removal handling
/obj/item/robot_module/proc/handle_custom_removal(component_id, mob/living/user, obj/item/W, params)
/obj/item/robot_module/proc/handle_custom_removal(component_id, mob/living/user, obj/item/W)
return FALSE
/obj/item/robot_module/proc/handle_death(gibbed)
@@ -358,10 +358,10 @@
fix_modules()
/obj/item/robot_module/miner/handle_custom_removal(component_id, mob/living/user, obj/item/W, params)
/obj/item/robot_module/miner/handle_custom_removal(component_id, mob/living/user, obj/item/W)
if(component_id == "KA modkits")
for(var/obj/item/gun/energy/kinetic_accelerator/cyborg/D in src)
D.attackby(W, user, params)
D.attackby(W, user)
return TRUE
return ..()
@@ -100,6 +100,25 @@
/mob/living/silicon/IsAdvancedToolUser()
return TRUE
/mob/living/silicon/robot/welder_act(mob/user, obj/item/I)
if(user.a_intent != INTENT_HELP)
return
if(user == src) //No self-repair dummy
return
. = TRUE
if(!getBruteLoss())
to_chat(user, "<span class='notice'>Nothing to fix!</span>")
return
else if(!getBruteLoss(TRUE))
to_chat(user, "<span class='warning'>The damaged components are beyond saving!</span>")
return
if(!I.use_tool(src, user, volume = I.tool_volume))
return
adjustBruteLoss(-30)
add_fingerprint(user)
user.visible_message("<span class='alert'>[user] patches some dents on [src] with [I].</span>")
/mob/living/silicon/bullet_act(var/obj/item/projectile/Proj)
@@ -357,25 +357,25 @@
user.visible_message("<span class='notice'>[user] uses [W] to pull [paicard] out of [bot_name]!</span>","<span class='notice'>You pull [paicard] out of [bot_name] with [W].</span>")
ejectpai(user)
else
user.changeNext_move(CLICK_CD_MELEE)
if(istype(W, /obj/item/weldingtool) && user.a_intent != INTENT_HARM)
if(health >= maxHealth)
to_chat(user, "<span class='warning'>[src] does not need a repair!</span>")
return
if(!open)
to_chat(user, "<span class='warning'>Unable to repair with the maintenance panel closed!</span>")
return
var/obj/item/weldingtool/WT = W
if(WT.remove_fuel(0, user))
adjustHealth(-10)
add_fingerprint(user)
user.visible_message("[user] repairs [src]!","<span class='notice'>You repair [src].</span>")
else
to_chat(user, "<span class='warning'>The welder must be on for this task!</span>")
else
if(W.force) //if force is non-zero
do_sparks(5, 1, src)
..()
return ..()
/mob/living/simple_animal/bot/welder_act(mob/user, obj/item/I)
if(user.a_intent != INTENT_HELP)
return
if(user == src) //No self-repair dummy
return
. = TRUE
if(health >= maxHealth)
to_chat(user, "<span class='warning'>[src] does not need a repair!</span>")
return
if(!open)
to_chat(user, "<span class='warning'>Unable to repair with the maintenance panel closed!</span>")
return
if(!I.use_tool(src, user, volume = I.tool_volume))
return
adjustBruteLoss(-10)
add_fingerprint(user)
user.visible_message("[user] repairs [src]!","<span class='notice'>You repair [src].</span>")
/mob/living/simple_animal/bot/bullet_act(obj/item/projectile/Proj)
if(Proj && (Proj.damage_type == BRUTE || Proj.damage_type == BURN))
@@ -96,12 +96,10 @@ var/robot_arm = /obj/item/robot_parts/l_arm
icon_state = "[lasercolor]ed209_shell"
if(3)
if(istype(W, /obj/item/weldingtool))
var/obj/item/weldingtool/WT = W
if(WT.remove_fuel(0,user))
build_step++
name = "shielded frame assembly"
to_chat(user, "<span class='notice'>You weld the vest to [src].</span>")
if(W.tool_behaviour == TOOL_WELDER && W.use_tool(src, user, volume = W.tool_volume))
build_step++
name = "shielded frame assembly"
to_chat(user, "<span class='notice'>You weld the vest to [src].</span>")
if(4)
switch(lasercolor)
if("b")
@@ -440,19 +438,15 @@ var/robot_arm = /obj/item/robot_parts/l_arm
/obj/item/secbot_assembly/attackby(obj/item/I, mob/user, params)
..()
if(istype(I, /obj/item/weldingtool))
if(I.tool_behaviour == TOOL_WELDER && I.use_tool(src, user, volume = I.tool_volume))
if(!build_step)
var/obj/item/weldingtool/WT = I
if(WT.remove_fuel(0, user))
build_step++
overlays += "hs_hole"
to_chat(user, "<span class='notice'>You weld a hole in [src]!</span>")
build_step++
overlays += "hs_hole"
to_chat(user, "<span class='notice'>You weld a hole in [src]!</span>")
else if(build_step == 1)
var/obj/item/weldingtool/WT = I
if(WT.remove_fuel(0, user))
build_step--
overlays -= "hs_hole"
to_chat(user, "<span class='notice'>You weld the hole in [src] shut!</span>")
build_step--
overlays -= "hs_hole"
to_chat(user, "<span class='notice'>You weld the hole in [src] shut!</span>")
else if(isprox(I) && (build_step == 1))
if(!user.unEquip(I))
@@ -87,19 +87,6 @@
update_icon()
return 1
else if(iswelder(O) && user.a_intent == INTENT_HELP)
var/obj/item/weldingtool/WT = O
user.changeNext_move(CLICK_CD_MELEE)
if(WT.remove_fuel(0))
if(health < maxHealth)
adjustHealth(-5)
playsound(loc, WT.usesound, 50, 1)
add_fingerprint(user)
visible_message("<span class='warning'>[user] has spot-welded some of the damage to [src]!</span>")
else
to_chat(user, "<span class='notice'>[src] is undamaged!</span>")
else
to_chat(user, "Need more welding fuel!")
else if(istype(O, /obj/item/card/id) || istype(O, /obj/item/pda))
if(!mmi)
to_chat(user, "<span class='warning'>There's no reason to swipe your ID - the spiderbot has no brain to remove.</span>")
@@ -128,6 +115,23 @@
else
..()
/mob/living/simple_animal/spiderbot/welder_act(mob/user, obj/item/I)
if(user.a_intent != INTENT_HELP)
return
if(user == src) //No self-repair dummy
return
if(health >= maxHealth)
to_chat(user, "<span class='warning'>[src] does not need repairing!</span>")
return
to_chat(user, "<span class='warning'>Unable to repair with the maintenance panel closed!</span>")
return
. = TRUE
if(!I.use_tool(src, user, volume = I.tool_volume))
return
adjustHealth(-5)
add_fingerprint(user)
user.visible_message("[user] repairs [src]!","<span class='notice'>You repair [src].</span>")
/mob/living/simple_animal/spiderbot/emag_act(mob/living/user)
if(emagged)
to_chat(user, "<span class='warning'>[src] doesn't seem to respond.</span>")