mirror of
https://github.com/vgstation-coders/vgstation13.git
synced 2025-12-10 18:32:03 +00:00
Construction restructuring.
Absolute pathed construction.dm. Fixed issues. Changed the way reversible works, to give more flexibility.
This commit is contained in:
@@ -2,14 +2,18 @@
|
||||
#define BACKWARD 1
|
||||
|
||||
#define Co_KEY "key"
|
||||
#define Co_BACKKEY "backkey"
|
||||
#define Co_VIS_MSG "vis_msg"
|
||||
#define Co_BACK_MSG "back_msg"
|
||||
#define Co_START_MSG "start_msg"
|
||||
#define Co_AMOUNT "amount"
|
||||
#define Co_MAX_AMOUNT "max_amount"
|
||||
#define Co_KEEP "keep"
|
||||
#define Co_DELAY "delay"
|
||||
#define Co_KEEP "keep" //if permanence is set to 0, we can still store specific step items by including this in the step
|
||||
#define Co_TAKE "take" //if we want to actually have a stack or weldingtool in construction, rather than weld or add a stack, we can use this override
|
||||
#define Co_DESC "desc"
|
||||
|
||||
#define Co_NEXTSTEP "nextstep"
|
||||
#define Co_BACKSTEP "backstep"
|
||||
|
||||
/datum/construction
|
||||
var/list/steps
|
||||
var/atom/holder
|
||||
@@ -20,234 +24,245 @@
|
||||
var/permanence = 0
|
||||
var/list/used_atoms = list() //contains the stuff we add. Can be used in multiple-choice construction
|
||||
|
||||
New(atom)
|
||||
..()
|
||||
holder = atom
|
||||
if(!holder) //don't want this without a holder
|
||||
spawn
|
||||
del src
|
||||
/datum/construction/New(atom)
|
||||
..()
|
||||
holder = atom
|
||||
if(!holder) //don't want this without a holder
|
||||
spawn
|
||||
del src
|
||||
set_desc(steps.len)
|
||||
add_max_amounts()
|
||||
return
|
||||
|
||||
/datum/construction/proc/next_step(mob/user as mob)
|
||||
steps.len--
|
||||
if(!steps.len)
|
||||
spawn_result(user)
|
||||
else
|
||||
set_desc(steps.len)
|
||||
add_max_amounts()
|
||||
return
|
||||
return
|
||||
|
||||
proc/next_step(mob/user as mob)
|
||||
steps.len--
|
||||
if(!steps.len)
|
||||
spawn_result(user)
|
||||
else
|
||||
set_desc(steps.len)
|
||||
return
|
||||
/datum/construction/proc/action(atom/used_atom,mob/user as mob)
|
||||
return
|
||||
|
||||
proc/action(atom/used_atom,mob/user as mob)
|
||||
return
|
||||
|
||||
proc/check_step(atom/used_atom,mob/user as mob) //check last step only
|
||||
var/valid_step = is_right_key(user,used_atom)
|
||||
if(valid_step && !assembling)
|
||||
assembling = 1
|
||||
if(custom_action(valid_step, used_atom, user))
|
||||
next_step(user)
|
||||
assembling = 0
|
||||
return 1
|
||||
/datum/construction/proc/check_step(atom/used_atom,mob/user as mob) //check last step only
|
||||
var/valid_step = is_right_key(user,used_atom)
|
||||
if(valid_step)
|
||||
assembling = 1
|
||||
if(custom_action(valid_step, used_atom, user))
|
||||
next_step(user)
|
||||
assembling = 0
|
||||
return 0
|
||||
|
||||
proc/is_right_key(mob/user as mob, atom/used_atom) // returns current step num if used_atom is of the right type.
|
||||
var/list/L = steps[steps.len]
|
||||
if((istype(L[Co_KEY], /list) && is_type_in_list(used_atom, L[Co_KEY])) || istype(used_atom, L[Co_KEY]))
|
||||
//if our keys are in a list, we want to check them all
|
||||
//otherwise, sanity permits setting it as a single type and checking that
|
||||
if(!try_consume(user, used_atom, L))
|
||||
return 0
|
||||
return steps.len
|
||||
return 0
|
||||
|
||||
proc/custom_action(step, used_atom, user)
|
||||
if(istype(used_atom, /obj/item/weapon/weldingtool))
|
||||
playsound(holder, 'sound/items/Welder2.ogg', 50, 1)
|
||||
|
||||
else if(istype(used_atom, /obj/item/weapon/wrench))
|
||||
playsound(holder, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
|
||||
else if(istype(used_atom, /obj/item/weapon/screwdriver))
|
||||
playsound(holder, 'sound/items/Screwdriver.ogg', 50, 1)
|
||||
|
||||
else if(istype(used_atom, /obj/item/weapon/wirecutters))
|
||||
playsound(holder, 'sound/items/Wirecutter.ogg', 50, 1)
|
||||
|
||||
construct_message(step, user)
|
||||
return 1
|
||||
|
||||
|
||||
proc/fixText(text,user)
|
||||
text = replacetext(text,"{USER}","[user]")
|
||||
text = replacetext(text,"{HOLDER}","[holder]")
|
||||
return text
|
||||
|
||||
proc/construct_message(step, mob/user)
|
||||
user.visible_message(fixText(step[Co_VIS_MSG],user))
|
||||
|
||||
proc/check_all_steps(atom/used_atom,mob/user as mob) //check all steps, remove matching one.
|
||||
for(var/i=1;i<=steps.len;i++)
|
||||
var/list/L = steps[i];
|
||||
if(istype(used_atom, L[Co_KEY]))
|
||||
if(custom_action(i, used_atom, user))
|
||||
steps[i]=null;//stupid byond list from list removal...
|
||||
listclearnulls(steps);
|
||||
if(!steps.len)
|
||||
spawn_result(user)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
proc/spawn_result(mob/user as mob)
|
||||
if(result)
|
||||
testing("[user] finished a [result]!")
|
||||
|
||||
new result(get_turf(holder))
|
||||
spawn()
|
||||
del holder
|
||||
return
|
||||
|
||||
proc/set_desc(index as num)
|
||||
var/list/step = steps[index]
|
||||
holder.desc = step[Co_DESC]
|
||||
return
|
||||
|
||||
proc/try_consume(mob/user as mob, atom/movable/used_atom, given_step)
|
||||
if(!(Co_AMOUNT in given_step))
|
||||
return 1
|
||||
var/amount = given_step[Co_AMOUNT]
|
||||
if(amount>0)
|
||||
// STACKS
|
||||
if(istype(used_atom,/obj/item/stack))
|
||||
var/obj/item/stack/stack=used_atom
|
||||
if(stack.amount < amount)
|
||||
user << "<span class='notice'>You start adding [stack] to the [holder]. It still needs [amount - stack.amount] [stack.singular_name].</span>"
|
||||
given_step[Co_AMOUNT] -= stack.amount
|
||||
stack.use(stack.amount)
|
||||
return 0
|
||||
stack.use(amount)
|
||||
// WELDER
|
||||
else if(istype(used_atom,/obj/item/weapon/weldingtool))
|
||||
var/obj/item/weapon/weldingtool/welder=used_atom
|
||||
if(!welder.isOn())
|
||||
user << "\blue You tap the [src] with your unlit welder. [pick("Ding","Dong")]."
|
||||
return 0
|
||||
if(!welder.remove_fuel(amount,user))
|
||||
user << "\red You don't have enough fuel!"
|
||||
return 0
|
||||
//generic things
|
||||
else
|
||||
if(permanence || (Co_KEEP in given_step))
|
||||
user.drop_item(holder)
|
||||
used_atom.loc = holder
|
||||
used_atoms.Add(list("[steps.Find(given_step)]" = used_atom))
|
||||
else
|
||||
qdel(used_atom)
|
||||
assembling = 0
|
||||
return 0
|
||||
|
||||
/datum/construction/proc/is_right_key(mob/user as mob, atom/used_atom) // returns current step num if used_atom is of the right type.
|
||||
if(assembling) return 0
|
||||
var/list/L = steps[steps.len]
|
||||
if((istype(L[Co_KEY], /list) && is_type_in_list(used_atom, L[Co_KEY])) || istype(used_atom, L[Co_KEY]))
|
||||
//if our keys are in a list, we want to check them all
|
||||
//otherwise, sanity permits setting it as a single type and checking that
|
||||
if(!try_consume(user, used_atom, L))
|
||||
return 0
|
||||
return steps.len
|
||||
return 0
|
||||
|
||||
/datum/construction/proc/custom_action(step, used_atom, user)
|
||||
if(istype(used_atom, /obj/item/weapon/weldingtool))
|
||||
playsound(holder, 'sound/items/Welder2.ogg', 50, 1)
|
||||
|
||||
else if(istype(used_atom, /obj/item/weapon/wrench))
|
||||
playsound(holder, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
|
||||
else if(istype(used_atom, /obj/item/weapon/screwdriver))
|
||||
playsound(holder, 'sound/items/Screwdriver.ogg', 50, 1)
|
||||
|
||||
else if(istype(used_atom, /obj/item/weapon/wirecutters))
|
||||
playsound(holder, 'sound/items/Wirecutter.ogg', 50, 1)
|
||||
|
||||
construct_message(step, user)
|
||||
return 1
|
||||
|
||||
|
||||
/datum/construction/proc/fixText(text,user,self=0)
|
||||
if(self)
|
||||
text = replacetext(text, "{s}", "")
|
||||
text = replacetext(text, "{USER}", "You")
|
||||
else
|
||||
text = replacetext(text, "{s}", "s")
|
||||
text = replacetext(text,"{USER}","[user]")
|
||||
text = replacetext(text,"{HOLDER}","[holder]")
|
||||
return text
|
||||
|
||||
/datum/construction/proc/construct_message(step, mob/user)
|
||||
user.visible_message(fixText(step[Co_VIS_MSG],user), fixText(step[Co_VIS_MSG],user,1))
|
||||
|
||||
/datum/construction/proc/start_construct_message(step, mob/user, atom/movable/used_atom)
|
||||
user.visible_message(fixText(step[Co_START_MSG],user), fixText(step[Co_START_MSG],user,1))
|
||||
|
||||
/datum/construction/proc/check_all_steps(atom/used_atom,mob/user as mob) //check all steps, remove matching one.
|
||||
for(var/i=1;i<=steps.len;i++)
|
||||
var/list/L = steps[i];
|
||||
if((islist(L[Co_KEY]) && is_type_in_list(used_atom, L[Co_KEY])) ||istype(used_atom, L[Co_KEY]))
|
||||
if(custom_action(i, used_atom, user))
|
||||
steps[i]=null;//stupid byond list from list removal...
|
||||
listclearnulls(steps);
|
||||
if(!steps.len)
|
||||
spawn_result(user)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/datum/construction/proc/spawn_result(mob/user as mob)
|
||||
if(result)
|
||||
testing("[user] finished a [result]!")
|
||||
|
||||
new result(get_turf(holder))
|
||||
spawn()
|
||||
del holder
|
||||
return
|
||||
|
||||
/datum/construction/proc/set_desc(index as num)
|
||||
var/list/step = steps[index]
|
||||
holder.desc = step[Co_DESC]
|
||||
return
|
||||
|
||||
/datum/construction/proc/try_consume(mob/user as mob, atom/movable/used_atom, given_step)
|
||||
if(!(Co_AMOUNT in given_step) && !(Co_DELAY in given_step))
|
||||
return 1
|
||||
|
||||
proc/add_max_amounts()
|
||||
for(var/list/this_step in steps)
|
||||
if((Co_AMOUNT in this_step) && this_step[Co_AMOUNT] > 1)
|
||||
this_step.Add(list(Co_MAX_AMOUNT = this_step[Co_AMOUNT])) //puts in something we can refer to when we reset the step
|
||||
|
||||
var/delay = 0
|
||||
if(Co_DELAY in given_step)
|
||||
delay = given_step[Co_DELAY]
|
||||
if(delay > 0)
|
||||
start_construct_message(given_step, user, used_atom)
|
||||
if(!do_after(user, delay, needhand = 1))
|
||||
return 0
|
||||
|
||||
var/amount = 0
|
||||
if(Co_AMOUNT in given_step)
|
||||
amount = given_step[Co_AMOUNT]
|
||||
if(amount>0)
|
||||
// STACKS
|
||||
if(istype(used_atom,/obj/item/stack) && !(Co_TAKE in given_step))
|
||||
var/obj/item/stack/stack=used_atom
|
||||
if(stack.amount < amount)
|
||||
user << "<span class='notice'>You start adding [stack] to \the [holder]. It still needs [amount - stack.amount] [stack.singular_name].</span>"
|
||||
given_step[Co_AMOUNT] -= stack.amount
|
||||
stack.use(stack.amount)
|
||||
return 0
|
||||
stack.use(amount)
|
||||
// WELDER
|
||||
else if(istype(used_atom,/obj/item/weapon/weldingtool) && !(Co_TAKE in given_step))
|
||||
var/obj/item/weapon/weldingtool/welder=used_atom
|
||||
if(!welder.isOn())
|
||||
user << "\blue You tap the [src] with your unlit welder. [pick("Ding","Dong")]."
|
||||
return 0
|
||||
if(!welder.remove_fuel(amount,user))
|
||||
user << "\red You don't have enough fuel!"
|
||||
return 0
|
||||
//generic things
|
||||
else
|
||||
var/atom_name = used_atom.name
|
||||
if(permanence || (Co_KEEP in given_step))
|
||||
user.drop_item(holder)
|
||||
used_atom.loc = holder
|
||||
used_atoms.Add(list("[steps.Find(given_step)]" = used_atom))
|
||||
else
|
||||
qdel(used_atom)
|
||||
given_step[Co_AMOUNT]--
|
||||
if(given_step[Co_AMOUNT] > 0)
|
||||
user << "<span class='notice'>You add \a [atom_name] to \the [holder]. It still needs [amount -1 ] [atom_name]\s.</span>"
|
||||
return 0
|
||||
given_step[Co_AMOUNT] = given_step[Co_MAX_AMOUNT]
|
||||
return 1
|
||||
|
||||
/datum/construction/proc/add_max_amounts()
|
||||
for(var/list/this_step in steps)
|
||||
if((Co_AMOUNT in this_step))
|
||||
this_step.Add(list(Co_MAX_AMOUNT = this_step[Co_AMOUNT])) //puts in something we can refer to when we reset the step
|
||||
|
||||
/datum/construction/reversible
|
||||
var/index
|
||||
|
||||
New(atom)
|
||||
..()
|
||||
index = steps.len
|
||||
return
|
||||
/datum/construction/reversible/New(atom)
|
||||
..()
|
||||
index = steps.len
|
||||
return
|
||||
|
||||
proc/update_index(diff as num, mob/user as mob)
|
||||
index+=diff
|
||||
if(index==0)
|
||||
spawn_result(user)
|
||||
else
|
||||
set_desc(index)
|
||||
return
|
||||
/datum/construction/reversible/proc/update_index(diff as num, mob/user as mob)
|
||||
index+=diff
|
||||
if(index==0)
|
||||
spawn_result(user)
|
||||
else
|
||||
set_desc(index)
|
||||
return
|
||||
|
||||
is_right_key(mob/user as mob,atom/used_atom) // returns index step
|
||||
var/list/L = steps[index]
|
||||
if((istype(L[Co_KEY], /list) && is_type_in_list(used_atom, L[Co_KEY])) || istype(used_atom, L[Co_KEY]))
|
||||
//if our keys are in a list, we want to check them all
|
||||
//otherwise, sanity permits setting it as a single type and checking that
|
||||
if(!try_consume(user, used_atom, L))
|
||||
return 0
|
||||
return FORWARD //to the first step -> forward
|
||||
if((istype(L[Co_BACKKEY], /list) && is_type_in_list(used_atom, L[Co_BACKKEY])) || istype(used_atom, L[Co_BACKKEY]))
|
||||
//if our keys are in a list, we want to check them all
|
||||
//otherwise, sanity permits setting it as a single type and checking that
|
||||
return BACKWARD //to the last step -> backwards
|
||||
return 0
|
||||
|
||||
check_step(atom/used_atom,mob/user as mob)
|
||||
var/diff = is_right_key(user,used_atom)
|
||||
if(diff && !assembling)
|
||||
assembling = 1
|
||||
if(custom_action(index, diff, used_atom, user))
|
||||
update_index(diff,user)
|
||||
assembling = 0
|
||||
return 1
|
||||
/datum/construction/reversible/is_right_key(mob/user as mob,atom/used_atom) // returns index step
|
||||
if(assembling) return 0
|
||||
assembling = 1
|
||||
var/list/step_next = get_forward_step(index)
|
||||
var/list/step_back = get_backward_step(index)
|
||||
if(step_next && (islist(step_next[Co_KEY]) && is_type_in_list(used_atom, step_next[Co_KEY])) || istype(used_atom, step_next[Co_KEY]))
|
||||
//if our keys are in a list, we want to check them all
|
||||
//otherwise, sanity permits setting it as a single type and checking that
|
||||
if(!try_consume(user, used_atom, step_next, index, FORWARD))
|
||||
assembling = 0
|
||||
return 0
|
||||
return 0
|
||||
return FORWARD //to the first step -> forward
|
||||
if(step_back && (islist(step_back[Co_KEY]) && is_type_in_list(used_atom, step_back[Co_KEY])) || istype(used_atom, step_back[Co_KEY]))
|
||||
if(!try_consume(user, used_atom, step_back, index, BACKWARD))
|
||||
assembling = 0
|
||||
return 0
|
||||
return BACKWARD //to the last step -> backwards
|
||||
assembling = 0
|
||||
return 0
|
||||
|
||||
custom_action(index, diff, used_atom, user)
|
||||
. = ..(index,used_atom,user)
|
||||
/datum/construction/reversible/check_step(atom/used_atom,mob/user as mob)
|
||||
var/diff = is_right_key(user,used_atom)
|
||||
if(diff)
|
||||
assembling = 1
|
||||
if(custom_action(index, diff, used_atom, user))
|
||||
update_index(diff,user)
|
||||
assembling = 0
|
||||
return 1
|
||||
assembling = 0
|
||||
return 0
|
||||
|
||||
if(.)
|
||||
construct_message(steps[index], user, diff, 1)
|
||||
//handles spawning consumed items
|
||||
if(. && diff == BACKWARD)
|
||||
/datum/construction/reversible/custom_action(index, diff, used_atom, user)
|
||||
. = ..(index,used_atom,user)
|
||||
|
||||
var/current_step = steps[index]
|
||||
if((Co_AMOUNT in current_step) && (Co_MAX_AMOUNT in current_step) && current_step[Co_AMOUNT] < current_step[Co_MAX_AMOUNT])
|
||||
var/obj/item/stack/S = new current_step[Co_KEY]
|
||||
if(istype(S))
|
||||
S.amount = current_step[Co_MAX_AMOUNT] - current_step[Co_AMOUNT]
|
||||
current_step[Co_AMOUNT] = current_step[Co_MAX_AMOUNT]
|
||||
S.loc = holder.loc
|
||||
if(.)
|
||||
construct_message(steps[index], user, diff, 1)
|
||||
|
||||
/datum/construction/reversible/construct_message(step, mob/user, diff, override)
|
||||
if(!override)
|
||||
return
|
||||
var/message_step
|
||||
if(diff == FORWARD && (Co_NEXTSTEP in step))
|
||||
message_step = step[Co_NEXTSTEP]
|
||||
else if (Co_BACKSTEP in step)
|
||||
message_step = step[Co_BACKSTEP]
|
||||
if(message_step)
|
||||
user.visible_message(fixText(message_step[Co_VIS_MSG],user), fixText(message_step[Co_VIS_MSG],user,1))
|
||||
|
||||
var/prev_step = steps[index + 1]
|
||||
var/atom/movable/to_drop
|
||||
if(("[index + 1]" in used_atoms) && used_atoms["[index + 1]"])
|
||||
to_drop = used_atoms["[index + 1]"]
|
||||
used_atoms.Remove("[index + 1]")
|
||||
else if(Co_AMOUNT in prev_step)
|
||||
var/to_create = prev_step[Co_KEY]
|
||||
to_drop = new to_create
|
||||
if(istype(to_drop, /obj/item/stack))
|
||||
var/obj/item/stack/S = to_drop
|
||||
if(Co_MAX_AMOUNT in prev_step)
|
||||
S.amount = prev_step[Co_MAX_AMOUNT]
|
||||
prev_step[Co_AMOUNT] = prev_step[Co_MAX_AMOUNT]
|
||||
else
|
||||
S.amount = 5
|
||||
prev_step[Co_AMOUNT] = 5
|
||||
prev_step[Co_MAX_AMOUNT] = 5
|
||||
if(to_drop)
|
||||
to_drop.loc = holder.loc
|
||||
/datum/construction/reversible/start_construct_message(step, mob/user, atom/movable/used_atom)
|
||||
user.visible_message(fixText(step[Co_START_MSG],user), fixText(step[Co_START_MSG],user,1))
|
||||
|
||||
construct_message(step, mob/user, diff, override = 0)
|
||||
if(!override)
|
||||
return
|
||||
if(diff == FORWARD && (Co_VIS_MSG in step))
|
||||
user.visible_message(fixText(step[Co_VIS_MSG], user),fixText(step[Co_VIS_MSG], user, 1))
|
||||
else if(diff == BACKWARD && (Co_BACK_MSG in step))
|
||||
user.visible_message(fixText(step[Co_BACK_MSG], user),fixText(step[Co_BACK_MSG], user, 1))
|
||||
/datum/construction/reversible/add_max_amounts()
|
||||
for(var/i = 1; i <= steps.len; i++)
|
||||
var/list/dir_step = get_forward_step(i)
|
||||
if((Co_AMOUNT in dir_step))
|
||||
dir_step.Add(list(Co_MAX_AMOUNT = dir_step[Co_AMOUNT])) //puts in something we can refer to when we reset the step
|
||||
|
||||
dir_step = get_backward_step(i)
|
||||
if((Co_AMOUNT in dir_step))
|
||||
dir_step.Add(list(Co_MAX_AMOUNT = dir_step[Co_AMOUNT]))
|
||||
|
||||
//NOT IN PLACE: message segments like verbs can be written as {UN|forwardmessage|backwardmessage}. This formats that in selection
|
||||
//the {s} tag makes a verb a plural
|
||||
fixText(message, mob/user, self = 0)
|
||||
var/text = message
|
||||
if(self)
|
||||
text = replacetext(text, "{s}", "")
|
||||
text = replacetext(text, "{USER}", "You")
|
||||
else
|
||||
text = replacetext(text, "{s}", "s")
|
||||
return ..(text, user)
|
||||
/datum/construction/reversible/fixText(message, mob/user, self = 0)
|
||||
return ..(message, user, self)
|
||||
/*
|
||||
while("{UN|" in text)
|
||||
var/start_bracket = findtext(text, "{")
|
||||
@@ -263,75 +278,114 @@
|
||||
replacetext(text, this_verb, final_verb)
|
||||
*/
|
||||
|
||||
|
||||
#define state_next "next"
|
||||
#define state_prev "prev"
|
||||
|
||||
/datum/construction/reversible2
|
||||
var/index
|
||||
var/base_icon = "durand"
|
||||
|
||||
New(atom)
|
||||
..()
|
||||
index = 1
|
||||
return
|
||||
|
||||
proc/update_index(diff as num, mob/user as mob)
|
||||
index-=diff
|
||||
if(index==steps.len+1)
|
||||
spawn_result(user)
|
||||
/datum/construction/reversible/try_consume(mob/user as mob, atom/movable/used_atom, given_step, index, diff)
|
||||
//if we've made some progress on a step, we want to drop it
|
||||
var/current_step = (diff == BACKWARD ? get_forward_step(index) : get_backward_step(index))
|
||||
if(current_step && (Co_AMOUNT in current_step) && (Co_MAX_AMOUNT in current_step) && (current_step[Co_AMOUNT] < current_step[Co_MAX_AMOUNT]))
|
||||
var/obj/item/stack/S
|
||||
if(used_atoms["[index][diff == FORWARD ? "+" : "-"]"])
|
||||
for(var/atom/movable/A in used_atoms["[index][diff == FORWARD ? "+" : "-"]"])
|
||||
A.loc = holder.loc
|
||||
used_atoms.Remove("[index][diff == FORWARD ? "+" : "-"]")
|
||||
else
|
||||
set_desc(index)
|
||||
return
|
||||
var/working_type = (islist(current_step[Co_KEY]) ? pick(current_step[Co_KEY]) : current_step[Co_KEY])
|
||||
S = new working_type(holder.loc)
|
||||
if(istype(S) && !(Co_KEEP in current_step))
|
||||
S.amount = current_step[Co_MAX_AMOUNT] - current_step[Co_AMOUNT]
|
||||
S.update_icon()
|
||||
else
|
||||
for(var/i = 2; i <= current_step[Co_MAX_AMOUNT] - current_step[Co_AMOUNT]; i++)
|
||||
new working_type(holder.loc)
|
||||
current_step[Co_AMOUNT] = current_step[Co_MAX_AMOUNT]
|
||||
|
||||
proc/update_icon()
|
||||
holder.icon_state="[base_icon]_[index]"
|
||||
|
||||
is_right_key(mob/user as mob,atom/used_atom) // returns index step
|
||||
var/list/state = steps[index]
|
||||
if(state_next in state)
|
||||
var/list/step = state[state_next]
|
||||
if(istype(used_atom, step[Co_KEY]))
|
||||
//if(L["consume"] && !try_consume(used_atom,L["consume"]))
|
||||
// return 0
|
||||
return FORWARD //to the first step -> forward
|
||||
else if(state_prev in state)
|
||||
var/list/step = state[state_prev]
|
||||
if(istype(used_atom, step[Co_KEY]))
|
||||
//if(L["consume"] && !try_consume(used_atom,L["consume"]))
|
||||
// return 0
|
||||
return BACKWARD //to the first step -> forward
|
||||
return 0
|
||||
|
||||
check_step(atom/used_atom,mob/user as mob)
|
||||
var/diff = is_right_key(user,used_atom)
|
||||
if(diff)
|
||||
if(custom_action(index, diff, used_atom, user))
|
||||
update_index(diff,user)
|
||||
update_icon()
|
||||
return 1
|
||||
return 0
|
||||
|
||||
custom_action(index, diff, used_atom, var/mob/user)
|
||||
if(!..(index,used_atom,user))
|
||||
var/delay = 0
|
||||
if(Co_DELAY in given_step)
|
||||
delay = given_step[Co_DELAY]
|
||||
if(delay > 0)
|
||||
start_construct_message(given_step, user, used_atom)
|
||||
if(!do_after(user, delay, needhand = 1))
|
||||
return 0
|
||||
|
||||
var/list/step = steps[index]
|
||||
var/list/state = step[diff==FORWARD ? state_next : state_prev]
|
||||
var/amount = 0
|
||||
if(Co_AMOUNT in given_step)
|
||||
amount = given_step[Co_AMOUNT]
|
||||
if(amount > 0)
|
||||
// STACKS
|
||||
if(istype(used_atom,/obj/item/stack) && !(Co_TAKE in given_step))
|
||||
var/obj/item/stack/stack=used_atom
|
||||
if(stack.amount < amount)
|
||||
user << "<span class='notice'>You start adding [stack] to \the [holder]. It still needs [amount - stack.amount] [stack.singular_name].</span>"
|
||||
given_step[Co_AMOUNT] -= stack.amount
|
||||
stack.use(stack.amount)
|
||||
return 0
|
||||
stack.use(amount)
|
||||
// WELDER
|
||||
else if(istype(used_atom,/obj/item/weapon/weldingtool) && !(Co_TAKE in given_step))
|
||||
var/obj/item/weapon/weldingtool/welder=used_atom
|
||||
if(!welder.isOn())
|
||||
user << "<span class='notice'>You tap the [holder] with your unlit welder. [pick("Ding","Dong")].</span>"
|
||||
return 0
|
||||
if(!welder.remove_fuel(amount,user))
|
||||
user << "<span class='rose'>You don't have enough fuel!</span>"
|
||||
return 0
|
||||
//generic things
|
||||
else
|
||||
var/atom_name = used_atom.name
|
||||
if(permanence || (Co_KEEP in given_step))
|
||||
user.drop_item(holder)
|
||||
used_atom.loc = holder
|
||||
if(!("[index][diff == FORWARD ? "+" : "-"]" in used_atoms))
|
||||
used_atoms.Add(list("[index][diff == FORWARD ? "+" : "-"]" = list()))
|
||||
used_atoms["[index][diff == FORWARD ? "+" : "-"]"] += used_atom
|
||||
else
|
||||
qdel(used_atom)
|
||||
given_step[Co_AMOUNT]--
|
||||
if(given_step[Co_AMOUNT] > 0)
|
||||
user << "<span class='notice'>You add \a [atom_name] to \the [holder]. It still needs [amount -1 ] [atom_name]\s.</span>"
|
||||
return 0
|
||||
given_step[Co_AMOUNT] = given_step[Co_MAX_AMOUNT]
|
||||
|
||||
if("delete" in state)
|
||||
qdel(used_atom)
|
||||
else if("spawn" in state)
|
||||
var/spawntype=state["spawn"]
|
||||
var/atom/A = new spawntype(holder.loc)
|
||||
if(Co_AMOUNT in state)
|
||||
if(istype(A,/obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/C=A
|
||||
C.amount=state[Co_AMOUNT]
|
||||
if(istype(A,/obj/item/stack))
|
||||
var/obj/item/stack/S=A
|
||||
S.amount=state[Co_AMOUNT]
|
||||
else
|
||||
var/list/spawn_step
|
||||
var/new_index = (diff == FORWARD ? index - 1 : index + 1)
|
||||
if(diff == FORWARD)
|
||||
spawn_step = get_backward_step(new_index)
|
||||
else if(diff == BACKWARD)
|
||||
spawn_step = get_forward_step(new_index)
|
||||
var/list/atom/movable/to_drop = list()
|
||||
|
||||
return 1
|
||||
action(used_atom,user)
|
||||
return check_step(used_atom,user)
|
||||
if(("[new_index][diff == FORWARD ? "-" : "+"]" in used_atoms) && used_atoms["[new_index][diff == FORWARD ? "-" : "+"]"])
|
||||
to_drop = used_atoms["[new_index][diff == FORWARD ? "-" : "+"]"]
|
||||
used_atoms.Remove("[new_index][diff == FORWARD ? "-" : "+"]")
|
||||
|
||||
else if(Co_AMOUNT in spawn_step)
|
||||
var/to_create = (islist(spawn_step[Co_KEY]) ? pick(spawn_step[Co_KEY]) : spawn_step[Co_KEY])
|
||||
var/test = new to_create
|
||||
if(istype(test, /obj/item/weapon/weldingtool) && !(Co_TAKE in spawn_step))
|
||||
qdel(test)
|
||||
else if(istype(test, /obj/item/stack) && !(Co_TAKE in spawn_step))
|
||||
var/obj/item/stack/S = test
|
||||
S.amount = spawn_step[Co_AMOUNT]
|
||||
to_drop.Add(S)
|
||||
else
|
||||
to_drop.Add(test)
|
||||
for(var/i = 1; i <= spawn_step[Co_AMOUNT] - 1; i++)
|
||||
to_drop.Add(new to_create)
|
||||
|
||||
for(var/atom/movable/this_drop in to_drop)
|
||||
this_drop.loc = holder.loc
|
||||
return 1
|
||||
|
||||
/datum/construction/reversible/proc/get_forward_step(index)
|
||||
if(index < 0 || index > steps.len)
|
||||
return
|
||||
var/list/S = steps[index]
|
||||
if(Co_NEXTSTEP in S)
|
||||
return S[Co_NEXTSTEP]
|
||||
|
||||
/datum/construction/reversible/proc/get_backward_step(index)
|
||||
if(index < 0 || index > steps.len)
|
||||
return
|
||||
var/list/S = steps[index]
|
||||
if(Co_BACKSTEP in S)
|
||||
return S[Co_BACKSTEP]
|
||||
Reference in New Issue
Block a user