Adds tool_behaviour support to crafting, door wires, surgeries and mech construction (#35384)

* Adds tool_behaviour support to construction datums (mech construction)

* Adds tool_behaviour support to wire datums

* Adds tool_behavior support to surgeries

* Adds tool_behavior support to crafting

* New proc, to be used for checking tool qualities in hands

* Improves tool quality support on wires
This commit is contained in:
ACCount
2018-02-12 22:52:11 +03:00
committed by AnturK
parent c794d13393
commit 6de835a629
16 changed files with 134 additions and 119 deletions

View File

@@ -23,33 +23,46 @@
set_desc(steps.len)
return
/datum/construction/proc/action(atom/used_atom,mob/user)
/datum/construction/proc/action(obj/item/I, mob/user)
return
/datum/construction/proc/check_step(atom/used_atom,mob/user) //check last step only
var/valid_step = is_right_key(used_atom)
/datum/construction/proc/check_step(obj/item/I, mob/user) //check last step only
var/valid_step = is_right_key(I)
if(valid_step)
if(custom_action(valid_step, used_atom, user))
if(custom_action(valid_step, I, user))
next_step()
return 1
return 0
/datum/construction/proc/is_right_key(atom/used_atom) // returns current step num if used_atom is of the right type.
/datum/construction/proc/is_right_key(obj/item/I) // returns current step num if I is of the right type.
var/list/L = steps[steps.len]
if(istype(used_atom, L["key"]))
if(check_used_item(I, L["key"]))
return steps.len
return 0
/datum/construction/proc/custom_action(step, used_atom, user)
/datum/construction/proc/check_used_item(obj/item/I, key)
if(!key)
return FALSE
if(ispath(key) && istype(I, key))
return TRUE
else if(I.tool_behaviour == key)
return TRUE
return FALSE
/datum/construction/proc/custom_action(step, obj/item/I, user)
return 1
/datum/construction/proc/check_all_steps(atom/used_atom,mob/user) //check all steps, remove matching one.
/datum/construction/proc/check_all_steps(obj/item/I, mob/user) //check all steps, remove matching one.
for(var/i=1;i<=steps.len;i++)
var/list/L = steps[i];
if(istype(used_atom, L["key"]))
if(custom_action(i, used_atom, user))
steps[i]=null;//stupid byond list from list removal...
listclearnulls(steps);
var/list/L = steps[i]
if(check_used_item(I, L["key"]))
if(custom_action(i, I, user))
steps[i] = null//stupid byond list from list removal...
listclearnulls(steps)
if(!steps.len)
spawn_result()
return 1
@@ -76,6 +89,9 @@
holder.desc = step["desc"]
return
/datum/construction/proc/drop_location()
return holder.drop_location()
/datum/construction/reversible
var/index
@@ -92,21 +108,21 @@
set_desc(index)
return
/datum/construction/reversible/is_right_key(atom/used_atom) // returns index step
/datum/construction/reversible/is_right_key(obj/item/I) // returns index step
var/list/L = steps[index]
if(istype(used_atom, L["key"]))
if(check_used_item(I, L["key"]))
return FORWARD //to the first step -> forward
else if(L["backkey"] && istype(used_atom, L["backkey"]))
else if(check_used_item(I, L["backkey"]))
return BACKWARD //to the last step -> backwards
return 0
return FALSE
/datum/construction/reversible/check_step(atom/used_atom,mob/user)
var/diff = is_right_key(used_atom)
/datum/construction/reversible/check_step(obj/item/I, mob/user)
var/diff = is_right_key(I)
if(diff)
if(custom_action(index, diff, used_atom, user))
if(custom_action(index, diff, I, user))
update_index(diff)
return 1
return 0
/datum/construction/reversible/custom_action(index, diff, used_atom, user)
/datum/construction/reversible/custom_action(index, diff, obj/item/I, user)
return 1

View File

@@ -1,15 +1,15 @@
#define MAXIMUM_EMP_WIRES 3
/proc/is_wire_tool(obj/item/I)
if(istype(I, /obj/item/device/multitool))
return TRUE
if(istype(I, /obj/item/wirecutters))
if(!I)
return
if(I.tool_behaviour == TOOL_WIRECUTTER || I.tool_behaviour == TOOL_MULTITOOL)
return TRUE
if(istype(I, /obj/item/device/assembly))
var/obj/item/device/assembly/A = I
if(A.attachable)
return TRUE
return
/atom
var/datum/wires/wires = null
@@ -244,10 +244,11 @@
return
var/target_wire = params["wire"]
var/mob/living/L = usr
var/obj/item/I = L.get_active_held_item()
var/obj/item/I
switch(action)
if("cut")
if(istype(I, /obj/item/wirecutters) || IsAdminGhost(usr))
I = L.is_holding_tool_quality(TOOL_WIRECUTTER)
if(I || IsAdminGhost(usr))
if(I)
I.play_tool_sound(src, 20)
cut_color(target_wire)
@@ -255,7 +256,8 @@
else
to_chat(L, "<span class='warning'>You need wirecutters!</span>")
if("pulse")
if(istype(I, /obj/item/device/multitool) || IsAdminGhost(usr))
I = L.is_holding_tool_quality(TOOL_MULTITOOL)
if(I || IsAdminGhost(usr))
if(I)
I.play_tool_sound(src, 20)
pulse_color(target_wire, L)
@@ -264,11 +266,12 @@
to_chat(L, "<span class='warning'>You need a multitool!</span>")
if("attach")
if(is_attached(target_wire))
var/obj/item/O = detach_assembly(target_wire)
if(O)
L.put_in_hands(O)
I = detach_assembly(target_wire)
if(I)
L.put_in_hands(I)
. = TRUE
else
I = L.get_active_held_item()
if(istype(I, /obj/item/device/assembly))
var/obj/item/device/assembly/A = I
if(A.attachable)

View File

@@ -105,22 +105,33 @@
/datum/personal_crafting/proc/check_tools(mob/user, datum/crafting_recipe/R, list/contents)
if(!R.tools.len)
return 1
return TRUE
var/list/possible_tools = list()
var/list/present_qualities = list()
for(var/obj/item/I in user.contents)
if(istype(I, /obj/item/storage))
for(var/obj/item/SI in I.contents)
possible_tools += SI.type
if(SI.tool_behaviour)
present_qualities.Add(SI.tool_behaviour)
possible_tools += I.type
if(I.tool_behaviour)
present_qualities.Add(I.tool_behaviour)
possible_tools += contents
main_loop:
for(var/A in R.tools)
for(var/I in possible_tools)
if(ispath(I,A))
continue main_loop
return 0
return 1
if(A in present_qualities)
continue
else
for(var/I in possible_tools)
if(ispath(I, A))
continue main_loop
return FALSE
return TRUE
/datum/personal_crafting/proc/construct_item(mob/user, datum/crafting_recipe/R)
var/list/contents = get_surroundings(user)
@@ -401,8 +412,7 @@
data["catalyst_text"] = catalyst_text
for(var/a in R.tools)
var/atom/A = a //cheat-typecast
tool_text += " [R.tools[A]] [initial(A.name)],"
tool_text += " [a],"
tool_text = replacetext(tool_text,",","",-1)
data["tool_text"] = tool_text

View File

@@ -16,7 +16,7 @@
result = /obj/item/gun
reqs = list(/obj/item/gun = 1)
parts = list(/obj/item/gun = 1)
tools = list(/obj/item/weldingtool, /obj/item/screwdriver, /obj/item/wirecutters)
tools = list(TOOL_WELDER, TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
time = 50
category = CAT_WEAPONRY
subcategory = CAT_WEAPON
@@ -134,7 +134,7 @@
/obj/item/gun/energy/e_gun/advtaser = 1,
/obj/item/stock_parts/cell = 1,
/obj/item/device/assembly/prox_sensor = 1)
tools = list(/obj/item/weldingtool, /obj/item/screwdriver)
tools = list(TOOL_WELDER, TOOL_SCREWDRIVER)
time = 60
category = CAT_ROBOT
@@ -146,7 +146,7 @@
/obj/item/melee/baton = 1,
/obj/item/device/assembly/prox_sensor = 1,
/obj/item/bodypart/r_arm/robot = 1)
tools = list(/obj/item/weldingtool)
tools = list(TOOL_WELDER)
time = 60
category = CAT_ROBOT
@@ -192,8 +192,7 @@
/datum/crafting_recipe/improvised_pneumatic_cannon //Pretty easy to obtain but
name = "Pneumatic Cannon"
result = /obj/item/pneumatic_cannon/ghetto
tools = list(/obj/item/weldingtool,
/obj/item/wrench)
tools = list(TOOL_WELDER, TOOL_WRENCH)
reqs = list(/obj/item/stack/sheet/metal = 4,
/obj/item/stack/packageWrap = 8,
/obj/item/pipe = 2)
@@ -209,7 +208,7 @@
/obj/item/stack/rods = 1)
parts = list(/obj/item/device/assembly/igniter = 1,
/obj/item/weldingtool = 1)
tools = list(/obj/item/screwdriver)
tools = list(TOOL_SCREWDRIVER)
time = 10
category = CAT_WEAPONRY
subcategory = CAT_WEAPON
@@ -220,7 +219,7 @@
reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
/obj/item/rcd_ammo = 1,
/obj/item/stock_parts/manipulator = 2)
tools = list(/obj/item/screwdriver)
tools = list(TOOL_SCREWDRIVER)
time = 5
category = CAT_WEAPONRY
subcategory = CAT_AMMO
@@ -231,7 +230,7 @@
reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
/obj/item/stock_parts/capacitor/adv = 2,
/obj/item/stock_parts/micro_laser/ultra = 1)
tools = list(/obj/item/screwdriver)
tools = list(TOOL_SCREWDRIVER)
time = 5
category = CAT_WEAPONRY
subcategory = CAT_AMMO
@@ -240,7 +239,7 @@
name = "Dragonsbreath Shell"
result = /obj/item/ammo_casing/shotgun/dragonsbreath
reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1, /datum/reagent/phosphorus = 5)
tools = list(/obj/item/screwdriver)
tools = list(TOOL_SCREWDRIVER)
time = 5
category = CAT_WEAPONRY
subcategory = CAT_AMMO
@@ -252,7 +251,7 @@
/datum/reagent/glycerol = 5,
/datum/reagent/toxin/acid = 5,
/datum/reagent/toxin/acid/fluacid = 5)
tools = list(/obj/item/screwdriver)
tools = list(TOOL_SCREWDRIVER)
time = 5
category = CAT_WEAPONRY
subcategory = CAT_AMMO
@@ -263,7 +262,7 @@
reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
/obj/item/stock_parts/micro_laser/ultra = 1,
/obj/item/stock_parts/subspace/crystal = 1)
tools = list(/obj/item/screwdriver)
tools = list(TOOL_SCREWDRIVER)
time = 5
category = CAT_WEAPONRY
subcategory = CAT_AMMO
@@ -275,7 +274,7 @@
/obj/item/stack/sheet/metal = 1,
/obj/item/stack/cable_coil = 1,
/datum/reagent/fuel = 10)
tools = list(/obj/item/screwdriver)
tools = list(TOOL_SCREWDRIVER)
time = 5
category = CAT_WEAPONRY
subcategory = CAT_AMMO
@@ -286,7 +285,7 @@
reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
/obj/item/stock_parts/capacitor/adv = 1,
/obj/item/stock_parts/micro_laser/high = 1)
tools = list(/obj/item/screwdriver)
tools = list(TOOL_SCREWDRIVER)
time = 5
category = CAT_WEAPONRY
subcategory = CAT_AMMO
@@ -298,7 +297,7 @@
/obj/item/pipe = 1,
/obj/item/weaponcrafting/stock = 1,
/obj/item/stack/packageWrap = 5)
tools = list(/obj/item/screwdriver)
tools = list(TOOL_SCREWDRIVER)
time = 100
category = CAT_WEAPONRY
subcategory = CAT_WEAPON
@@ -309,7 +308,7 @@
reqs = list(/obj/item/circular_saw = 1,
/obj/item/stack/cable_coil = 3,
/obj/item/stack/sheet/plasteel = 5)
tools = list(/obj/item/weldingtool)
tools = list(TOOL_WELDER)
time = 50
category = CAT_WEAPONRY
subcategory = CAT_WEAPON
@@ -590,7 +589,7 @@
name = "Makeshift Rapid Cable Layer"
result = /obj/item/twohanded/rcl/ghetto
time = 40
tools = list(/obj/item/weldingtool, /obj/item/screwdriver, /obj/item/wrench)
tools = list(TOOL_WELDER, TOOL_SCREWDRIVER, TOOL_WRENCH)
reqs = list(/obj/item/stack/sheet/metal = 15)
category = CAT_MISC

