mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-04 22:11:27 +00:00
Makes the code compatible with 515.1594+
Few simple changes and one very painful one.
Let's start with the easy:
* puts call behind `LIBCALL` define, so call_ext is properly used in 515
* Adds `NAMEOF_STATIC(_,X)` macro for nameof in static definitions since
src is now invalid there.
* Fixes tgui and devserver. From 515 onward the tmp3333{procid} cache
directory is not appened to base path in browser controls so we don't
check for it in base js and put the dev server dummy window file in
actual directory not the byond root.
* Renames the few things that had /final/ in typepath to ultimate since
final is a new keyword
And the very painful change:
`.proc/whatever` format is no longer valid, so we're replacing it with
new nameof() function. All this wrapped in three new macros.
`PROC_REF(X)`,`TYPE_PROC_REF(TYPE,X)`,`GLOBAL_PROC_REF(X)`. Global is
not actually necessary but if we get nameof that does not allow globals
it would be nice validation.
This is pretty unwieldy but there's no real alternative.
If you notice anything weird in the commits let me know because majority
was done with regex replace.
@tgstation/commit-access Since the .proc/stuff is pretty big change.
Co-authored-by: san7890 <the@san7890.com>
Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
264 lines
11 KiB
Plaintext
264 lines
11 KiB
Plaintext
#define MOD_ACTIVATION_STEP_FLAGS IGNORE_USER_LOC_CHANGE|IGNORE_TARGET_LOC_CHANGE|IGNORE_HELD_ITEM|IGNORE_INCAPACITATED|IGNORE_SLOWDOWNS
|
|
|
|
/// Creates a radial menu from which the user chooses parts of the suit to deploy/retract. Repeats until all parts are extended or retracted.
|
|
/obj/item/mod/control/proc/choose_deploy(mob/user)
|
|
if(!length(mod_parts))
|
|
return
|
|
var/list/display_names = list()
|
|
var/list/items = list()
|
|
for(var/obj/item/part as anything in mod_parts)
|
|
display_names[part.name] = REF(part)
|
|
var/image/part_image = image(icon = part.icon, icon_state = part.icon_state)
|
|
if(part.loc != src)
|
|
part_image.underlays += image(icon = 'icons/hud/radial.dmi', icon_state = "module_active")
|
|
items += list(part.name = part_image)
|
|
var/pick = show_radial_menu(user, src, items, custom_check = FALSE, require_near = TRUE, tooltips = TRUE)
|
|
if(!pick)
|
|
return
|
|
var/part_reference = display_names[pick]
|
|
var/obj/item/part = locate(part_reference) in mod_parts
|
|
if(!istype(part) || user.incapacitated())
|
|
return
|
|
if(active || activating)
|
|
balloon_alert(user, "deactivate the suit first!")
|
|
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
|
|
return
|
|
var/parts_to_check = mod_parts - part
|
|
if(part.loc == src)
|
|
deploy(user, part)
|
|
on_mod_deployed(user)
|
|
for(var/obj/item/checking_part as anything in parts_to_check)
|
|
if(checking_part.loc != src)
|
|
continue
|
|
choose_deploy(user)
|
|
break
|
|
else
|
|
retract(user, part)
|
|
on_mod_retracted(user)
|
|
for(var/obj/item/checking_part as anything in parts_to_check)
|
|
if(checking_part.loc == src)
|
|
continue
|
|
choose_deploy(user)
|
|
break
|
|
|
|
/// Quickly deploys all parts (or retracts if all are on the wearer)
|
|
/obj/item/mod/control/proc/quick_deploy(mob/user)
|
|
if(active || activating)
|
|
balloon_alert(user, "deactivate the suit first!")
|
|
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
|
|
return FALSE
|
|
var/deploy = TRUE
|
|
for(var/obj/item/part as anything in mod_parts)
|
|
if(part.loc == src)
|
|
continue
|
|
deploy = FALSE
|
|
break
|
|
for(var/obj/item/part as anything in mod_parts)
|
|
if(deploy && part.loc == src)
|
|
deploy(null, part)
|
|
else if(!deploy && part.loc != src)
|
|
retract(null, part)
|
|
wearer.visible_message(span_notice("[wearer]'s [src] [deploy ? "deploys" : "retracts"] its' parts with a mechanical hiss."),
|
|
span_notice("[src] [deploy ? "deploys" : "retracts"] its' parts with a mechanical hiss."),
|
|
span_hear("You hear a mechanical hiss."))
|
|
playsound(src, 'sound/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
|
|
if(deploy)
|
|
on_mod_deployed(user)
|
|
else
|
|
on_mod_retracted(user)
|
|
return TRUE
|
|
|
|
/// Deploys a part of the suit onto the user.
|
|
/obj/item/mod/control/proc/deploy(mob/user, obj/item/part)
|
|
if(part.loc != src)
|
|
if(!user)
|
|
return FALSE
|
|
balloon_alert(user, "[part.name] already deployed!")
|
|
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
|
|
if(part in overslotting_parts)
|
|
var/obj/item/overslot = wearer.get_item_by_slot(part.slot_flags)
|
|
if(overslot)
|
|
overslotting_parts[part] = overslot
|
|
wearer.transferItemToLoc(overslot, part, force = TRUE)
|
|
RegisterSignal(part, COMSIG_ATOM_EXITED, PROC_REF(on_overslot_exit))
|
|
if(wearer.equip_to_slot_if_possible(part, part.slot_flags, qdel_on_fail = FALSE, disable_warning = TRUE))
|
|
ADD_TRAIT(part, TRAIT_NODROP, MOD_TRAIT)
|
|
if(!user)
|
|
return TRUE
|
|
wearer.visible_message(span_notice("[wearer]'s [part.name] deploy[part.p_s()] with a mechanical hiss."),
|
|
span_notice("[part] deploy[part.p_s()] with a mechanical hiss."),
|
|
span_hear("You hear a mechanical hiss."))
|
|
playsound(src, 'sound/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
|
|
return TRUE
|
|
else
|
|
if(!user)
|
|
return FALSE
|
|
balloon_alert(user, "bodypart clothed!")
|
|
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
|
|
return FALSE
|
|
|
|
/// Retract a part of the suit from the user.
|
|
/obj/item/mod/control/proc/retract(mob/user, obj/item/part)
|
|
if(part.loc == src)
|
|
if(!user)
|
|
return FALSE
|
|
balloon_alert(user, "[part.name] already retracted!")
|
|
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
|
|
REMOVE_TRAIT(part, TRAIT_NODROP, MOD_TRAIT)
|
|
wearer.transferItemToLoc(part, src, force = TRUE)
|
|
if(overslotting_parts[part])
|
|
UnregisterSignal(part, COMSIG_ATOM_EXITED)
|
|
var/obj/item/overslot = overslotting_parts[part]
|
|
if(!wearer.equip_to_slot_if_possible(overslot, overslot.slot_flags, qdel_on_fail = FALSE, disable_warning = TRUE))
|
|
wearer.dropItemToGround(overslot, force = TRUE, silent = TRUE)
|
|
overslotting_parts[part] = null
|
|
if(!user)
|
|
return
|
|
wearer.visible_message(span_notice("[wearer]'s [part.name] retract[part.p_s()] back into [src] with a mechanical hiss."),
|
|
span_notice("[part] retract[part.p_s()] back into [src] with a mechanical hiss."),
|
|
span_hear("You hear a mechanical hiss."))
|
|
playsound(src, 'sound/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
|
|
|
|
/// Starts the activation sequence, where parts of the suit activate one by one until the whole suit is on
|
|
/obj/item/mod/control/proc/toggle_activate(mob/user, force_deactivate = FALSE)
|
|
if(!wearer)
|
|
if(!force_deactivate)
|
|
balloon_alert(user, "equip suit first!")
|
|
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
|
|
return FALSE
|
|
if(!force_deactivate && (SEND_SIGNAL(src, COMSIG_MOD_ACTIVATE, user) & MOD_CANCEL_ACTIVATE))
|
|
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
|
|
return FALSE
|
|
for(var/obj/item/part as anything in mod_parts)
|
|
if(!force_deactivate && part.loc == src)
|
|
balloon_alert(user, "deploy all parts first!")
|
|
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
|
|
return FALSE
|
|
if(locked && !active && !allowed(user) && !force_deactivate)
|
|
balloon_alert(user, "access insufficient!")
|
|
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
|
|
return FALSE
|
|
if(!get_charge() && !force_deactivate)
|
|
balloon_alert(user, "suit not powered!")
|
|
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
|
|
return FALSE
|
|
if(open && !force_deactivate)
|
|
balloon_alert(user, "close the suit panel!")
|
|
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
|
|
return FALSE
|
|
if(activating)
|
|
if(!force_deactivate)
|
|
balloon_alert(user, "suit already [active ? "shutting down" : "starting up"]!")
|
|
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
|
|
return FALSE
|
|
for(var/obj/item/mod/module/module as anything in modules)
|
|
if(!module.active || module.allowed_inactive)
|
|
continue
|
|
module.on_deactivation(display_message = FALSE)
|
|
activating = TRUE
|
|
to_chat(wearer, span_notice("MODsuit [active ? "shutting down" : "starting up"]."))
|
|
if(do_after(wearer, activation_step_time, wearer, MOD_ACTIVATION_STEP_FLAGS, extra_checks = CALLBACK(src, PROC_REF(has_wearer))))
|
|
to_chat(wearer, span_notice("[boots] [active ? "relax their grip on your legs" : "seal around your feet"]."))
|
|
playsound(src, 'sound/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
|
|
seal_part(boots, seal = !active)
|
|
if(do_after(wearer, activation_step_time, wearer, MOD_ACTIVATION_STEP_FLAGS, extra_checks = CALLBACK(src, PROC_REF(has_wearer))))
|
|
to_chat(wearer, span_notice("[gauntlets] [active ? "become loose around your fingers" : "tighten around your fingers and wrists"]."))
|
|
playsound(src, 'sound/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
|
|
seal_part(gauntlets, seal = !active)
|
|
if(do_after(wearer, activation_step_time, wearer, MOD_ACTIVATION_STEP_FLAGS, extra_checks = CALLBACK(src, PROC_REF(has_wearer))))
|
|
to_chat(wearer, span_notice("[chestplate] [active ? "releases your chest" : "cinches tightly against your chest"]."))
|
|
playsound(src, 'sound/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
|
|
seal_part(chestplate, seal = !active)
|
|
if(do_after(wearer, activation_step_time, wearer, MOD_ACTIVATION_STEP_FLAGS, extra_checks = CALLBACK(src, PROC_REF(has_wearer))))
|
|
to_chat(wearer, span_notice("[helmet] hisses [active ? "open" : "closed"]."))
|
|
playsound(src, 'sound/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
|
|
seal_part(helmet, seal = !active)
|
|
if(do_after(wearer, activation_step_time, wearer, MOD_ACTIVATION_STEP_FLAGS, extra_checks = CALLBACK(src, PROC_REF(has_wearer))))
|
|
to_chat(wearer, span_notice("Systems [active ? "shut down. Parts unsealed. Goodbye" : "started up. Parts sealed. Welcome"], [wearer]."))
|
|
if(ai)
|
|
to_chat(ai, span_notice("<b>SYSTEMS [active ? "DEACTIVATED. GOODBYE" : "ACTIVATED. WELCOME"]: \"[ai]\"</b>"))
|
|
finish_activation(on = !active)
|
|
if(active)
|
|
playsound(src, 'sound/machines/synth_yes.ogg', 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE, frequency = 6000)
|
|
if(!malfunctioning)
|
|
wearer.playsound_local(get_turf(src), 'sound/mecha/nominal.ogg', 50)
|
|
else
|
|
playsound(src, 'sound/machines/synth_no.ogg', 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE, frequency = 6000)
|
|
activating = FALSE
|
|
SEND_SIGNAL(src, COMSIG_MOD_TOGGLED, user)
|
|
return TRUE
|
|
|
|
///Seals or unseals the given part
|
|
/obj/item/mod/control/proc/seal_part(obj/item/clothing/part, seal)
|
|
if(seal)
|
|
part.clothing_flags |= part.visor_flags
|
|
part.flags_inv |= part.visor_flags_inv
|
|
part.flags_cover |= part.visor_flags_cover
|
|
part.heat_protection = initial(part.heat_protection)
|
|
part.cold_protection = initial(part.cold_protection)
|
|
part.alternate_worn_layer = null
|
|
else
|
|
part.flags_cover &= ~part.visor_flags_cover
|
|
part.flags_inv &= ~part.visor_flags_inv
|
|
part.clothing_flags &= ~part.visor_flags
|
|
part.heat_protection = NONE
|
|
part.cold_protection = NONE
|
|
part.alternate_worn_layer = mod_parts[part]
|
|
if(part == boots)
|
|
boots.icon_state = "[skin]-boots[seal ? "-sealed" : ""]"
|
|
wearer.update_worn_shoes()
|
|
if(part == gauntlets)
|
|
gauntlets.icon_state = "[skin]-gauntlets[seal ? "-sealed" : ""]"
|
|
wearer.update_worn_gloves()
|
|
if(part == chestplate)
|
|
chestplate.icon_state = "[skin]-chestplate[seal ? "-sealed" : ""]"
|
|
wearer.update_worn_oversuit()
|
|
wearer.update_worn_undersuit()
|
|
if(part == helmet)
|
|
helmet.icon_state = "[skin]-helmet[seal ? "-sealed" : ""]"
|
|
wearer.update_worn_head()
|
|
wearer.update_worn_mask()
|
|
wearer.update_worn_glasses()
|
|
wearer.update_body_parts()
|
|
// Close internal air tank if MOD helmet is unsealed and was the only breathing apparatus.
|
|
if (!seal && wearer?.invalid_internals())
|
|
wearer.cutoff_internals()
|
|
|
|
/// Finishes the suit's activation, starts processing
|
|
/obj/item/mod/control/proc/finish_activation(on)
|
|
active = on
|
|
if(active)
|
|
for(var/obj/item/mod/module/module as anything in modules)
|
|
module.on_suit_activation()
|
|
START_PROCESSING(SSobj, src)
|
|
else
|
|
for(var/obj/item/mod/module/module as anything in modules)
|
|
module.on_suit_deactivation()
|
|
STOP_PROCESSING(SSobj, src)
|
|
update_speed()
|
|
update_icon_state()
|
|
wearer.update_clothing(slot_flags)
|
|
|
|
/// Quickly deploys all the suit parts and if successful, seals them and turns on the suit. Intended mostly for outfits.
|
|
/obj/item/mod/control/proc/quick_activation()
|
|
var/seal = TRUE
|
|
for(var/obj/item/part as anything in mod_parts)
|
|
if(!deploy(null, part))
|
|
seal = FALSE
|
|
if(!seal)
|
|
return
|
|
for(var/obj/item/part as anything in mod_parts)
|
|
seal_part(part, seal = TRUE)
|
|
finish_activation(on = TRUE)
|
|
|
|
/obj/item/mod/control/proc/has_wearer()
|
|
return wearer
|
|
|
|
/obj/item/mod/control/proc/on_mod_deployed(mob/user)
|
|
SEND_SIGNAL(src, COMSIG_MOD_DEPLOYED, user)
|
|
|
|
/obj/item/mod/control/proc/on_mod_retracted(mob/user)
|
|
SEND_SIGNAL(src, COMSIG_MOD_RETRACTED, user)
|
|
|
|
#undef MOD_ACTIVATION_STEP_FLAGS
|