beeg commit
This commit is contained in:
@@ -3,28 +3,41 @@
|
||||
icon_icon = 'icons/mob/actions/actions_mod.dmi'
|
||||
check_flags = AB_CHECK_CONSCIOUS
|
||||
var/obj/item/mod/control/mod
|
||||
/// Whether this action is intended for the AI. Stuff breaks a lot if this is done differently.
|
||||
var/ai_action = FALSE
|
||||
/// Whether this action is intended for the inserted pAI. Stuff breaks a lot if this is done differently.
|
||||
var/pai_action = FALSE
|
||||
|
||||
/datum/action/item_action/mod/New(Target)
|
||||
..()
|
||||
mod = Target
|
||||
|
||||
/datum/action/item_action/mod/Grant(mob/M)
|
||||
if(owner)
|
||||
Share(M)
|
||||
if(!istype(Target, /obj/item/mod/control))
|
||||
qdel(src)
|
||||
return
|
||||
..()
|
||||
if(ai_action)
|
||||
background_icon_state = ACTION_BUTTON_DEFAULT_BACKGROUND
|
||||
|
||||
/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/Grant(mob/user)
|
||||
mod = target
|
||||
if(ai_action && user != mod.ai)
|
||||
return
|
||||
else if(!ai_action && user == mod.ai)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/datum/action/item_action/mod/Remove(mob/user)
|
||||
if(ai_action && mod && user != mod.ai)
|
||||
return
|
||||
else if(!ai_action && mod && user == mod.ai)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/datum/action/item_action/mod/Trigger(trigger_flags)
|
||||
if(!IsAvailable())
|
||||
return FALSE
|
||||
if(mod.malfunctioning && prob(75))
|
||||
mod.balloon_alert(usr, "button malfunctions!")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/action/item_action/mod/deploy
|
||||
name = "Deploy MODsuit"
|
||||
@@ -37,6 +50,12 @@
|
||||
mod.choose_deploy(usr)
|
||||
return TRUE
|
||||
|
||||
/datum/action/item_action/mod/deploy/ai
|
||||
ai_action = TRUE
|
||||
|
||||
/datum/action/item_action/mod/deploy/pai
|
||||
pai_action = TRUE
|
||||
|
||||
/datum/action/item_action/mod/activate
|
||||
name = "Activate MODsuit"
|
||||
desc = "Activate/Deactivate the MODsuit."
|
||||
@@ -48,6 +67,12 @@
|
||||
mod.toggle_activate(usr)
|
||||
return TRUE
|
||||
|
||||
/datum/action/item_action/mod/activate/ai
|
||||
ai_action = TRUE
|
||||
|
||||
/datum/action/item_action/mod/activate/pai
|
||||
pai_action = TRUE
|
||||
|
||||
/datum/action/item_action/mod/module
|
||||
name = "Toggle Module"
|
||||
desc = "Toggle a MODsuit module."
|
||||
@@ -59,6 +84,12 @@
|
||||
mod.quick_module(usr)
|
||||
return TRUE
|
||||
|
||||
/datum/action/item_action/mod/module/ai
|
||||
ai_action = TRUE
|
||||
|
||||
/datum/action/item_action/mod/module/pai
|
||||
pai_action = TRUE
|
||||
|
||||
/datum/action/item_action/mod/panel
|
||||
name = "MODsuit Panel"
|
||||
desc = "Open the MODsuit's panel."
|
||||
@@ -69,3 +100,9 @@
|
||||
return FALSE
|
||||
mod.ui_interact(usr)
|
||||
return TRUE
|
||||
|
||||
/datum/action/item_action/mod/panel/ai
|
||||
ai_action = TRUE
|
||||
|
||||
/datum/action/item_action/mod/panel/pai
|
||||
pai_action = TRUE
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#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.
|
||||
@@ -72,7 +71,8 @@
|
||||
/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(wearer)
|
||||
wearer.transferItemToLoc(piece, src, force = TRUE)
|
||||
if(piece == gauntlets)
|
||||
gauntlets.show_overslot()
|
||||
if(piece == boots)
|
||||
@@ -117,28 +117,36 @@
|
||||
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)
|
||||
if(!module.active || module.allowed_inactive)
|
||||
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))
|
||||
if(do_after(wearer, MOD_ACTIVATION_STEP_TIME, target = wearer, required_mobility_flags = NONE))
|
||||
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))
|
||||
else
|
||||
return toggle_activate_fail()
|
||||
if(do_after(wearer, MOD_ACTIVATION_STEP_TIME, target = wearer, required_mobility_flags = NONE))
|
||||
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))
|
||||
else
|
||||
return toggle_activate_fail()
|
||||
if(do_after(wearer, MOD_ACTIVATION_STEP_TIME, target = wearer, required_mobility_flags = NONE))
|
||||
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))
|
||||
else
|
||||
return toggle_activate_fail()
|
||||
if(do_after(wearer, MOD_ACTIVATION_STEP_TIME, target = wearer, required_mobility_flags = NONE))
|
||||
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))
|
||||
else
|
||||
return toggle_activate_fail()
|
||||
if(do_after(wearer, MOD_ACTIVATION_STEP_TIME, target = wearer, required_mobility_flags = NONE))
|
||||
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>"))
|
||||
@@ -148,9 +156,20 @@
|
||||
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)
|
||||
else
|
||||
return toggle_activate_fail()
|
||||
activating = FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/mod/control/proc/toggle_activate_fail()
|
||||
seal_part(boots, seal = active)
|
||||
seal_part(gauntlets, seal = active)
|
||||
seal_part(chestplate,seal = active)
|
||||
seal_part(helmet, seal = active)
|
||||
to_chat(wearer, span_warning("[active ? "Shut down" : "Start up"] cancelled."))
|
||||
activating = FALSE
|
||||
return FALSE
|
||||
|
||||
///Seals or unseals the given part
|
||||
/obj/item/mod/control/proc/seal_part(obj/item/clothing/part, seal)
|
||||
if(seal)
|
||||
@@ -165,18 +184,16 @@
|
||||
part.clothing_flags &= ~part.visor_flags
|
||||
part.heat_protection = NONE
|
||||
part.cold_protection = NONE
|
||||
part.icon_state = "[skin]-[initial(part.icon_state)][seal ? "-sealed" : ""]"
|
||||
part.item_state = "[skin]-[initial(part.item_state)][seal ? "-sealed" : ""]"
|
||||
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
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
if(!do_after(user, 5 SECONDS, target = src))
|
||||
balloon_alert(user, "interrupted!")
|
||||
return
|
||||
if(!ai)
|
||||
return
|
||||
intAI = ai
|
||||
intAI.ai_restore_power()//So the AI initially has power.
|
||||
intAI.control_disabled = TRUE
|
||||
@@ -22,10 +24,7 @@
|
||||
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)
|
||||
action.Remove(intAI)
|
||||
intAI.controlled_equipment = null
|
||||
intAI.remote_control = null
|
||||
balloon_alert(intAI, "transferred to a card")
|
||||
@@ -37,6 +36,9 @@
|
||||
if(!intAI)
|
||||
balloon_alert(user, "no AI in card!")
|
||||
return
|
||||
if(ai)
|
||||
balloon_alert(user, "already has AI!")
|
||||
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)
|
||||
@@ -46,6 +48,8 @@
|
||||
if(!do_after(user, 5 SECONDS, target = src))
|
||||
balloon_alert(user, "interrupted!")
|
||||
return
|
||||
if(ai)
|
||||
return
|
||||
balloon_alert(user, "AI transferred to suit")
|
||||
ai_enter_mod(intAI)
|
||||
card.AI = null
|
||||
@@ -63,14 +67,95 @@
|
||||
for(var/datum/action/action as anything in actions)
|
||||
action.Grant(new_ai)
|
||||
|
||||
/**
|
||||
* Simple proc to insert the pAI into the MODsuit.
|
||||
*
|
||||
* user - The person trying to put the pAI into the MODsuit.
|
||||
* card - The pAI card we're slotting in the MODsuit.
|
||||
*/
|
||||
|
||||
/obj/item/mod/control/proc/insert_pai(mob/user, obj/item/paicard/card)
|
||||
if(mod_pai)
|
||||
balloon_alert(user, "pAI already installed!")
|
||||
return
|
||||
if(!card.pai || !card.pai.mind)
|
||||
balloon_alert(user, "pAI unresponsive!")
|
||||
return
|
||||
balloon_alert(user, "transferring to suit...")
|
||||
if(!do_after(user, 5 SECONDS, target = src))
|
||||
balloon_alert(user, "interrupted!")
|
||||
return FALSE
|
||||
if(!user.transferItemToLoc(card, src))
|
||||
return
|
||||
|
||||
mod_pai = card.pai
|
||||
balloon_alert(user, "pAI transferred to suit")
|
||||
balloon_alert(mod_pai, "transferred to a suit")
|
||||
mod_pai.canholo = FALSE
|
||||
mod_pai.remote_control = src
|
||||
for(var/datum/action/action as anything in actions)
|
||||
action.Grant(mod_pai)
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Simple proc to extract the pAI from the MODsuit. It's the proc to call if you want to take it out,
|
||||
* remove_pai() is there so atom_destruction() doesn't have any risk of sleeping.
|
||||
*
|
||||
* user - The person trying to take out the pAI from the MODsuit.
|
||||
* forced - Whether or not we skip the checks and just eject the pAI. Defaults to FALSE.
|
||||
* feedback - Whether to give feedback via balloon alerts or not. Defaults to TRUE.
|
||||
*/
|
||||
/obj/item/mod/control/proc/extract_pai(mob/user, forced = FALSE, feedback = TRUE)
|
||||
if(!mod_pai)
|
||||
if(user && feedback)
|
||||
balloon_alert(user, "no pAI to remove!")
|
||||
return
|
||||
if(!forced)
|
||||
if(!open)
|
||||
if(user && feedback)
|
||||
balloon_alert(user, "open the suit panel!")
|
||||
return FALSE
|
||||
if(!do_after(user, 5 SECONDS, target = src))
|
||||
if(user && feedback)
|
||||
balloon_alert(user, "interrupted!")
|
||||
return FALSE
|
||||
|
||||
remove_pai(feedback)
|
||||
|
||||
if(feedback && user)
|
||||
balloon_alert(user, "pAI removed from the suit")
|
||||
|
||||
/**
|
||||
* Simple proc that handles the safe removal of the pAI from a MOD control unit.
|
||||
*
|
||||
* Arguments:
|
||||
* * feedback - Whether or not we want to give balloon alert feedback to the mod_pai. Defaults to FALSE.
|
||||
*/
|
||||
/obj/item/mod/control/proc/remove_pai(feedback = FALSE)
|
||||
var/turf/drop_off = get_turf(src)
|
||||
if(drop_off) // In case there's no drop_off, the pAI will simply get deleted.
|
||||
mod_pai.card.forceMove(drop_off)
|
||||
|
||||
for(var/datum/action/action as anything in actions)
|
||||
if(action.owner == mod_pai)
|
||||
action.Remove(mod_pai)
|
||||
|
||||
if(feedback)
|
||||
balloon_alert(mod_pai, "removed from a suit")
|
||||
mod_pai.remote_control = null
|
||||
mod_pai.canholo = TRUE
|
||||
mod_pai = null
|
||||
|
||||
#define MOVE_DELAY 2
|
||||
#define WEARER_DELAY 1
|
||||
#define LONE_DELAY 5
|
||||
#define CELL_PER_STEP DEFAULT_CELL_DRAIN * 2.5
|
||||
#define CELL_PER_STEP (DEFAULT_CHARGE_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
|
||||
if(wearer && (wearer.pulledby?.grab_state || wearer.incapacitated() || wearer.stat))
|
||||
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)
|
||||
@@ -86,3 +171,8 @@
|
||||
#undef WEARER_DELAY
|
||||
#undef LONE_DELAY
|
||||
#undef CELL_PER_STEP
|
||||
|
||||
/obj/item/mod/control/ui_state(mob/user)
|
||||
if(user == mod_pai)
|
||||
return GLOB.contained_state
|
||||
return ..()
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/obj/item/clothing/head/helmet/space/mod
|
||||
name = "MOD helmet"
|
||||
desc = "A helmet for a MODsuit."
|
||||
icon = 'icons/obj/mod.dmi'
|
||||
icon = 'icons/obj/clothing/modsuit/mod_clothing.dmi'
|
||||
mob_overlay_icon = 'icons/mob/clothing/modsuit/mod_clothing.dmi'
|
||||
anthro_mob_worn_overlay = 'icons/mob/clothing/modsuit/mod_clothing.dmi'
|
||||
taur_mob_worn_overlay = 'icons/mob/clothing/modsuit/mod_clothing.dmi'
|
||||
icon_state = "helmet"
|
||||
worn_icon = 'icons/mob/mod.dmi'
|
||||
item_state = "helmet"
|
||||
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
|
||||
@@ -12,15 +15,16 @@
|
||||
min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT
|
||||
clothing_flags = THICKMATERIAL
|
||||
resistance_flags = NONE
|
||||
flash_protect = FLASH_PROTECTION_NONE
|
||||
clothing_flags = SNUG_FIT
|
||||
flash_protect = 0
|
||||
clothing_flags = NONE
|
||||
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
|
||||
visor_flags_cover = HEADCOVERSMOUTH|HEADCOVERSEYES
|
||||
var/alternate_layer = NECK_LAYER
|
||||
var/obj/item/mod/control/mod
|
||||
mutantrace_variation = STYLE_MUZZLE
|
||||
|
||||
/obj/item/clothing/head/helmet/space/mod/Destroy()
|
||||
if(!QDELETED(mod))
|
||||
@@ -32,9 +36,12 @@
|
||||
/obj/item/clothing/suit/armor/mod
|
||||
name = "MOD chestplate"
|
||||
desc = "A chestplate for a MODsuit."
|
||||
icon = 'icons/obj/mod.dmi'
|
||||
icon = 'icons/obj/clothing/modsuit/mod_clothing.dmi'
|
||||
mob_overlay_icon = 'icons/mob/clothing/modsuit/mod_clothing.dmi'
|
||||
anthro_mob_worn_overlay = 'icons/mob/clothing/modsuit/mod_clothing.dmi'
|
||||
taur_mob_worn_overlay = 'icons/mob/clothing/modsuit/mod_clothing.dmi'
|
||||
icon_state = "chestplate"
|
||||
worn_icon = 'icons/mob/mod.dmi'
|
||||
item_state = "chestplate"
|
||||
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
|
||||
@@ -48,6 +55,7 @@
|
||||
allowed = list(/obj/item/flashlight, /obj/item/tank/internals)
|
||||
resistance_flags = NONE
|
||||
var/obj/item/mod/control/mod
|
||||
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_SNEK_TAURIC|STYLE_PAW_TAURIC
|
||||
|
||||
/obj/item/clothing/suit/armor/mod/Destroy()
|
||||
if(!QDELETED(mod))
|
||||
@@ -59,9 +67,12 @@
|
||||
/obj/item/clothing/gloves/mod
|
||||
name = "MOD gauntlets"
|
||||
desc = "A pair of gauntlets for a MODsuit."
|
||||
icon = 'icons/obj/mod.dmi'
|
||||
icon = 'icons/obj/clothing/modsuit/mod_clothing.dmi'
|
||||
mob_overlay_icon = 'icons/mob/clothing/modsuit/mod_clothing.dmi'
|
||||
anthro_mob_worn_overlay = 'icons/mob/clothing/modsuit/mod_clothing.dmi'
|
||||
taur_mob_worn_overlay = 'icons/mob/clothing/modsuit/mod_clothing.dmi'
|
||||
icon_state = "gauntlets"
|
||||
worn_icon = 'icons/mob/mod.dmi'
|
||||
item_state = "gauntlets"
|
||||
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
|
||||
@@ -86,15 +97,18 @@
|
||||
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)
|
||||
mod.wearer.dropItemToGround(overslot, force = 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 = 'icons/obj/clothing/modsuit/mod_clothing.dmi'
|
||||
mob_overlay_icon = 'icons/mob/clothing/modsuit/mod_clothing.dmi'
|
||||
anthro_mob_worn_overlay = 'icons/mob/clothing/modsuit/mod_clothing.dmi'
|
||||
taur_mob_worn_overlay = 'icons/mob/clothing/modsuit/mod_clothing.dmi'
|
||||
icon_state = "boots"
|
||||
worn_icon = 'icons/mob/mod.dmi'
|
||||
item_state = "boots"
|
||||
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
|
||||
@@ -103,7 +117,7 @@
|
||||
min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT
|
||||
clothing_flags = THICKMATERIAL
|
||||
resistance_flags = NONE
|
||||
item_flags = IGNORE_DIGITIGRADE
|
||||
item_flags = NONE
|
||||
var/obj/item/mod/control/mod
|
||||
var/obj/item/clothing/overslot
|
||||
|
||||
@@ -119,5 +133,5 @@
|
||||
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)
|
||||
mod.wearer.dropItemToGround(overslot, force = TRUE)
|
||||
overslot = null
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/obj/item/mod/construction
|
||||
desc = "A part used in MOD construction."
|
||||
inhand_icon_state = "rack_parts"
|
||||
icon = 'icons/obj/clothing/modsuit/mod_construction.dmi'
|
||||
item_state = "rack_parts"
|
||||
|
||||
/obj/item/mod/construction/helmet
|
||||
name = "MOD helmet"
|
||||
@@ -20,7 +21,7 @@
|
||||
|
||||
/obj/item/mod/construction/core
|
||||
name = "MOD core"
|
||||
icon_state = "mod-core"
|
||||
icon_state = "mod-core-standard"
|
||||
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\
|
||||
@@ -29,7 +30,7 @@
|
||||
|
||||
/obj/item/mod/construction/broken_core
|
||||
name = "broken MOD core"
|
||||
icon_state = "mod-core-broken"
|
||||
icon_state = "mod-core"
|
||||
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)
|
||||
@@ -46,7 +47,7 @@
|
||||
/obj/item/mod/construction/armor
|
||||
name = "MOD armor plates"
|
||||
desc = "Armor plates used to finish a MOD."
|
||||
icon_state = "standard-armor"
|
||||
icon_state = "standard-plating"
|
||||
var/datum/mod_theme/theme = /datum/mod_theme
|
||||
|
||||
/obj/item/mod/construction/armor/Initialize(mapload)
|
||||
@@ -54,7 +55,7 @@
|
||||
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"
|
||||
icon_state = "[used_theme.default_skin]-plating"
|
||||
|
||||
/obj/item/mod/construction/armor/engineering
|
||||
theme = /datum/mod_theme/engineering
|
||||
@@ -77,7 +78,7 @@
|
||||
/obj/item/mod/paint
|
||||
name = "MOD paint kit"
|
||||
desc = "This kit will repaint your MODsuit to something unique."
|
||||
icon = 'icons/obj/mod.dmi'
|
||||
icon = 'icons/obj/clothing/modsuit/mod_construction.dmi'
|
||||
icon_state = "paintkit"
|
||||
|
||||
#define START_STEP "start"
|
||||
|
||||
@@ -2,15 +2,18 @@
|
||||
/obj/item/mod
|
||||
name = "Base MOD"
|
||||
desc = "You should not see this, yell at a coder!"
|
||||
icon = 'icons/obj/mod.dmi'
|
||||
icon = 'icons/obj/clothing/modsuit/mod_clothing.dmi'
|
||||
mob_overlay_icon = 'icons/mob/clothing/modsuit/mod_clothing.dmi'
|
||||
anthro_mob_worn_overlay = 'icons/mob/clothing/modsuit/mod_clothing.dmi'
|
||||
taur_mob_worn_overlay = 'icons/mob/clothing/modsuit/mod_clothing.dmi'
|
||||
icon_state = "standard-control"
|
||||
worn_icon = 'icons/mob/mod.dmi'
|
||||
item_state = "standard-control"
|
||||
|
||||
/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"
|
||||
item_state = "control"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
slot_flags = ITEM_SLOT_BACK
|
||||
strip_delay = 10 SECONDS
|
||||
@@ -48,7 +51,7 @@
|
||||
/// How much module complexity this MOD is carrying.
|
||||
var/complexity = 0
|
||||
/// Power usage of the MOD.
|
||||
var/cell_drain = DEFAULT_CELL_DRAIN
|
||||
var/cell_drain = DEFAULT_CHARGE_DRAIN
|
||||
/// Slowdown of the MOD when not active.
|
||||
var/slowdown_inactive = 2
|
||||
/// Slowdown of the MOD when active.
|
||||
@@ -73,6 +76,8 @@
|
||||
var/obj/item/mod/module/selected_module
|
||||
/// AI mob inhabiting the MOD.
|
||||
var/mob/living/silicon/ai/ai
|
||||
/// pAI mob inhabiting the MOD.
|
||||
var/mob/living/silicon/pai/mod_pai
|
||||
/// Delay between moves as AI.
|
||||
var/movedelay = 0
|
||||
/// Cooldown for AI moves.
|
||||
@@ -123,6 +128,7 @@
|
||||
piece.permeability_coefficient = theme.permeability_coefficient
|
||||
piece.siemens_coefficient = theme.siemens_coefficient
|
||||
piece.icon_state = "[skin]-[initial(piece.icon_state)]"
|
||||
piece.item_state = "[skin]-[initial(piece.item_state)]"
|
||||
update_flags()
|
||||
for(var/obj/item/mod/module/module as anything in initial_modules)
|
||||
module = new module(src)
|
||||
@@ -206,6 +212,7 @@
|
||||
balloon_alert(carbon_user, "retract parts first!")
|
||||
playsound(src, 'sound/machines/scanbuzz.ogg', 25, FALSE, SILENCED_SOUND_EXTRARANGE)
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/item/mod/control/MouseDrop(atom/over_object)
|
||||
if(src != wearer?.back || !istype(over_object, /atom/movable/screen/inventory/hand))
|
||||
@@ -241,10 +248,22 @@
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/item/mod/control/AltClick(mob/user)
|
||||
if(seconds_electrified && cell?.charge)
|
||||
if(shock(user))
|
||||
return
|
||||
if(!open)
|
||||
for(var/obj/item/mod/module/storage/S in modules)
|
||||
if(S.stored)
|
||||
playsound(user, "rustle", 50, 1, -5)
|
||||
SEND_SIGNAL(S.stored, COMSIG_TRY_STORAGE_SHOW, wearer, TRUE)
|
||||
return
|
||||
. = ..()
|
||||
|
||||
/obj/item/mod/control/screwdriver_act(mob/living/user, obj/item/screwdriver)
|
||||
if(..())
|
||||
return TRUE
|
||||
if(active || activating || ai_controller)
|
||||
if(active || activating)
|
||||
balloon_alert(user, "deactivate suit first!")
|
||||
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
|
||||
return FALSE
|
||||
@@ -330,12 +349,6 @@
|
||||
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"]")
|
||||
@@ -363,12 +376,12 @@
|
||||
conceal(null, part)
|
||||
return ..()
|
||||
|
||||
/obj/item/mod/control/worn_overlays(mutable_appearance/standing, isinhands = FALSE, icon_file)
|
||||
/obj/item/mod/control/worn_overlays(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)
|
||||
var/list/module_icons = module.generate_worn_overlay()
|
||||
if(!length(module_icons))
|
||||
continue
|
||||
. += module_icons
|
||||
@@ -394,8 +407,8 @@
|
||||
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]
|
||||
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)
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
/// 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
|
||||
var/cell_drain = DEFAULT_CHARGE_DRAIN
|
||||
/// Slowdown of the MOD when not active.
|
||||
var/slowdown_inactive = 1.25
|
||||
/// Slowdown of the MOD when active.
|
||||
@@ -44,11 +44,11 @@
|
||||
"standard" = list(
|
||||
HELMET_LAYER = NECK_LAYER,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT,
|
||||
UNSEALED_CLOTHING = NONE,
|
||||
SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
@@ -67,10 +67,10 @@
|
||||
"civilian" = list(
|
||||
HELMET_LAYER = null,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT|THICKMATERIAL,
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
UNSEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
UNSEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
@@ -102,11 +102,11 @@
|
||||
"engineering" = list(
|
||||
HELMET_LAYER = NECK_LAYER,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT,
|
||||
UNSEALED_CLOTHING = NONE,
|
||||
SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
@@ -137,12 +137,12 @@
|
||||
"atmospheric" = list(
|
||||
HELMET_LAYER = NECK_LAYER,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT,
|
||||
UNSEALED_CLOTHING = NONE,
|
||||
SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDESNOUT,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR,
|
||||
UNSEALED_COVER = HEADCOVERSMOUTH,
|
||||
SEALED_COVER = HEADCOVERSEYES|PEPPERPROOF,
|
||||
SEALED_COVER = HEADCOVERSEYES,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
@@ -175,11 +175,11 @@
|
||||
"advanced" = list(
|
||||
HELMET_LAYER = NECK_LAYER,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT,
|
||||
UNSEALED_CLOTHING = NONE,
|
||||
SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
@@ -204,17 +204,17 @@
|
||||
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
|
||||
cell_drain = DEFAULT_CHARGE_DRAIN * 2
|
||||
complexity_max = DEFAULT_MAX_COMPLEXITY + 5
|
||||
skins = list(
|
||||
"mining" = list(
|
||||
HELMET_LAYER = null,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT|THICKMATERIAL,
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEEARS|HIDEHAIR|HIDESNOUT,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEYES|HIDEFACE,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
@@ -237,18 +237,18 @@
|
||||
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
|
||||
cell_drain = DEFAULT_CHARGE_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,
|
||||
UNSEALED_CLOTHING = NONE,
|
||||
SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
@@ -267,11 +267,11 @@
|
||||
"corpsman" = list(
|
||||
HELMET_LAYER = NECK_LAYER,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT,
|
||||
UNSEALED_CLOTHING = NONE,
|
||||
SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
@@ -296,7 +296,7 @@
|
||||
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
|
||||
cell_drain = DEFAULT_CHARGE_DRAIN * 1.5
|
||||
slowdown_inactive = 0.75
|
||||
slowdown_active = 0.25
|
||||
inbuilt_modules = list(/obj/item/mod/module/quick_carry/advanced)
|
||||
@@ -304,11 +304,11 @@
|
||||
"rescue" = list(
|
||||
HELMET_LAYER = NECK_LAYER,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT,
|
||||
UNSEALED_CLOTHING = NONE,
|
||||
SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
@@ -341,10 +341,10 @@
|
||||
"research" = list(
|
||||
HELMET_LAYER = null,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT|THICKMATERIAL,
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
UNSEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
UNSEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
@@ -375,12 +375,12 @@
|
||||
"security" = list(
|
||||
HELMET_LAYER = null,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT|THICKMATERIAL,
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEEARS|HIDEHAIR|HIDESNOUT,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEYES|HIDEFACE,
|
||||
UNSEALED_COVER = HEADCOVERSMOUTH,
|
||||
SEALED_COVER = HEADCOVERSEYES|PEPPERPROOF,
|
||||
SEALED_COVER = HEADCOVERSEYES,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
@@ -413,10 +413,10 @@
|
||||
"safeguard" = list(
|
||||
HELMET_LAYER = null,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT|THICKMATERIAL,
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
UNSEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
UNSEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
@@ -449,11 +449,11 @@
|
||||
"magnate" = list(
|
||||
HELMET_LAYER = NECK_LAYER,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT,
|
||||
UNSEALED_CLOTHING = NONE,
|
||||
SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
@@ -476,18 +476,18 @@
|
||||
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
|
||||
cell_drain = DEFAULT_CHARGE_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,
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEEARS|HIDEHAIR,
|
||||
SEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEMASK|HIDEEYES|HIDEFACE|HIDESNOUT,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
@@ -515,16 +515,16 @@
|
||||
slowdown_inactive = 1
|
||||
slowdown_active = 0.5
|
||||
ui_theme = "syndicate"
|
||||
inbuilt_modules = list(/obj/item/mod/module/armor_booster)
|
||||
inbuilt_modules = list()
|
||||
skins = list(
|
||||
"syndicate" = list(
|
||||
HELMET_LAYER = NECK_LAYER,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT,
|
||||
UNSEALED_CLOTHING = NONE,
|
||||
SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
@@ -553,16 +553,16 @@
|
||||
slowdown_inactive = 0.75
|
||||
slowdown_active = 0.25
|
||||
ui_theme = "syndicate"
|
||||
inbuilt_modules = list(/obj/item/mod/module/armor_booster/elite)
|
||||
inbuilt_modules = list()
|
||||
skins = list(
|
||||
"elite" = list(
|
||||
HELMET_LAYER = null,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT,
|
||||
UNSEALED_CLOTHING = NONE,
|
||||
SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
@@ -597,10 +597,10 @@
|
||||
"enchanted" = list(
|
||||
HELMET_LAYER = null,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT|THICKMATERIAL,
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
UNSEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
UNSEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
@@ -633,10 +633,10 @@
|
||||
"prototype" = list(
|
||||
HELMET_LAYER = null,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT|THICKMATERIAL,
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
UNSEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
UNSEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
@@ -668,11 +668,11 @@
|
||||
"responsory" = list(
|
||||
HELMET_LAYER = NECK_LAYER,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT,
|
||||
UNSEALED_CLOTHING = NONE,
|
||||
SEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
@@ -691,10 +691,10 @@
|
||||
"inquisitory" = list(
|
||||
HELMET_LAYER = null,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT|THICKMATERIAL,
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT,
|
||||
UNSEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
UNSEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
@@ -725,11 +725,11 @@
|
||||
"apocryphal" = list(
|
||||
HELMET_LAYER = null,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT|THICKMATERIAL,
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEEARS|HIDEHAIR,
|
||||
SEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEMASK|HIDEEYES|HIDEFACE|HIDESNOUT,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
@@ -761,11 +761,11 @@
|
||||
"corporate" = list(
|
||||
HELMET_LAYER = null,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT|THICKMATERIAL,
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEEARS|HIDEHAIR|HIDESNOUT,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEYES|HIDEFACE,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
SEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
@@ -797,12 +797,12 @@
|
||||
"debug" = list(
|
||||
HELMET_LAYER = null,
|
||||
HELMET_FLAGS = list(
|
||||
UNSEALED_CLOTHING = SNUG_FIT|THICKMATERIAL,
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
SEALED_CLOTHING = STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEEARS|HIDEHAIR|HIDESNOUT,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE,
|
||||
UNSEALED_COVER = HEADCOVERSMOUTH,
|
||||
SEALED_COVER = HEADCOVERSEYES|PEPPERPROOF,
|
||||
SEALED_COVER = HEADCOVERSEYES,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL,
|
||||
@@ -828,20 +828,20 @@
|
||||
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
|
||||
cell_drain = DEFAULT_CHARGE_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_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE,
|
||||
UNSEALED_INVISIBILITY = HIDEFACIALHAIR|HIDEEARS|HIDEHAIR|HIDESNOUT,
|
||||
SEALED_INVISIBILITY = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE,
|
||||
UNSEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF,
|
||||
UNSEALED_COVER = HEADCOVERSMOUTH|HEADCOVERSEYES,
|
||||
),
|
||||
CHESTPLATE_FLAGS = list(
|
||||
UNSEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE|BLOCKS_SHOVE_KNOCKDOWN,
|
||||
UNSEALED_CLOTHING = THICKMATERIAL|STOPSPRESSUREDAMAGE,
|
||||
SEALED_INVISIBILITY = HIDEJUMPSUIT,
|
||||
),
|
||||
GAUNTLETS_FLAGS = list(
|
||||
|
||||
@@ -20,12 +20,12 @@
|
||||
/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)
|
||||
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/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)
|
||||
initial_modules = list(/obj/item/mod/module/storage, /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
|
||||
@@ -34,12 +34,12 @@
|
||||
/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)
|
||||
initial_modules = list(/obj/item/mod/module/storage, /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)
|
||||
initial_modules = list(/obj/item/mod/module/storage, /obj/item/mod/module/welding, /obj/item/mod/module/flashlight, /obj/item/mod/module/t_ray)
|
||||
|
||||
/obj/item/mod/control/pre_equipped/security
|
||||
theme = /datum/mod_theme/security
|
||||
@@ -48,42 +48,37 @@
|
||||
/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)
|
||||
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/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)
|
||||
initial_modules = list(/obj/item/mod/module/storage, /obj/item/mod/module/welding, /obj/item/mod/module/holster)
|
||||
|
||||
/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)
|
||||
initial_modules = list(/obj/item/mod/module/storage, /obj/item/mod/module/welding, /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)
|
||||
initial_modules = list(/obj/item/mod/module/storage, /obj/item/mod/module/welding, /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)
|
||||
initial_modules = list(/obj/item/mod/module/storage, /obj/item/mod/module/welding, /obj/item/mod/module/emp_shield, /obj/item/mod/module/visor/thermal, /obj/item/mod/module/flashlight, /obj/item/mod/module/holster)
|
||||
|
||||
/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)
|
||||
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/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)
|
||||
initial_modules = list(/obj/item/mod/module/storage, /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)
|
||||
@@ -112,7 +107,7 @@
|
||||
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)
|
||||
initial_modules = list(/obj/item/mod/module/storage, /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
|
||||
@@ -130,22 +125,22 @@
|
||||
/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)
|
||||
initial_modules = list(/obj/item/mod/module/storage, /obj/item/mod/module/welding, /obj/item/mod/module/emp_shield, /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)
|
||||
initial_modules = list(/obj/item/mod/module/storage, /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
|
||||
initial_modules = list(/obj/item/mod/module/storage, /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/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)
|
||||
initial_modules = list(/obj/item/mod/module/storage, /obj/item/mod/module/welding, /obj/item/mod/module/quick_carry/advanced, /obj/item/mod/module/magboot/advanced)
|
||||
|
||||
//these exist for the prefs menu
|
||||
/obj/item/mod/control/pre_equipped/syndicate_empty
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(!allowed(usr) && locked)
|
||||
if(locked && !allowed(usr))
|
||||
balloon_alert(usr, "insufficient access!")
|
||||
playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE)
|
||||
return
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/obj/item/mod/module
|
||||
name = "MOD module"
|
||||
icon = 'icons/obj/clothing/modsuit/mod_modules.dmi'
|
||||
icon_state = "module"
|
||||
/// If it can be removed
|
||||
var/removable = TRUE
|
||||
@@ -10,11 +11,11 @@
|
||||
/// How much space it takes up in the MOD
|
||||
var/complexity = 0
|
||||
/// Power use when idle
|
||||
var/idle_power_cost = DEFAULT_CELL_DRAIN * 0
|
||||
var/idle_power_cost = DEFAULT_CHARGE_DRAIN * 0
|
||||
/// Power use when active
|
||||
var/active_power_cost = DEFAULT_CELL_DRAIN * 0
|
||||
var/active_power_cost = DEFAULT_CHARGE_DRAIN * 0
|
||||
/// Power use when used, we call it manually
|
||||
var/use_power_cost = DEFAULT_CELL_DRAIN * 0
|
||||
var/use_power_cost = DEFAULT_CHARGE_DRAIN * 0
|
||||
/// ID used by their TGUI
|
||||
var/tgui_id
|
||||
/// Linked MODsuit
|
||||
@@ -27,12 +28,20 @@
|
||||
var/overlay_state_active
|
||||
/// Overlay given to the user when the module is used, lasts until cooldown finishes
|
||||
var/overlay_state_use
|
||||
/// Icon file for the overlay.
|
||||
var/overlay_icon_file = 'icons/mob/clothing/modsuit/mod_modules.dmi'
|
||||
/// Does the overlay use the control unit's colors?
|
||||
var/use_mod_colors = FALSE
|
||||
/// 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
|
||||
/// If we're allowed to use this module while phased out.
|
||||
var/allowed_in_phaseout = FALSE
|
||||
/// If we're allowed to use this module while the suit is disabled.
|
||||
var/allowed_inactive = FALSE
|
||||
/// Timer for the cooldown
|
||||
COOLDOWN_DECLARE(cooldown_timer)
|
||||
|
||||
@@ -55,7 +64,7 @@
|
||||
|
||||
/obj/item/mod/module/examine(mob/user)
|
||||
. = ..()
|
||||
if(HAS_TRAIT(user, TRAIT_DIAGNOSTIC_HUD))
|
||||
if(user.hud_list[DIAG_HUD] && user.client.images & user.hud_list[DIAG_HUD])
|
||||
. += span_notice("Complexity level: [complexity]")
|
||||
|
||||
/// Called from MODsuit's install() proc, so when the module is installed.
|
||||
@@ -84,7 +93,9 @@
|
||||
|
||||
/// 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)
|
||||
if(((!mod.active || mod.activating) && !allowed_inactive) || module_type == MODULE_PASSIVE)
|
||||
if(mod.wearer)
|
||||
balloon_alert(mod.wearer, "not active!")
|
||||
return
|
||||
if(module_type != MODULE_USABLE)
|
||||
if(active)
|
||||
@@ -93,7 +104,7 @@
|
||||
on_activation()
|
||||
else
|
||||
on_use()
|
||||
SEND_SIGNAL(mod, COMSIG_MOD_MODULE_SELECTED)
|
||||
SEND_SIGNAL(mod, COMSIG_MOD_MODULE_SELECTED, src)
|
||||
|
||||
/// Called when the module is activated
|
||||
/obj/item/mod/module/proc/on_activation()
|
||||
@@ -103,6 +114,10 @@
|
||||
if(!mod.active || mod.activating || !mod.cell?.charge)
|
||||
balloon_alert(mod.wearer, "unpowered!")
|
||||
return FALSE
|
||||
if(!allowed_in_phaseout && istype(mod.wearer.loc, /obj/effect/dummy/phased_mob))
|
||||
//specifically a to_chat because the user is phased out.
|
||||
to_chat(mod.wearer, span_warning("You cannot activate this right now."))
|
||||
return FALSE
|
||||
if(module_type == MODULE_ACTIVE)
|
||||
if(mod.selected_module && !mod.selected_module.on_deactivation())
|
||||
return
|
||||
@@ -115,9 +130,8 @@
|
||||
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")
|
||||
update_signal()
|
||||
balloon_alert(mod.wearer, "[src] activated, alt-click to use")
|
||||
active = TRUE
|
||||
COOLDOWN_START(src, cooldown_timer, cooldown_time)
|
||||
mod.wearer.update_inv_back()
|
||||
@@ -145,6 +159,10 @@
|
||||
return FALSE
|
||||
if(!check_power(use_power_cost))
|
||||
return FALSE
|
||||
if(!allowed_in_phaseout && istype(mod.wearer.loc, /obj/effect/dummy/phased_mob))
|
||||
//specifically a to_chat because the user is phased out.
|
||||
to_chat(mod.wearer, span_warning("You cannot activate this right now."))
|
||||
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()
|
||||
@@ -228,8 +246,10 @@
|
||||
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)
|
||||
/obj/item/mod/module/proc/generate_worn_overlay()
|
||||
. = list()
|
||||
if(!mod.active)
|
||||
return
|
||||
var/used_overlay
|
||||
if(overlay_state_use && !COOLDOWN_FINISHED(src, cooldown_timer))
|
||||
used_overlay = overlay_state_use
|
||||
@@ -239,14 +259,98 @@
|
||||
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)
|
||||
var/mutable_appearance/module_icon = mutable_appearance(overlay_icon_file, used_overlay)
|
||||
if(!use_mod_colors)
|
||||
module_icon.appearance_flags |= RESET_COLOR
|
||||
. += 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
|
||||
/obj/item/mod/module/proc/update_signal()
|
||||
mod.selected_module.used_signal = COMSIG_MOB_ALTCLICKON
|
||||
RegisterSignal(mod.wearer, mod.selected_module.used_signal, /obj/item/mod/module.proc/on_special_click)
|
||||
|
||||
/obj/item/mod/module/anomaly_locked
|
||||
name = "MOD anomaly locked module"
|
||||
desc = "A form of a module, locked behind an anomalous core to function."
|
||||
incompatible_modules = list(/obj/item/mod/module/anomaly_locked)
|
||||
/// The core item the module runs off.
|
||||
var/obj/item/assembly/signaler/anomaly/core
|
||||
/// Accepted types of anomaly cores.
|
||||
var/list/accepted_anomalies = list(/obj/item/assembly/signaler/anomaly)
|
||||
/// If this one starts with a core in.
|
||||
var/prebuilt = FALSE
|
||||
|
||||
/obj/item/mod/module/anomaly_locked/Initialize(mapload)
|
||||
. = ..()
|
||||
if(!prebuilt || !length(accepted_anomalies))
|
||||
return
|
||||
var/core_path = pick(accepted_anomalies)
|
||||
core = new core_path(src)
|
||||
update_icon_state()
|
||||
|
||||
/obj/item/mod/module/anomaly_locked/Destroy()
|
||||
QDEL_NULL(core)
|
||||
return ..()
|
||||
|
||||
/obj/item/mod/module/anomaly_locked/examine(mob/user)
|
||||
. = ..()
|
||||
if(!length(accepted_anomalies))
|
||||
return
|
||||
if(core)
|
||||
. += span_notice("There is a [core.name] installed in it. You could remove it with a <b>screwdriver</b>...")
|
||||
else
|
||||
var/list/core_list = list()
|
||||
for(var/path in accepted_anomalies)
|
||||
var/atom/core_path = path
|
||||
core_list += initial(core_path.name)
|
||||
. += span_notice("You need to insert \a [english_list(core_list, and_text = " or ")] for this module to function.")
|
||||
|
||||
/obj/item/mod/module/anomaly_locked/on_select()
|
||||
if(!core)
|
||||
balloon_alert(mod.wearer, "no core!")
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/item/mod/module/anomaly_locked/on_process(delta_time)
|
||||
. = ..()
|
||||
if(!core)
|
||||
return FALSE
|
||||
|
||||
/obj/item/mod/module/anomaly_locked/on_active_process(delta_time)
|
||||
if(!core)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/mod/module/anomaly_locked/attackby(obj/item/item, mob/living/user, params)
|
||||
if(item.type in accepted_anomalies)
|
||||
if(core)
|
||||
balloon_alert(user, "core already in!")
|
||||
return
|
||||
if(!user.transferItemToLoc(item, src))
|
||||
return
|
||||
core = item
|
||||
balloon_alert(user, "core installed")
|
||||
playsound(src, 'sound/machines/click.ogg', 30, TRUE)
|
||||
update_icon_state()
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/mod/module/anomaly_locked/screwdriver_act(mob/living/user, obj/item/tool)
|
||||
. = ..()
|
||||
if(!core)
|
||||
balloon_alert(user, "no core!")
|
||||
return
|
||||
balloon_alert(user, "removing core...")
|
||||
if(!do_after(user, 3 SECONDS, target = src))
|
||||
balloon_alert(user, "interrupted!")
|
||||
return
|
||||
balloon_alert(user, "core removed")
|
||||
core.forceMove(drop_location())
|
||||
if(Adjacent(user) && !issilicon(user))
|
||||
user.put_in_hands(core)
|
||||
core = null
|
||||
update_icon_state()
|
||||
|
||||
/obj/item/mod/module/anomaly_locked/update_icon_state()
|
||||
icon_state = initial(icon_state) + (core ? "-core" : "")
|
||||
return ..()
|
||||
|
||||
@@ -1,259 +1,3 @@
|
||||
/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)
|
||||
@@ -288,8 +32,8 @@
|
||||
module_type = MODULE_TOGGLE
|
||||
// complexity = 3
|
||||
complexity = 0
|
||||
active_power_cost = DEFAULT_CELL_DRAIN*0.75
|
||||
// use_power_cost = DEFAULT_CELL_DRAIN*3
|
||||
active_power_cost = DEFAULT_CHARGE_DRAIN*0.75
|
||||
// use_power_cost = DEFAULT_CHARGE_DRAIN*3
|
||||
removable = FALSE
|
||||
incompatible_modules = list(/obj/item/mod/module/kinesis)
|
||||
cooldown_time = 0.5 SECONDS
|
||||
@@ -324,7 +68,7 @@
|
||||
incompatible_modules = list(/obj/item/mod/module/insignia)
|
||||
overlay_state_inactive = "insignia"
|
||||
|
||||
/obj/item/mod/module/insignia/generate_worn_overlay(mutable_appearance/standing)
|
||||
/obj/item/mod/module/insignia/generate_worn_overlay()
|
||||
overlay_state_inactive = "[initial(overlay_state_inactive)]-[mod.skin]"
|
||||
. = ..()
|
||||
for(var/mutable_appearance/appearance as anything in .)
|
||||
|
||||
154
code/modules/mod/modules/modules_engineering.dm
Normal file
154
code/modules/mod/modules/modules_engineering.dm
Normal file
@@ -0,0 +1,154 @@
|
||||
//Engineering modules for MODsuits
|
||||
|
||||
///Welding Protection - Makes the helmet protect from flashes and welding.
|
||||
/obj/item/mod/module/welding
|
||||
name = "MOD welding protection module"
|
||||
desc = "A module installed into the visor of the suit, this projects a \
|
||||
polarized, holographic overlay in front of the user's eyes. It's rated high enough for \
|
||||
immunity against extremities such as spot and arc welding, solar eclipses, and handheld flashlights."
|
||||
icon_state = "welding"
|
||||
complexity = 1
|
||||
incompatible_modules = list(/obj/item/mod/module/welding)
|
||||
overlay_state_inactive = "module_welding"
|
||||
|
||||
/obj/item/mod/module/welding/on_suit_activation()
|
||||
mod.helmet.flash_protect = 2
|
||||
|
||||
/obj/item/mod/module/welding/on_suit_deactivation(deleting = FALSE)
|
||||
if(deleting)
|
||||
return
|
||||
mod.helmet.flash_protect = initial(mod.helmet.flash_protect)
|
||||
|
||||
///T-Ray Scan - Scans the terrain for undertile objects.
|
||||
/obj/item/mod/module/t_ray
|
||||
name = "MOD t-ray scan module"
|
||||
desc = "A module installed into the visor of the suit, allowing the user to use a pulse of terahertz radiation \
|
||||
to essentially echolocate things beneath the floor, mostly cables and pipes. \
|
||||
A staple of atmospherics work, and counter-smuggling work."
|
||||
icon_state = "tray"
|
||||
module_type = MODULE_TOGGLE
|
||||
complexity = 1
|
||||
active_power_cost = DEFAULT_CHARGE_DRAIN * 0.5
|
||||
incompatible_modules = list(/obj/item/mod/module/t_ray)
|
||||
cooldown_time = 0.5 SECONDS
|
||||
/// T-ray scan range.
|
||||
var/range = 4
|
||||
|
||||
/obj/item/mod/module/t_ray/on_active_process(delta_time)
|
||||
t_ray_scan(mod.wearer, 0.8 SECONDS, range)
|
||||
|
||||
///Magnetic Stability - Gives the user a slowdown but makes them negate gravity and be immune to slips.
|
||||
/obj/item/mod/module/magboot
|
||||
name = "MOD magnetic stability module"
|
||||
desc = "These are powerful electromagnets fitted into the suit's boots, allowing users both \
|
||||
excellent traction no matter the condition indoors, and to essentially hitch a ride on the exterior of a hull. \
|
||||
However, these basic models do not feature computerized systems to automatically toggle them on and off, \
|
||||
so numerous users report a certain stickiness to their steps."
|
||||
icon_state = "magnet"
|
||||
module_type = MODULE_TOGGLE
|
||||
complexity = 2
|
||||
active_power_cost = DEFAULT_CHARGE_DRAIN * 0.5
|
||||
incompatible_modules = list(/obj/item/mod/module/magboot)
|
||||
cooldown_time = 0.5 SECONDS
|
||||
/// Slowdown added onto the suit.
|
||||
var/slowdown_active = 0.5
|
||||
|
||||
/obj/item/mod/module/magboot/on_activation()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
ADD_TRAIT(mod.wearer, TRAIT_NEGATES_GRAVITY, MOD_TRAIT)
|
||||
ADD_TRAIT(mod.wearer, TRAIT_NOSLIPWATER, MOD_TRAIT)
|
||||
mod.slowdown += slowdown_active
|
||||
mod.wearer.update_gravity(mod.wearer.has_gravity())
|
||||
mod.wearer.update_equipment_speed_mods()
|
||||
|
||||
/obj/item/mod/module/magboot/on_deactivation(display_message = TRUE, deleting = FALSE)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
REMOVE_TRAIT(mod.wearer, TRAIT_NEGATES_GRAVITY, MOD_TRAIT)
|
||||
REMOVE_TRAIT(mod.wearer, TRAIT_NOSLIPWATER, MOD_TRAIT)
|
||||
mod.slowdown -= slowdown_active
|
||||
mod.wearer.update_gravity(mod.wearer.has_gravity())
|
||||
mod.wearer.update_equipment_speed_mods()
|
||||
|
||||
/obj/item/mod/module/magboot/advanced
|
||||
name = "MOD advanced magnetic stability module"
|
||||
removable = FALSE
|
||||
complexity = 0
|
||||
slowdown_active = 0
|
||||
|
||||
// No tether module, sorry!
|
||||
|
||||
///Radiation Protection - Protects the user from radiation, gives them a geiger counter and rad info in the panel.
|
||||
/obj/item/mod/module/rad_protection
|
||||
name = "MOD radiation protection module"
|
||||
desc = "A module utilizing polymers and reflective shielding to protect the user against ionizing radiation."
|
||||
icon_state = "radshield"
|
||||
complexity = 2
|
||||
idle_power_cost = DEFAULT_CHARGE_DRAIN * 0.3
|
||||
incompatible_modules = list(/obj/item/mod/module/rad_protection)
|
||||
|
||||
/obj/item/mod/module/rad_protection/on_suit_activation()
|
||||
for(var/obj/item/part in mod.mod_parts)
|
||||
armor[RAD] = 65
|
||||
rad_flags = RAD_PROTECT_CONTENTS|RAD_NO_CONTAMINATE
|
||||
|
||||
/obj/item/mod/module/rad_protection/on_suit_deactivation(deleting = FALSE)
|
||||
for(var/obj/item/part in mod.mod_parts)
|
||||
armor[RAD] = 0
|
||||
rad_flags = NONE
|
||||
|
||||
///Constructor - Lets you build quicker and create RCD holograms.
|
||||
/obj/item/mod/module/constructor
|
||||
name = "MOD constructor module"
|
||||
desc = "This module entirely occupies the wearer's forearm, notably causing conflict with \
|
||||
advanced arm servos meant to carry crewmembers. However, it contains the \
|
||||
latest engineering schematics combined with inbuilt memory to help the user build walls."
|
||||
icon_state = "constructor"
|
||||
module_type = MODULE_USABLE
|
||||
complexity = 2
|
||||
idle_power_cost = DEFAULT_CHARGE_DRAIN * 0.2
|
||||
use_power_cost = DEFAULT_CHARGE_DRAIN * 2
|
||||
incompatible_modules = list(/obj/item/mod/module/constructor, /obj/item/mod/module/quick_carry)
|
||||
cooldown_time = 11 SECONDS
|
||||
|
||||
/obj/item/mod/module/constructor/on_suit_activation()
|
||||
ADD_TRAIT(mod.wearer, TRAIT_QUICK_BUILD, MOD_TRAIT)
|
||||
|
||||
/obj/item/mod/module/constructor/on_suit_deactivation(deleting = FALSE)
|
||||
REMOVE_TRAIT(mod.wearer, TRAIT_QUICK_BUILD, MOD_TRAIT)
|
||||
|
||||
///Mister - Sprays water over an area.
|
||||
/obj/item/mod/module/mister
|
||||
name = "MOD water mister module"
|
||||
desc = "A module containing a mister, able to spray it over areas."
|
||||
icon_state = "mister"
|
||||
module_type = MODULE_ACTIVE
|
||||
complexity = 2
|
||||
active_power_cost = DEFAULT_CHARGE_DRAIN * 0.3
|
||||
device = /obj/item/reagent_containers/spray/mister
|
||||
incompatible_modules = list(/obj/item/mod/module/mister)
|
||||
cooldown_time = 0.5 SECONDS
|
||||
/// Volume of our reagent holder.
|
||||
var/volume = 500
|
||||
|
||||
/obj/item/mod/module/mister/Initialize(mapload)
|
||||
create_reagents(volume, OPENCONTAINER)
|
||||
return ..()
|
||||
|
||||
///Resin Mister - Sprays resin over an area.
|
||||
/obj/item/mod/module/mister/atmos
|
||||
name = "MOD resin mister module"
|
||||
desc = "An atmospheric resin mister, able to fix up areas quickly."
|
||||
device = /obj/item/extinguisher/mini/nozzle/mod
|
||||
volume = 250
|
||||
|
||||
/obj/item/mod/module/mister/atmos/Initialize(mapload)
|
||||
. = ..()
|
||||
reagents.add_reagent(/datum/reagent/water, volume)
|
||||
|
||||
/obj/item/extinguisher/mini/nozzle/mod
|
||||
name = "MOD atmospheric mister"
|
||||
desc = "An atmospheric resin mister with three modes, mounted as a module."
|
||||
339
code/modules/mod/modules/modules_general.dm
Normal file
339
code/modules/mod/modules/modules_general.dm
Normal file
@@ -0,0 +1,339 @@
|
||||
//General modules for MODsuits
|
||||
|
||||
///Storage - Adds a storage component to the suit.
|
||||
/obj/item/mod/module/storage
|
||||
name = "MOD storage containment module"
|
||||
desc = "What amounts to a series of integrated storage compartments and specialized pockets installed across \
|
||||
the surface of the suit, useful for storing various bits, and or bobs."
|
||||
icon_state = "storage"
|
||||
complexity = 3
|
||||
incompatible_modules = list(/obj/item/mod/module/storage)
|
||||
module_type = MODULE_USABLE
|
||||
cooldown_time = 0.5 SECONDS
|
||||
allowed_inactive = TRUE
|
||||
/// Bag we have stored.
|
||||
var/obj/item/storage/backpack/stored
|
||||
|
||||
/obj/item/mod/module/storage/attackby(obj/item/I, mob/user, params)
|
||||
if(!istype(I, /obj/item/storage/backpack))
|
||||
return ..()
|
||||
var/obj/item/storage/backpack/B = I
|
||||
if(stored)
|
||||
balloon_alert(user, "backpack already installed!")
|
||||
return
|
||||
if(!user.transferItemToLoc(B, src))
|
||||
return
|
||||
stored = B
|
||||
balloon_alert(user, "backpack installed")
|
||||
playsound(src, 'sound/machines/click.ogg', 30, TRUE)
|
||||
|
||||
/obj/item/mod/module/storage/screwdriver_act(mob/living/user, obj/item/tool)
|
||||
. = ..()
|
||||
if(!stored)
|
||||
balloon_alert(user, "no backpack!")
|
||||
return
|
||||
balloon_alert(user, "removing backpack...")
|
||||
if(!do_after(user, 3 SECONDS, target = src))
|
||||
balloon_alert(user, "interrupted!")
|
||||
return
|
||||
balloon_alert(user, "backpack removed")
|
||||
stored.forceMove(drop_location())
|
||||
if(Adjacent(user) && !issilicon(user))
|
||||
user.put_in_hands(stored)
|
||||
stored = null
|
||||
|
||||
/obj/item/mod/module/storage/on_use()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(!stored)
|
||||
var/obj/item/storage/backpack/holding = mod.wearer.get_active_held_item()
|
||||
if(!holding)
|
||||
balloon_alert(mod.wearer, "no backpack installed!")
|
||||
return
|
||||
if(mod.wearer.transferItemToLoc(holding, src, force = FALSE, silent = TRUE))
|
||||
stored = holding
|
||||
balloon_alert(mod.wearer, "backpack stored")
|
||||
playsound(src, 'sound/weapons/revolverempty.ogg', 100, TRUE)
|
||||
else if(mod.wearer.put_in_active_hand(stored, forced = FALSE, ignore_animation = TRUE))
|
||||
balloon_alert(mod.wearer, "backpack retrieved")
|
||||
playsound(src, 'sound/weapons/revolverempty.ogg', 100, TRUE)
|
||||
else
|
||||
balloon_alert(mod.wearer, "backpack storage full!")
|
||||
|
||||
/obj/item/mod/module/storage/Exited(atom/movable/gone, direction)
|
||||
. = ..()
|
||||
if(gone == stored)
|
||||
stored = null
|
||||
|
||||
/obj/item/mod/module/storage/Destroy()
|
||||
QDEL_NULL(stored)
|
||||
return ..()
|
||||
|
||||
/// No Ion Jetpack
|
||||
|
||||
///Eating Apparatus - Lets the user eat/drink with the suit on.
|
||||
/obj/item/mod/module/mouthhole
|
||||
name = "MOD eating apparatus module"
|
||||
desc = "A favorite by Miners, this modification to the helmet utilizes a nanotechnology barrier infront of the mouth \
|
||||
to allow eating and drinking while retaining protection and atmosphere. However, it won't free you from masks, \
|
||||
lets pepper spray pass through and it will do nothing to improve the taste of a goliath steak."
|
||||
icon_state = "apparatus"
|
||||
complexity = 1
|
||||
incompatible_modules = list(/obj/item/mod/module/mouthhole)
|
||||
overlay_state_inactive = "module_apparatus"
|
||||
/// Former flags of the helmet.
|
||||
var/former_flags = NONE
|
||||
/// Former visor flags of the helmet.
|
||||
var/former_visor_flags = NONE
|
||||
|
||||
/obj/item/mod/module/mouthhole/on_install()
|
||||
former_flags = mod.helmet.flags_cover
|
||||
former_visor_flags = mod.helmet.visor_flags_cover
|
||||
mod.helmet.flags_cover &= ~HEADCOVERSMOUTH
|
||||
mod.helmet.visor_flags_cover &= ~HEADCOVERSMOUTH
|
||||
|
||||
/obj/item/mod/module/mouthhole/on_uninstall(deleting = FALSE)
|
||||
if(deleting)
|
||||
return
|
||||
mod.helmet.flags_cover |= former_flags
|
||||
mod.helmet.visor_flags_cover |= former_visor_flags
|
||||
|
||||
///EMP Shield - Protects the suit from EMPs.
|
||||
/obj/item/mod/module/emp_shield
|
||||
name = "MOD EMP shield module"
|
||||
desc = "A field inhibitor installed into the suit, protecting it against feedback such as \
|
||||
electromagnetic pulses that would otherwise damage the electronic systems of the suit or it's modules. \
|
||||
However, it will take from the suit's power to do so."
|
||||
icon_state = "empshield"
|
||||
complexity = 1
|
||||
idle_power_cost = DEFAULT_CHARGE_DRAIN * 0.3
|
||||
incompatible_modules = list(/obj/item/mod/module/emp_shield)
|
||||
|
||||
/obj/item/mod/module/emp_shield/on_install()
|
||||
mod.AddElement(/datum/element/empprotection, EMP_PROTECT_SELF|EMP_PROTECT_WIRES|EMP_PROTECT_CONTENTS)
|
||||
|
||||
/obj/item/mod/module/emp_shield/on_uninstall(deleting = FALSE)
|
||||
mod.RemoveElement(/datum/element/empprotection, EMP_PROTECT_SELF|EMP_PROTECT_WIRES|EMP_PROTECT_CONTENTS)
|
||||
|
||||
/obj/item/mod/module/emp_shield/advanced
|
||||
name = "MOD advanced EMP shield module"
|
||||
desc = "An advanced field inhibitor installed into the suit, protecting it against feedback such as \
|
||||
electromagnetic pulses that would otherwise damage the electronic systems of the suit or electronic devices on the wearer, \
|
||||
including augmentations. However, it will take from the suit's power to do so."
|
||||
complexity = 2
|
||||
|
||||
/obj/item/mod/module/emp_shield/advanced/on_suit_activation()
|
||||
mod.wearer.AddElement(/datum/element/empprotection, EMP_PROTECT_SELF|EMP_PROTECT_CONTENTS)
|
||||
|
||||
/obj/item/mod/module/emp_shield/advanced/on_suit_deactivation(deleting)
|
||||
mod.wearer.RemoveElement(/datum/element/empprotection, EMP_PROTECT_SELF|EMP_PROTECT_CONTENTS)
|
||||
|
||||
///Flashlight - Gives the suit a customizable flashlight.
|
||||
/obj/item/mod/module/flashlight
|
||||
name = "MOD flashlight module"
|
||||
desc = "A simple pair of configurable flashlights installed on the left and right sides of the helmet, \
|
||||
useful for providing light in a variety of ranges and colors. \
|
||||
Some survivalists prefer the color green for their illumination, for reasons unknown."
|
||||
icon_state = "flashlight"
|
||||
module_type = MODULE_TOGGLE
|
||||
complexity = 1
|
||||
active_power_cost = DEFAULT_CHARGE_DRAIN * 0.3
|
||||
incompatible_modules = list(/obj/item/mod/module/flashlight)
|
||||
cooldown_time = 0.5 SECONDS
|
||||
overlay_state_inactive = "module_light"
|
||||
light_color = COLOR_WHITE
|
||||
light_range = 4
|
||||
light_power = 1
|
||||
/// Charge drain per range amount.
|
||||
var/base_power = DEFAULT_CHARGE_DRAIN * 0.1
|
||||
/// Minimum range we can set.
|
||||
var/min_range = 2
|
||||
/// Maximum range we can set.
|
||||
var/max_range = 5
|
||||
|
||||
/obj/item/mod/module/flashlight/on_activation()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
mod.set_light(light_range, light_power, light_color)
|
||||
active_power_cost = base_power * light_range
|
||||
|
||||
/obj/item/mod/module/flashlight/on_deactivation(display_message = TRUE, deleting = FALSE)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
mod.set_light(0, 0)
|
||||
|
||||
/obj/item/mod/module/flashlight/on_process(delta_time)
|
||||
active_power_cost = base_power * light_range
|
||||
return ..()
|
||||
|
||||
/obj/item/mod/module/flashlight/generate_worn_overlay()
|
||||
. = ..()
|
||||
if(!active)
|
||||
return
|
||||
var/mutable_appearance/light_icon = mutable_appearance(overlay_icon_file, "module_light_on")
|
||||
light_icon.appearance_flags = RESET_COLOR
|
||||
light_icon.color = light_color
|
||||
. += light_icon
|
||||
|
||||
/obj/item/mod/module/flashlight/get_configuration()
|
||||
. = ..()
|
||||
.["light_color"] = add_ui_configuration("Light Color", "color", light_color)
|
||||
.["light_range"] = add_ui_configuration("Light Range", "number", light_range)
|
||||
|
||||
/obj/item/mod/module/flashlight/configure_edit(key, value)
|
||||
switch(key)
|
||||
if("light_color")
|
||||
value = input(usr, "Pick new light color", "Flashlight Color") as color|null
|
||||
if(!value)
|
||||
return
|
||||
var/list/hsl = rgb2hsl(hex2num(copytext(value,2,4)),hex2num(copytext(value,4,6)),hex2num(copytext(value,6,8)))
|
||||
if(hsl[3] < 0.5)
|
||||
balloon_alert(mod.wearer, "too dark!")
|
||||
return
|
||||
mod.set_light_color(value)
|
||||
mod.wearer.regenerate_icons()
|
||||
light_color = value
|
||||
if("light_range")
|
||||
mod.set_light_range(clamp(value, min_range, max_range))
|
||||
light_range = clamp(value, min_range, max_range)
|
||||
|
||||
///Dispenser - Dispenses an item after a time passes.
|
||||
/obj/item/mod/module/dispenser
|
||||
name = "MOD burger dispenser module"
|
||||
desc = "A rare piece of technology reverse-engineered from a prototype found in a Donk Corporation vessel. \
|
||||
This can draw incredible amounts of power from the suit's charge to create edible organic matter in the \
|
||||
palm of the wearer's glove; however, research seemed to have entirely stopped at burgers. \
|
||||
Notably, all attempts to get it to dispense Earl Grey tea have failed."
|
||||
icon_state = "dispenser"
|
||||
module_type = MODULE_USABLE
|
||||
complexity = 3
|
||||
use_power_cost = DEFAULT_CHARGE_DRAIN * 2
|
||||
incompatible_modules = list(/obj/item/mod/module/dispenser)
|
||||
cooldown_time = 5 SECONDS
|
||||
/// Path we dispense.
|
||||
var/dispense_type = /obj/item/reagent_containers/food/snacks/burger/plain
|
||||
/// Time it takes for us to dispense.
|
||||
var/dispense_time = 0 SECONDS
|
||||
|
||||
/obj/item/mod/module/dispenser/on_use()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(dispense_time && !do_after(mod.wearer, dispense_time, target = mod))
|
||||
balloon_alert(mod.wearer, "interrupted!")
|
||||
return FALSE
|
||||
var/obj/item/dispensed = new dispense_type(mod.wearer.loc)
|
||||
mod.wearer.put_in_hands(dispensed)
|
||||
balloon_alert(mod.wearer, "[dispensed] dispensed")
|
||||
playsound(src, 'sound/machines/click.ogg', 100, TRUE)
|
||||
drain_power(use_power_cost)
|
||||
return dispensed
|
||||
|
||||
///Longfall - Nullifies fall damage, removing charge instead.
|
||||
/obj/item/mod/module/longfall
|
||||
name = "MOD longfall module"
|
||||
desc = "Useful for protecting both the suit and the wearer, \
|
||||
utilizing commonplace systems to convert the possible damage from a fall into kinetic charge, \
|
||||
as well as internal gyroscopes to ensure the user's safe falling. \
|
||||
Useful for mining, monorail tracks, or even skydiving!"
|
||||
icon_state = "longfall"
|
||||
complexity = 1
|
||||
use_power_cost = DEFAULT_CHARGE_DRAIN * 5
|
||||
incompatible_modules = list(/obj/item/mod/module/longfall)
|
||||
|
||||
/obj/item/mod/module/longfall/on_suit_activation()
|
||||
RegisterSignal(mod.wearer, COMSIG_LIVING_Z_IMPACT, .proc/z_impact_react)
|
||||
|
||||
/obj/item/mod/module/longfall/on_suit_deactivation(deleting = FALSE)
|
||||
UnregisterSignal(mod.wearer, COMSIG_LIVING_Z_IMPACT)
|
||||
|
||||
/obj/item/mod/module/longfall/proc/z_impact_react(datum/source, levels, turf/fell_on)
|
||||
if(!drain_power(use_power_cost*levels))
|
||||
return
|
||||
new /obj/effect/temp_visual/mook_dust(fell_on)
|
||||
mod.wearer.Stun(levels * 1 SECONDS)
|
||||
to_chat(mod.wearer, span_notice("[src] protects you from the damage!"))
|
||||
return NO_Z_IMPACT_DAMAGE
|
||||
|
||||
///Thermal Regulator - Naw.
|
||||
|
||||
///DNA Lock - Prevents people without the set DNA from activating the suit.
|
||||
/obj/item/mod/module/dna_lock
|
||||
name = "MOD DNA lock module"
|
||||
desc = "A module which engages with the various locks and seals tied to the suit's systems, \
|
||||
enabling it to only be worn by someone corresponding with the user's exact DNA profile; \
|
||||
however, this incredibly sensitive module is shorted out by EMPs. Luckily, cloning has been outlawed."
|
||||
icon_state = "dnalock"
|
||||
module_type = MODULE_USABLE
|
||||
complexity = 2
|
||||
use_power_cost = DEFAULT_CHARGE_DRAIN * 3
|
||||
incompatible_modules = list(/obj/item/mod/module/dna_lock)
|
||||
cooldown_time = 0.5 SECONDS
|
||||
/// The DNA we lock with.
|
||||
var/dna = null
|
||||
|
||||
/obj/item/mod/module/dna_lock/on_install()
|
||||
RegisterSignal(mod, COMSIG_MOD_ACTIVATE, .proc/on_mod_activation)
|
||||
RegisterSignal(mod, COMSIG_MOD_MODULE_REMOVAL, .proc/on_mod_removal)
|
||||
RegisterSignal(mod, COMSIG_ATOM_EMP_ACT, .proc/on_emp)
|
||||
RegisterSignal(mod, COMSIG_ATOM_EMAG_ACT, .proc/on_emag)
|
||||
|
||||
/obj/item/mod/module/dna_lock/on_uninstall(deleting = FALSE)
|
||||
UnregisterSignal(mod, COMSIG_MOD_ACTIVATE)
|
||||
UnregisterSignal(mod, COMSIG_MOD_MODULE_REMOVAL)
|
||||
UnregisterSignal(mod, COMSIG_ATOM_EMP_ACT)
|
||||
UnregisterSignal(mod, COMSIG_ATOM_EMAG_ACT)
|
||||
|
||||
/obj/item/mod/module/dna_lock/on_use()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
dna = mod.wearer.dna.unique_enzymes
|
||||
balloon_alert(mod.wearer, "dna updated")
|
||||
drain_power(use_power_cost)
|
||||
|
||||
/obj/item/mod/module/dna_lock/emp_act(severity)
|
||||
. = ..()
|
||||
if(. & EMP_PROTECT_SELF)
|
||||
return
|
||||
on_emp(src, severity)
|
||||
|
||||
/obj/item/mod/module/dna_lock/emag_act(mob/user, obj/item/card/emag/emag_card)
|
||||
. = ..()
|
||||
on_emag(src, user, emag_card)
|
||||
|
||||
/obj/item/mod/module/dna_lock/proc/dna_check(mob/user)
|
||||
if(!iscarbon(user))
|
||||
return FALSE
|
||||
var/mob/living/carbon/carbon_user = user
|
||||
if(!dna || (carbon_user.has_dna() && carbon_user.dna.unique_enzymes == dna))
|
||||
return TRUE
|
||||
balloon_alert(user, "dna locked!")
|
||||
return FALSE
|
||||
|
||||
/obj/item/mod/module/dna_lock/proc/on_emp(datum/source, severity)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
dna = null
|
||||
|
||||
/obj/item/mod/module/dna_lock/proc/on_emag(datum/source, mob/user, obj/item/card/emag/emag_card)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
dna = null
|
||||
|
||||
/obj/item/mod/module/dna_lock/proc/on_mod_activation(datum/source, mob/user)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!dna_check(user))
|
||||
return MOD_CANCEL_ACTIVATE
|
||||
|
||||
/obj/item/mod/module/dna_lock/proc/on_mod_removal(datum/source, mob/user)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!dna_check(user))
|
||||
return MOD_CANCEL_REMOVAL
|
||||
|
||||
///Sign Language Translator - I want, but no
|
||||
101
code/modules/mod/modules/modules_maint.dm
Normal file
101
code/modules/mod/modules/modules_maint.dm
Normal file
@@ -0,0 +1,101 @@
|
||||
//Maint modules for MODsuits
|
||||
|
||||
///Springlock Mechanism - Nope
|
||||
|
||||
///Rave Visor - Pointless
|
||||
|
||||
///Tanner - Maybe another time
|
||||
|
||||
///Balloon Blower - Blows a balloon.
|
||||
/obj/item/mod/module/balloon
|
||||
name = "MOD balloon blower module"
|
||||
desc = "A strange module invented years ago by some ingenious mimes. It blows balloons."
|
||||
icon_state = "bloon"
|
||||
module_type = MODULE_USABLE
|
||||
complexity = 1
|
||||
use_power_cost = DEFAULT_CHARGE_DRAIN * 0.5
|
||||
incompatible_modules = list(/obj/item/mod/module/balloon)
|
||||
cooldown_time = 15 SECONDS
|
||||
|
||||
/obj/item/mod/module/balloon/on_use()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(!do_after(mod.wearer, 10 SECONDS, target = mod))
|
||||
return FALSE
|
||||
mod.wearer.adjustOxyLoss(20)
|
||||
playsound(src, 'sound/items/modsuit/inflate_bloon.ogg', 50, TRUE)
|
||||
var/obj/item/toy/balloon/balloon = new(get_turf(src))
|
||||
mod.wearer.put_in_hands(balloon)
|
||||
drain_power(use_power_cost)
|
||||
|
||||
///Paper Dispenser - Dispenses (sometimes burning) paper sheets.
|
||||
/obj/item/mod/module/paper_dispenser
|
||||
name = "MOD paper dispenser module"
|
||||
desc = "A simple module designed by the bureaucrats of Torch Bay. \
|
||||
It dispenses 'warm, clean, and crisp sheets of paper' onto a nearby table. Usually."
|
||||
icon_state = "paper_maker"
|
||||
module_type = MODULE_USABLE
|
||||
complexity = 1
|
||||
use_power_cost = DEFAULT_CHARGE_DRAIN * 0.5
|
||||
incompatible_modules = list(/obj/item/mod/module/paper_dispenser)
|
||||
cooldown_time = 5 SECONDS
|
||||
/// The total number of sheets created by this MOD. The more sheets, them more likely they set on fire.
|
||||
var/num_sheets_dispensed = 0
|
||||
|
||||
/obj/item/mod/module/paper_dispenser/on_use()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(!do_after(mod.wearer, 1 SECONDS, target = mod))
|
||||
return FALSE
|
||||
|
||||
var/obj/item/paper/crisp_paper = new(get_turf(src))
|
||||
crisp_paper.desc = "It's crisp and warm to the touch. Must be fresh."
|
||||
|
||||
var/obj/structure/table/nearby_table = locate() in range(1, mod.wearer)
|
||||
playsound(get_turf(src), 'sound/machines/click.ogg', 50, TRUE)
|
||||
balloon_alert(mod.wearer, "dispensed paper[nearby_table ? " onto table":""]")
|
||||
|
||||
mod.wearer.put_in_hands(crisp_paper)
|
||||
if(nearby_table)
|
||||
mod.wearer.transferItemToLoc(crisp_paper, nearby_table.drop_location(), silent = FALSE)
|
||||
|
||||
// Up to a 30% chance to set the sheet on fire, +2% per sheet made
|
||||
if(prob(min(num_sheets_dispensed * 2, 30)))
|
||||
if(crisp_paper in mod.wearer.held_items)
|
||||
mod.wearer.dropItemToGround(crisp_paper, force = TRUE)
|
||||
crisp_paper.balloon_alert(mod.wearer, "PC LOAD LETTER!")
|
||||
crisp_paper.visible_message(span_warning("[crisp_paper] bursts into flames, it's too crisp!"))
|
||||
crisp_paper.fire_act(1000, 100)
|
||||
|
||||
drain_power(use_power_cost)
|
||||
num_sheets_dispensed++
|
||||
|
||||
|
||||
///Stamper - Extends a stamp that can switch between accept/deny modes.
|
||||
/obj/item/mod/module/stamp
|
||||
name = "MOD stamper module"
|
||||
desc = "A module installed into the wrist of the suit, this functions as a high-power stamp, \
|
||||
able to switch between accept and deny modes."
|
||||
icon_state = "stamp"
|
||||
module_type = MODULE_ACTIVE
|
||||
complexity = 1
|
||||
active_power_cost = DEFAULT_CHARGE_DRAIN * 0.3
|
||||
device = /obj/item/stamp/mod
|
||||
incompatible_modules = list(/obj/item/mod/module/stamp)
|
||||
cooldown_time = 0.5 SECONDS
|
||||
|
||||
/obj/item/stamp/mod
|
||||
name = "MOD electronic stamp"
|
||||
desc = "A high-power stamp, able to switch between accept and deny mode when used."
|
||||
|
||||
/obj/item/stamp/mod/attack_self(mob/user, modifiers)
|
||||
. = ..()
|
||||
if(icon_state == "stamp-ok")
|
||||
icon_state = "stamp-deny"
|
||||
else
|
||||
icon_state = "stamp-ok"
|
||||
balloon_alert(user, "switched mode")
|
||||
|
||||
///Atrocinator - Perhaps another time
|
||||
208
code/modules/mod/modules/modules_medical.dm
Normal file
208
code/modules/mod/modules/modules_medical.dm
Normal file
@@ -0,0 +1,208 @@
|
||||
//Medical modules for MODsuits
|
||||
|
||||
#define HEALTH_SCAN "Health"
|
||||
#define WOUND_SCAN "Wound"
|
||||
#define CHEM_SCAN "Chemical"
|
||||
|
||||
///Health Analyzer - Gives the user a ranged health analyzer and their health status in the panel.
|
||||
/obj/item/mod/module/health_analyzer
|
||||
name = "MOD health analyzer module"
|
||||
desc = "A module installed into the glove of the suit. This is a high-tech biological scanning suite, \
|
||||
allowing the user indepth information on the vitals and injuries of others even at a distance, \
|
||||
all with the flick of the wrist. Data is displayed in a convenient package on HUD in the helmet, \
|
||||
but it's up to you to do something with it."
|
||||
icon_state = "health"
|
||||
module_type = MODULE_ACTIVE
|
||||
complexity = 2
|
||||
use_power_cost = DEFAULT_CHARGE_DRAIN
|
||||
incompatible_modules = list(/obj/item/mod/module/health_analyzer)
|
||||
cooldown_time = 0.5 SECONDS
|
||||
tgui_id = "health_analyzer"
|
||||
/// Scanning mode, changes how we scan something.
|
||||
var/mode = HEALTH_SCAN
|
||||
/// List of all scanning modes.
|
||||
var/static/list/modes = list(HEALTH_SCAN, WOUND_SCAN, CHEM_SCAN)
|
||||
|
||||
/obj/item/mod/module/health_analyzer/add_ui_data()
|
||||
. = ..()
|
||||
.["userhealth"] = mod.wearer?.health || 0
|
||||
.["usermaxhealth"] = mod.wearer?.getMaxHealth() || 0
|
||||
.["userbrute"] = mod.wearer?.getBruteLoss() || 0
|
||||
.["userburn"] = mod.wearer?.getFireLoss() || 0
|
||||
.["usertoxin"] = mod.wearer?.getToxLoss() || 0
|
||||
.["useroxy"] = mod.wearer?.getOxyLoss() || 0
|
||||
|
||||
/obj/item/mod/module/health_analyzer/on_select_use(atom/target)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(!isliving(target) || !mod.wearer.can_read(src))
|
||||
return
|
||||
switch(mode)
|
||||
if(HEALTH_SCAN)
|
||||
healthscan(mod.wearer, target)
|
||||
if(WOUND_SCAN)
|
||||
woundscan(mod.wearer, target)
|
||||
if(CHEM_SCAN)
|
||||
chemscan(mod.wearer, target)
|
||||
drain_power(use_power_cost)
|
||||
|
||||
/obj/item/mod/module/health_analyzer/get_configuration()
|
||||
. = ..()
|
||||
.["mode"] = add_ui_configuration("Scan Mode", "list", mode, modes)
|
||||
|
||||
/obj/item/mod/module/health_analyzer/configure_edit(key, value)
|
||||
switch(key)
|
||||
if("mode")
|
||||
mode = value
|
||||
|
||||
#undef HEALTH_SCAN
|
||||
#undef WOUND_SCAN
|
||||
#undef CHEM_SCAN
|
||||
|
||||
///Quick Carry - Lets the user carry bodies quicker.
|
||||
/obj/item/mod/module/quick_carry
|
||||
name = "MOD quick carry module"
|
||||
desc = "A suite of advanced servos, redirecting power from the suit's arms to help carry the wounded; \
|
||||
or simply for fun. However, Nanotrasen has locked the module's ability to assist in hand-to-hand combat."
|
||||
icon_state = "carry"
|
||||
complexity = 1
|
||||
idle_power_cost = DEFAULT_CHARGE_DRAIN * 0.3
|
||||
incompatible_modules = list(/obj/item/mod/module/quick_carry, /obj/item/mod/module/constructor)
|
||||
|
||||
/obj/item/mod/module/quick_carry/on_suit_activation()
|
||||
ADD_TRAIT(mod.wearer, TRAIT_QUICKER_CARRY, MOD_TRAIT)
|
||||
|
||||
/obj/item/mod/module/quick_carry/on_suit_deactivation(deleting = FALSE)
|
||||
REMOVE_TRAIT(mod.wearer, TRAIT_QUICKER_CARRY, MOD_TRAIT)
|
||||
|
||||
/obj/item/mod/module/quick_carry/advanced
|
||||
name = "MOD advanced quick carry module"
|
||||
removable = FALSE
|
||||
complexity = 0
|
||||
|
||||
///Injector - Gives the suit an extendable large-capacity piercing syringe.
|
||||
/obj/item/mod/module/injector
|
||||
name = "MOD injector module"
|
||||
desc = "A module installed into the wrist of the suit, this functions as a high-capacity syringe, \
|
||||
with a tip fine enough to locate the emergency injection ports on any suit of armor, \
|
||||
penetrating it with ease. Even yours."
|
||||
icon_state = "injector"
|
||||
module_type = MODULE_ACTIVE
|
||||
complexity = 1
|
||||
active_power_cost = DEFAULT_CHARGE_DRAIN * 0.3
|
||||
device = /obj/item/reagent_containers/syringe/mod
|
||||
incompatible_modules = list(/obj/item/mod/module/injector)
|
||||
cooldown_time = 0.5 SECONDS
|
||||
|
||||
/obj/item/reagent_containers/syringe/mod
|
||||
name = "MOD injector syringe"
|
||||
desc = "A high-capacity syringe, with a tip fine enough to locate \
|
||||
the emergency injection ports on any suit of armor, penetrating it with ease. Even yours."
|
||||
icon_state = "mod_0"
|
||||
base_icon_state = "mod"
|
||||
amount_per_transfer_from_this = 30
|
||||
possible_transfer_amounts = list(5, 10, 15, 20, 30)
|
||||
volume = 30
|
||||
proj_piercing = 1
|
||||
|
||||
///Organ Thrower
|
||||
|
||||
///Patrient Transport
|
||||
|
||||
///Defibrillator - Gives the suit an extendable pair of shock paddles.
|
||||
/obj/item/mod/module/defibrillator
|
||||
name = "MOD defibrillator module"
|
||||
desc = "A module built into the gauntlets of the suit; commonly known as the 'Healing Hands' by medical professionals. \
|
||||
The user places their palms above the patient. Onboard computers in the suit calculate the necessary voltage, \
|
||||
and a modded targeting computer determines the best position for the user to push. \
|
||||
Twenty five pounds of force are applied to the patient's skin. Shocks travel from the suit's gloves \
|
||||
and counter-shock the heart, and the wearer returns to Medical a hero. Don't you even think about using it as a weapon; \
|
||||
regulations on manufacture and software locks expressly forbid it."
|
||||
icon_state = "defibrillator"
|
||||
module_type = MODULE_ACTIVE
|
||||
complexity = 2
|
||||
use_power_cost = DEFAULT_CHARGE_DRAIN * 25
|
||||
device = /obj/item/shockpaddles/mod
|
||||
overlay_state_inactive = "module_defibrillator"
|
||||
overlay_state_active = "module_defibrillator_active"
|
||||
incompatible_modules = list(/obj/item/mod/module/defibrillator)
|
||||
cooldown_time = 0.5 SECONDS
|
||||
var/defib_cooldown = 5 SECONDS
|
||||
|
||||
/obj/item/mod/module/defibrillator/Initialize(mapload)
|
||||
. = ..()
|
||||
RegisterSignal(device, COMSIG_DEFIBRILLATOR_SUCCESS, .proc/on_defib_success)
|
||||
|
||||
/obj/item/mod/module/defibrillator/proc/on_defib_success(obj/item/shockpaddles/source)
|
||||
drain_power(use_power_cost)
|
||||
source.recharge(defib_cooldown)
|
||||
return COMPONENT_DEFIB_STOP
|
||||
|
||||
/obj/item/shockpaddles/mod
|
||||
name = "MOD defibrillator gauntlets"
|
||||
req_defib = FALSE
|
||||
icon_state = "defibgauntlets0"
|
||||
item_state = "defibgauntlets0"
|
||||
base_icon_state = "defibgauntlets"
|
||||
|
||||
/obj/item/mod/module/defibrillator/combat
|
||||
name = "MOD combat defibrillator module"
|
||||
desc = "A module built into the gauntlets of the suit; commonly known as the 'Healing Hands' by medical professionals. \
|
||||
The user places their palms above the patient. Onboard computers in the suit calculate the necessary voltage, \
|
||||
and a modded targeting computer determines the best position for the user to push. \
|
||||
Twenty five pounds of force are applied to the patient's skin. Shocks travel from the suit's gloves \
|
||||
and counter-shock the heart, and the wearer returns to Medical a hero. \
|
||||
Interdyne Pharmaceutics marketed the domestic version of the Healing Hands as foolproof and unusable as a weapon. \
|
||||
But when it came time to provide their operatives with usable medical equipment, they didn't hesitate to remove \
|
||||
those in-built safeties. Operatives in the field can benefit from what they dub as 'Stun Gloves', able to apply shocks \
|
||||
straight to a victims heart to disable them, or maybe even outright stop their heart with enough power."
|
||||
complexity = 1
|
||||
module_type = MODULE_ACTIVE
|
||||
overlay_state_inactive = "module_defibrillator_combat"
|
||||
overlay_state_active = "module_defibrillator_combat_active"
|
||||
device = /obj/item/shockpaddles/syndicate/mod
|
||||
defib_cooldown = 2.5 SECONDS
|
||||
|
||||
/obj/item/shockpaddles/syndicate/mod
|
||||
name = "MOD combat defibrillator gauntlets"
|
||||
req_defib = FALSE
|
||||
icon_state = "syndiegauntlets0"
|
||||
item_state = "syndiegauntlets0"
|
||||
base_icon_state = "syndiegauntlets"
|
||||
|
||||
///Thread Ripper
|
||||
|
||||
///Surgical Processor - Lets you do advanced surgeries portably.
|
||||
/obj/item/mod/module/surgical_processor
|
||||
name = "MOD surgical processor module"
|
||||
desc = "A module using an onboard surgical computer which can be connected to other computers to download and \
|
||||
perform advanced surgeries on the go."
|
||||
icon_state = "surgical_processor"
|
||||
module_type = MODULE_ACTIVE
|
||||
complexity = 2
|
||||
active_power_cost = DEFAULT_CHARGE_DRAIN
|
||||
device = /obj/item/surgical_processor/mod
|
||||
incompatible_modules = list(/obj/item/mod/module/surgical_processor)
|
||||
cooldown_time = 0.5 SECONDS
|
||||
|
||||
/obj/item/surgical_processor/mod
|
||||
name = "MOD surgical processor"
|
||||
|
||||
/obj/item/mod/module/surgical_processor/preloaded
|
||||
desc = "A module using an onboard surgical computer which can be connected to other computers to download and \
|
||||
perform advanced surgeries on the go. This one came pre-loaded with some advanced surgeries."
|
||||
device = /obj/item/surgical_processor/mod/preloaded
|
||||
|
||||
/obj/item/surgical_processor/mod/preloaded
|
||||
advanced_surgeries = list(
|
||||
/datum/surgery/advanced/pacify,
|
||||
/datum/surgery/healing/combo/upgraded/femto,
|
||||
/datum/surgery/advanced/brainwashing,
|
||||
/datum/surgery/advanced/bioware/nerve_splicing,
|
||||
/datum/surgery/advanced/bioware/nerve_grounding,
|
||||
/datum/surgery/advanced/bioware/vein_threading,
|
||||
/datum/surgery/advanced/bioware/muscled_veins,
|
||||
/datum/surgery/advanced/bioware/ligament_hook,
|
||||
/datum/surgery/advanced/bioware/ligament_reinforcement
|
||||
)
|
||||
135
code/modules/mod/modules/modules_science.dm
Normal file
135
code/modules/mod/modules/modules_science.dm
Normal file
@@ -0,0 +1,135 @@
|
||||
//Science modules for MODsuits
|
||||
|
||||
///Reagent Scanner - Lets the user scan reagents.
|
||||
/obj/item/mod/module/reagent_scanner
|
||||
name = "MOD reagent scanner module"
|
||||
desc = "A module based off research-oriented Nanotrasen HUDs, this is capable of scanning the contents of \
|
||||
containers and projecting the information in an easy-to-read format on the wearer's display. \
|
||||
It cannot detect flavors, so that's up to you."
|
||||
icon_state = "scanner"
|
||||
module_type = MODULE_TOGGLE
|
||||
complexity = 1
|
||||
active_power_cost = DEFAULT_CHARGE_DRAIN * 0.2
|
||||
incompatible_modules = list(/obj/item/mod/module/reagent_scanner)
|
||||
cooldown_time = 0.5 SECONDS
|
||||
|
||||
/obj/item/mod/module/reagent_scanner/on_activation()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
ADD_TRAIT(mod.wearer, TRAIT_REAGENT_SCANNER, MOD_TRAIT)
|
||||
|
||||
/obj/item/mod/module/reagent_scanner/on_deactivation(display_message = TRUE, deleting = FALSE)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
REMOVE_TRAIT(mod.wearer, TRAIT_REAGENT_SCANNER, MOD_TRAIT)
|
||||
|
||||
/obj/item/mod/module/reagent_scanner/advanced
|
||||
name = "MOD advanced reagent scanner module"
|
||||
complexity = 0
|
||||
removable = FALSE
|
||||
var/explosion_detection_dist = 21
|
||||
var/had_research_scanner = FALSE
|
||||
|
||||
/obj/item/mod/module/reagent_scanner/advanced/on_activation()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
had_research_scanner = mod.wearer.research_scanner
|
||||
mod.wearer.research_scanner = TRUE
|
||||
RegisterSignal(SSdcs, COMSIG_GLOB_EXPLOSION, .proc/sense_explosion)
|
||||
|
||||
/obj/item/mod/module/reagent_scanner/advanced/on_deactivation(display_message = TRUE, deleting = FALSE)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
mod.wearer.research_scanner = had_research_scanner
|
||||
had_research_scanner = FALSE
|
||||
UnregisterSignal(SSdcs, COMSIG_GLOB_EXPLOSION)
|
||||
|
||||
/obj/item/mod/module/reagent_scanner/advanced/proc/sense_explosion(datum/source, turf/epicenter,
|
||||
devastation_range, heavy_impact_range, light_impact_range, took, orig_dev_range, orig_heavy_range, orig_light_range)
|
||||
SIGNAL_HANDLER
|
||||
var/turf/wearer_turf = get_turf(mod.wearer)
|
||||
if(wearer_turf.z == epicenter.z)
|
||||
return
|
||||
if(get_dist(epicenter, wearer_turf) > explosion_detection_dist)
|
||||
return
|
||||
to_chat(mod.wearer, span_notice("Explosion detected! Epicenter: [devastation_range], Outer: [heavy_impact_range], Shock: [light_impact_range]"))
|
||||
|
||||
///Anti-Gravity - Makes the user weightless.
|
||||
/obj/item/mod/module/anomaly_locked/antigrav
|
||||
name = "MOD anti-gravity module"
|
||||
desc = "A module that uses a gravitational core to make the user completely weightless."
|
||||
icon_state = "antigrav"
|
||||
module_type = MODULE_TOGGLE
|
||||
complexity = 3
|
||||
active_power_cost = DEFAULT_CHARGE_DRAIN * 0.7
|
||||
incompatible_modules = list(/obj/item/mod/module/anomaly_locked)
|
||||
cooldown_time = 0.5 SECONDS
|
||||
accepted_anomalies = list(/obj/item/assembly/signaler/anomaly/grav)
|
||||
|
||||
/obj/item/mod/module/anomaly_locked/antigrav/on_activation()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(mod.wearer.has_gravity())
|
||||
new /obj/effect/temp_visual/mook_dust(get_turf(src))
|
||||
mod.wearer.AddElement(/datum/element/forced_gravity, 0)
|
||||
mod.wearer.update_gravity(mod.wearer.has_gravity())
|
||||
playsound(src, 'sound/effects/gravhit.ogg', 50)
|
||||
|
||||
/obj/item/mod/module/anomaly_locked/antigrav/on_deactivation(display_message = TRUE, deleting = FALSE)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
mod.wearer.RemoveElement(/datum/element/forced_gravity, 0)
|
||||
mod.wearer.update_gravity(mod.wearer.has_gravity())
|
||||
if(deleting)
|
||||
return
|
||||
if(mod.wearer.has_gravity())
|
||||
new /obj/effect/temp_visual/mook_dust(get_turf(src))
|
||||
playsound(src, 'sound/effects/gravhit.ogg', 50)
|
||||
|
||||
/obj/item/mod/module/anomaly_locked/antigrav/prebuilt
|
||||
prebuilt = TRUE
|
||||
|
||||
///Teleporter - Lets the user teleport to a nearby location.
|
||||
/obj/item/mod/module/anomaly_locked/teleporter
|
||||
name = "MOD teleporter module"
|
||||
desc = "A module that uses a bluespace core to let the user transport their particles elsewhere."
|
||||
icon_state = "teleporter"
|
||||
module_type = MODULE_ACTIVE
|
||||
complexity = 3
|
||||
use_power_cost = DEFAULT_CHARGE_DRAIN * 5
|
||||
cooldown_time = 5 SECONDS
|
||||
accepted_anomalies = list(/obj/item/assembly/signaler/anomaly/bluespace)
|
||||
/// Time it takes to teleport
|
||||
var/teleport_time = 3 SECONDS
|
||||
|
||||
/obj/item/mod/module/anomaly_locked/teleporter/on_select_use(atom/target)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
var/turf/open/target_turf = get_turf(target)
|
||||
if(!istype(target_turf) || is_blocked_turf(target_turf) || !(target_turf in view(mod.wearer)))
|
||||
balloon_alert(mod.wearer, "invalid target!")
|
||||
return
|
||||
balloon_alert(mod.wearer, "teleporting...")
|
||||
var/matrix/pre_matrix = matrix()
|
||||
pre_matrix.Scale(4, 0.25)
|
||||
var/matrix/post_matrix = matrix()
|
||||
post_matrix.Scale(0.25, 4)
|
||||
animate(mod.wearer, teleport_time, color = COLOR_CYAN, transform = pre_matrix.Multiply(mod.wearer.transform), easing = SINE_EASING|EASE_OUT)
|
||||
if(!do_after(mod.wearer, teleport_time, target = mod))
|
||||
balloon_alert(mod.wearer, "interrupted!")
|
||||
animate(mod.wearer, teleport_time*0.1, color = null, transform = post_matrix.Multiply(mod.wearer.transform), easing = SINE_EASING|EASE_IN)
|
||||
return
|
||||
animate(mod.wearer, teleport_time*0.1, color = null, transform = post_matrix.Multiply(mod.wearer.transform), easing = SINE_EASING|EASE_IN)
|
||||
if(!do_teleport(mod.wearer, target_turf, asoundin = 'sound/effects/phasein.ogg'))
|
||||
return
|
||||
drain_power(use_power_cost)
|
||||
|
||||
/obj/item/mod/module/anomaly_locked/teleporter/prebuilt
|
||||
prebuilt = TRUE
|
||||
207
code/modules/mod/modules/modules_security.dm
Normal file
207
code/modules/mod/modules/modules_security.dm
Normal file
@@ -0,0 +1,207 @@
|
||||
//Security modules for MODsuits
|
||||
|
||||
///Cloaking - Lowers the user's visibility, can be interrupted by being touched or attacked.
|
||||
/obj/item/mod/module/stealth
|
||||
name = "MOD prototype cloaking module"
|
||||
desc = "A complete retrofitting of the suit, this is a form of visual concealment tech employing esoteric technology \
|
||||
to bend light around the user, as well as mimetic materials to make the surface of the suit match the \
|
||||
surroundings based off sensor data. For some reason, this tech is rarely seen."
|
||||
icon_state = "cloak"
|
||||
module_type = MODULE_TOGGLE
|
||||
complexity = 4
|
||||
active_power_cost = DEFAULT_CHARGE_DRAIN * 2
|
||||
use_power_cost = DEFAULT_CHARGE_DRAIN * 10
|
||||
incompatible_modules = list(/obj/item/mod/module/stealth)
|
||||
cooldown_time = 5 SECONDS
|
||||
/// Whether or not the cloak turns off on bumping.
|
||||
var/bumpoff = TRUE
|
||||
/// The alpha applied when the cloak is on.
|
||||
var/stealth_alpha = 50
|
||||
|
||||
/obj/item/mod/module/stealth/on_activation()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(bumpoff)
|
||||
RegisterSignal(mod.wearer, COMSIG_LIVING_MOB_BUMP, .proc/unstealth)
|
||||
RegisterSignal(mod.wearer, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, .proc/on_unarmed_attack)
|
||||
RegisterSignal(mod.wearer, COMSIG_ATOM_BULLET_ACT, .proc/on_bullet_act)
|
||||
RegisterSignal(mod.wearer, list(COMSIG_MOB_ITEM_ATTACK, COMSIG_PARENT_ATTACKBY, COMSIG_ATOM_ATTACK_HAND, COMSIG_ATOM_HULK_ATTACK, COMSIG_ATOM_ATTACK_PAW), .proc/unstealth)
|
||||
animate(mod.wearer, alpha = stealth_alpha, time = 1.5 SECONDS)
|
||||
drain_power(use_power_cost)
|
||||
|
||||
/obj/item/mod/module/stealth/on_deactivation(display_message = TRUE, deleting = FALSE)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(bumpoff)
|
||||
UnregisterSignal(mod.wearer, COMSIG_LIVING_MOB_BUMP)
|
||||
UnregisterSignal(mod.wearer, list(COMSIG_HUMAN_MELEE_UNARMED_ATTACK, COMSIG_MOB_ITEM_ATTACK, COMSIG_PARENT_ATTACKBY, COMSIG_ATOM_ATTACK_HAND, COMSIG_ATOM_BULLET_ACT, COMSIG_ATOM_HULK_ATTACK, COMSIG_ATOM_ATTACK_PAW))
|
||||
animate(mod.wearer, alpha = 255, time = 1.5 SECONDS)
|
||||
|
||||
/obj/item/mod/module/stealth/proc/unstealth(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
to_chat(mod.wearer, span_warning("[src] gets discharged from contact!"))
|
||||
do_sparks(2, TRUE, src)
|
||||
drain_power(use_power_cost)
|
||||
on_deactivation(display_message = TRUE, deleting = FALSE)
|
||||
|
||||
/obj/item/mod/module/stealth/proc/on_unarmed_attack(datum/source, atom/target)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!isliving(target))
|
||||
return
|
||||
unstealth(source)
|
||||
|
||||
/obj/item/mod/module/stealth/proc/on_bullet_act(datum/source, obj/item/projectile/projectile)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(projectile.nodamage)
|
||||
return
|
||||
unstealth(source)
|
||||
|
||||
///Magnetic Harness - Automatically puts guns in your suit storage when you drop them.
|
||||
/obj/item/mod/module/magnetic_harness
|
||||
name = "MOD magnetic harness module"
|
||||
desc = "Based off old TerraGov harness kits, this magnetic harness automatically attaches dropped guns back to the wearer."
|
||||
icon_state = "mag_harness"
|
||||
complexity = 2
|
||||
use_power_cost = DEFAULT_CHARGE_DRAIN
|
||||
incompatible_modules = list(/obj/item/mod/module/magnetic_harness)
|
||||
/// Time before we activate the magnet.
|
||||
var/magnet_delay = 0.8 SECONDS
|
||||
/// The typecache of all guns we allow.
|
||||
var/static/list/guns_typecache
|
||||
/// The guns already allowed by the modsuit chestplate.
|
||||
var/list/already_allowed_guns = list()
|
||||
|
||||
/obj/item/mod/module/magnetic_harness/Initialize(mapload)
|
||||
. = ..()
|
||||
if(!guns_typecache)
|
||||
guns_typecache = typecacheof(list(/obj/item/gun/ballistic, /obj/item/gun/energy, /obj/item/gun/grenadelauncher, /obj/item/gun/chem, /obj/item/gun/syringe))
|
||||
|
||||
/obj/item/mod/module/magnetic_harness/on_install()
|
||||
already_allowed_guns = guns_typecache & mod.chestplate.allowed
|
||||
mod.chestplate.allowed |= guns_typecache
|
||||
|
||||
/obj/item/mod/module/magnetic_harness/on_uninstall(deleting = FALSE)
|
||||
if(deleting)
|
||||
return
|
||||
mod.chestplate.allowed -= (guns_typecache - already_allowed_guns)
|
||||
|
||||
/obj/item/mod/module/magnetic_harness/on_suit_activation()
|
||||
RegisterSignal(mod.wearer, COMSIG_MOB_UNEQUIPPED_ITEM, .proc/check_dropped_item)
|
||||
|
||||
/obj/item/mod/module/magnetic_harness/on_suit_deactivation(deleting = FALSE)
|
||||
UnregisterSignal(mod.wearer, COMSIG_MOB_UNEQUIPPED_ITEM)
|
||||
|
||||
/obj/item/mod/module/magnetic_harness/proc/check_dropped_item(datum/source, obj/item/dropped_item, force, new_location)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!is_type_in_typecache(dropped_item, guns_typecache))
|
||||
return
|
||||
if(new_location != get_turf(src))
|
||||
return
|
||||
addtimer(CALLBACK(src, .proc/pick_up_item, dropped_item), magnet_delay)
|
||||
|
||||
/obj/item/mod/module/magnetic_harness/proc/pick_up_item(obj/item/item)
|
||||
if(!isturf(item.loc) || !item.Adjacent(mod.wearer))
|
||||
return
|
||||
if(!mod.wearer.equip_to_slot_if_possible(item, ITEM_SLOT_SUITSTORE, qdel_on_fail = FALSE, disable_warning = TRUE))
|
||||
return
|
||||
playsound(src, 'sound/items/modsuit/magnetic_harness.ogg', 50, TRUE)
|
||||
balloon_alert(mod.wearer, "[item] reattached")
|
||||
drain_power(use_power_cost)
|
||||
|
||||
///Pepper Shoulders
|
||||
|
||||
///Holster - Instantly holsters any not huge gun.
|
||||
/obj/item/mod/module/holster
|
||||
name = "MOD holster module"
|
||||
desc = "Based off typical storage compartments, this system allows the suit to holster a \
|
||||
standard firearm across its surface and allow for extremely quick retrieval. \
|
||||
While some users prefer the chest, others the forearm for quick deployment, \
|
||||
some law enforcement prefer the holster to extend from the thigh."
|
||||
icon_state = "holster"
|
||||
module_type = MODULE_USABLE
|
||||
complexity = 2
|
||||
incompatible_modules = list(/obj/item/mod/module/holster)
|
||||
cooldown_time = 0.5 SECONDS
|
||||
allowed_inactive = TRUE
|
||||
/// Gun we have holstered.
|
||||
var/obj/item/gun/holstered
|
||||
|
||||
/obj/item/mod/module/holster/on_use()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(!holstered)
|
||||
var/obj/item/gun/holding = mod.wearer.get_active_held_item()
|
||||
if(!holding)
|
||||
balloon_alert(mod.wearer, "nothing to holster!")
|
||||
return
|
||||
if(!istype(holding) || holding.w_class > WEIGHT_CLASS_BULKY)
|
||||
balloon_alert(mod.wearer, "it doesn't fit!")
|
||||
return
|
||||
if(mod.wearer.transferItemToLoc(holding, src, force = FALSE, silent = TRUE))
|
||||
holstered = holding
|
||||
balloon_alert(mod.wearer, "weapon holstered")
|
||||
playsound(src, 'sound/weapons/revolverempty.ogg', 100, TRUE)
|
||||
else if(mod.wearer.put_in_active_hand(holstered, forced = FALSE, ignore_animation = TRUE))
|
||||
balloon_alert(mod.wearer, "weapon drawn")
|
||||
playsound(src, 'sound/weapons/revolverempty.ogg', 100, TRUE)
|
||||
else
|
||||
balloon_alert(mod.wearer, "holster full!")
|
||||
|
||||
/obj/item/mod/module/holster/on_uninstall(deleting = FALSE)
|
||||
if(holstered)
|
||||
holstered.forceMove(drop_location())
|
||||
|
||||
/obj/item/mod/module/holster/Exited(atom/movable/gone, direction)
|
||||
. = ..()
|
||||
if(gone == holstered)
|
||||
holstered = null
|
||||
|
||||
/obj/item/mod/module/holster/Destroy()
|
||||
QDEL_NULL(holstered)
|
||||
return ..()
|
||||
|
||||
///Megaphone - Lets you speak loud.
|
||||
/obj/item/mod/module/megaphone
|
||||
name = "MOD megaphone module"
|
||||
desc = "A microchip megaphone linked to a MODsuit, for very important purposes, like: loudness."
|
||||
icon_state = "megaphone"
|
||||
module_type = MODULE_TOGGLE
|
||||
complexity = 1
|
||||
use_power_cost = DEFAULT_CHARGE_DRAIN * 0.5
|
||||
incompatible_modules = list(/obj/item/mod/module/megaphone)
|
||||
cooldown_time = 0.5 SECONDS
|
||||
/// List of spans we add to the speaker.
|
||||
var/list/voicespan = list(SPAN_COMMAND)
|
||||
|
||||
/obj/item/mod/module/megaphone/on_activation()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
RegisterSignal(mod.wearer, COMSIG_MOB_SAY, .proc/handle_speech)
|
||||
|
||||
/obj/item/mod/module/megaphone/on_deactivation(display_message = TRUE, deleting = FALSE)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
UnregisterSignal(mod.wearer, COMSIG_MOB_SAY)
|
||||
|
||||
/obj/item/mod/module/megaphone/proc/handle_speech(datum/source, list/speech_args)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
speech_args[SPEECH_SPANS] |= voicespan
|
||||
drain_power(use_power_cost)
|
||||
|
||||
///Criminal Capture
|
||||
|
||||
///Mirage grenade dispenser
|
||||
|
||||
///Projectile Dampener
|
||||
|
||||
///Active Sonar
|
||||
65
code/modules/mod/modules/modules_service.dm
Normal file
65
code/modules/mod/modules/modules_service.dm
Normal file
@@ -0,0 +1,65 @@
|
||||
//Service modules for MODsuits
|
||||
|
||||
///Bike Horn - Plays a bike horn sound.
|
||||
/obj/item/mod/module/bikehorn
|
||||
name = "MOD bike horn module"
|
||||
desc = "A shoulder-mounted piece of heavy sonic artillery, this module uses the finest femto-manipulator technology to \
|
||||
precisely deliver an almost lethal squeeze to... a bike horn, producing a significantly memorable sound."
|
||||
icon_state = "bikehorn"
|
||||
module_type = MODULE_USABLE
|
||||
complexity = 1
|
||||
use_power_cost = DEFAULT_CHARGE_DRAIN
|
||||
incompatible_modules = list(/obj/item/mod/module/bikehorn)
|
||||
cooldown_time = 1 SECONDS
|
||||
|
||||
/obj/item/mod/module/bikehorn/on_use()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
playsound(src, 'sound/items/bikehorn.ogg', 100, FALSE)
|
||||
drain_power(use_power_cost)
|
||||
|
||||
///Microwave Beam - Microwaves items instantly.
|
||||
/obj/item/mod/module/microwave_beam
|
||||
name = "MOD microwave beam module"
|
||||
desc = "An oddly domestic device, this module is installed into the user's palm, \
|
||||
hooking up with culinary scanners located in the helmet to blast food with precise microwave radiation, \
|
||||
allowing them to cook food from a distance, with the greatest of ease. Not recommended for use against grapes."
|
||||
icon_state = "microwave_beam"
|
||||
module_type = MODULE_ACTIVE
|
||||
complexity = 2
|
||||
use_power_cost = DEFAULT_CHARGE_DRAIN * 5
|
||||
incompatible_modules = list(/obj/item/mod/module/microwave_beam)
|
||||
cooldown_time = 10 SECONDS
|
||||
var/obj/machinery/microwave/microwave
|
||||
|
||||
/obj/item/mod/module/microwave_beam/Initialize(mapload)
|
||||
microwave = new()
|
||||
. = ..()
|
||||
|
||||
/obj/item/mod/module/microwave_beam/Destroy()
|
||||
QDEL_NULL(microwave)
|
||||
. = ..()
|
||||
|
||||
/obj/item/mod/module/microwave_beam/on_select_use(atom/target)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(!isitem(target))
|
||||
return
|
||||
if(!isturf(target.loc))
|
||||
balloon_alert(mod.wearer, "must be on the floor!")
|
||||
return
|
||||
var/obj/item/microwave_target = target
|
||||
var/datum/effect_system/spark_spread/spark_effect = new()
|
||||
spark_effect.set_up(2, 1, mod.wearer)
|
||||
spark_effect.start()
|
||||
mod.wearer.Beam(target,icon_state="lightning[rand(1,12)]", time = 5)
|
||||
if(microwave_target.microwave_act(microwave))
|
||||
playsound(src, 'sound/machines/microwave/microwave-end.ogg', 50, FALSE)
|
||||
else
|
||||
balloon_alert(mod.wearer, "can't be microwaved!")
|
||||
var/datum/effect_system/spark_spread/spark_effect_two = new()
|
||||
spark_effect_two.set_up(2, 1, microwave_target)
|
||||
spark_effect_two.start()
|
||||
drain_power(use_power_cost)
|
||||
174
code/modules/mod/modules/modules_supply.dm
Normal file
174
code/modules/mod/modules/modules_supply.dm
Normal file
@@ -0,0 +1,174 @@
|
||||
//Supply modules for MODsuits
|
||||
|
||||
///Internal GPS - Extends a GPS you can use.
|
||||
/obj/item/mod/module/gps
|
||||
name = "MOD internal GPS module"
|
||||
desc = "This module uses common Nanotrasen technology to calculate the user's position anywhere in space, \
|
||||
down to the exact coordinates. This information is fed to a central database viewable from the device itself, \
|
||||
though using it to help people is up to you."
|
||||
icon_state = "gps"
|
||||
module_type = MODULE_USABLE
|
||||
complexity = 1
|
||||
use_power_cost = DEFAULT_CHARGE_DRAIN * 0.2
|
||||
incompatible_modules = list(/obj/item/mod/module/gps)
|
||||
cooldown_time = 0.5 SECONDS
|
||||
allowed_inactive = TRUE
|
||||
|
||||
/obj/item/mod/module/gps/Initialize(mapload)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/gps/item, "MOD0", state = GLOB.deep_inventory_state, overlay_state = FALSE)
|
||||
|
||||
/obj/item/mod/module/gps/on_use()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
attack_self(mod.wearer)
|
||||
|
||||
///Hydraulic Clamp - Lets you pick up and drop crates.
|
||||
/obj/item/mod/module/clamp
|
||||
name = "MOD hydraulic clamp module"
|
||||
desc = "A series of actuators installed into both arms of the suit, boasting a lifting capacity of almost a ton. \
|
||||
However, this design has been locked by Nanotrasen to be primarily utilized for lifting various crates. \
|
||||
A lot of people would say that loading cargo is a dull job, but you could not disagree more."
|
||||
icon_state = "clamp"
|
||||
module_type = MODULE_ACTIVE
|
||||
complexity = 3
|
||||
use_power_cost = DEFAULT_CHARGE_DRAIN
|
||||
incompatible_modules = list(/obj/item/mod/module/clamp)
|
||||
cooldown_time = 0.5 SECONDS
|
||||
overlay_state_inactive = "module_clamp"
|
||||
overlay_state_active = "module_clamp_on"
|
||||
/// Time it takes to load a crate.
|
||||
var/load_time = 3 SECONDS
|
||||
/// The max amount of crates you can carry.
|
||||
var/max_crates = 3
|
||||
/// The crates stored in the module.
|
||||
var/list/stored_crates = list()
|
||||
|
||||
/obj/item/mod/module/clamp/on_select_use(atom/target)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(!mod.wearer.Adjacent(target))
|
||||
return
|
||||
if(istype(target, /obj/structure/closet/crate) || istype(target, /obj/structure/bigDelivery))
|
||||
var/atom/movable/picked_crate = target
|
||||
if(!check_crate_pickup(picked_crate))
|
||||
return
|
||||
playsound(src, 'sound/mecha/hydraulic.ogg', 25, TRUE)
|
||||
if(!do_after(mod.wearer, load_time, target = target))
|
||||
balloon_alert(mod.wearer, "interrupted!")
|
||||
return
|
||||
if(!check_crate_pickup(picked_crate))
|
||||
return
|
||||
stored_crates += picked_crate
|
||||
picked_crate.forceMove(src)
|
||||
balloon_alert(mod.wearer, "picked up [picked_crate]")
|
||||
drain_power(use_power_cost)
|
||||
else if(length(stored_crates))
|
||||
var/turf/target_turf = get_turf(target)
|
||||
if(is_blocked_turf(target_turf))
|
||||
return
|
||||
playsound(src, 'sound/mecha/hydraulic.ogg', 25, TRUE)
|
||||
if(!do_after(mod.wearer, load_time, target = target))
|
||||
balloon_alert(mod.wearer, "interrupted!")
|
||||
return
|
||||
if(is_blocked_turf(target_turf))
|
||||
return
|
||||
var/atom/movable/dropped_crate = pop(stored_crates)
|
||||
dropped_crate.forceMove(target_turf)
|
||||
balloon_alert(mod.wearer, "dropped [dropped_crate]")
|
||||
drain_power(use_power_cost)
|
||||
else
|
||||
balloon_alert(mod.wearer, "invalid target!")
|
||||
|
||||
/obj/item/mod/module/clamp/on_suit_deactivation(deleting = FALSE)
|
||||
if(deleting)
|
||||
return
|
||||
for(var/atom/movable/crate as anything in stored_crates)
|
||||
crate.forceMove(drop_location())
|
||||
stored_crates -= crate
|
||||
|
||||
/obj/item/mod/module/clamp/proc/check_crate_pickup(atom/movable/target)
|
||||
if(length(stored_crates) >= max_crates)
|
||||
balloon_alert(mod.wearer, "too many crates!")
|
||||
return FALSE
|
||||
for(var/mob/living/mob in target.GetAllContents())
|
||||
if(mob.mob_size < MOB_SIZE_HUMAN)
|
||||
continue
|
||||
balloon_alert(mod.wearer, "crate too heavy!")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/mod/module/clamp/loader
|
||||
name = "MOD loader hydraulic clamp module"
|
||||
icon_state = "clamp_loader"
|
||||
complexity = 0
|
||||
removable = FALSE
|
||||
overlay_state_inactive = null
|
||||
overlay_state_active = "module_clamp_loader"
|
||||
load_time = 1 SECONDS
|
||||
max_crates = 5
|
||||
use_mod_colors = TRUE
|
||||
|
||||
///Drill - Lets you dig through rock and basalt.
|
||||
/obj/item/mod/module/drill // TODO: Would be cooler with a built-in drill, but meh
|
||||
name = "MOD pickaxe/drill storage module"
|
||||
desc = "Provides a convenient storage compartment for pickaxes and drills."
|
||||
icon_state = "drill"
|
||||
complexity = 2
|
||||
incompatible_modules = list(/obj/item/mod/module/drill)
|
||||
cooldown_time = 0.5 SECONDS
|
||||
allowed_inactive = TRUE
|
||||
module_type = MODULE_USABLE
|
||||
/// Pickaxe we have stored.
|
||||
var/obj/item/pickaxe/stored
|
||||
|
||||
/obj/item/mod/module/drill/on_use()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(!stored)
|
||||
var/obj/item/pickaxe/holding = mod.wearer.get_active_held_item()
|
||||
if(!holding)
|
||||
balloon_alert(mod.wearer, "nothing to store!")
|
||||
return
|
||||
if(!istype(holding))
|
||||
balloon_alert(mod.wearer, "it doesn't fit!")
|
||||
return
|
||||
if(mod.wearer.transferItemToLoc(holding, src, force = FALSE, silent = TRUE))
|
||||
stored = holding
|
||||
balloon_alert(mod.wearer, "mining instrument stored")
|
||||
playsound(src, 'sound/weapons/revolverempty.ogg', 100, TRUE)
|
||||
else if(mod.wearer.put_in_active_hand(stored, forced = FALSE, ignore_animation = TRUE))
|
||||
balloon_alert(mod.wearer, "mining instrument retrieved")
|
||||
playsound(src, 'sound/weapons/revolverempty.ogg', 100, TRUE)
|
||||
else
|
||||
balloon_alert(mod.wearer, "mining instrument storage full!")
|
||||
|
||||
/obj/item/mod/module/drill/on_uninstall(deleting = FALSE)
|
||||
if(stored)
|
||||
stored.forceMove(drop_location())
|
||||
|
||||
/obj/item/mod/module/drill/Exited(atom/movable/gone, direction)
|
||||
. = ..()
|
||||
if(gone == stored)
|
||||
stored = null
|
||||
|
||||
/obj/item/mod/module/drill/Destroy()
|
||||
QDEL_NULL(stored)
|
||||
return ..()
|
||||
|
||||
/obj/item/mod/module/orebag // TODO
|
||||
name = "MOD mining satchel storage module"
|
||||
desc = "Provides a convenient storage department for a mining satchel."
|
||||
icon_state = "ore"
|
||||
module_type = MODULE_USABLE
|
||||
complexity = 1
|
||||
use_power_cost = DEFAULT_CHARGE_DRAIN * 0.2
|
||||
incompatible_modules = list(/obj/item/mod/module/orebag)
|
||||
cooldown_time = 0.5 SECONDS
|
||||
allowed_inactive = TRUE
|
||||
|
||||
// Ash accretion looks cool, but can't be arsed to implement
|
||||
// Same with sphere transformation
|
||||
91
code/modules/mod/modules/modules_visor.dm
Normal file
91
code/modules/mod/modules/modules_visor.dm
Normal file
@@ -0,0 +1,91 @@
|
||||
//Visor modules for MODsuits
|
||||
|
||||
///Base Visor - Adds a specific HUD and traits to you.
|
||||
/obj/item/mod/module/visor
|
||||
name = "MOD visor module"
|
||||
desc = "A heads-up display installed into the visor of the suit. They say these also let you see behind you."
|
||||
module_type = MODULE_TOGGLE
|
||||
complexity = 2
|
||||
active_power_cost = DEFAULT_CHARGE_DRAIN * 0.3
|
||||
incompatible_modules = list(/obj/item/mod/module/visor)
|
||||
cooldown_time = 0.5 SECONDS
|
||||
/// The HUD type given by the visor.
|
||||
var/hud_type
|
||||
/// The traits given by the visor.
|
||||
var/list/visor_traits = list()
|
||||
|
||||
/obj/item/mod/module/visor/on_activation()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(hud_type)
|
||||
var/datum/atom_hud/hud = GLOB.huds[hud_type]
|
||||
hud.add_hud_to(mod.wearer)
|
||||
for(var/trait in visor_traits)
|
||||
ADD_TRAIT(mod.wearer, trait, MOD_TRAIT)
|
||||
mod.wearer.update_sight()
|
||||
|
||||
/obj/item/mod/module/visor/on_deactivation(display_message = TRUE, deleting = FALSE)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(hud_type)
|
||||
var/datum/atom_hud/hud = GLOB.huds[hud_type]
|
||||
hud.remove_hud_from(mod.wearer)
|
||||
for(var/trait in visor_traits)
|
||||
REMOVE_TRAIT(mod.wearer, trait, MOD_TRAIT)
|
||||
mod.wearer.update_sight()
|
||||
|
||||
//Medical Visor - Gives you a medical HUD.
|
||||
/obj/item/mod/module/visor/medhud
|
||||
name = "MOD medical visor module"
|
||||
desc = "A heads-up display installed into the visor of the suit. This cross-references suit sensor data with a modern \
|
||||
biological scanning suite, allowing the user to visualize the current health of organic lifeforms, as well as \
|
||||
access data such as patient files in a convenient readout. They say these also let you see behind you."
|
||||
icon_state = "medhud_visor"
|
||||
hud_type = DATA_HUD_MEDICAL_ADVANCED
|
||||
|
||||
//Diagnostic Visor - Gives you a diagnostic HUD.
|
||||
/obj/item/mod/module/visor/diaghud
|
||||
name = "MOD diagnostic visor module"
|
||||
desc = "A heads-up display installed into the visor of the suit. This uses a series of advanced sensors to access data \
|
||||
from advanced machinery, exosuits, and other devices, allowing the user to visualize current power levels \
|
||||
and integrity of such. They say these also let you see behind you."
|
||||
icon_state = "diaghud_visor"
|
||||
hud_type = DATA_HUD_DIAGNOSTIC_ADVANCED
|
||||
|
||||
//Security Visor - Gives you a security HUD.
|
||||
/obj/item/mod/module/visor/sechud
|
||||
name = "MOD security visor module"
|
||||
desc = "A heads-up display installed into the visor of the suit. This module is a heavily-retrofitted targeting system, \
|
||||
plugged into various criminal databases to be able to view arrest records, command simple security-oriented robots, \
|
||||
and generally know who to shoot. They say these also let you see behind you."
|
||||
icon_state = "sechud_visor"
|
||||
hud_type = DATA_HUD_SECURITY_ADVANCED
|
||||
|
||||
//Meson Visor - Gives you meson vision.
|
||||
/obj/item/mod/module/visor/meson
|
||||
name = "MOD meson visor module"
|
||||
desc = "A heads-up display installed into the visor of the suit. This module is based off well-loved meson scanner \
|
||||
technology, used by construction workers and miners across the galaxy to see basic structural and terrain layouts \
|
||||
through walls, regardless of lighting conditions. They say these also let you see behind you."
|
||||
icon_state = "meson_visor"
|
||||
visor_traits = list(TRAIT_MESON_VISION)
|
||||
|
||||
//Thermal Visor - Gives you thermal vision.
|
||||
/obj/item/mod/module/visor/thermal
|
||||
name = "MOD thermal visor module"
|
||||
desc = "A heads-up display installed into the visor of the suit. This uses a small IR scanner to detect and identify \
|
||||
the thermal radiation output of objects near the user. While it can detect the heat output of even something as \
|
||||
small as a rodent, it still produces irritating red overlay. They say these also let you see behind you."
|
||||
icon_state = "thermal_visor"
|
||||
visor_traits = list(TRAIT_THERMAL_VISION)
|
||||
|
||||
//Night Visor - Gives you night vision.
|
||||
/obj/item/mod/module/visor/night
|
||||
name = "MOD night visor module"
|
||||
desc = "A heads-up display installed into the visor of the suit. Typical for both civilian and military applications, \
|
||||
this allows the user to perceive their surroundings while in complete darkness, enhancing the view by tenfold; \
|
||||
yet brightening everything into a spooky green glow. They say these also let you see behind you."
|
||||
icon_state = "night_visor"
|
||||
visor_traits = list(TRAIT_TRUE_NIGHT_VISION)
|
||||
Reference in New Issue
Block a user