View File

@@ -121,6 +121,19 @@
return I
return FALSE
//Checks if we're holding a tool that has given quality
//Returns the tool that has the best version of this quality
/mob/proc/is_holding_tool_quality(quality)
var/obj/item/best_item
var/best_quality = INFINITY
for(var/obj/item/I in held_items)
if(I.tool_behaviour == quality && I.toolspeed < best_quality)
best_item = I
best_quality = I.toolspeed
return best_item
//To appropriately fluff things like "they are holding [I] in their [get_held_index_name(get_held_index_of_item(I))]"
//Can be overriden to pass off the fluff to something else (eg: science allowing people to add extra robotic limbs, and having this proc react to that

View File

@@ -14,7 +14,7 @@
/datum/surgery_step/fix_brain
name = "fix brain"
implements = list(/obj/item/hemostat = 85, /obj/item/screwdriver = 35, /obj/item/pen = 15) //don't worry, pouring some alcohol on their open brain will get that chance to 100
implements = list(/obj/item/hemostat = 85, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15) //don't worry, pouring some alcohol on their open brain will get that chance to 100
time = 120 //long and complicated
/datum/surgery/brain_surgery/can_start(mob/user, mob/living/carbon/target)

View File

@@ -12,7 +12,7 @@
//extract brain
/datum/surgery_step/extract_core
name = "extract core"
implements = list(/obj/item/hemostat = 100, /obj/item/crowbar = 100)
implements = list(/obj/item/hemostat = 100, TOOL_CROWBAR = 100)
time = 16
/datum/surgery_step/extract_core/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)

