modsuits part 2
This commit is contained in:
committed by
Jerry Wester
parent
183b554ed3
commit
b538ad721b
@@ -1,48 +0,0 @@
|
||||
/// An AI controller for the MODsuit pathfinder module. It's activated by implant and attaches itself to the user.
|
||||
/datum/ai_controller/mod
|
||||
blackboard = list(
|
||||
BB_MOD_TARGET,
|
||||
BB_MOD_IMPLANT,
|
||||
)
|
||||
max_target_distance = MOD_AI_RANGE //a little spicy but its one specific item that summons it, and it doesnt run otherwise
|
||||
ai_movement = /datum/ai_movement/jps
|
||||
///ID card generated from the suit's required access. Used for pathing.
|
||||
var/obj/item/card/id/advanced/id_card
|
||||
|
||||
/datum/ai_controller/mod/TryPossessPawn(atom/new_pawn)
|
||||
if(!istype(new_pawn, /obj/item/mod/control))
|
||||
return AI_CONTROLLER_INCOMPATIBLE
|
||||
var/obj/item/mod/control/mod = new_pawn
|
||||
id_card = new /obj/item/card/id/advanced/simple_bot()
|
||||
if(length(mod.req_access))
|
||||
id_card.set_access(mod.req_access)
|
||||
return ..() //Run parent at end
|
||||
|
||||
/datum/ai_controller/mod/UnpossessPawn(destroy)
|
||||
QDEL_NULL(id_card)
|
||||
return ..() //Run parent at end
|
||||
|
||||
/datum/ai_controller/mod/SelectBehaviors(delta_time)
|
||||
current_behaviors = list()
|
||||
if(blackboard[BB_MOD_TARGET] && blackboard[BB_MOD_IMPLANT])
|
||||
queue_behavior(/datum/ai_behavior/mod_attach)
|
||||
|
||||
/datum/ai_controller/mod/get_access()
|
||||
return id_card
|
||||
|
||||
/datum/ai_behavior/mod_attach
|
||||
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT|AI_BEHAVIOR_MOVE_AND_PERFORM
|
||||
|
||||
/datum/ai_behavior/mod_attach/perform(delta_time, datum/ai_controller/controller)
|
||||
. = ..()
|
||||
if(!controller.pawn.Adjacent(controller.blackboard[BB_MOD_TARGET]))
|
||||
return
|
||||
var/obj/item/implant/mod/implant = controller.blackboard[BB_MOD_IMPLANT]
|
||||
implant.module.attach(controller.blackboard[BB_MOD_TARGET])
|
||||
finish_action(controller, TRUE)
|
||||
|
||||
/datum/ai_behavior/mod_attach/finish_action(datum/ai_controller/controller, succeeded)
|
||||
. = ..()
|
||||
controller.blackboard[BB_MOD_TARGET] = null
|
||||
var/obj/item/implant/mod/implant = controller.blackboard[BB_MOD_IMPLANT]
|
||||
implant.end_recall(succeeded)
|
||||
@@ -0,0 +1,23 @@
|
||||
/// Switches between mouse buttons for MODsuit active modules
|
||||
/datum/preference/choiced/mod_select
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "mod_select"
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
|
||||
/datum/preference/choiced/mod_select/init_possible_values()
|
||||
return list(MIDDLE_CLICK, ALT_CLICK)
|
||||
|
||||
/datum/preference/choiced/mod_select/create_default_value()
|
||||
return MIDDLE_CLICK
|
||||
|
||||
/datum/preference/choiced/mod_select/apply_to_client_updated(client/client, value)
|
||||
if(!ishuman(client.mob))
|
||||
return
|
||||
var/mob/living/carbon/human/client_owner = client.mob
|
||||
if(!istype(client_owner.back, /obj/item/mod/control))
|
||||
return
|
||||
var/obj/item/mod/control/mod = client_owner.back
|
||||
if(!mod.selected_module)
|
||||
return
|
||||
UnregisterSignal(mod.wearer, mod.selected_module.used_signal)
|
||||
mod.selected_module.update_signal(value)
|
||||
@@ -27,8 +27,8 @@
|
||||
if(prob(40))
|
||||
if(prob(25))
|
||||
audible_message("<span class='warning'>You hear something rumbling inside [src]'s stomach...</span>", \
|
||||
"<span class='warning'>You hear something rumbling.</span>", 4,\
|
||||
"<span class='userdanger'>Something is rumbling inside your stomach!</span>")
|
||||
"<span class='warning'>You hear something rumbling.</span>", 4,\
|
||||
"<span class='userdanger'>Something is rumbling inside your stomach!</span>")
|
||||
var/obj/item/I = user.get_active_held_item()
|
||||
if(I && I.force)
|
||||
var/d = rand(round(I.force / 4), I.force)
|
||||
@@ -624,12 +624,21 @@
|
||||
if(M.name == XRAY)
|
||||
sight |= (SEE_TURFS|SEE_MOBS|SEE_OBJS)
|
||||
see_in_dark = max(see_in_dark, 8)
|
||||
|
||||
if(HAS_TRAIT(src, TRAIT_TRUE_NIGHT_VISION))
|
||||
lighting_alpha = min(lighting_alpha, LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE)
|
||||
see_in_dark = max(see_in_dark, 8)
|
||||
|
||||
if(HAS_TRAIT(src, TRAIT_MESON_VISION))
|
||||
sight |= SEE_TURFS
|
||||
lighting_alpha = min(lighting_alpha, LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE)
|
||||
|
||||
if(HAS_TRAIT(src, TRAIT_THERMAL_VISION))
|
||||
sight |= (SEE_MOBS)
|
||||
sight |= SEE_MOBS
|
||||
lighting_alpha = min(lighting_alpha, LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE)
|
||||
|
||||
if(HAS_TRAIT(src, TRAIT_XRAY_VISION))
|
||||
sight |= (SEE_TURFS|SEE_MOBS|SEE_OBJS)
|
||||
sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS
|
||||
see_in_dark = max(see_in_dark, 8)
|
||||
|
||||
if(see_override)
|
||||
|
||||
@@ -304,7 +304,8 @@
|
||||
if(equip_to_slot_if_possible(thing, ITEM_SLOT_BACK))
|
||||
update_inv_hands()
|
||||
return
|
||||
if(!SEND_SIGNAL(equipped_back, COMSIG_CONTAINS_STORAGE)) // not a storage item
|
||||
var/datum/component/storage/storage = equipped_back.GetComponent(/datum/component/storage)
|
||||
if(!storage)
|
||||
if(!thing)
|
||||
equipped_back.attack_hand(src)
|
||||
else
|
||||
@@ -314,10 +315,11 @@
|
||||
if(!SEND_SIGNAL(equipped_back, COMSIG_TRY_STORAGE_INSERT, thing, src))
|
||||
to_chat(src, "<span class='warning'>You can't fit anything in!</span>")
|
||||
return
|
||||
if(!equipped_back.contents.len) // nothing to take out
|
||||
to_chat(src, "<span class='warning'>There's nothing in your backpack to take out!</span>")
|
||||
var/atom/real_location = storage.real_location()
|
||||
if(!real_location.contents.len) // nothing to take out
|
||||
to_chat(src, "<span class='warning'>There's nothing in your [equipped_back.name] to take out!</span>")
|
||||
return
|
||||
var/obj/item/stored = equipped_back.contents[equipped_back.contents.len]
|
||||
var/obj/item/stored = real_location.contents[real_location.contents.len]
|
||||
if(!stored || stored.on_found(src))
|
||||
return
|
||||
stored.attack_hand(src) // take out thing from backpack
|
||||
|
||||
@@ -1303,7 +1303,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(ITEM_SLOT_FEET)
|
||||
if(H.shoes)
|
||||
return FALSE
|
||||
if( !(I.slot_flags & ITEM_SLOT_FEET) )
|
||||
if((DIGITIGRADE in species_traits) && !(I.item_flags & IGNORE_DIGITIGRADE))
|
||||
return FALSE
|
||||
if(num_legs < 2)
|
||||
return FALSE
|
||||
|
||||
@@ -47,6 +47,8 @@
|
||||
return ..()
|
||||
|
||||
/mob/living/proc/ZImpactDamage(turf/T, levels)
|
||||
if(SEND_SIGNAL(src, COMSIG_LIVING_Z_IMPACT, levels, T) & NO_Z_IMPACT_DAMAGE)
|
||||
return
|
||||
visible_message("<span class='danger'>[src] crashes into [T] with a sickening noise!</span>", \
|
||||
"<span class='userdanger'>You crash into [T] with a sickening noise!</span>")
|
||||
adjustBruteLoss((levels * 5) ** 1.5)
|
||||
@@ -753,7 +755,8 @@
|
||||
return pick("trails_1", "trails_2")
|
||||
|
||||
/mob/living/experience_pressure_difference(pressure_difference, direction, pressure_resistance_prob_delta = 0)
|
||||
if(buckled)
|
||||
playsound(src, 'sound/effects/space_wind.ogg', 50, TRUE)
|
||||
if(buckled || mob_negates_gravity())
|
||||
return
|
||||
if(client && client.move_delay >= world.time + world.tick_lag*2)
|
||||
pressure_resistance_prob_delta -= 30
|
||||
|
||||
@@ -38,8 +38,8 @@
|
||||
var/can_be_carded = TRUE
|
||||
var/alarms = list("Motion"=list(), "Fire"=list(), "Atmosphere"=list(), "Power"=list(), "Camera"=list(), "Burglar"=list())
|
||||
var/viewalerts = 0
|
||||
var/icon/holo_icon//Female is assigned when AI is created.
|
||||
var/obj/vehicle/sealed/mecha/controlled_mech //For controlled_mech a mech, to determine whether to relaymove or use the AI eye.
|
||||
var/icon/holo_icon //Female is assigned when AI is created.
|
||||
var/obj/controlled_equipment //A piece of equipment, to determine whether to relaymove or use the AI eye.
|
||||
var/radio_enabled = TRUE //Determins if a carded AI can speak with its built in radio or not.
|
||||
radiomod = ";" //AIs will, by default, state their laws on the internal radio.
|
||||
var/obj/item/pda/ai/aiPDA
|
||||
@@ -173,10 +173,20 @@
|
||||
GLOB.ai_list -= src
|
||||
GLOB.shuttle_caller_list -= src
|
||||
SSshuttle.autoEvac()
|
||||
qdel(eyeobj) // No AI, no Eye
|
||||
QDEL_NULL(eyeobj) // No AI, no Eye
|
||||
QDEL_NULL(spark_system)
|
||||
QDEL_NULL(malf_picker)
|
||||
QDEL_NULL(doomsday_device)
|
||||
QDEL_NULL(robot_control)
|
||||
QDEL_NULL(aiMulti)
|
||||
QDEL_NULL(alert_control)
|
||||
malfhack = null
|
||||
|
||||
. = ..()
|
||||
current = null
|
||||
Bot = null
|
||||
controlled_equipment = null
|
||||
linked_core = null
|
||||
apc_override = null
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/ai/IgniteMob()
|
||||
fire_stacks = 0
|
||||
@@ -410,7 +420,7 @@
|
||||
|
||||
if (href_list["ai_take_control"]) //Mech domination
|
||||
var/obj/vehicle/sealed/mecha/M = locate(href_list["ai_take_control"])
|
||||
if(controlled_mech)
|
||||
if(controlled_equipment)
|
||||
to_chat(src, "<span class='warning'>You are already loaded into an onboard computer!</span>")
|
||||
return
|
||||
if(!GLOB.cameranet.checkCameraVis(M))
|
||||
|
||||
@@ -722,7 +722,7 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
|
||||
return pick(protection_sources)
|
||||
else
|
||||
return src
|
||||
if((magic && HAS_TRAIT(src, TRAIT_ANTIMAGIC)) || (holy && HAS_TRAIT(src, TRAIT_HOLY)))
|
||||
if((magic && HAS_TRAIT(src, TRAIT_ANTIMAGIC)) || (!self && magic && HAS_TRAIT(src, TRAIT_ANTIMAGIC_NO_SELFBLOCK)) || (holy && HAS_TRAIT(src, TRAIT_HOLY)))
|
||||
return src
|
||||
|
||||
//You can buckle on mobs if you're next to them since most are dense
|
||||
|
||||
@@ -585,7 +585,7 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
|
||||
|
||||
//Can the mob see reagents inside of containers?
|
||||
/mob/proc/can_see_reagents()
|
||||
return stat == DEAD || silicon_privileges //Dead guys and silicons can always see reagents
|
||||
return stat == DEAD || silicon_privileges || HAS_TRAIT(src, TRAIT_REAGENT_SCANNER) //Dead guys and silicons can always see reagents
|
||||
|
||||
/mob/proc/is_blind()
|
||||
SHOULD_BE_PURE(TRUE)
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/datum/action/item_action/mod
|
||||
background_icon_state = "bg_tech_blue"
|
||||
icon_icon = 'icons/mob/actions/actions_mod.dmi'
|
||||
check_flags = AB_CHECK_CONSCIOUS
|
||||
var/obj/item/mod/control/mod
|
||||
|
||||
/datum/action/item_action/mod/New(Target)
|
||||
..()
|
||||
mod = Target
|
||||
|
||||
/datum/action/item_action/mod/Grant(mob/M)
|
||||
if(owner)
|
||||
Share(M)
|
||||
return
|
||||
..()
|
||||
|
||||
/datum/action/item_action/mod/Remove(mob/M)
|
||||
var/mob_to_grant
|
||||
for(var/datum/weakref/reference as anything in sharers)
|
||||
var/mob/freeloader = reference.resolve()
|
||||
if(!freeloader)
|
||||
continue
|
||||
mob_to_grant = freeloader
|
||||
break
|
||||
..()
|
||||
if(mob_to_grant)
|
||||
Grant(mob_to_grant)
|
||||
|
||||
/datum/action/item_action/mod/deploy
|
||||
name = "Deploy MODsuit"
|
||||
desc = "Deploy/Conceal a part of the MODsuit."
|
||||
button_icon_state = "deploy"
|
||||
|
||||
/datum/action/item_action/mod/deploy/Trigger()
|
||||
if(!IsAvailable())
|
||||
return FALSE
|
||||
mod.choose_deploy(usr)
|
||||
return TRUE
|
||||
|
||||
/datum/action/item_action/mod/activate
|
||||
name = "Activate MODsuit"
|
||||
desc = "Activate/Deactivate the MODsuit."
|
||||
button_icon_state = "activate"
|
||||
|
||||
/datum/action/item_action/mod/activate/Trigger()
|
||||
if(!IsAvailable())
|
||||
return FALSE
|
||||
mod.toggle_activate(usr)
|
||||
return TRUE
|
||||
|
||||
/datum/action/item_action/mod/module
|
||||
name = "Toggle Module"
|
||||
desc = "Toggle a MODsuit module."
|
||||
button_icon_state = "module"
|
||||
|
||||
/datum/action/item_action/mod/module/Trigger()
|
||||
if(!IsAvailable())
|
||||
return FALSE
|
||||
mod.quick_module(usr)
|
||||
return TRUE
|
||||
|
||||
/datum/action/item_action/mod/panel
|
||||
name = "MODsuit Panel"
|
||||
desc = "Open the MODsuit's panel."
|
||||
button_icon_state = "panel"
|
||||
|
||||
/datum/action/item_action/mod/panel/Trigger()
|
||||
if(!IsAvailable())
|
||||
return FALSE
|
||||
mod.ui_interact(usr)
|
||||
return TRUE
|
||||
@@ -0,0 +1,217 @@
|
||||
#define MOD_ACTIVATION_STEP_TIME 2 SECONDS
|
||||
#define MOD_ACTIVATION_STEP_FLAGS IGNORE_USER_LOC_CHANGE|IGNORE_TARGET_LOC_CHANGE|IGNORE_HELD_ITEM|IGNORE_INCAPACITATED
|
||||
|
||||
/// 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/piece as anything in mod_parts)
|
||||
display_names[piece.name] = REF(piece)
|
||||
var/image/piece_image = image(icon = piece.icon, icon_state = piece.icon_state)
|
||||
items += list(piece.name = piece_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)
|
||||
for(var/obj/item/piece as anything in parts_to_check)
|
||||
if(piece.loc != src)
|
||||
continue
|
||||
choose_deploy(user)
|
||||
break
|
||||
else
|
||||
conceal(user, part)
|
||||
for(var/obj/item/piece as anything in parts_to_check)
|
||||
if(piece.loc == src)
|
||||
continue
|
||||
choose_deploy(user)
|
||||
break
|
||||
|
||||
/// Deploys a part of the suit onto the user.
|
||||
/obj/item/mod/control/proc/deploy(mob/user, part)
|
||||
var/obj/item/piece = part
|
||||
if(piece == gauntlets && wearer.gloves)
|
||||
gauntlets.overslot = wearer.gloves
|
||||
wearer.transferItemToLoc(gauntlets.overslot, gauntlets, force = TRUE)
|
||||
if(piece == boots && wearer.shoes)
|
||||
boots.overslot = wearer.shoes
|
||||
wearer.transferItemToLoc(boots.overslot, boots, force = TRUE)
|
||||
if(wearer.equip_to_slot_if_possible(piece, piece.slot_flags, qdel_on_fail = FALSE, disable_warning = TRUE))
|
||||
ADD_TRAIT(piece, TRAIT_NODROP, MOD_TRAIT)
|
||||
if(!user)
|
||||
return TRUE
|
||||
wearer.visible_message(span_notice("[wearer]'s [piece] deploy[piece.p_s()] with a mechanical hiss."),
|
||||
span_notice("[piece] deploy[piece.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(piece.loc != src)
|
||||
if(!user)
|
||||
return FALSE
|
||||
balloon_alert(user, "[piece] already deployed!")
|
||||
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
|
||||
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/conceal(mob/user, part)
|
||||
var/obj/item/piece = part
|
||||
REMOVE_TRAIT(piece, TRAIT_NODROP, MOD_TRAIT)
|
||||
wearer.transferItemToLoc(piece, src, force = TRUE)
|
||||
if(piece == gauntlets)
|
||||
gauntlets.show_overslot()
|
||||
if(piece == boots)
|
||||
boots.show_overslot()
|
||||
if(!user)
|
||||
return
|
||||
wearer.visible_message(span_notice("[wearer]'s [piece] retract[piece.p_s()] back into [src] with a mechanical hiss."),
|
||||
span_notice("[piece] retract[piece.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, "put suit on back!")
|
||||
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(!cell?.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)
|
||||
continue
|
||||
module.on_deactivation()
|
||||
activating = TRUE
|
||||
to_chat(wearer, span_notice("MODsuit [active ? "shutting down" : "starting up"]."))
|
||||
if(do_after(wearer, MOD_ACTIVATION_STEP_TIME, wearer, MOD_ACTIVATION_STEP_FLAGS))
|
||||
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, MOD_ACTIVATION_STEP_TIME, wearer, MOD_ACTIVATION_STEP_FLAGS))
|
||||
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, MOD_ACTIVATION_STEP_TIME, wearer, MOD_ACTIVATION_STEP_FLAGS))
|
||||
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, MOD_ACTIVATION_STEP_TIME, wearer, MOD_ACTIVATION_STEP_FLAGS))
|
||||
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, MOD_ACTIVATION_STEP_TIME, wearer, MOD_ACTIVATION_STEP_FLAGS))
|
||||
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)
|
||||
SEND_SOUND(wearer, sound('sound/mecha/nominal.ogg',volume=50))
|
||||
else
|
||||
playsound(src, 'sound/machines/synth_no.ogg', 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE, frequency = 6000)
|
||||
activating = FALSE
|
||||
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)
|
||||
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
|
||||
if(part == boots)
|
||||
boots.icon_state = "[skin]-boots[seal ? "-sealed" : ""]"
|
||||
wearer.update_inv_shoes()
|
||||
if(part == gauntlets)
|
||||
gauntlets.icon_state = "[skin]-gauntlets[seal ? "-sealed" : ""]"
|
||||
wearer.update_inv_gloves()
|
||||
if(part == chestplate)
|
||||
chestplate.icon_state = "[skin]-chestplate[seal ? "-sealed" : ""]"
|
||||
wearer.update_inv_wear_suit()
|
||||
wearer.update_inv_w_uniform()
|
||||
if(part == helmet)
|
||||
helmet.icon_state = "[skin]-helmet[seal ? "-sealed" : ""]"
|
||||
if(seal)
|
||||
helmet.alternate_worn_layer = null
|
||||
else
|
||||
helmet.alternate_worn_layer = helmet.alternate_layer
|
||||
wearer.update_inv_head()
|
||||
wearer.update_inv_wear_mask()
|
||||
wearer.update_hair()
|
||||
|
||||
/// Finishes the suit's activation, starts processing
|
||||
/obj/item/mod/control/proc/finish_activation(on)
|
||||
icon_state = "[skin]-control[on ? "-sealed" : ""]"
|
||||
slowdown = on ? slowdown_active : slowdown_inactive
|
||||
if(on)
|
||||
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)
|
||||
wearer.update_equipment_speed_mods()
|
||||
active = on
|
||||
wearer.update_inv_back()
|
||||
|
||||
/// 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 in mod_parts)
|
||||
if(!deploy(null, part))
|
||||
seal = FALSE
|
||||
if(!seal)
|
||||
return
|
||||
for(var/obj/item/part in mod_parts)
|
||||
seal_part(part, seal = TRUE)
|
||||
finish_activation(on = TRUE)
|
||||
|
||||
#undef MOD_ACTIVATION_STEP_TIME
|
||||
#undef MOD_ACTIVATION_STEP_FLAGS
|
||||
@@ -0,0 +1,88 @@
|
||||
/obj/item/mod/control/transfer_ai(interaction, mob/user, mob/living/silicon/ai/intAI, obj/item/aicard/card)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(!open) //mod must be open
|
||||
balloon_alert(user, "suit must be open to transfer!")
|
||||
return
|
||||
switch(interaction)
|
||||
if(AI_TRANS_TO_CARD)
|
||||
if(!ai)
|
||||
balloon_alert(user, "no AI in suit!")
|
||||
return
|
||||
balloon_alert(user, "transferring to card...")
|
||||
if(!do_after(user, 5 SECONDS, target = src))
|
||||
balloon_alert(user, "interrupted!")
|
||||
return
|
||||
intAI = ai
|
||||
intAI.ai_restore_power()//So the AI initially has power.
|
||||
intAI.control_disabled = TRUE
|
||||
intAI.radio_enabled = FALSE
|
||||
intAI.disconnect_shell()
|
||||
intAI.forceMove(card)
|
||||
card.AI = intAI
|
||||
for(var/datum/action/action as anything in actions)
|
||||
if(action.owner == intAI)
|
||||
action.Remove(intAI)
|
||||
else
|
||||
action.Unshare(intAI)
|
||||
intAI.controlled_equipment = null
|
||||
intAI.remote_control = null
|
||||
balloon_alert(intAI, "transferred to a card")
|
||||
balloon_alert(user, "AI transferred to card")
|
||||
ai = null
|
||||
|
||||
if(AI_TRANS_FROM_CARD) //Using an AI card to upload to the suit.
|
||||
intAI = card.AI
|
||||
if(!intAI)
|
||||
balloon_alert(user, "no AI in card!")
|
||||
return
|
||||
if(intAI.deployed_shell) //Recall AI if shelled so it can be checked for a client
|
||||
intAI.disconnect_shell()
|
||||
if(intAI.stat || !intAI.client)
|
||||
balloon_alert(user, "AI unresponsive!")
|
||||
return
|
||||
balloon_alert(user, "transferring to suit...")
|
||||
if(!do_after(user, 5 SECONDS, target = src))
|
||||
balloon_alert(user, "interrupted!")
|
||||
return
|
||||
balloon_alert(user, "AI transferred to suit")
|
||||
ai_enter_mod(intAI)
|
||||
card.AI = null
|
||||
|
||||
/obj/item/mod/control/proc/ai_enter_mod(mob/living/silicon/ai/new_ai)
|
||||
new_ai.control_disabled = FALSE
|
||||
new_ai.radio_enabled = TRUE
|
||||
new_ai.ai_restore_power()
|
||||
new_ai.cancel_camera()
|
||||
new_ai.controlled_equipment = src
|
||||
new_ai.remote_control = src
|
||||
new_ai.forceMove(src)
|
||||
ai = new_ai
|
||||
balloon_alert(new_ai, "transferred to a suit")
|
||||
for(var/datum/action/action as anything in actions)
|
||||
action.Grant(new_ai)
|
||||
|
||||
#define MOVE_DELAY 2
|
||||
#define WEARER_DELAY 1
|
||||
#define LONE_DELAY 5
|
||||
#define CELL_PER_STEP DEFAULT_CELL_DRAIN * 2.5
|
||||
|
||||
/obj/item/mod/control/relaymove(mob/user, direction)
|
||||
if((!active && wearer) || !cell || cell.charge < CELL_PER_STEP || user != ai || !COOLDOWN_FINISHED(src, cooldown_mod_move) || (wearer?.pulledby?.grab_state > GRAB_PASSIVE))
|
||||
return FALSE
|
||||
var/timemodifier = MOVE_DELAY * (ISDIAGONALDIR(direction) ? SQRT_2 : 1) * (wearer ? WEARER_DELAY : LONE_DELAY)
|
||||
COOLDOWN_START(src, cooldown_mod_move, movedelay * timemodifier + slowdown)
|
||||
playsound(src, 'sound/mecha/mechmove01.ogg', 25, TRUE)
|
||||
cell.charge = max(0, cell.charge - CELL_PER_STEP)
|
||||
if(ismovable(wearer?.loc))
|
||||
return wearer.loc.relaymove(wearer, direction)
|
||||
if(wearer && !wearer.Process_Spacemove(direction))
|
||||
return FALSE
|
||||
var/atom/movable/mover = wearer || src
|
||||
return step(mover, direction)
|
||||
|
||||
#undef MOVE_DELAY
|
||||
#undef WEARER_DELAY
|
||||
#undef LONE_DELAY
|
||||
#undef CELL_PER_STEP
|
||||
@@ -0,0 +1,123 @@
|
||||
/obj/item/clothing/head/helmet/space/mod
|
||||
name = "MOD helmet"
|
||||
desc = "A helmet for a MODsuit."
|
||||
icon = 'icons/obj/mod.dmi'
|
||||
icon_state = "helmet"
|
||||
worn_icon = 'icons/mob/mod.dmi'
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, FIRE = 25, ACID = 25, WOUND = 10)
|
||||
body_parts_covered = HEAD
|
||||
heat_protection = HEAD
|
||||
cold_protection = HEAD
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT
|
||||
min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT
|
||||
clothing_flags = THICKMATERIAL
|
||||
resistance_flags = NONE
|
||||
flash_protect = FLASH_PROTECTION_NONE
|
||||
clothing_flags = SNUG_FIT
|
||||
flags_inv = HIDEFACIALHAIR
|
||||
flags_cover = NONE
|
||||
visor_flags = THICKMATERIAL|STOPSPRESSUREDAMAGE
|
||||
visor_flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT
|
||||
visor_flags_cover = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF
|
||||
var/alternate_layer = NECK_LAYER
|
||||
var/obj/item/mod/control/mod
|
||||
|
||||
/obj/item/clothing/head/helmet/space/mod/Destroy()
|
||||
if(!QDELETED(mod))
|
||||
mod.helmet = null
|
||||
mod.mod_parts -= src
|
||||
QDEL_NULL(mod)
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/suit/armor/mod
|
||||
name = "MOD chestplate"
|
||||
desc = "A chestplate for a MODsuit."
|
||||
icon = 'icons/obj/mod.dmi'
|
||||
icon_state = "chestplate"
|
||||
worn_icon = 'icons/mob/mod.dmi'
|
||||
blood_overlay_type = "armor"
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, FIRE = 25, ACID = 25, WOUND = 10)
|
||||
body_parts_covered = CHEST|GROIN
|
||||
heat_protection = CHEST|GROIN
|
||||
cold_protection = CHEST|GROIN
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT
|
||||
min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT
|
||||
clothing_flags = THICKMATERIAL
|
||||
visor_flags = STOPSPRESSUREDAMAGE
|
||||
visor_flags_inv = HIDEJUMPSUIT
|
||||
allowed = list(/obj/item/flashlight, /obj/item/tank/internals)
|
||||
resistance_flags = NONE
|
||||
var/obj/item/mod/control/mod
|
||||
|
||||
/obj/item/clothing/suit/armor/mod/Destroy()
|
||||
if(!QDELETED(mod))
|
||||
mod.chestplate = null
|
||||
mod.mod_parts -= src
|
||||
QDEL_NULL(mod)
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/gloves/mod
|
||||
name = "MOD gauntlets"
|
||||
desc = "A pair of gauntlets for a MODsuit."
|
||||
icon = 'icons/obj/mod.dmi'
|
||||
icon_state = "gauntlets"
|
||||
worn_icon = 'icons/mob/mod.dmi'
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, FIRE = 25, ACID = 25, WOUND = 10)
|
||||
body_parts_covered = HANDS|ARMS
|
||||
heat_protection = HANDS|ARMS
|
||||
cold_protection = HANDS|ARMS
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT
|
||||
min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT
|
||||
clothing_flags = THICKMATERIAL
|
||||
resistance_flags = NONE
|
||||
var/obj/item/mod/control/mod
|
||||
var/obj/item/clothing/overslot
|
||||
|
||||
/obj/item/clothing/gloves/mod/Destroy()
|
||||
if(!QDELETED(mod))
|
||||
mod.gauntlets = null
|
||||
mod.mod_parts -= src
|
||||
QDEL_NULL(mod)
|
||||
return ..()
|
||||
|
||||
/// Replaces these gloves on the wearer with the overslot ones
|
||||
|
||||
/obj/item/clothing/gloves/mod/proc/show_overslot()
|
||||
if(!overslot)
|
||||
return
|
||||
if(!mod.wearer.equip_to_slot_if_possible(overslot, overslot.slot_flags, qdel_on_fail = FALSE, disable_warning = TRUE))
|
||||
mod.wearer.dropItemToGround(overslot, force = TRUE, silent = TRUE)
|
||||
overslot = null
|
||||
|
||||
/obj/item/clothing/shoes/mod
|
||||
name = "MOD boots"
|
||||
desc = "A pair of boots for a MODsuit."
|
||||
icon = 'icons/obj/mod.dmi'
|
||||
icon_state = "boots"
|
||||
worn_icon = 'icons/mob/mod.dmi'
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, FIRE = 25, ACID = 25, WOUND = 10)
|
||||
body_parts_covered = FEET|LEGS
|
||||
heat_protection = FEET|LEGS
|
||||
cold_protection = FEET|LEGS
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT
|
||||
min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT
|
||||
clothing_flags = THICKMATERIAL
|
||||
resistance_flags = NONE
|
||||
item_flags = IGNORE_DIGITIGRADE
|
||||
var/obj/item/mod/control/mod
|
||||
var/obj/item/clothing/overslot
|
||||
|
||||
/obj/item/clothing/shoes/mod/Destroy()
|
||||
if(!QDELETED(mod))
|
||||
mod.boots = null
|
||||
mod.mod_parts -= src
|
||||
QDEL_NULL(mod)
|
||||
return ..()
|
||||
|
||||
/// Replaces these shoes on the wearer with the overslot ones
|
||||
/obj/item/clothing/shoes/mod/proc/show_overslot()
|
||||
if(!overslot)
|
||||
return
|
||||
if(!mod.wearer.equip_to_slot_if_possible(overslot, overslot.slot_flags, qdel_on_fail = FALSE, disable_warning = TRUE))
|
||||
mod.wearer.dropItemToGround(overslot, force = TRUE, silent = TRUE)
|
||||
overslot = null
|
||||
@@ -0,0 +1,278 @@
|
||||
/obj/item/mod/construction
|
||||
desc = "A part used in MOD construction."
|
||||
inhand_icon_state = "rack_parts"
|
||||
|
||||
/obj/item/mod/construction/helmet
|
||||
name = "MOD helmet"
|
||||
icon_state = "helmet"
|
||||
|
||||
/obj/item/mod/construction/chestplate
|
||||
name = "MOD chestplate"
|
||||
icon_state = "chestplate"
|
||||
|
||||
/obj/item/mod/construction/gauntlets
|
||||
name = "MOD gauntlets"
|
||||
icon_state = "gauntlets"
|
||||
|
||||
/obj/item/mod/construction/boots
|
||||
name = "MOD boots"
|
||||
icon_state = "boots"
|
||||
|
||||
/obj/item/mod/construction/core
|
||||
name = "MOD core"
|
||||
icon_state = "mod-core"
|
||||
desc = "Growing in the most lush, fertile areas of the planet Sprout, there is a crystal known as the Heartbloom. \
|
||||
These rare, organic piezoelectric crystals are of incredible cultural significance to the artist castes of the Ethereals, \
|
||||
owing to their appearance; which is exactly similar to that of an Ethereal's heart. \n\
|
||||
Which one you have in your suit is unclear, but either way, \
|
||||
it's been repurposed to be an internal power source for a Modular Outerwear Device."
|
||||
|
||||
/obj/item/mod/construction/broken_core
|
||||
name = "broken MOD core"
|
||||
icon_state = "mod-core-broken"
|
||||
desc = "An internal power source for a Modular Outerwear Device. You don't seem to be able to source any power from this one, though."
|
||||
|
||||
/obj/item/mod/construction/broken_core/examine(mob/user)
|
||||
. = ..()
|
||||
. += span_notice("You could repair it with a <b>screwdriver</b>...")
|
||||
|
||||
/obj/item/mod/construction/broken_core/screwdriver_act(mob/living/user, obj/item/tool)
|
||||
. = ..()
|
||||
if(!tool.use_tool(src, user, 5 SECONDS, volume = 30))
|
||||
return
|
||||
new /obj/item/mod/construction/core(drop_location())
|
||||
qdel(src)
|
||||
|
||||
/obj/item/mod/construction/armor
|
||||
name = "MOD armor plates"
|
||||
desc = "Armor plates used to finish a MOD."
|
||||
icon_state = "standard-armor"
|
||||
var/datum/mod_theme/theme = /datum/mod_theme
|
||||
|
||||
/obj/item/mod/construction/armor/Initialize(mapload)
|
||||
. = ..()
|
||||
var/datum/mod_theme/used_theme = GLOB.mod_themes[theme]
|
||||
name = "MOD [used_theme.name] armor plates"
|
||||
desc = "[desc] [used_theme.desc]"
|
||||
icon_state = "[used_theme.default_skin]-armor"
|
||||
|
||||
/obj/item/mod/construction/armor/engineering
|
||||
theme = /datum/mod_theme/engineering
|
||||
|
||||
/obj/item/mod/construction/armor/atmospheric
|
||||
theme = /datum/mod_theme/atmospheric
|
||||
|
||||
/obj/item/mod/construction/armor/mining
|
||||
theme = /datum/mod_theme/mining
|
||||
|
||||
/obj/item/mod/construction/armor/medical
|
||||
theme = /datum/mod_theme/medical
|
||||
|
||||
/obj/item/mod/construction/armor/security
|
||||
theme = /datum/mod_theme/security
|
||||
|
||||
/obj/item/mod/construction/armor/cosmohonk
|
||||
theme = /datum/mod_theme/cosmohonk
|
||||
|
||||
/obj/item/mod/paint
|
||||
name = "MOD paint kit"
|
||||
desc = "This kit will repaint your MODsuit to something unique."
|
||||
icon = 'icons/obj/mod.dmi'
|
||||
icon_state = "paintkit"
|
||||
|
||||
#define START_STEP "start"
|
||||
#define CORE_STEP "core"
|
||||
#define SCREWED_CORE_STEP "screwed_core"
|
||||
#define HELMET_STEP "helmet"
|
||||
#define CHESTPLATE_STEP "chestplate"
|
||||
#define GAUNTLETS_STEP "gauntlets"
|
||||
#define BOOTS_STEP "boots"
|
||||
#define WRENCHED_ASSEMBLY_STEP "wrenched_assembly"
|
||||
#define SCREWED_ASSEMBLY_STEP "screwed_assembly"
|
||||
|
||||
/obj/item/mod/construction/shell
|
||||
name = "MOD shell"
|
||||
icon_state = "mod-construction_start"
|
||||
desc = "A MOD shell."
|
||||
var/obj/item/core
|
||||
var/obj/item/helmet
|
||||
var/obj/item/chestplate
|
||||
var/obj/item/gauntlets
|
||||
var/obj/item/boots
|
||||
var/step = START_STEP
|
||||
|
||||
/obj/item/mod/construction/shell/examine(mob/user)
|
||||
. = ..()
|
||||
var/display_text
|
||||
switch(step)
|
||||
if(START_STEP)
|
||||
display_text = "It looks like it's missing a <b>MOD core</b>..."
|
||||
if(CORE_STEP)
|
||||
display_text = "The core seems <b>loose</b>..."
|
||||
if(SCREWED_CORE_STEP)
|
||||
display_text = "It looks like it's missing a <b>helmet</b>..."
|
||||
if(HELMET_STEP)
|
||||
display_text = "It looks like it's missing a <b>chestplate</b>..."
|
||||
if(CHESTPLATE_STEP)
|
||||
display_text = "It looks like it's missing <b>gauntlets</b>..."
|
||||
if(GAUNTLETS_STEP)
|
||||
display_text = "It looks like it's missing <b>boots</b>..."
|
||||
if(BOOTS_STEP)
|
||||
display_text = "The assembly seems <b>unsecured</b>..."
|
||||
if(WRENCHED_ASSEMBLY_STEP)
|
||||
display_text = "The assembly seems <b>loose</b>..."
|
||||
if(SCREWED_ASSEMBLY_STEP)
|
||||
display_text = "All it's missing is <b>external armor</b>..."
|
||||
. += span_notice(display_text)
|
||||
|
||||
/obj/item/mod/construction/shell/attackby(obj/item/part, mob/user, params)
|
||||
. = ..()
|
||||
switch(step)
|
||||
if(START_STEP)
|
||||
if(!istype(part, /obj/item/mod/construction/core))
|
||||
return
|
||||
if(!user.transferItemToLoc(part, src))
|
||||
balloon_alert(user, "core stuck to your hand!")
|
||||
return
|
||||
playsound(src, 'sound/machines/click.ogg', 30, TRUE)
|
||||
balloon_alert(user, "core inserted")
|
||||
core = part
|
||||
step = CORE_STEP
|
||||
if(CORE_STEP)
|
||||
if(part.tool_behaviour == TOOL_SCREWDRIVER) //Construct
|
||||
if(part.use_tool(src, user, 0, volume=30))
|
||||
balloon_alert(user, "core screwed")
|
||||
step = SCREWED_CORE_STEP
|
||||
else if(part.tool_behaviour == TOOL_CROWBAR) //Deconstruct
|
||||
if(part.use_tool(src, user, 0, volume=30))
|
||||
core.forceMove(drop_location())
|
||||
balloon_alert(user, "core taken out")
|
||||
step = START_STEP
|
||||
if(SCREWED_CORE_STEP)
|
||||
if(istype(part, /obj/item/mod/construction/helmet)) //Construct
|
||||
if(!user.transferItemToLoc(part, src))
|
||||
balloon_alert(user, "helmet stuck to your hand!")
|
||||
return
|
||||
playsound(src, 'sound/machines/click.ogg', 30, TRUE)
|
||||
balloon_alert(user, "helmet added")
|
||||
helmet = part
|
||||
step = HELMET_STEP
|
||||
else if(part.tool_behaviour == TOOL_SCREWDRIVER) //Deconstruct
|
||||
if(part.use_tool(src, user, 0, volume=30))
|
||||
balloon_alert(user, "core unscrewed")
|
||||
step = CORE_STEP
|
||||
if(HELMET_STEP)
|
||||
if(istype(part, /obj/item/mod/construction/chestplate)) //Construct
|
||||
if(!user.transferItemToLoc(part, src))
|
||||
balloon_alert(user, "chestplate stuck to your hand!")
|
||||
return
|
||||
playsound(src, 'sound/machines/click.ogg', 30, TRUE)
|
||||
balloon_alert(user, "chestplate added")
|
||||
chestplate = part
|
||||
step = CHESTPLATE_STEP
|
||||
else if(part.tool_behaviour == TOOL_CROWBAR) //Deconstruct
|
||||
if(part.use_tool(src, user, 0, volume=30))
|
||||
helmet.forceMove(drop_location())
|
||||
balloon_alert(user, "helmet removed")
|
||||
helmet = null
|
||||
step = SCREWED_CORE_STEP
|
||||
if(CHESTPLATE_STEP)
|
||||
if(istype(part, /obj/item/mod/construction/gauntlets)) //Construct
|
||||
if(!user.transferItemToLoc(part, src))
|
||||
balloon_alert(user, "gauntlets stuck to your hand!")
|
||||
return
|
||||
playsound(src, 'sound/machines/click.ogg', 30, TRUE)
|
||||
balloon_alert(user, "gauntlets added")
|
||||
gauntlets = part
|
||||
step = GAUNTLETS_STEP
|
||||
else if(part.tool_behaviour == TOOL_CROWBAR) //Deconstruct
|
||||
if(part.use_tool(src, user, 0, volume=30))
|
||||
chestplate.forceMove(drop_location())
|
||||
balloon_alert(user, "chestplate removed")
|
||||
chestplate = null
|
||||
step = HELMET_STEP
|
||||
if(GAUNTLETS_STEP)
|
||||
if(istype(part, /obj/item/mod/construction/boots)) //Construct
|
||||
if(!user.transferItemToLoc(part, src))
|
||||
balloon_alert(user, "boots added")
|
||||
return
|
||||
playsound(src, 'sound/machines/click.ogg', 30, TRUE)
|
||||
balloon_alert(user, "You fit [part] onto [src].")
|
||||
boots = part
|
||||
step = BOOTS_STEP
|
||||
else if(part.tool_behaviour == TOOL_CROWBAR) //Deconstruct
|
||||
if(part.use_tool(src, user, 0, volume=30))
|
||||
gauntlets.forceMove(drop_location())
|
||||
balloon_alert(user, "gauntlets removed")
|
||||
gauntlets = null
|
||||
step = CHESTPLATE_STEP
|
||||
if(BOOTS_STEP)
|
||||
if(part.tool_behaviour == TOOL_WRENCH) //Construct
|
||||
if(part.use_tool(src, user, 0, volume=30))
|
||||
balloon_alert(user, "assembly secured")
|
||||
step = WRENCHED_ASSEMBLY_STEP
|
||||
else if(part.tool_behaviour == TOOL_CROWBAR) //Deconstruct
|
||||
if(part.use_tool(src, user, 0, volume=30))
|
||||
boots.forceMove(drop_location())
|
||||
balloon_alert(user, "boots removed")
|
||||
boots = null
|
||||
step = GAUNTLETS_STEP
|
||||
if(WRENCHED_ASSEMBLY_STEP)
|
||||
if(part.tool_behaviour == TOOL_SCREWDRIVER) //Construct
|
||||
if(part.use_tool(src, user, 0, volume=30))
|
||||
balloon_alert(user, "assembly screwed")
|
||||
step = SCREWED_ASSEMBLY_STEP
|
||||
else if(part.tool_behaviour == TOOL_WRENCH) //Deconstruct
|
||||
if(part.use_tool(src, user, 0, volume=30))
|
||||
balloon_alert(user, "assembly unsecured")
|
||||
step = BOOTS_STEP
|
||||
if(SCREWED_ASSEMBLY_STEP)
|
||||
if(istype(part, /obj/item/mod/construction/armor)) //Construct
|
||||
var/obj/item/mod/construction/armor/external_armor = part
|
||||
if(!user.transferItemToLoc(part, src))
|
||||
return
|
||||
playsound(src, 'sound/machines/click.ogg', 30, TRUE)
|
||||
balloon_alert(user, "suit finished")
|
||||
var/obj/item/modsuit = new /obj/item/mod/control(drop_location(), external_armor.theme)
|
||||
qdel(src)
|
||||
user.put_in_hands(modsuit)
|
||||
else if(part.tool_behaviour == TOOL_SCREWDRIVER) //Construct
|
||||
if(part.use_tool(src, user, 0, volume=30))
|
||||
balloon_alert(user, "assembly unscrewed")
|
||||
step = SCREWED_ASSEMBLY_STEP
|
||||
update_icon_state()
|
||||
|
||||
/obj/item/mod/construction/shell/update_icon_state()
|
||||
. = ..()
|
||||
icon_state = "mod-construction_[step]"
|
||||
|
||||
/obj/item/mod/construction/shell/Destroy()
|
||||
QDEL_NULL(core)
|
||||
QDEL_NULL(helmet)
|
||||
QDEL_NULL(chestplate)
|
||||
QDEL_NULL(gauntlets)
|
||||
QDEL_NULL(boots)
|
||||
return ..()
|
||||
|
||||
/obj/item/mod/construction/shell/handle_atom_del(atom/deleted_atom)
|
||||
if(deleted_atom == core)
|
||||
core = null
|
||||
if(deleted_atom == helmet)
|
||||
helmet = null
|
||||
if(deleted_atom == chestplate)
|
||||
chestplate = null
|
||||
if(deleted_atom == gauntlets)
|
||||
gauntlets = null
|
||||
if(deleted_atom == boots)
|
||||
boots = null
|
||||
return ..()
|
||||
|
||||
#undef START_STEP
|
||||
#undef CORE_STEP
|
||||
#undef SCREWED_CORE_STEP
|
||||
#undef HELMET_STEP
|
||||
#undef CHESTPLATE_STEP
|
||||
#undef GAUNTLETS_STEP
|
||||
#undef BOOTS_STEP
|
||||
#undef WRENCHED_ASSEMBLY_STEP
|
||||
#undef SCREWED_ASSEMBLY_STEP
|
||||
@@ -0,0 +1,559 @@
|
||||
/// MODsuits, trade-off between armor and utility
|
||||
/obj/item/mod
|
||||
name = "Base MOD"
|
||||
desc = "You should not see this, yell at a coder!"
|
||||
icon = 'icons/obj/mod.dmi'
|
||||
icon_state = "standard-control"
|
||||
worn_icon = 'icons/mob/mod.dmi'
|
||||
|
||||
/obj/item/mod/control
|
||||
name = "MOD control unit"
|
||||
desc = "The control unit of a Modular Outerwear Device, a powered, back-mounted suit that protects against various environments."
|
||||
icon_state = "control"
|
||||
inhand_icon_state = "mod_control"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
slot_flags = ITEM_SLOT_BACK
|
||||
strip_delay = 10 SECONDS
|
||||
slowdown = 2
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, FIRE = 25, ACID = 25, WOUND = 10)
|
||||
actions_types = list(/datum/action/item_action/mod/deploy, /datum/action/item_action/mod/activate, /datum/action/item_action/mod/module, /datum/action/item_action/mod/panel)
|
||||
resistance_flags = NONE
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT
|
||||
min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT
|
||||
permeability_coefficient = 0.01
|
||||
siemens_coefficient = 0.5
|
||||
alternate_worn_layer = BODY_FRONT_LAYER
|
||||
/// The MOD's theme, decides on some stuff like armor and statistics.
|
||||
var/datum/mod_theme/theme = /datum/mod_theme
|
||||
/// Looks of the MOD.
|
||||
var/skin = "standard"
|
||||
/// Theme of the MOD TGUI
|
||||
var/ui_theme = "ntos"
|
||||
/// If the suit is deployed and turned on.
|
||||
var/active = FALSE
|
||||
/// If the suit wire/module hatch is open.
|
||||
var/open = FALSE
|
||||
/// If the suit is ID locked.
|
||||
var/locked = FALSE
|
||||
/// If the suit is malfunctioning.
|
||||
var/malfunctioning = FALSE
|
||||
/// If the suit is currently activating/deactivating.
|
||||
var/activating = FALSE
|
||||
/// How long the MOD is electrified for.
|
||||
var/seconds_electrified = MACHINE_NOT_ELECTRIFIED
|
||||
/// If the suit interface is broken.
|
||||
var/interface_break = FALSE
|
||||
/// How much module complexity can this MOD carry.
|
||||
var/complexity_max = DEFAULT_MAX_COMPLEXITY
|
||||
/// How much module complexity this MOD is carrying.
|
||||
var/complexity = 0
|
||||
/// Power usage of the MOD.
|
||||
var/cell_drain = DEFAULT_CELL_DRAIN
|
||||
/// Slowdown of the MOD when not active.
|
||||
var/slowdown_inactive = 2
|
||||
/// Slowdown of the MOD when active.
|
||||
var/slowdown_active = 1
|
||||
/// MOD cell.
|
||||
var/obj/item/stock_parts/cell/cell
|
||||
/// MOD helmet.
|
||||
var/obj/item/clothing/head/helmet/space/mod/helmet
|
||||
/// MOD chestplate.
|
||||
var/obj/item/clothing/suit/armor/mod/chestplate
|
||||
/// MOD gauntlets.
|
||||
var/obj/item/clothing/gloves/mod/gauntlets
|
||||
/// MOD boots.
|
||||
var/obj/item/clothing/shoes/mod/boots
|
||||
/// List of parts (helmet, chestplate, gauntlets, boots).
|
||||
var/list/mod_parts = list()
|
||||
/// Modules the MOD should spawn with.
|
||||
var/list/initial_modules = list()
|
||||
/// Modules the MOD currently possesses.
|
||||
var/list/modules = list()
|
||||
/// Currently used module.
|
||||
var/obj/item/mod/module/selected_module
|
||||
/// AI mob inhabiting the MOD.
|
||||
var/mob/living/silicon/ai/ai
|
||||
/// Delay between moves as AI.
|
||||
var/movedelay = 0
|
||||
/// Cooldown for AI moves.
|
||||
COOLDOWN_DECLARE(cooldown_mod_move)
|
||||
/// Person wearing the MODsuit.
|
||||
var/mob/living/carbon/human/wearer
|
||||
|
||||
/obj/item/mod/control/Initialize(mapload, new_theme, new_skin)
|
||||
. = ..()
|
||||
if(new_theme)
|
||||
theme = new_theme
|
||||
theme = GLOB.mod_themes[theme]
|
||||
slowdown_inactive = theme.slowdown_inactive
|
||||
slowdown_active = theme.slowdown_active
|
||||
slowdown = slowdown_inactive
|
||||
complexity_max = theme.complexity_max
|
||||
skin = new_skin || theme.default_skin
|
||||
ui_theme = theme.ui_theme
|
||||
cell_drain = theme.cell_drain
|
||||
initial_modules += theme.inbuilt_modules
|
||||
wires = new /datum/wires/mod(src)
|
||||
if(length(req_access))
|
||||
locked = TRUE
|
||||
if(ispath(cell))
|
||||
cell = new cell(src)
|
||||
helmet = new /obj/item/clothing/head/helmet/space/mod(src)
|
||||
helmet.mod = src
|
||||
mod_parts += helmet
|
||||
chestplate = new /obj/item/clothing/suit/armor/mod(src)
|
||||
chestplate.mod = src
|
||||
mod_parts += chestplate
|
||||
gauntlets = new /obj/item/clothing/gloves/mod(src)
|
||||
gauntlets.mod = src
|
||||
mod_parts += gauntlets
|
||||
boots = new /obj/item/clothing/shoes/mod(src)
|
||||
boots.mod = src
|
||||
mod_parts += boots
|
||||
var/list/all_parts = mod_parts.Copy() + src
|
||||
for(var/obj/item/piece as anything in all_parts)
|
||||
piece.name = "[theme.name] [piece.name]"
|
||||
piece.desc = "[piece.desc] [theme.desc]"
|
||||
piece.armor = getArmor(arglist(theme.armor))
|
||||
piece.resistance_flags = theme.resistance_flags
|
||||
piece.heat_protection = NONE
|
||||
piece.cold_protection = NONE
|
||||
piece.max_heat_protection_temperature = theme.max_heat_protection_temperature
|
||||
piece.min_cold_protection_temperature = theme.min_cold_protection_temperature
|
||||
piece.permeability_coefficient = theme.permeability_coefficient
|
||||
piece.siemens_coefficient = theme.siemens_coefficient
|
||||
piece.icon_state = "[skin]-[initial(piece.icon_state)]"
|
||||
update_flags()
|
||||
for(var/obj/item/mod/module/module as anything in initial_modules)
|
||||
module = new module(src)
|
||||
install(module)
|
||||
RegisterSignal(src, COMSIG_ATOM_EXITED, .proc/on_exit)
|
||||
movedelay = CONFIG_GET(number/movedelay/run_delay)
|
||||
|
||||
/obj/item/mod/control/Destroy()
|
||||
if(active)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
var/atom/deleting_atom
|
||||
if(!QDELETED(helmet))
|
||||
deleting_atom = helmet
|
||||
helmet.mod = null
|
||||
helmet = null
|
||||
mod_parts -= deleting_atom
|
||||
qdel(deleting_atom)
|
||||
if(!QDELETED(chestplate))
|
||||
deleting_atom = chestplate
|
||||
chestplate.mod = null
|
||||
chestplate = null
|
||||
mod_parts -= deleting_atom
|
||||
qdel(deleting_atom)
|
||||
if(!QDELETED(gauntlets))
|
||||
deleting_atom = gauntlets
|
||||
gauntlets.mod = null
|
||||
gauntlets = null
|
||||
mod_parts -= deleting_atom
|
||||
qdel(deleting_atom)
|
||||
if(!QDELETED(boots))
|
||||
deleting_atom = boots
|
||||
boots.mod = null
|
||||
boots = null
|
||||
mod_parts -= deleting_atom
|
||||
qdel(deleting_atom)
|
||||
for(var/obj/item/mod/module/module as anything in modules)
|
||||
module.mod = null
|
||||
modules -= module
|
||||
QDEL_NULL(wires)
|
||||
QDEL_NULL(cell)
|
||||
return ..()
|
||||
|
||||
/obj/item/mod/control/process(delta_time)
|
||||
if(seconds_electrified > MACHINE_NOT_ELECTRIFIED)
|
||||
seconds_electrified--
|
||||
if((!cell || !cell.charge) && active && !activating)
|
||||
power_off()
|
||||
return PROCESS_KILL
|
||||
var/malfunctioning_charge_drain = 0
|
||||
if(malfunctioning)
|
||||
malfunctioning_charge_drain = rand(1,20)
|
||||
cell.charge = max(0, cell.charge - (cell_drain + malfunctioning_charge_drain)*delta_time)
|
||||
update_cell_alert()
|
||||
for(var/obj/item/mod/module/module as anything in modules)
|
||||
if(malfunctioning && module.active && DT_PROB(5, delta_time))
|
||||
module.on_deactivation()
|
||||
module.on_process(delta_time)
|
||||
|
||||
/obj/item/mod/control/equipped(mob/user, slot)
|
||||
..()
|
||||
if(slot == ITEM_SLOT_BACK)
|
||||
set_wearer(user)
|
||||
else if(wearer)
|
||||
unset_wearer()
|
||||
|
||||
/obj/item/mod/control/dropped(mob/user)
|
||||
. = ..()
|
||||
if(wearer)
|
||||
unset_wearer()
|
||||
|
||||
/obj/item/mod/control/item_action_slot_check(slot)
|
||||
if(slot == ITEM_SLOT_BACK)
|
||||
return TRUE
|
||||
|
||||
/obj/item/mod/control/allow_attack_hand_drop(mob/user)
|
||||
var/mob/living/carbon/carbon_user = user
|
||||
if(!istype(carbon_user) || src != carbon_user.back)
|
||||
return ..()
|
||||
for(var/obj/item/part in mod_parts)
|
||||
if(part.loc != src)
|
||||
balloon_alert(carbon_user, "retract parts first!")
|
||||
playsound(src, 'sound/machines/scanbuzz.ogg', 25, FALSE, SILENCED_SOUND_EXTRARANGE)
|
||||
return FALSE
|
||||
|
||||
/obj/item/mod/control/MouseDrop(atom/over_object)
|
||||
if(src != wearer?.back || !istype(over_object, /atom/movable/screen/inventory/hand))
|
||||
return ..()
|
||||
for(var/obj/item/part in mod_parts)
|
||||
if(part.loc != src)
|
||||
balloon_alert(wearer, "retract parts first!")
|
||||
playsound(src, 'sound/machines/scanbuzz.ogg', 25, FALSE, SILENCED_SOUND_EXTRARANGE)
|
||||
return
|
||||
if(!wearer.incapacitated())
|
||||
var/atom/movable/screen/inventory/hand/ui_hand = over_object
|
||||
if(wearer.putItemFromInventoryInHandIfPossible(src, ui_hand.held_index))
|
||||
add_fingerprint(usr)
|
||||
return ..()
|
||||
|
||||
/obj/item/mod/control/attack_hand(mob/user)
|
||||
if(seconds_electrified && cell?.charge)
|
||||
if(shock(user))
|
||||
return
|
||||
if(open && loc == user)
|
||||
if(!cell)
|
||||
balloon_alert(user, "no cell!")
|
||||
return
|
||||
balloon_alert(user, "removing cell...")
|
||||
if(!do_after(user, 1.5 SECONDS, target = src))
|
||||
balloon_alert(user, "interrupted!")
|
||||
return
|
||||
balloon_alert(user, "cell removed")
|
||||
playsound(src, 'sound/machines/click.ogg', 50, TRUE, SILENCED_SOUND_EXTRARANGE)
|
||||
if(!user.put_in_hands(cell))
|
||||
cell.forceMove(drop_location())
|
||||
update_cell_alert()
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/item/mod/control/screwdriver_act(mob/living/user, obj/item/screwdriver)
|
||||
if(..())
|
||||
return TRUE
|
||||
if(active || activating || ai_controller)
|
||||
balloon_alert(user, "deactivate suit first!")
|
||||
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
|
||||
return FALSE
|
||||
balloon_alert(user, "[open ? "closing" : "opening"] panel...")
|
||||
screwdriver.play_tool_sound(src, 100)
|
||||
if(screwdriver.use_tool(src, user, 1 SECONDS))
|
||||
if(active || activating)
|
||||
balloon_alert(user, "deactivate suit first!")
|
||||
screwdriver.play_tool_sound(src, 100)
|
||||
balloon_alert(user, "panel [open ? "closed" : "opened"]")
|
||||
open = !open
|
||||
else
|
||||
balloon_alert(user, "interrupted!")
|
||||
return TRUE
|
||||
|
||||
/obj/item/mod/control/crowbar_act(mob/living/user, obj/item/crowbar)
|
||||
. = ..()
|
||||
if(!open)
|
||||
balloon_alert(user, "open the panel first!")
|
||||
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
|
||||
return FALSE
|
||||
if(!allowed(user))
|
||||
balloon_alert(user, "insufficient access!")
|
||||
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
|
||||
return
|
||||
if(length(modules))
|
||||
var/list/removable_modules = list()
|
||||
for(var/obj/item/mod/module/module as anything in modules)
|
||||
if(!module.removable)
|
||||
continue
|
||||
removable_modules += module
|
||||
var/obj/item/mod/module/module_to_remove = tgui_input_list(user, "Which module to remove?", "Module Removal", removable_modules)
|
||||
if(!module_to_remove?.mod)
|
||||
return FALSE
|
||||
uninstall(module_to_remove)
|
||||
module_to_remove.forceMove(drop_location())
|
||||
crowbar.play_tool_sound(src, 100)
|
||||
return TRUE
|
||||
balloon_alert(user, "no modules!")
|
||||
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
|
||||
return FALSE
|
||||
|
||||
/obj/item/mod/control/attackby(obj/item/attacking_item, mob/living/user, params)
|
||||
if(istype(attacking_item, /obj/item/mod/module))
|
||||
if(!open)
|
||||
balloon_alert(user, "open the panel first!")
|
||||
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
|
||||
return FALSE
|
||||
install(attacking_item, user)
|
||||
return TRUE
|
||||
else if(istype(attacking_item, /obj/item/stock_parts/cell))
|
||||
if(!open)
|
||||
balloon_alert(user, "open the panel first!")
|
||||
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
|
||||
return FALSE
|
||||
if(cell)
|
||||
balloon_alert(user, "cell already installed!")
|
||||
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
|
||||
return FALSE
|
||||
attacking_item.forceMove(src)
|
||||
cell = attacking_item
|
||||
balloon_alert(user, "cell installed")
|
||||
playsound(src, 'sound/machines/click.ogg', 50, TRUE, SILENCED_SOUND_EXTRARANGE)
|
||||
update_cell_alert()
|
||||
return TRUE
|
||||
else if(is_wire_tool(attacking_item) && open)
|
||||
wires.interact(user)
|
||||
return TRUE
|
||||
else if(istype(attacking_item, /obj/item/mod/paint))
|
||||
if(active || activating)
|
||||
balloon_alert(user, "suit is active!")
|
||||
else if(paint(user, attacking_item))
|
||||
balloon_alert(user, "suit painted")
|
||||
else
|
||||
balloon_alert(user, "not painted!")
|
||||
return TRUE
|
||||
else if(open && attacking_item.GetID())
|
||||
update_access(user, attacking_item)
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/obj/item/mod/control/get_cell()
|
||||
if(open)
|
||||
return cell
|
||||
|
||||
/obj/item/mod/control/GetAccess()
|
||||
if(ai_controller)
|
||||
return req_access.Copy()
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/mod/control/emag_act(mob/user)
|
||||
locked = !locked
|
||||
balloon_alert(user, "[locked ? "locked" : "unlocked"]")
|
||||
|
||||
/obj/item/mod/control/emp_act(severity)
|
||||
. = ..()
|
||||
to_chat(wearer, span_notice("[severity > 1 ? "Light" : "Strong"] electromagnetic pulse detected!"))
|
||||
if(!active || !wearer || . & EMP_PROTECT_CONTENTS)
|
||||
return
|
||||
selected_module = null
|
||||
wearer.apply_damage(10 / severity, BURN, spread_damage=TRUE)
|
||||
to_chat(wearer, span_danger("You feel [src] heat up from the EMP, burning you slightly."))
|
||||
if (wearer.stat < UNCONSCIOUS && prob(10))
|
||||
wearer.emote("scream")
|
||||
|
||||
/obj/item/mod/control/on_outfit_equip(mob/living/carbon/human/outfit_wearer, visuals_only, item_slot)
|
||||
if(visuals_only)
|
||||
set_wearer(outfit_wearer) //we need to set wearer manually since it doesnt call equipped
|
||||
quick_activation()
|
||||
|
||||
/obj/item/mod/control/doStrip(mob/stripper, mob/owner)
|
||||
if(active && !toggle_activate(stripper, force_deactivate = TRUE))
|
||||
return
|
||||
for(var/obj/item/part in mod_parts)
|
||||
conceal(null, part)
|
||||
return ..()
|
||||
|
||||
/obj/item/mod/control/worn_overlays(mutable_appearance/standing, isinhands = FALSE, icon_file)
|
||||
. = ..()
|
||||
if(!active)
|
||||
return
|
||||
for(var/obj/item/mod/module/module as anything in modules)
|
||||
var/list/module_icons = module.generate_worn_overlay(standing)
|
||||
if(!length(module_icons))
|
||||
continue
|
||||
. += module_icons
|
||||
|
||||
/obj/item/mod/control/proc/set_wearer(mob/user)
|
||||
wearer = user
|
||||
RegisterSignal(wearer, COMSIG_ATOM_EXITED, .proc/on_exit)
|
||||
RegisterSignal(wearer, COMSIG_PROCESS_BORGCHARGER_OCCUPANT, .proc/on_borg_charge)
|
||||
update_cell_alert()
|
||||
for(var/obj/item/mod/module/module as anything in modules)
|
||||
module.on_equip()
|
||||
|
||||
/obj/item/mod/control/proc/unset_wearer()
|
||||
for(var/obj/item/mod/module/module as anything in modules)
|
||||
module.on_unequip()
|
||||
UnregisterSignal(wearer, list(COMSIG_ATOM_EXITED, COMSIG_PROCESS_BORGCHARGER_OCCUPANT))
|
||||
wearer.clear_alert("mod_charge")
|
||||
wearer = null
|
||||
|
||||
/obj/item/mod/control/proc/update_flags()
|
||||
var/list/used_skin = theme.skins[skin]
|
||||
for(var/obj/item/clothing/part as anything in mod_parts)
|
||||
var/used_category
|
||||
if(part == helmet)
|
||||
used_category = HELMET_FLAGS
|
||||
helmet.alternate_worn_layer = used_skin[HELMET_LAYER]
|
||||
helmet.alternate_layer = used_skin[HELMET_LAYER]
|
||||
if(part == chestplate)
|
||||
used_category = CHESTPLATE_FLAGS
|
||||
if(part == gauntlets)
|
||||
used_category = GAUNTLETS_FLAGS
|
||||
if(part == boots)
|
||||
used_category = BOOTS_FLAGS
|
||||
var/list/category = used_skin[used_category]
|
||||
part.clothing_flags = category[UNSEALED_CLOTHING] || NONE
|
||||
part.visor_flags = category[SEALED_CLOTHING] || NONE
|
||||
part.flags_inv = category[UNSEALED_INVISIBILITY] || NONE
|
||||
part.visor_flags_inv = category[SEALED_INVISIBILITY] || NONE
|
||||
part.flags_cover = category[UNSEALED_COVER] || NONE
|
||||
part.visor_flags_cover = category[SEALED_COVER] || NONE
|
||||
|
||||
/obj/item/mod/control/proc/quick_module(mob/user)
|
||||
if(!length(modules))
|
||||
return
|
||||
var/list/display_names = list()
|
||||
var/list/items = list()
|
||||
for(var/obj/item/mod/module/module as anything in modules)
|
||||
if(module.module_type == MODULE_PASSIVE)
|
||||
continue
|
||||
display_names[module.name] = REF(module)
|
||||
var/image/module_image = image(icon = module.icon, icon_state = module.icon_state)
|
||||
items += list(module.name = module_image)
|
||||
if(!length(items))
|
||||
return
|
||||
var/pick = show_radial_menu(user, src, items, custom_check = FALSE, require_near = TRUE)
|
||||
if(!pick)
|
||||
return
|
||||
var/module_reference = display_names[pick]
|
||||
var/obj/item/mod/module/selected_module = locate(module_reference) in modules
|
||||
if(!istype(selected_module) || user.incapacitated())
|
||||
return
|
||||
selected_module.on_select()
|
||||
|
||||
/obj/item/mod/control/proc/paint(mob/user, obj/item/paint)
|
||||
if(length(theme.skins) <= 1)
|
||||
return FALSE
|
||||
var/list/skins = list()
|
||||
for(var/mod_skin in theme.skins)
|
||||
skins[mod_skin] = image(icon = icon, icon_state = "[mod_skin]-control")
|
||||
var/pick = show_radial_menu(user, src, skins, custom_check = FALSE, require_near = TRUE)
|
||||
if(!pick || !user.is_holding(paint))
|
||||
return FALSE
|
||||
skin = pick
|
||||
var/list/skin_updating = mod_parts.Copy() + src
|
||||
for(var/obj/item/piece as anything in skin_updating)
|
||||
piece.icon_state = "[skin]-[initial(piece.icon_state)]"
|
||||
update_flags()
|
||||
wearer?.regenerate_icons()
|
||||
return TRUE
|
||||
|
||||
/obj/item/mod/control/proc/shock(mob/living/user)
|
||||
if(!istype(user) || cell?.charge < 1)
|
||||
return FALSE
|
||||
do_sparks(5, TRUE, src)
|
||||
var/check_range = TRUE
|
||||
return electrocute_mob(user, cell, src, 0.7, check_range)
|
||||
|
||||
/obj/item/mod/control/proc/install(module, mob/user)
|
||||
var/obj/item/mod/module/new_module = module
|
||||
for(var/obj/item/mod/module/old_module as anything in modules)
|
||||
if(is_type_in_list(new_module, old_module.incompatible_modules) || is_type_in_list(old_module, new_module.incompatible_modules))
|
||||
if(user)
|
||||
balloon_alert(user, "[new_module] incompatible with [old_module]!")
|
||||
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
|
||||
return
|
||||
if(is_type_in_list(module, theme.module_blacklist))
|
||||
if(user)
|
||||
balloon_alert(user, "[src] doesn't accept [new_module]!")
|
||||
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
|
||||
return
|
||||
var/complexity_with_module = complexity
|
||||
complexity_with_module += new_module.complexity
|
||||
if(complexity_with_module > complexity_max)
|
||||
if(user)
|
||||
balloon_alert(user, "[new_module] would make [src] too complex!")
|
||||
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
|
||||
return
|
||||
new_module.forceMove(src)
|
||||
modules += new_module
|
||||
complexity += new_module.complexity
|
||||
new_module.mod = src
|
||||
new_module.on_install()
|
||||
if(wearer)
|
||||
new_module.on_equip()
|
||||
if(user)
|
||||
balloon_alert(user, "[new_module] added")
|
||||
playsound(src, 'sound/machines/click.ogg', 50, TRUE, SILENCED_SOUND_EXTRARANGE)
|
||||
|
||||
/obj/item/mod/control/proc/uninstall(module)
|
||||
var/obj/item/mod/module/old_module = module
|
||||
modules -= old_module
|
||||
complexity -= old_module.complexity
|
||||
if(active)
|
||||
old_module.on_suit_deactivation()
|
||||
if(old_module.active)
|
||||
old_module.on_deactivation()
|
||||
if(wearer)
|
||||
old_module.on_unequip()
|
||||
old_module.on_uninstall()
|
||||
old_module.mod = null
|
||||
|
||||
/obj/item/mod/control/proc/update_access(mob/user, obj/item/card/id/card)
|
||||
if(!allowed(user))
|
||||
balloon_alert(user, "insufficient access!")
|
||||
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
|
||||
return
|
||||
req_access = card.access.Copy()
|
||||
balloon_alert(user, "access updated")
|
||||
|
||||
/obj/item/mod/control/proc/update_cell_alert()
|
||||
if(!wearer)
|
||||
return
|
||||
if(!cell)
|
||||
wearer.throw_alert("mod_charge", /atom/movable/screen/alert/nocell)
|
||||
return
|
||||
var/remaining_cell = cell.charge/cell.maxcharge
|
||||
switch(remaining_cell)
|
||||
if(0.75 to INFINITY)
|
||||
wearer.clear_alert("mod_charge")
|
||||
if(0.5 to 0.75)
|
||||
wearer.throw_alert("mod_charge", /atom/movable/screen/alert/lowcell, 1)
|
||||
if(0.25 to 0.5)
|
||||
wearer.throw_alert("mod_charge", /atom/movable/screen/alert/lowcell, 2)
|
||||
if(0.01 to 0.25)
|
||||
wearer.throw_alert("mod_charge", /atom/movable/screen/alert/lowcell, 3)
|
||||
else
|
||||
wearer.throw_alert("mod_charge", /atom/movable/screen/alert/emptycell)
|
||||
|
||||
/obj/item/mod/control/proc/power_off()
|
||||
balloon_alert(wearer, "no power!")
|
||||
toggle_activate(wearer, force_deactivate = TRUE)
|
||||
|
||||
/obj/item/mod/control/proc/on_exit(datum/source, atom/movable/part, direction)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(part.loc == src)
|
||||
return
|
||||
if(part == cell)
|
||||
cell = null
|
||||
update_cell_alert()
|
||||
return
|
||||
if(part.loc == wearer)
|
||||
return
|
||||
if(modules.Find(part))
|
||||
uninstall(part)
|
||||
return
|
||||
if(mod_parts.Find(part))
|
||||
conceal(wearer, part)
|
||||
if(active)
|
||||
INVOKE_ASYNC(src, .proc/toggle_activate, wearer, TRUE)
|
||||
return
|
||||
|
||||
/obj/item/mod/control/proc/on_borg_charge(datum/source, amount)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!cell)
|
||||
return
|
||||
cell.give(amount)
|
||||
@@ -0,0 +1,854 @@
|
||||
/// Global proc that sets up all MOD themes as singletons in a list and returns it.
|
||||
/proc/setup_mod_themes()
|
||||
. = list()
|
||||
for(var/path in typesof(/datum/mod_theme))
|
||||
var/datum/mod_theme/new_theme = new path()
|
||||
.[path] = new_theme
|
||||
|
||||
/// MODsuit theme, instanced once and then used by MODsuits to grab various statistics.
|
||||
/datum/mod_theme
|
||||
/// Theme name for the MOD.
|
||||
var/name = "standard"
|
||||
/// Description added to the MOD.
|
||||
var/desc = "A civilian class suit by Nakamura Engineering, doesn't offer much other than slightly quicker movement."
|
||||
/// Default skin of the MOD.
|
||||
var/default_skin = "standard"
|
||||
/// Armor shared across the MOD pieces.
|
||||
var/armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, FIRE = 25, ACID = 25, WOUND = 10)
|
||||
/// Resistance flags shared across the MOD pieces.
|
||||
var/resistance_flags = NONE
|
||||
/// Max heat protection shared across the MOD pieces.
|
||||
var/max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT
|
||||
/// Max cold protection shared across the MOD pieces.
|
||||
var/min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT
|
||||
/// Permeability shared across the MOD pieces.
|
||||
var/permeability_coefficient = 0.01
|
||||
/// Siemens shared across the MOD pieces.
|
||||
var/siemens_coefficient = 0.5
|
||||
/// How much modules can the MOD carry without malfunctioning.
|
||||
var/complexity_max = DEFAULT_MAX_COMPLEXITY
|
||||
/// How much battery power the MOD uses by just being on
|
||||
var/cell_drain = DEFAULT_CELL_DRAIN
|
||||
/// Slowdown of the MOD when not active.
|
||||
var/slowdown_inactive = 1.25
|
||||
/// Slowdown of the MOD when active.
|
||||
var/slowdown_active = 0.75
|
||||
/// Theme used by the MOD TGUI.
|
||||
var/ui_theme = "ntos"
|
||||
/// List of inbuilt modules. These are different from the pre-equipped suits, you should mainly use these for unremovable modules with 0 complexity.
|
||||
var/list/inbuilt_modules = list()
|
||||
/// Modules blacklisted from the MOD.
|
||||
var/list/module_blacklist = list()
|
||||
/// List of skins with their appropriate clothing flags.
|
||||
var/list/skins = list(
|
||||
"standard" = list(
|
||||
HELMET_LAYER = NECK_LAYER,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT,
|
||||
SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
SEALED_INVISIBILITY = HIDEJUMPSUIT,
|
||||
),
|
||||
GAUNTLETS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
BOOTS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
),
|
||||
"civilian" = list(
|
||||
HELMET_LAYER = null,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT|THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
UNSEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
SEALED_INVISIBILITY = HIDEJUMPSUIT,
|
||||
),
|
||||
GAUNTLETS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
BOOTS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
/datum/mod_theme/engineering
|
||||
name = "engineering"
|
||||
desc = "An engineer-fit suit with heat and shock resistance. Nakamura Engineering's classic."
|
||||
default_skin = "engineering"
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 10, BIO = 100, FIRE = 100, ACID = 25, WOUND = 10)
|
||||
resistance_flags = FIRE_PROOF
|
||||
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
|
||||
siemens_coefficient = 0
|
||||
slowdown_inactive = 1.5
|
||||
slowdown_active = 1
|
||||
skins = list(
|
||||
"engineering" = list(
|
||||
HELMET_LAYER = NECK_LAYER,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT,
|
||||
SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
SEALED_INVISIBILITY = HIDEJUMPSUIT,
|
||||
),
|
||||
GAUNTLETS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
BOOTS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
/datum/mod_theme/atmospheric
|
||||
name = "atmospheric"
|
||||
desc = "An atmospheric-resistant suit by Nakamura Engineering, offering extreme heat resistance compared to the engineer suit."
|
||||
default_skin = "atmospheric"
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 10, BIO = 100, FIRE = 100, ACID = 75, WOUND = 10)
|
||||
resistance_flags = FIRE_PROOF
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
|
||||
slowdown_inactive = 1.5
|
||||
slowdown_active = 1
|
||||
skins = list(
|
||||
"atmospheric" = list(
|
||||
HELMET_LAYER = NECK_LAYER,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT,
|
||||
SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDESNOUT,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR,
|
||||
UNSEALED_COVER = HEADCOVERSMOUTH,
|
||||
SEALED_COVER = HEADCOVERSEYES|PEPPERPROOF,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
SEALED_INVISIBILITY = HIDEJUMPSUIT,
|
||||
),
|
||||
GAUNTLETS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
BOOTS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
/datum/mod_theme/advanced
|
||||
name = "advanced"
|
||||
desc = "An advanced version of Nakamura Engineering's classic suit, shining with a white, acid and fire resistant polish."
|
||||
default_skin = "advanced"
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 50, BIO = 100, FIRE = 100, ACID = 90, WOUND = 10)
|
||||
resistance_flags = FIRE_PROOF
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
|
||||
siemens_coefficient = 0
|
||||
slowdown_inactive = 1
|
||||
slowdown_active = 0.5
|
||||
inbuilt_modules = list(/obj/item/mod/module/magboot/advanced)
|
||||
skins = list(
|
||||
"advanced" = list(
|
||||
HELMET_LAYER = NECK_LAYER,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT,
|
||||
SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
SEALED_INVISIBILITY = HIDEJUMPSUIT,
|
||||
),
|
||||
GAUNTLETS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
BOOTS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
/datum/mod_theme/mining
|
||||
name = "mining"
|
||||
desc = "A high-power Nanotrasen mining suit, supporting more complexity at a bigger drain."
|
||||
default_skin = "mining"
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 50, BIO = 100, FIRE = 100, ACID = 75, WOUND = 15)
|
||||
resistance_flags = FIRE_PROOF
|
||||
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
|
||||
cell_drain = DEFAULT_CELL_DRAIN * 2
|
||||
complexity_max = DEFAULT_MAX_COMPLEXITY + 5
|
||||
skins = list(
|
||||
"mining" = list(
|
||||
HELMET_LAYER = null,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT|THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEEARS|HIDEHAIR|HIDESNOUT,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEYES|HIDEFACE,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
SEALED_INVISIBILITY = HIDEJUMPSUIT,
|
||||
),
|
||||
GAUNTLETS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
BOOTS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
/datum/mod_theme/medical
|
||||
name = "medical"
|
||||
desc = "A lightweight suit by DeForest Medical Corporation, allows for easier movement."
|
||||
default_skin = "medical"
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 10, BIO = 100, FIRE = 60, ACID = 75, WOUND = 10)
|
||||
cell_drain = DEFAULT_CELL_DRAIN * 1.5
|
||||
slowdown_inactive = 1
|
||||
slowdown_active = 0.5
|
||||
skins = list(
|
||||
"medical" = list(
|
||||
HELMET_LAYER = NECK_LAYER,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT,
|
||||
SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
SEALED_INVISIBILITY = HIDEJUMPSUIT,
|
||||
),
|
||||
GAUNTLETS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
BOOTS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
),
|
||||
"corpsman" = list(
|
||||
HELMET_LAYER = NECK_LAYER,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT,
|
||||
SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
SEALED_INVISIBILITY = HIDEJUMPSUIT,
|
||||
),
|
||||
GAUNTLETS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
BOOTS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
/datum/mod_theme/rescue
|
||||
name = "rescue"
|
||||
desc = "An advanced version of DeForest Medical Corporation's medical suit, designed for quick rescue of bodies from the most dangerous environments."
|
||||
default_skin = "rescue"
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 10, BIO = 100, FIRE = 100, ACID = 100, WOUND = 10)
|
||||
resistance_flags = FIRE_PROOF|ACID_PROOF
|
||||
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
|
||||
cell_drain = DEFAULT_CELL_DRAIN * 1.5
|
||||
slowdown_inactive = 0.75
|
||||
slowdown_active = 0.25
|
||||
inbuilt_modules = list(/obj/item/mod/module/quick_carry/advanced)
|
||||
skins = list(
|
||||
"rescue" = list(
|
||||
HELMET_LAYER = NECK_LAYER,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT,
|
||||
SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
SEALED_INVISIBILITY = HIDEJUMPSUIT,
|
||||
),
|
||||
GAUNTLETS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
BOOTS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
/datum/mod_theme/research
|
||||
name = "research"
|
||||
desc = "A private military EOD suit by Aussec Armory, intended for explosive research. Bulky, but expansive."
|
||||
default_skin = "research"
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 100, BIO = 100, FIRE = 100, ACID = 100, WOUND = 15)
|
||||
resistance_flags = FIRE_PROOF|ACID_PROOF
|
||||
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
|
||||
complexity_max = DEFAULT_MAX_COMPLEXITY + 5
|
||||
slowdown_inactive = 2
|
||||
slowdown_active = 1.5
|
||||
inbuilt_modules = list(/obj/item/mod/module/reagent_scanner/advanced)
|
||||
skins = list(
|
||||
"research" = list(
|
||||
HELMET_LAYER = null,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT|THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
UNSEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
SEALED_INVISIBILITY = HIDEJUMPSUIT,
|
||||
),
|
||||
GAUNTLETS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
BOOTS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
/datum/mod_theme/security
|
||||
name = "security"
|
||||
desc = "An Apadyne Technologies security suit, offering shock protection and quicker speed, at the cost of carrying capacity."
|
||||
default_skin = "security"
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 10, BIO = 100, FIRE = 75, ACID = 75, WOUND = 20)
|
||||
siemens_coefficient = 0
|
||||
complexity_max = DEFAULT_MAX_COMPLEXITY - 5
|
||||
slowdown_inactive = 1
|
||||
slowdown_active = 0.5
|
||||
skins = list(
|
||||
"security" = list(
|
||||
HELMET_LAYER = null,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT|THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEEARS|HIDEHAIR|HIDESNOUT,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEYES|HIDEFACE,
|
||||
UNSEALED_COVER = HEADCOVERSMOUTH,
|
||||
SEALED_COVER = HEADCOVERSEYES|PEPPERPROOF,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
SEALED_INVISIBILITY = HIDEJUMPSUIT,
|
||||
),
|
||||
GAUNTLETS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
BOOTS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
/datum/mod_theme/safeguard
|
||||
name = "safeguard"
|
||||
desc = "An Apadyne Technologies advanced security suit, offering greater speed and fire protection than the standard security model."
|
||||
default_skin = "safeguard"
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 25, BIO = 100, FIRE = 100, ACID = 95, WOUND = 25)
|
||||
resistance_flags = FIRE_PROOF
|
||||
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
|
||||
siemens_coefficient = 0
|
||||
complexity_max = DEFAULT_MAX_COMPLEXITY - 5
|
||||
slowdown_inactive = 0.75
|
||||
slowdown_active = 0.25
|
||||
skins = list(
|
||||
"safeguard" = list(
|
||||
HELMET_LAYER = null,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT|THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
UNSEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
SEALED_INVISIBILITY = HIDEJUMPSUIT,
|
||||
),
|
||||
GAUNTLETS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
BOOTS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
/datum/mod_theme/magnate
|
||||
name = "magnate"
|
||||
desc = "A fancy, very protective suit for Nanotrasen's captains. Shock, fire and acid-proof while also having a large capacity and high speed."
|
||||
default_skin = "magnate"
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 50, BIO = 100, FIRE = 100, ACID = 100, WOUND = 20)
|
||||
resistance_flags = FIRE_PROOF|ACID_PROOF
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
|
||||
siemens_coefficient = 0
|
||||
complexity_max = DEFAULT_MAX_COMPLEXITY + 5
|
||||
slowdown_inactive = 0.75
|
||||
slowdown_active = 0.25
|
||||
skins = list(
|
||||
"magnate" = list(
|
||||
HELMET_LAYER = NECK_LAYER,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT,
|
||||
SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
SEALED_INVISIBILITY = HIDEJUMPSUIT,
|
||||
),
|
||||
GAUNTLETS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
BOOTS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
/datum/mod_theme/cosmohonk
|
||||
name = "cosmohonk"
|
||||
desc = "A suit by Honk Ltd. Protects against low humor environments. Most of the tech went to lower the power cost."
|
||||
default_skin = "cosmohonk"
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 10, BIO = 100, FIRE = 60, ACID = 30, WOUND = 5)
|
||||
cell_drain = DEFAULT_CELL_DRAIN * 0.25
|
||||
slowdown_inactive = 1.75
|
||||
slowdown_active = 1.25
|
||||
skins = list(
|
||||
"cosmohonk" = list(
|
||||
HELMET_LAYER = NECK_LAYER,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT|THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEEARS|HIDEHAIR,
|
||||
SEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEMASK|HIDEEYES|HIDEFACE|HIDESNOUT,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
SEALED_INVISIBILITY = HIDEJUMPSUIT,
|
||||
),
|
||||
GAUNTLETS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
BOOTS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
/datum/mod_theme/syndicate
|
||||
name = "syndicate"
|
||||
desc = "A suit designed by Gorlex Marauders, offering armor ruled illegal in most of Spinward Stellar."
|
||||
default_skin = "syndicate"
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 35, BIO = 100, FIRE = 50, ACID = 90, WOUND = 25)
|
||||
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
|
||||
siemens_coefficient = 0
|
||||
slowdown_inactive = 1
|
||||
slowdown_active = 0.5
|
||||
ui_theme = "syndicate"
|
||||
inbuilt_modules = list(/obj/item/mod/module/armor_booster)
|
||||
skins = list(
|
||||
"syndicate" = list(
|
||||
HELMET_LAYER = NECK_LAYER,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT,
|
||||
SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
SEALED_INVISIBILITY = HIDEJUMPSUIT,
|
||||
),
|
||||
GAUNTLETS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
BOOTS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
/datum/mod_theme/elite
|
||||
name = "elite"
|
||||
desc = "An elite suit upgraded by Cybersun Industries, offering upgraded armor values."
|
||||
default_skin = "elite"
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 55, BIO = 100, FIRE = 100, ACID = 100, WOUND = 25)
|
||||
resistance_flags = FIRE_PROOF|ACID_PROOF
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
|
||||
siemens_coefficient = 0
|
||||
slowdown_inactive = 0.75
|
||||
slowdown_active = 0.25
|
||||
ui_theme = "syndicate"
|
||||
inbuilt_modules = list(/obj/item/mod/module/armor_booster/elite)
|
||||
skins = list(
|
||||
"elite" = list(
|
||||
HELMET_LAYER = null,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT,
|
||||
SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
SEALED_INVISIBILITY = HIDEJUMPSUIT,
|
||||
),
|
||||
GAUNTLETS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
BOOTS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
/datum/mod_theme/enchanted
|
||||
name = "enchanted"
|
||||
desc = "The Wizard Federation's relatively low-tech MODsuit. Is very protective, though."
|
||||
default_skin = "enchanted"
|
||||
armor = list(MELEE = 40, BULLET = 40, LASER = 40, ENERGY = 50, BOMB = 35, BIO = 100, FIRE = 100, ACID = 100, WOUND = 30)
|
||||
resistance_flags = FIRE_PROOF|ACID_PROOF
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
|
||||
siemens_coefficient = 0
|
||||
complexity_max = DEFAULT_MAX_COMPLEXITY - 5
|
||||
slowdown_inactive = 0.75
|
||||
slowdown_active = 0.25
|
||||
ui_theme = "wizard"
|
||||
inbuilt_modules = list(/obj/item/mod/module/anti_magic/wizard)
|
||||
skins = list(
|
||||
"enchanted" = list(
|
||||
HELMET_LAYER = null,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT|THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
UNSEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
SEALED_INVISIBILITY = HIDEJUMPSUIT,
|
||||
),
|
||||
GAUNTLETS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
BOOTS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
/datum/mod_theme/prototype
|
||||
name = "prototype"
|
||||
desc = "A prototype modular suit powered by locomotives. While it is comfortable and has a big capacity, it remains very bulky and power-inefficient."
|
||||
default_skin = "prototype"
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 50, BIO = 100, FIRE = 100, ACID = 75, WOUND = 5)
|
||||
resistance_flags = FIRE_PROOF
|
||||
complexity_max = DEFAULT_MAX_COMPLEXITY + 10
|
||||
slowdown_inactive = 2.5
|
||||
slowdown_active = 2
|
||||
ui_theme = "hackerman"
|
||||
inbuilt_modules = list(/obj/item/mod/module/kinesis)
|
||||
skins = list(
|
||||
"prototype" = list(
|
||||
HELMET_LAYER = null,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT|THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
UNSEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
SEALED_INVISIBILITY = HIDEJUMPSUIT,
|
||||
),
|
||||
GAUNTLETS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
BOOTS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
/datum/mod_theme/responsory
|
||||
name = "responsory"
|
||||
desc = "A high-speed rescue suit by Nanotrasen, intended for its' emergency response teams."
|
||||
default_skin = "responsory"
|
||||
armor = list(MELEE = 35, BULLET = 30, LASER = 30, ENERGY = 40, BOMB = 50, BIO = 100, FIRE = 100, ACID = 90, WOUND = 15)
|
||||
resistance_flags = FIRE_PROOF
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
|
||||
siemens_coefficient = 0
|
||||
slowdown_inactive = 0.5
|
||||
slowdown_active = 0
|
||||
skins = list(
|
||||
"responsory" = list(
|
||||
HELMET_LAYER = NECK_LAYER,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT,
|
||||
SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
SEALED_INVISIBILITY = HIDEJUMPSUIT,
|
||||
),
|
||||
GAUNTLETS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
BOOTS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
),
|
||||
"inquisitory" = list(
|
||||
HELMET_LAYER = null,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT|THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
UNSEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
SEALED_INVISIBILITY = HIDEJUMPSUIT,
|
||||
),
|
||||
GAUNTLETS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
BOOTS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
/datum/mod_theme/apocryphal
|
||||
name = "apocryphal"
|
||||
desc = "A high-tech, only technically legal, armored suit created by a collaboration effort between Nanotrasen and Apadyne Technologies."
|
||||
default_skin = "apocryphal"
|
||||
armor = list(MELEE = 80, BULLET = 80, LASER = 50, ENERGY = 60, BOMB = 100, BIO = 100, FIRE = 100, ACID = 100, WOUND = 25)
|
||||
resistance_flags = FIRE_PROOF|ACID_PROOF
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
|
||||
siemens_coefficient = 0
|
||||
complexity_max = DEFAULT_MAX_COMPLEXITY + 10
|
||||
skins = list(
|
||||
"apocryphal" = list(
|
||||
HELMET_LAYER = null,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT|THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEEARS|HIDEHAIR,
|
||||
SEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEMASK|HIDEEYES|HIDEFACE|HIDESNOUT,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
SEALED_INVISIBILITY = HIDEJUMPSUIT,
|
||||
),
|
||||
GAUNTLETS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
BOOTS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
/datum/mod_theme/corporate
|
||||
name = "corporate"
|
||||
desc = "A fancy, high-tech suit for Nanotrasen's high ranking officers."
|
||||
default_skin = "corporate"
|
||||
armor = list(MELEE = 35, BULLET = 40, LASER = 40, ENERGY = 50, BOMB = 50, BIO = 100, FIRE = 100, ACID = 100, WOUND = 15)
|
||||
resistance_flags = FIRE_PROOF|ACID_PROOF
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
|
||||
siemens_coefficient = 0
|
||||
slowdown_inactive = 0.5
|
||||
slowdown_active = 0
|
||||
skins = list(
|
||||
"corporate" = list(
|
||||
HELMET_LAYER = null,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT|THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEEARS|HIDEHAIR|HIDESNOUT,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEYES|HIDEFACE,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
SEALED_INVISIBILITY = HIDEJUMPSUIT,
|
||||
),
|
||||
GAUNTLETS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
BOOTS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
/datum/mod_theme/debug
|
||||
name = "debug"
|
||||
desc = "Strangely nostalgic."
|
||||
default_skin = "debug"
|
||||
armor = list(MELEE = 50, BULLET = 50, LASER = 50, ENERGY = 50, BOMB = 100, BIO = 100, FIRE = 100, ACID = 100, WOUND = 0)
|
||||
resistance_flags = FIRE_PROOF|ACID_PROOF
|
||||
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
|
||||
complexity_max = 50
|
||||
slowdown_inactive = 0.5
|
||||
slowdown_active = 0
|
||||
skins = list(
|
||||
"debug" = list(
|
||||
HELMET_LAYER = null,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT|THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEEARS|HIDEHAIR|HIDESNOUT,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE,
|
||||
UNSEALED_COVER = HEADCOVERSMOUTH,
|
||||
SEALED_COVER = HEADCOVERSEYES|PEPPERPROOF,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
SEALED_INVISIBILITY = HIDEJUMPSUIT,
|
||||
),
|
||||
GAUNTLETS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
BOOTS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
/datum/mod_theme/administrative
|
||||
name = "administrative"
|
||||
desc = "A suit made of adminium. Who comes up with these stupid mineral names?"
|
||||
default_skin = "debug"
|
||||
armor = list(MELEE = 100, BULLET = 100, LASER = 100, ENERGY = 100, BOMB = 100, BIO = 100, FIRE = 100, ACID = 100, WOUND = 100)
|
||||
resistance_flags = INDESTRUCTIBLE|LAVA_PROOF|FIRE_PROOF|UNACIDABLE|ACID_PROOF
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
|
||||
complexity_max = 1000
|
||||
cell_drain = DEFAULT_CELL_DRAIN * 0
|
||||
slowdown_inactive = 0
|
||||
slowdown_active = 0
|
||||
skins = list(
|
||||
"debug" = list(
|
||||
HELMET_LAYER = null,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT|THICKMATERIAL|STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEEARS|HIDEHAIR|HIDESNOUT,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE,
|
||||
UNSEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE|BLOCKS_SHOVE_KNOCKDOWN,
|
||||
SEALED_INVISIBILITY = HIDEJUMPSUIT,
|
||||
),
|
||||
GAUNTLETS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
BOOTS_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE,
|
||||
),
|
||||
),
|
||||
)
|
||||
@@ -0,0 +1,157 @@
|
||||
/obj/item/mod/control/pre_equipped
|
||||
cell = /obj/item/stock_parts/cell/high
|
||||
var/applied_skin
|
||||
|
||||
/obj/item/mod/control/pre_equipped/Initialize(mapload, new_theme, new_skin)
|
||||
new_skin = applied_skin
|
||||
return ..()
|
||||
|
||||
/obj/item/mod/control/pre_equipped/standard
|
||||
initial_modules = list(/obj/item/mod/module/storage, /obj/item/mod/module/welding, /obj/item/mod/module/flashlight)
|
||||
|
||||
/obj/item/mod/control/pre_equipped/engineering
|
||||
theme = /datum/mod_theme/engineering
|
||||
initial_modules = list(/obj/item/mod/module/storage, /obj/item/mod/module/welding, /obj/item/mod/module/rad_protection, /obj/item/mod/module/flashlight, /obj/item/mod/module/magboot)
|
||||
|
||||
/obj/item/mod/control/pre_equipped/atmospheric
|
||||
theme = /datum/mod_theme/atmospheric
|
||||
initial_modules = list(/obj/item/mod/module/storage, /obj/item/mod/module/welding, /obj/item/mod/module/rad_protection, /obj/item/mod/module/flashlight, /obj/item/mod/module/t_ray)
|
||||
|
||||
/obj/item/mod/control/pre_equipped/advanced
|
||||
theme = /datum/mod_theme/advanced
|
||||
cell = /obj/item/stock_parts/cell/super
|
||||
initial_modules = list(/obj/item/mod/module/storage/large_capacity, /obj/item/mod/module/welding, /obj/item/mod/module/rad_protection, /obj/item/mod/module/jetpack, /obj/item/mod/module/flashlight)
|
||||
|
||||
/obj/item/mod/control/pre_equipped/mining
|
||||
theme = /datum/mod_theme/mining
|
||||
cell = /obj/item/stock_parts/cell/high/plus
|
||||
initial_modules = list(/obj/item/mod/module/storage/large_capacity, /obj/item/mod/module/welding, /obj/item/mod/module/orebag, /obj/item/mod/module/flashlight, /obj/item/mod/module/magboot, /obj/item/mod/module/drill)
|
||||
|
||||
/obj/item/mod/control/pre_equipped/medical
|
||||
theme = /datum/mod_theme/medical
|
||||
initial_modules = list(/obj/item/mod/module/storage, /obj/item/mod/module/flashlight, /obj/item/mod/module/health_analyzer, /obj/item/mod/module/quick_carry)
|
||||
|
||||
/obj/item/mod/control/pre_equipped/rescue
|
||||
theme = /datum/mod_theme/rescue
|
||||
cell = /obj/item/stock_parts/cell/super
|
||||
initial_modules = list(/obj/item/mod/module/storage/large_capacity, /obj/item/mod/module/flashlight, /obj/item/mod/module/health_analyzer, /obj/item/mod/module/injector)
|
||||
|
||||
/obj/item/mod/control/pre_equipped/research
|
||||
theme = /datum/mod_theme/research
|
||||
cell = /obj/item/stock_parts/cell/super
|
||||
initial_modules = list(/obj/item/mod/module/storage/large_capacity, /obj/item/mod/module/welding, /obj/item/mod/module/flashlight, /obj/item/mod/module/circuit, /obj/item/mod/module/t_ray)
|
||||
|
||||
/obj/item/mod/control/pre_equipped/security
|
||||
theme = /datum/mod_theme/security
|
||||
initial_modules = list(/obj/item/mod/module/storage, /obj/item/mod/module/welding, /obj/item/mod/module/flashlight, /obj/item/mod/module/holster)
|
||||
|
||||
/obj/item/mod/control/pre_equipped/safeguard
|
||||
theme = /datum/mod_theme/safeguard
|
||||
cell = /obj/item/stock_parts/cell/super
|
||||
initial_modules = list(/obj/item/mod/module/storage/large_capacity, /obj/item/mod/module/welding, /obj/item/mod/module/flashlight, /obj/item/mod/module/jetpack, /obj/item/mod/module/holster)
|
||||
|
||||
/obj/item/mod/control/pre_equipped/magnate
|
||||
theme = /datum/mod_theme/magnate
|
||||
cell = /obj/item/stock_parts/cell/hyper
|
||||
initial_modules = list(/obj/item/mod/module/storage/large_capacity, /obj/item/mod/module/welding, /obj/item/mod/module/holster, /obj/item/mod/module/pathfinder)
|
||||
|
||||
/obj/item/mod/control/pre_equipped/traitor
|
||||
theme = /datum/mod_theme/syndicate
|
||||
cell = /obj/item/stock_parts/cell/super
|
||||
initial_modules = list(/obj/item/mod/module/storage/syndicate, /obj/item/mod/module/welding, /obj/item/mod/module/tether, /obj/item/mod/module/pathfinder, /obj/item/mod/module/flashlight, /obj/item/mod/module/dna_lock)
|
||||
|
||||
/obj/item/mod/control/pre_equipped/nuclear
|
||||
theme = /datum/mod_theme/syndicate
|
||||
cell = /obj/item/stock_parts/cell/hyper
|
||||
initial_modules = list(/obj/item/mod/module/storage/syndicate, /obj/item/mod/module/welding, /obj/item/mod/module/jetpack, /obj/item/mod/module/visor/thermal, /obj/item/mod/module/flashlight, /obj/item/mod/module/holster)
|
||||
|
||||
/obj/item/mod/control/pre_equipped/elite
|
||||
theme = /datum/mod_theme/elite
|
||||
cell = /obj/item/stock_parts/cell/bluespace
|
||||
initial_modules = list(/obj/item/mod/module/storage/syndicate, /obj/item/mod/module/welding, /obj/item/mod/module/emp_shield, /obj/item/mod/module/jetpack, /obj/item/mod/module/visor/thermal, /obj/item/mod/module/flashlight, /obj/item/mod/module/holster)
|
||||
|
||||
/obj/item/mod/control/pre_equipped/enchanted
|
||||
theme = /datum/mod_theme/enchanted
|
||||
cell = /obj/item/stock_parts/cell/crystal_cell/wizard
|
||||
initial_modules = list(/obj/item/mod/module/storage/large_capacity, /obj/item/mod/module/energy_shield/wizard, /obj/item/mod/module/emp_shield)
|
||||
|
||||
/obj/item/mod/control/pre_equipped/prototype
|
||||
theme = /datum/mod_theme/prototype
|
||||
cell = /obj/item/stock_parts/cell/high/plus
|
||||
initial_modules = list(/obj/item/mod/module/storage, /obj/item/mod/module/welding, /obj/item/mod/module/rad_protection, /obj/item/mod/module/flashlight, /obj/item/mod/module/tether)
|
||||
|
||||
/obj/item/mod/control/pre_equipped/responsory
|
||||
theme = /datum/mod_theme/responsory
|
||||
cell = /obj/item/stock_parts/cell/hyper
|
||||
initial_modules = list(/obj/item/mod/module/storage/large_capacity, /obj/item/mod/module/welding, /obj/item/mod/module/emp_shield, /obj/item/mod/module/flashlight, /obj/item/mod/module/holster)
|
||||
var/insignia_type = /obj/item/mod/module/insignia
|
||||
|
||||
/obj/item/mod/control/pre_equipped/responsory/Initialize(mapload, new_theme, new_skin)
|
||||
initial_modules.Insert(1, insignia_type)
|
||||
return ..()
|
||||
|
||||
/obj/item/mod/control/pre_equipped/responsory/commander
|
||||
insignia_type = /obj/item/mod/module/insignia/commander
|
||||
|
||||
/obj/item/mod/control/pre_equipped/responsory/security
|
||||
insignia_type = /obj/item/mod/module/insignia/security
|
||||
|
||||
/obj/item/mod/control/pre_equipped/responsory/engineer
|
||||
insignia_type = /obj/item/mod/module/insignia/engineer
|
||||
|
||||
/obj/item/mod/control/pre_equipped/responsory/medic
|
||||
insignia_type = /obj/item/mod/module/insignia/medic
|
||||
|
||||
/obj/item/mod/control/pre_equipped/responsory/janitor
|
||||
insignia_type = /obj/item/mod/module/insignia/janitor
|
||||
|
||||
/obj/item/mod/control/pre_equipped/responsory/clown
|
||||
insignia_type = /obj/item/mod/module/insignia/clown
|
||||
|
||||
/obj/item/mod/control/pre_equipped/responsory/chaplain
|
||||
insignia_type = /obj/item/mod/module/insignia/chaplain
|
||||
|
||||
/obj/item/mod/control/pre_equipped/responsory/inquisitory
|
||||
initial_modules = list(/obj/item/mod/module/storage/large_capacity, /obj/item/mod/module/anti_magic, /obj/item/mod/module/welding, /obj/item/mod/module/emp_shield, /obj/item/mod/module/flashlight, /obj/item/mod/module/holster)
|
||||
applied_skin = "inquisitory"
|
||||
|
||||
/obj/item/mod/control/pre_equipped/responsory/inquisitory/commander
|
||||
insignia_type = /obj/item/mod/module/insignia/commander
|
||||
|
||||
/obj/item/mod/control/pre_equipped/responsory/inquisitory/security
|
||||
insignia_type = /obj/item/mod/module/insignia/security
|
||||
|
||||
/obj/item/mod/control/pre_equipped/responsory/inquisitory/medic
|
||||
insignia_type = /obj/item/mod/module/insignia/medic
|
||||
|
||||
/obj/item/mod/control/pre_equipped/responsory/inquisitory/chaplain
|
||||
insignia_type = /obj/item/mod/module/insignia/chaplain
|
||||
|
||||
/obj/item/mod/control/pre_equipped/apocryphal
|
||||
theme = /datum/mod_theme/apocryphal
|
||||
cell = /obj/item/stock_parts/cell/bluespace
|
||||
initial_modules = list(/obj/item/mod/module/storage/bluespace, /obj/item/mod/module/welding, /obj/item/mod/module/emp_shield, /obj/item/mod/module/jetpack, /obj/item/mod/module/holster)
|
||||
|
||||
/obj/item/mod/control/pre_equipped/corporate
|
||||
theme = /datum/mod_theme/corporate
|
||||
cell = /obj/item/stock_parts/cell/bluespace
|
||||
initial_modules = list(/obj/item/mod/module/storage/bluespace, /obj/item/mod/module/holster)
|
||||
|
||||
/obj/item/mod/control/pre_equipped/debug
|
||||
theme = /datum/mod_theme/debug
|
||||
cell = /obj/item/stock_parts/cell/bluespace
|
||||
initial_modules = list(/obj/item/mod/module/storage/bluespace, /obj/item/mod/module/welding, /obj/item/mod/module/flashlight, /obj/item/mod/module/bikehorn, /obj/item/mod/module/rad_protection, /obj/item/mod/module/tether, /obj/item/mod/module/injector) //one of every type of module, for testing if they all work correctly
|
||||
|
||||
/obj/item/mod/control/pre_equipped/administrative
|
||||
theme = /datum/mod_theme/administrative
|
||||
cell = /obj/item/stock_parts/cell/infinite/abductor
|
||||
initial_modules = list(/obj/item/mod/module/storage/bluespace, /obj/item/mod/module/welding, /obj/item/mod/module/stealth/ninja, /obj/item/mod/module/quick_carry/advanced, /obj/item/mod/module/magboot/advanced, /obj/item/mod/module/jetpack)
|
||||
|
||||
//these exist for the prefs menu
|
||||
/obj/item/mod/control/pre_equipped/syndicate_empty
|
||||
theme = /datum/mod_theme/syndicate
|
||||
|
||||
/obj/item/mod/control/pre_equipped/syndicate_empty/elite
|
||||
theme = /datum/mod_theme/elite
|
||||
|
||||
INITIALIZE_IMMEDIATE(/obj/item/mod/control/pre_equipped/syndicate_empty)
|
||||
@@ -0,0 +1,80 @@
|
||||
/obj/item/mod/control/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "MODsuit", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/mod/control/ui_data()
|
||||
var/data = list()
|
||||
data["interface_break"] = interface_break
|
||||
data["malfunctioning"] = malfunctioning
|
||||
data["open"] = open
|
||||
data["active"] = active
|
||||
data["locked"] = locked
|
||||
data["complexity"] = complexity
|
||||
data["selected_module"] = selected_module?.name
|
||||
data["wearer_name"] = wearer ? (wearer.get_authentification_name("Unknown") || "Unknown") : "No Occupant"
|
||||
data["wearer_job"] = wearer ? wearer.get_assignment("Unknown", "Unknown", FALSE) : "No Job"
|
||||
data["AI"] = ai?.name
|
||||
data["cell"] = cell?.name
|
||||
data["charge"] = cell ? round(cell.percent(), 1) : 0
|
||||
data["modules"] = list()
|
||||
for(var/obj/item/mod/module/module as anything in modules)
|
||||
var/list/module_data = list(
|
||||
name = module.name,
|
||||
description = module.desc,
|
||||
module_type = module.module_type,
|
||||
active = module.active,
|
||||
idle_power = module.idle_power_cost,
|
||||
active_power = module.active_power_cost,
|
||||
use_power = module.use_power_cost,
|
||||
complexity = module.complexity,
|
||||
cooldown_time = module.cooldown_time,
|
||||
cooldown = round(COOLDOWN_TIMELEFT(module, cooldown_timer), 1 SECONDS),
|
||||
id = module.tgui_id,
|
||||
ref = REF(module),
|
||||
configuration_data = module.get_configuration()
|
||||
)
|
||||
module_data += module.add_ui_data()
|
||||
data["modules"] += list(module_data)
|
||||
return data
|
||||
|
||||
/obj/item/mod/control/ui_static_data(mob/user)
|
||||
var/data = list()
|
||||
data["ui_theme"] = ui_theme
|
||||
data["control"] = name
|
||||
data["complexity_max"] = complexity_max
|
||||
data["helmet"] = helmet?.name
|
||||
data["chestplate"] = chestplate?.name
|
||||
data["gauntlets"] = gauntlets?.name
|
||||
data["boots"] = boots?.name
|
||||
return data
|
||||
|
||||
/obj/item/mod/control/ui_act(action, params)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(!allowed(usr) && locked)
|
||||
balloon_alert(usr, "insufficient access!")
|
||||
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
|
||||
return
|
||||
if(malfunctioning && prob(75))
|
||||
balloon_alert(usr, "button malfunctions!")
|
||||
return
|
||||
switch(action)
|
||||
if("lock")
|
||||
locked = !locked
|
||||
balloon_alert(usr, "[locked ? "locked" : "unlocked"]!")
|
||||
if("activate")
|
||||
toggle_activate(usr)
|
||||
if("select")
|
||||
var/obj/item/mod/module/module = locate(params["ref"]) in modules
|
||||
if(!module)
|
||||
return
|
||||
module.on_select()
|
||||
if("configure")
|
||||
var/obj/item/mod/module/module = locate(params["ref"]) in modules
|
||||
if(!module)
|
||||
return
|
||||
module.configure_edit(params["key"], params["value"])
|
||||
return TRUE
|
||||
@@ -0,0 +1,252 @@
|
||||
/obj/item/mod/module
|
||||
name = "MOD module"
|
||||
icon_state = "module"
|
||||
/// If it can be removed
|
||||
var/removable = TRUE
|
||||
/// If it's passive, togglable, usable or active
|
||||
var/module_type = MODULE_PASSIVE
|
||||
/// Is the module active
|
||||
var/active = FALSE
|
||||
/// How much space it takes up in the MOD
|
||||
var/complexity = 0
|
||||
/// Power use when idle
|
||||
var/idle_power_cost = DEFAULT_CELL_DRAIN * 0
|
||||
/// Power use when active
|
||||
var/active_power_cost = DEFAULT_CELL_DRAIN * 0
|
||||
/// Power use when used, we call it manually
|
||||
var/use_power_cost = DEFAULT_CELL_DRAIN * 0
|
||||
/// ID used by their TGUI
|
||||
var/tgui_id
|
||||
/// Linked MODsuit
|
||||
var/obj/item/mod/control/mod
|
||||
/// If we're an active module, what item are we?
|
||||
var/obj/item/device
|
||||
/// Overlay given to the user when the module is inactive
|
||||
var/overlay_state_inactive
|
||||
/// Overlay given to the user when the module is active
|
||||
var/overlay_state_active
|
||||
/// Overlay given to the user when the module is used, lasts until cooldown finishes
|
||||
var/overlay_state_use
|
||||
/// What modules are we incompatible with?
|
||||
var/list/incompatible_modules = list()
|
||||
/// Cooldown after use
|
||||
var/cooldown_time = 0
|
||||
/// The mouse button needed to use this module
|
||||
var/used_signal
|
||||
/// Timer for the cooldown
|
||||
COOLDOWN_DECLARE(cooldown_timer)
|
||||
|
||||
/obj/item/mod/module/Initialize(mapload)
|
||||
. = ..()
|
||||
if(module_type != MODULE_ACTIVE)
|
||||
return
|
||||
if(ispath(device))
|
||||
device = new device(src)
|
||||
ADD_TRAIT(device, TRAIT_NODROP, MOD_TRAIT)
|
||||
RegisterSignal(device, COMSIG_PARENT_PREQDELETED, .proc/on_device_deletion)
|
||||
RegisterSignal(src, COMSIG_ATOM_EXITED, .proc/on_exit)
|
||||
|
||||
/obj/item/mod/module/Destroy()
|
||||
mod?.uninstall(src)
|
||||
if(device)
|
||||
UnregisterSignal(device, COMSIG_PARENT_PREQDELETED)
|
||||
QDEL_NULL(device)
|
||||
return ..()
|
||||
|
||||
/obj/item/mod/module/examine(mob/user)
|
||||
. = ..()
|
||||
if(HAS_TRAIT(user, TRAIT_DIAGNOSTIC_HUD))
|
||||
. += span_notice("Complexity level: [complexity]")
|
||||
|
||||
/// Called from MODsuit's install() proc, so when the module is installed.
|
||||
/obj/item/mod/module/proc/on_install()
|
||||
return
|
||||
|
||||
/// Called from MODsuit's uninstall() proc, so when the module is uninstalled.
|
||||
/obj/item/mod/module/proc/on_uninstall()
|
||||
return
|
||||
|
||||
/// Called when the MODsuit is activated
|
||||
/obj/item/mod/module/proc/on_suit_activation()
|
||||
return
|
||||
|
||||
/// Called when the MODsuit is deactivated
|
||||
/obj/item/mod/module/proc/on_suit_deactivation()
|
||||
return
|
||||
|
||||
/// Called when the MODsuit is equipped
|
||||
/obj/item/mod/module/proc/on_equip()
|
||||
return
|
||||
|
||||
/// Called when the MODsuit is unequipped
|
||||
/obj/item/mod/module/proc/on_unequip()
|
||||
return
|
||||
|
||||
/// Called when the module is selected from the TGUI
|
||||
/obj/item/mod/module/proc/on_select()
|
||||
if(!mod.active || mod.activating || module_type == MODULE_PASSIVE)
|
||||
return
|
||||
if(module_type != MODULE_USABLE)
|
||||
if(active)
|
||||
on_deactivation()
|
||||
else
|
||||
on_activation()
|
||||
else
|
||||
on_use()
|
||||
SEND_SIGNAL(mod, COMSIG_MOD_MODULE_SELECTED)
|
||||
|
||||
/// Called when the module is activated
|
||||
/obj/item/mod/module/proc/on_activation()
|
||||
if(!COOLDOWN_FINISHED(src, cooldown_timer))
|
||||
balloon_alert(mod.wearer, "on cooldown!")
|
||||
return FALSE
|
||||
if(!mod.active || mod.activating || !mod.cell?.charge)
|
||||
balloon_alert(mod.wearer, "unpowered!")
|
||||
return FALSE
|
||||
if(module_type == MODULE_ACTIVE)
|
||||
if(mod.selected_module && !mod.selected_module.on_deactivation())
|
||||
return
|
||||
mod.selected_module = src
|
||||
if(device)
|
||||
if(mod.wearer.put_in_hands(device))
|
||||
balloon_alert(mod.wearer, "[device] extended")
|
||||
RegisterSignal(mod.wearer, COMSIG_ATOM_EXITED, .proc/on_exit)
|
||||
else
|
||||
balloon_alert(mod.wearer, "can't extend [device]!")
|
||||
return
|
||||
else
|
||||
var/used_button = mod.wearer.client?.prefs.read_preference(/datum/preference/choiced/mod_select) || MIDDLE_CLICK
|
||||
update_signal(used_button)
|
||||
balloon_alert(mod.wearer, "[src] activated, [used_button]-click to use")
|
||||
active = TRUE
|
||||
COOLDOWN_START(src, cooldown_timer, cooldown_time)
|
||||
mod.wearer.update_inv_back()
|
||||
return TRUE
|
||||
|
||||
/// Called when the module is deactivated
|
||||
/obj/item/mod/module/proc/on_deactivation()
|
||||
active = FALSE
|
||||
if(module_type == MODULE_ACTIVE)
|
||||
mod.selected_module = null
|
||||
if(device)
|
||||
mod.wearer.transferItemToLoc(device, src, TRUE)
|
||||
balloon_alert(mod.wearer, "[device] retracted")
|
||||
UnregisterSignal(mod.wearer, COMSIG_ATOM_EXITED)
|
||||
else
|
||||
balloon_alert(mod.wearer, "[src] deactivated")
|
||||
UnregisterSignal(mod.wearer, used_signal)
|
||||
used_signal = null
|
||||
mod.wearer.update_inv_back()
|
||||
return TRUE
|
||||
|
||||
/// Called when the module is used
|
||||
/obj/item/mod/module/proc/on_use()
|
||||
if(!COOLDOWN_FINISHED(src, cooldown_timer))
|
||||
return FALSE
|
||||
if(!check_power(use_power_cost))
|
||||
return FALSE
|
||||
COOLDOWN_START(src, cooldown_timer, cooldown_time)
|
||||
addtimer(CALLBACK(mod.wearer, /mob.proc/update_inv_back), cooldown_time)
|
||||
mod.wearer.update_inv_back()
|
||||
return TRUE
|
||||
|
||||
/// Called when an activated module without a device is used
|
||||
/obj/item/mod/module/proc/on_select_use(atom/target)
|
||||
mod.wearer.face_atom(target)
|
||||
if(!on_use())
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/// Called when an activated module without a device is active and the user alt/middle-clicks
|
||||
/obj/item/mod/module/proc/on_special_click(mob/source, atom/target)
|
||||
SIGNAL_HANDLER
|
||||
on_select_use(target)
|
||||
return COMSIG_MOB_CANCEL_CLICKON
|
||||
|
||||
/// Called on the MODsuit's process
|
||||
/obj/item/mod/module/proc/on_process(delta_time)
|
||||
if(active)
|
||||
if(!drain_power(active_power_cost * delta_time))
|
||||
on_deactivation()
|
||||
return FALSE
|
||||
on_active_process(delta_time)
|
||||
else
|
||||
drain_power(idle_power_cost * delta_time)
|
||||
return TRUE
|
||||
|
||||
/// Called on the MODsuit's process if it is an active module
|
||||
/obj/item/mod/module/proc/on_active_process(delta_time)
|
||||
return
|
||||
|
||||
/// Drains power from the suit cell
|
||||
/obj/item/mod/module/proc/drain_power(amount)
|
||||
if(!check_power(amount))
|
||||
return FALSE
|
||||
mod.cell.charge = max(0, mod.cell.charge - amount)
|
||||
return TRUE
|
||||
|
||||
/obj/item/mod/module/proc/check_power(amount)
|
||||
if(!mod.cell || (mod.cell.charge < amount))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/// Adds additional things to the MODsuit ui_data()
|
||||
/obj/item/mod/module/proc/add_ui_data()
|
||||
return list()
|
||||
|
||||
/// Creates a list of configuring options for this module
|
||||
/obj/item/mod/module/proc/get_configuration()
|
||||
return list()
|
||||
|
||||
/// Generates an element of the get_configuration list with a display name, type and value
|
||||
/obj/item/mod/module/proc/add_ui_configuration(display_name, type, value, list/values)
|
||||
return list("display_name" = display_name, "type" = type, "value" = value, "values" = values)
|
||||
|
||||
/// Receives configure edits from the TGUI and edits the vars
|
||||
/obj/item/mod/module/proc/configure_edit(key, value)
|
||||
return
|
||||
|
||||
/// Called when the device moves to a different place on active modules
|
||||
/obj/item/mod/module/proc/on_exit(datum/source, atom/movable/part, direction)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!active)
|
||||
return
|
||||
if(part.loc == src)
|
||||
return
|
||||
if(part.loc == mod.wearer)
|
||||
return
|
||||
if(part == device)
|
||||
on_deactivation()
|
||||
|
||||
/// Called when the device gets deleted on active modules
|
||||
/obj/item/mod/module/proc/on_device_deletion(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(source == device)
|
||||
device = null
|
||||
qdel(src)
|
||||
|
||||
/// Generates an icon to be used for the suit's worn overlays
|
||||
/obj/item/mod/module/proc/generate_worn_overlay(mutable_appearance/standing)
|
||||
. = list()
|
||||
var/used_overlay
|
||||
if(overlay_state_use && !COOLDOWN_FINISHED(src, cooldown_timer))
|
||||
used_overlay = overlay_state_use
|
||||
else if(overlay_state_active && active)
|
||||
used_overlay = overlay_state_active
|
||||
else if(overlay_state_inactive)
|
||||
used_overlay = overlay_state_inactive
|
||||
else
|
||||
return
|
||||
var/mutable_appearance/module_icon = mutable_appearance('icons/mob/mod.dmi', used_overlay, layer = standing.layer + 0.1)
|
||||
. += module_icon
|
||||
|
||||
/// Updates the signal used by active modules to be activated
|
||||
/obj/item/mod/module/proc/update_signal(value)
|
||||
switch(value)
|
||||
if(MIDDLE_CLICK)
|
||||
mod.selected_module.used_signal = COMSIG_MOB_MIDDLECLICKON
|
||||
if(ALT_CLICK)
|
||||
mod.selected_module.used_signal = COMSIG_MOB_ALTCLICKON
|
||||
RegisterSignal(mod.wearer, mod.selected_module.used_signal, /obj/item/mod/module.proc/on_special_click)
|
||||
@@ -0,0 +1,352 @@
|
||||
/obj/item/mod/module
|
||||
name = "MOD module"
|
||||
icon_state = "module"
|
||||
/// If it can be removed
|
||||
var/removable = TRUE
|
||||
/// If it's passive, togglable, usable or active
|
||||
var/module_type = MODULE_PASSIVE
|
||||
/// Is the module active
|
||||
var/active = FALSE
|
||||
/// How much space it takes up in the MOD
|
||||
var/complexity = 0
|
||||
/// Power use when idle
|
||||
var/idle_power_cost = DEFAULT_CELL_DRAIN * 0
|
||||
/// Power use when active
|
||||
var/active_power_cost = DEFAULT_CELL_DRAIN * 0
|
||||
/// Power use when used, we call it manually
|
||||
var/use_power_cost = DEFAULT_CELL_DRAIN * 0
|
||||
/// ID used by their TGUI
|
||||
var/tgui_id
|
||||
/// Linked MODsuit
|
||||
var/obj/item/mod/control/mod
|
||||
/// If we're an active module, what item are we?
|
||||
var/obj/item/device
|
||||
/// Overlay given to the user when the module is inactive
|
||||
var/overlay_state_inactive
|
||||
/// Overlay given to the user when the module is active
|
||||
var/overlay_state_active
|
||||
/// Overlay given to the user when the module is used, lasts until cooldown finishes
|
||||
var/overlay_state_use
|
||||
/// What modules are we incompatible with?
|
||||
var/list/incompatible_modules = list()
|
||||
/// Cooldown after use
|
||||
var/cooldown_time = 0
|
||||
/// The mouse button needed to use this module
|
||||
var/used_signal
|
||||
/// Timer for the cooldown
|
||||
COOLDOWN_DECLARE(cooldown_timer)
|
||||
|
||||
/obj/item/mod/module/Initialize(mapload)
|
||||
. = ..()
|
||||
if(module_type != MODULE_ACTIVE)
|
||||
return
|
||||
if(ispath(device))
|
||||
device = new device(src)
|
||||
ADD_TRAIT(device, TRAIT_NODROP, MOD_TRAIT)
|
||||
RegisterSignal(device, COMSIG_PARENT_PREQDELETED, .proc/on_device_deletion)
|
||||
RegisterSignal(src, COMSIG_ATOM_EXITED, .proc/on_exit)
|
||||
|
||||
/obj/item/mod/module/Destroy()
|
||||
mod?.uninstall(src)
|
||||
if(device)
|
||||
UnregisterSignal(device, COMSIG_PARENT_PREQDELETED)
|
||||
QDEL_NULL(device)
|
||||
return ..()
|
||||
|
||||
/obj/item/mod/module/examine(mob/user)
|
||||
. = ..()
|
||||
if(HAS_TRAIT(user, TRAIT_DIAGNOSTIC_HUD))
|
||||
. += span_notice("Complexity level: [complexity]")
|
||||
|
||||
/// Called from MODsuit's install() proc, so when the module is installed.
|
||||
/obj/item/mod/module/proc/on_install()
|
||||
return
|
||||
|
||||
/// Called from MODsuit's uninstall() proc, so when the module is uninstalled.
|
||||
/obj/item/mod/module/proc/on_uninstall()
|
||||
return
|
||||
|
||||
/// Called when the MODsuit is activated
|
||||
/obj/item/mod/module/proc/on_suit_activation()
|
||||
return
|
||||
|
||||
/// Called when the MODsuit is deactivated
|
||||
/obj/item/mod/module/proc/on_suit_deactivation()
|
||||
return
|
||||
|
||||
/// Called when the MODsuit is equipped
|
||||
/obj/item/mod/module/proc/on_equip()
|
||||
return
|
||||
|
||||
/// Called when the MODsuit is unequipped
|
||||
/obj/item/mod/module/proc/on_unequip()
|
||||
return
|
||||
|
||||
/// Called when the module is selected from the TGUI
|
||||
/obj/item/mod/module/proc/on_select()
|
||||
if(!mod.active || mod.activating || module_type == MODULE_PASSIVE)
|
||||
return
|
||||
if(module_type != MODULE_USABLE)
|
||||
if(active)
|
||||
on_deactivation()
|
||||
else
|
||||
on_activation()
|
||||
else
|
||||
on_use()
|
||||
SEND_SIGNAL(mod, COMSIG_MOD_MODULE_SELECTED)
|
||||
|
||||
/// Called when the module is activated
|
||||
/obj/item/mod/module/proc/on_activation()
|
||||
if(!COOLDOWN_FINISHED(src, cooldown_timer))
|
||||
balloon_alert(mod.wearer, "on cooldown!")
|
||||
return FALSE
|
||||
if(!mod.active || mod.activating || !mod.cell?.charge)
|
||||
balloon_alert(mod.wearer, "unpowered!")
|
||||
return FALSE
|
||||
if(module_type == MODULE_ACTIVE)
|
||||
if(mod.selected_module && !mod.selected_module.on_deactivation())
|
||||
return
|
||||
mod.selected_module = src
|
||||
if(device)
|
||||
if(mod.wearer.put_in_hands(device))
|
||||
balloon_alert(mod.wearer, "[device] extended")
|
||||
RegisterSignal(mod.wearer, COMSIG_ATOM_EXITED, .proc/on_exit)
|
||||
else
|
||||
balloon_alert(mod.wearer, "can't extend [device]!")
|
||||
return
|
||||
else
|
||||
var/used_button = mod.wearer.client?.prefs.read_preference(/datum/preference/choiced/mod_select) || MIDDLE_CLICK
|
||||
update_signal(used_button)
|
||||
balloon_alert(mod.wearer, "[src] activated, [used_button]-click to use")
|
||||
active = TRUE
|
||||
COOLDOWN_START(src, cooldown_timer, cooldown_time)
|
||||
mod.wearer.update_inv_back()
|
||||
return TRUE
|
||||
|
||||
/// Called when the module is deactivated
|
||||
/obj/item/mod/module/proc/on_deactivation()
|
||||
active = FALSE
|
||||
if(module_type == MODULE_ACTIVE)
|
||||
mod.selected_module = null
|
||||
if(device)
|
||||
mod.wearer.transferItemToLoc(device, src, TRUE)
|
||||
balloon_alert(mod.wearer, "[device] retracted")
|
||||
UnregisterSignal(mod.wearer, COMSIG_ATOM_EXITED)
|
||||
else
|
||||
balloon_alert(mod.wearer, "[src] deactivated")
|
||||
UnregisterSignal(mod.wearer, used_signal)
|
||||
used_signal = null
|
||||
mod.wearer.update_inv_back()
|
||||
return TRUE
|
||||
|
||||
/// Called when the module is used
|
||||
/obj/item/mod/module/proc/on_use()
|
||||
if(!COOLDOWN_FINISHED(src, cooldown_timer))
|
||||
return FALSE
|
||||
if(!check_power(use_power_cost))
|
||||
return FALSE
|
||||
COOLDOWN_START(src, cooldown_timer, cooldown_time)
|
||||
addtimer(CALLBACK(mod.wearer, /mob.proc/update_inv_back), cooldown_time)
|
||||
mod.wearer.update_inv_back()
|
||||
return TRUE
|
||||
|
||||
/// Called when an activated module without a device is used
|
||||
/obj/item/mod/module/proc/on_select_use(atom/target)
|
||||
mod.wearer.face_atom(target)
|
||||
if(!on_use())
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/// Called when an activated module without a device is active and the user alt/middle-clicks
|
||||
/obj/item/mod/module/proc/on_special_click(mob/source, atom/target)
|
||||
SIGNAL_HANDLER
|
||||
on_select_use(target)
|
||||
return COMSIG_MOB_CANCEL_CLICKON
|
||||
|
||||
/// Called on the MODsuit's process
|
||||
/obj/item/mod/module/proc/on_process(delta_time)
|
||||
if(active)
|
||||
if(!drain_power(active_power_cost * delta_time))
|
||||
on_deactivation()
|
||||
return FALSE
|
||||
on_active_process(delta_time)
|
||||
else
|
||||
drain_power(idle_power_cost * delta_time)
|
||||
return TRUE
|
||||
|
||||
/// Called on the MODsuit's process if it is an active module
|
||||
/obj/item/mod/module/proc/on_active_process(delta_time)
|
||||
return
|
||||
|
||||
/// Drains power from the suit cell
|
||||
/obj/item/mod/module/proc/drain_power(amount)
|
||||
if(!check_power(amount))
|
||||
return FALSE
|
||||
mod.cell.charge = max(0, mod.cell.charge - amount)
|
||||
return TRUE
|
||||
|
||||
/obj/item/mod/module/proc/check_power(amount)
|
||||
if(!mod.cell || (mod.cell.charge < amount))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/// Adds additional things to the MODsuit ui_data()
|
||||
/obj/item/mod/module/proc/add_ui_data()
|
||||
return list()
|
||||
|
||||
/// Creates a list of configuring options for this module
|
||||
/obj/item/mod/module/proc/get_configuration()
|
||||
return list()
|
||||
|
||||
/// Generates an element of the get_configuration list with a display name, type and value
|
||||
/obj/item/mod/module/proc/add_ui_configuration(display_name, type, value, list/values)
|
||||
return list("display_name" = display_name, "type" = type, "value" = value, "values" = values)
|
||||
|
||||
/// Receives configure edits from the TGUI and edits the vars
|
||||
/obj/item/mod/module/proc/configure_edit(key, value)
|
||||
return
|
||||
|
||||
/// Called when the device moves to a different place on active modules
|
||||
/obj/item/mod/module/proc/on_exit(datum/source, atom/movable/part, direction)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!active)
|
||||
return
|
||||
if(part.loc == src)
|
||||
return
|
||||
if(part.loc == mod.wearer)
|
||||
return
|
||||
if(part == device)
|
||||
on_deactivation()
|
||||
|
||||
/// Called when the device gets deleted on active modules
|
||||
/obj/item/mod/module/proc/on_device_deletion(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(source == device)
|
||||
device = null
|
||||
qdel(src)
|
||||
|
||||
/// Generates an icon to be used for the suit's worn overlays
|
||||
/obj/item/mod/module/proc/generate_worn_overlay(mutable_appearance/standing)
|
||||
. = list()
|
||||
var/used_overlay
|
||||
if(overlay_state_use && !COOLDOWN_FINISHED(src, cooldown_timer))
|
||||
used_overlay = overlay_state_use
|
||||
else if(overlay_state_active && active)
|
||||
used_overlay = overlay_state_active
|
||||
else if(overlay_state_inactive)
|
||||
used_overlay = overlay_state_inactive
|
||||
else
|
||||
return
|
||||
var/mutable_appearance/module_icon = mutable_appearance('icons/mob/mod.dmi', used_overlay, layer = standing.layer + 0.1)
|
||||
. += module_icon
|
||||
|
||||
/// Updates the signal used by active modules to be activated
|
||||
/obj/item/mod/module/proc/update_signal(value)
|
||||
switch(value)
|
||||
if(MIDDLE_CLICK)
|
||||
mod.selected_module.used_signal = COMSIG_MOB_MIDDLECLICKON
|
||||
if(ALT_CLICK)
|
||||
mod.selected_module.used_signal = COMSIG_MOB_ALTCLICKON
|
||||
RegisterSignal(mod.wearer, mod.selected_module.used_signal, /obj/item/mod/module.proc/on_special_click)
|
||||
icon_state = "magic_nullifier"
|
||||
removable = FALSE
|
||||
incompatible_modules = list(/obj/item/mod/module/anti_magic)
|
||||
|
||||
/obj/item/mod/module/anti_magic/on_suit_activation()
|
||||
ADD_TRAIT(mod.wearer, TRAIT_ANTIMAGIC, MOD_TRAIT)
|
||||
ADD_TRAIT(mod.wearer, TRAIT_HOLY, MOD_TRAIT)
|
||||
|
||||
/obj/item/mod/module/anti_magic/on_suit_deactivation()
|
||||
REMOVE_TRAIT(mod.wearer, TRAIT_ANTIMAGIC, MOD_TRAIT)
|
||||
REMOVE_TRAIT(mod.wearer, TRAIT_HOLY, MOD_TRAIT)
|
||||
|
||||
/obj/item/mod/module/anti_magic/wizard
|
||||
name = "MOD magic neutralizer module"
|
||||
desc = "The caster wielding this spell gains an invisible barrier around them, channeling arcane power through \
|
||||
specialized runes engraved onto the surface of the suit to generate anti-magic field. \
|
||||
The field will neutralize all magic that comes into contact with the user. \
|
||||
It will not protect the caster from social ridicule."
|
||||
icon_state = "magic_neutralizer"
|
||||
|
||||
/obj/item/mod/module/anti_magic/wizard/on_suit_activation()
|
||||
ADD_TRAIT(mod.wearer, TRAIT_ANTIMAGIC_NO_SELFBLOCK, MOD_TRAIT)
|
||||
|
||||
/obj/item/mod/module/anti_magic/wizard/on_suit_deactivation()
|
||||
REMOVE_TRAIT(mod.wearer, TRAIT_ANTIMAGIC_NO_SELFBLOCK, MOD_TRAIT)
|
||||
|
||||
/obj/item/mod/module/kinesis //TODO POST-MERGE MAKE NOT SUCK ASS, MAKE BALLER AS FUCK
|
||||
name = "MOD kinesis module"
|
||||
desc = "A modular plug-in to the forearm, this module was presumed lost for many years, \
|
||||
despite the suits it used to be mounted on still seeing some circulation. \
|
||||
This piece of technology allows the user to generate precise anti-gravity fields, \
|
||||
letting them move objects as small as a titanium rod to as large as industrial machinery. \
|
||||
Oddly enough, it doesn't seem to work on living creatures."
|
||||
icon_state = "kinesis"
|
||||
// module_type = MODULE_ACTIVE
|
||||
module_type = MODULE_TOGGLE
|
||||
// complexity = 3
|
||||
complexity = 0
|
||||
active_power_cost = DEFAULT_CELL_DRAIN*0.75
|
||||
// use_power_cost = DEFAULT_CELL_DRAIN*3
|
||||
removable = FALSE
|
||||
incompatible_modules = list(/obj/item/mod/module/kinesis)
|
||||
cooldown_time = 0.5 SECONDS
|
||||
var/has_tk = FALSE
|
||||
|
||||
/obj/item/mod/module/kinesis/on_activation()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(mod.wearer.dna.check_mutation(TK))
|
||||
has_tk = TRUE
|
||||
else
|
||||
mod.wearer.dna.add_mutation(TK)
|
||||
|
||||
/obj/item/mod/module/kinesis/on_deactivation()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(has_tk)
|
||||
has_tk = FALSE
|
||||
return
|
||||
mod.wearer.dna.remove_mutation(TK)
|
||||
|
||||
/obj/item/mod/module/insignia
|
||||
name = "MOD insignia module"
|
||||
desc = "Despite the existence of IFF systems, radio communique, and modern methods of deductive reasoning involving \
|
||||
the wearer's own eyes, colorful paint jobs remain a popular way for different factions in the galaxy to display who \
|
||||
they are. This system utilizes a series of tiny moving paint sprayers to both apply and remove different \
|
||||
color patterns to and from the suit."
|
||||
icon_state = "insignia"
|
||||
removable = FALSE
|
||||
incompatible_modules = list(/obj/item/mod/module/insignia)
|
||||
overlay_state_inactive = "insignia"
|
||||
|
||||
/obj/item/mod/module/insignia/generate_worn_overlay(mutable_appearance/standing)
|
||||
overlay_state_inactive = "[initial(overlay_state_inactive)]-[mod.skin]"
|
||||
. = ..()
|
||||
for(var/mutable_appearance/appearance as anything in .)
|
||||
appearance.color = color
|
||||
|
||||
/obj/item/mod/module/insignia/commander
|
||||
color = "#4980a5"
|
||||
|
||||
/obj/item/mod/module/insignia/security
|
||||
color = "#b30d1e"
|
||||
|
||||
/obj/item/mod/module/insignia/engineer
|
||||
color = "#e9c80e"
|
||||
|
||||
/obj/item/mod/module/insignia/medic
|
||||
color = "#ebebf5"
|
||||
|
||||
/obj/item/mod/module/insignia/janitor
|
||||
color = "#7925c7"
|
||||
|
||||
/obj/item/mod/module/insignia/clown
|
||||
color = "#ff1fc7"
|
||||
|
||||
/obj/item/mod/module/insignia/chaplain
|
||||
color = "#f0a00c"
|
||||
+13
-1
@@ -506,7 +506,6 @@
|
||||
#include "code\datums\achievements\misc_scores.dm"
|
||||
#include "code\datums\achievements\skill_achievements.dm"
|
||||
#include "code\datums\actions\beam_rifle.dm"
|
||||
#include "code\datums\ai\objects\mod.dm"
|
||||
#include "code\datums\announcers\_announcer.dm"
|
||||
#include "code\datums\announcers\default_announcer.dm"
|
||||
#include "code\datums\announcers\intern_announcer.dm"
|
||||
@@ -2023,6 +2022,7 @@
|
||||
#include "code\modules\client\preferences_savefile.dm"
|
||||
#include "code\modules\client\preferences_toggles.dm"
|
||||
#include "code\modules\client\preferences_vr.dm"
|
||||
#include "code\modules\client\preferences\mod_select.dm"
|
||||
#include "code\modules\client\verbs\aooc.dm"
|
||||
#include "code\modules\client\verbs\autobunker.dm"
|
||||
#include "code\modules\client\verbs\etips.dm"
|
||||
@@ -2958,6 +2958,18 @@
|
||||
#include "code\modules\mob\living\simple_animal\slime\slime.dm"
|
||||
#include "code\modules\mob\living\simple_animal\slime\slime_mobility.dm"
|
||||
#include "code\modules\mob\living\simple_animal\slime\subtypes.dm"
|
||||
#include "code\modules\mod\mod_actions.dm"
|
||||
#include "code\modules\mod\mod_activation.dm"
|
||||
#include "code\modules\mod\mod_ai.dm"
|
||||
#include "code\modules\mod\mod_clothes.dm"
|
||||
#include "code\modules\mod\mod_construction.dm"
|
||||
#include "code\modules\mod\mod_construction.dm"
|
||||
#include "code\modules\mod\mod_control.dm"
|
||||
#include "code\modules\mod\mod_theme.dm"
|
||||
#include "code\modules\mod\mod_types.dm"
|
||||
#include "code\modules\mod\mod_ui.dm"
|
||||
#include "code\modules\mod\modules\_module.dm"
|
||||
#include "code\modules\mod\modules\modules.dm"
|
||||
#include "code\modules\modular_computers\laptop_vendor.dm"
|
||||
#include "code\modules\modular_computers\computers\_modular_computer_shared.dm"
|
||||
#include "code\modules\modular_computers\computers\item\computer.dm"
|
||||
|
||||
Reference in New Issue
Block a user