View File

@@ -8,7 +8,7 @@
//fix eyes
/datum/surgery_step/fix_eyes
name = "fix eyes"
implements = list(/obj/item/hemostat = 100, /obj/item/screwdriver = 45, /obj/item/pen = 25)
implements = list(/obj/item/hemostat = 100, TOOL_SCREWDRIVER = 45, /obj/item/pen = 25)
time = 64
/datum/surgery/eye_surgery/can_start(mob/user, mob/living/carbon/target)

View File

@@ -8,7 +8,7 @@
//extract implant
/datum/surgery_step/extract_implant
name = "extract implant"
implements = list(/obj/item/hemostat = 100, /obj/item/crowbar = 65)
implements = list(/obj/item/hemostat = 100, TOOL_CROWBAR = 65)
time = 64
var/obj/item/implant/I = null

View File

@@ -6,7 +6,7 @@
/datum/surgery_step/replace
name = "sever muscles"
implements = list(/obj/item/scalpel = 100, /obj/item/wirecutters = 55)
implements = list(/obj/item/scalpel = 100, TOOL_WIRECUTTER = 55)
time = 32

View File

@@ -25,7 +25,7 @@
//remove fat
/datum/surgery_step/remove_fat
name = "remove loose fat"
implements = list(/obj/item/retractor = 100, /obj/item/screwdriver = 45, /obj/item/wirecutters = 35)
implements = list(/obj/item/retractor = 100, TOOL_SCREWDRIVER = 45, TOOL_WIRECUTTER = 35)
time = 32
/datum/surgery_step/remove_fat/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)

View File

@@ -2,7 +2,7 @@
/datum/surgery_step/mechanic_open
name = "unscrew shell"
implements = list(
/obj/item/screwdriver = 100,
TOOL_SCREWDRIVER = 100,
/obj/item/scalpel = 75, // med borgs could try to unskrew shell with scalpel
/obj/item/kitchen/knife = 50,
/obj/item = 10) // 10% success with any sharp item.
@@ -22,7 +22,7 @@
/datum/surgery_step/mechanic_close
name = "screw shell"
implements = list(
/obj/item/screwdriver = 100,
TOOL_SCREWDRIVER = 100,
/obj/item/scalpel = 75,
/obj/item/kitchen/knife = 50,
/obj/item = 10) // 10% success with any sharp item.
@@ -42,7 +42,7 @@
/datum/surgery_step/prepare_electronics
name = "prepare electronics"
implements = list(
/obj/item/device/multitool = 100,
TOOL_MULTITOOL = 100,
/obj/item/hemostat = 10) // try to reboot internal controllers via short circuit with some conductor
time = 24
@@ -54,7 +54,7 @@
/datum/surgery_step/mechanic_unwrench
name = "unwrench bolts"
implements = list(
/obj/item/wrench = 100,
TOOL_WRENCH = 100,
/obj/item/retractor = 10)
time = 24
@@ -66,7 +66,7 @@
/datum/surgery_step/mechanic_wrench
name = "wrench bolts"
implements = list(
/obj/item/wrench = 100,
TOOL_WRENCH = 100,
/obj/item/retractor = 10)
time = 24

View File

@@ -67,7 +67,7 @@
name = "manipulate organs"
repeatable = 1
implements = list(/obj/item/organ = 100, /obj/item/reagent_containers/food/snacks/organ = 0, /obj/item/organ_storage = 100)
var/implements_extract = list(/obj/item/hemostat = 100, /obj/item/crowbar = 55)
var/implements_extract = list(/obj/item/hemostat = 100, TOOL_CROWBAR = 55)
var/current_type
var/obj/item/organ/I = null
@@ -75,25 +75,6 @@
..()
implements = implements + implements_extract
/datum/surgery_step/manipulate_organs/tool_check(mob/user, obj/item/tool)
if(istype(tool, /obj/item/weldingtool))
var/obj/item/weldingtool/WT = tool
if(!WT.isOn())
return 0
else if(istype(tool, /obj/item/lighter))
var/obj/item/lighter/L = tool
if(!L.lit)
return 0
else if(istype(tool, /obj/item/match))
var/obj/item/match/M = tool
if(!M.lit)
return 0
return 1
/datum/surgery_step/manipulate_organs/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
I = null
if(istype(tool, /obj/item/organ_storage))

View File

@@ -19,7 +19,7 @@
//clamp bleeders
/datum/surgery_step/clamp_bleeders
name = "clamp bleeders"
implements = list(/obj/item/hemostat = 100, /obj/item/wirecutters = 60, /obj/item/stack/packageWrap = 35, /obj/item/stack/cable_coil = 15)
implements = list(/obj/item/hemostat = 100, TOOL_WIRECUTTER = 60, /obj/item/stack/packageWrap = 35, /obj/item/stack/cable_coil = 15)
time = 24
/datum/surgery_step/clamp_bleeders/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
@@ -35,7 +35,7 @@
//retract skin
/datum/surgery_step/retract_skin
name = "retract skin"
implements = list(/obj/item/retractor = 100, /obj/item/screwdriver = 45, /obj/item/wirecutters = 35)
implements = list(/obj/item/retractor = 100, TOOL_SCREWDRIVER = 45, TOOL_WIRECUTTER = 35)
time = 24
/datum/surgery_step/retract_skin/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
@@ -47,35 +47,19 @@
//close incision
/datum/surgery_step/close
name = "mend incision"
implements = list(/obj/item/cautery = 100, /obj/item/gun/energy/laser = 90, /obj/item/weldingtool = 70,
/obj/item/lighter = 45, /obj/item/match = 20)
implements = list(/obj/item/cautery = 100, /obj/item/gun/energy/laser = 90, TOOL_WELDER = 70,
/obj/item = 30) // 30% success with any hot item.
time = 24
/datum/surgery_step/close/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
user.visible_message("[user] begins to mend the incision in [target]'s [parse_zone(target_zone)].",
"<span class='notice'>You begin to mend the incision in [target]'s [parse_zone(target_zone)]...</span>")
/datum/surgery_step/close/tool_check(mob/user, obj/item/tool)
if(istype(tool, /obj/item/cautery))
return 1
if(implement_type == TOOL_WELDER || implement_type == /obj/item)
return tool.is_hot()
if(istype(tool, /obj/item/weldingtool))
var/obj/item/weldingtool/WT = tool
if(WT.isOn())
return 1
else if(istype(tool, /obj/item/lighter))
var/obj/item/lighter/L = tool
if(L.lit)
return 1
else if(istype(tool, /obj/item/match))
var/obj/item/match/M = tool
if(M.lit)
return 1
return 0
return TRUE
/datum/surgery_step/close/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
if(locate(/datum/surgery_step/saw) in surgery.steps)
@@ -105,7 +89,7 @@
//drill bone
/datum/surgery_step/drill
name = "drill bone"
implements = list(/obj/item/surgicaldrill = 100, /obj/item/pickaxe/drill = 60, /obj/item/mecha_parts/mecha_equipment/drill = 60, /obj/item/screwdriver = 20)
implements = list(/obj/item/surgicaldrill = 100, /obj/item/pickaxe/drill = 60, /obj/item/mecha_parts/mecha_equipment/drill = 60, TOOL_SCREWDRIVER = 20)
time = 30
/datum/surgery_step/drill/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)

View File

@@ -6,7 +6,7 @@
//reshape_face
/datum/surgery_step/reshape_face
name = "reshape face"
implements = list(/obj/item/scalpel = 100, /obj/item/kitchen/knife = 50, /obj/item/wirecutters = 35)
implements = list(/obj/item/scalpel = 100, /obj/item/kitchen/knife = 50, TOOL_WIRECUTTER = 35)
time = 64
/datum/surgery_step/reshape_face/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)

View File

@@ -9,19 +9,28 @@
/datum/surgery_step/proc/try_op(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
var/success = 0
var/success = FALSE
if(accept_hand)
if(!tool)
success = 1
success = TRUE
if(accept_any_item)
if(tool && tool_check(user, tool))
success = 1
else
for(var/path in implements)
if(istype(tool, path))
implement_type = path
success = TRUE
else if(tool)
for(var/key in implements)
var/match = FALSE
if(ispath(key) && istype(tool, key))
match = TRUE
else if(tool.tool_behaviour == key)
match = TRUE
if(match)
implement_type = key
if(tool_check(user, tool))
success = 1
success = TRUE
break
if(success)