modsuits part 1

This commit is contained in:
PeriodicChaos
2022-08-19 15:42:47 -04:00
committed by Jerry Wester
parent 792790216d
commit 183b554ed3
32 changed files with 421 additions and 50 deletions

6
code/__DEFINES/ai.dm Normal file
View File

@@ -0,0 +1,6 @@
///Mob the MOD is trying to attach to
#define BB_MOD_TARGET "BB_mod_target"
///The implant the AI was created from
#define BB_MOD_IMPLANT "BB_mod_implant"
///Range for a MOD AI controller.
#define MOD_AI_RANGE 100

View File

@@ -0,0 +1,3 @@
/// from base of atom/movable/Process_Spacemove(): (movement_dir)
#define COMSIG_MOVABLE_SPACEMOVE "spacemove"
#define COMSIG_MOVABLE_STOP_SPACEMOVE (1<<0)

View File

@@ -0,0 +1,3 @@
/// from base of atom/movable/Process_Spacemove(): (movement_dir)
#define COMSIG_MOVABLE_SPACEMOVE "spacemove"
#define COMSIG_MOVABLE_STOP_SPACEMOVE (1<<0)

View File

@@ -1,2 +1,6 @@
///From base of mob/living/MobBump() (mob/living)
#define COMSIG_LIVING_MOB_BUMP "living_mob_bump"
///From base of mob/living/ZImpactDamage() (mob/living, levels, turf/t)
#define COMSIG_LIVING_Z_IMPACT "living_z_impact"
#define NO_Z_IMPACT_DAMAGE (1<<0)

View File

@@ -0,0 +1,7 @@
//MODsuit signals
/// Called when a module is selected to be the active one from on_select()
#define COMSIG_MOD_MODULE_SELECTED "mod_module_selected"
/// Called when a MOD activation is called from toggle_activate(mob/user)
#define COMSIG_MOD_ACTIVATE "mod_activate"
/// Cancels the suit's activation
#define MOD_CANCEL_ACTIVATE (1 << 0)

31
code/__DEFINES/mod.dm Normal file
View File

@@ -0,0 +1,31 @@
/// Default value for the max_complexity var on MODsuits
#define DEFAULT_MAX_COMPLEXITY 15
/// Default cell drain per process on MODsuits
#define DEFAULT_CELL_DRAIN 5
/// Passive module, just acts when put in naturally.
#define MODULE_PASSIVE 0
/// Usable module, does something when you press a button.
#define MODULE_USABLE 1
/// Toggle module, you turn it on/off and it does stuff.
#define MODULE_TOGGLE 2
/// Actively usable module, you may only have one selected at a time.
#define MODULE_ACTIVE 3
//Defines used by the theme for clothing flags and similar
#define HELMET_LAYER "helmet_layer"
#define HELMET_FLAGS "helmet_flags"
#define CHESTPLATE_FLAGS "chestplate_flags"
#define GAUNTLETS_FLAGS "gauntlets_flags"
#define BOOTS_FLAGS "boots_flags"
#define UNSEALED_CLOTHING "unsealed_clothing"
#define SEALED_CLOTHING "sealed_clothing"
#define UNSEALED_INVISIBILITY "unsealed_invisibility"
#define SEALED_INVISIBILITY "sealed_invisibility"
#define UNSEALED_COVER "unsealed_cover"
#define SEALED_COVER "sealed_cover"
/// Global list of all /datum/mod_theme
GLOBAL_LIST_INIT(mod_themes, setup_mod_themes())

View File

@@ -158,6 +158,22 @@
#define TRAIT_CALCIUM_HEALER "calcium_healer"
#define TRAIT_MAGIC_CHOKE "magic_choke"
#define TRAIT_CAPTAIN_METABOLISM "captain-metabolism"
/// Prevents plasmamen from self-igniting
#define TRAIT_NOSELFIGNITION "no_selfignition"
/// Like antimagic, but doesn't block the user from casting
#define TRAIT_ANTIMAGIC_NO_SELFBLOCK "anti_magic_no_selfblock"
/// Gives us turf, mob and object vision through walls
#define TRAIT_XRAY_VISION "xray_vision"
/// Gives us mob vision through walls and slight night vision
#define TRAIT_THERMAL_VISION "thermal_vision"
/// Gives us turf vision through walls and slight night vision
#define TRAIT_MESON_VISION "meson_vision"
/// Gives us Night vision
#define TRAIT_TRUE_NIGHT_VISION "true_night_vision"
/// Negates our gravity, letting us move normally on floors in 0-g
#define TRAIT_NEGATES_GRAVITY "negates_gravity"
/// Lets us scan reagents
#define TRAIT_REAGENT_SCANNER "reagent_scanner"
#define TRAIT_ABDUCTOR_TRAINING "abductor-training"
#define TRAIT_ABDUCTOR_SCIENTIST_TRAINING "abductor-scientist-training"
#define TRAIT_SURGEON "surgeon"
@@ -377,3 +393,5 @@
#define STATION_TRAIT_FILLED_MAINT "station_trait_filled_maint"
#define STATION_TRAIT_EMPTY_MAINT "station_trait_empty_maint"
#define STATION_TRAIT_PDA_GLITCHED "station_trait_pda_glitched"
/// Trait applied by MODsuits.
#define MOD_TRAIT "mod"

View File

@@ -0,0 +1,4 @@
#define SHELL_FLAG_CIRCUIT_UNREMOVABLE (1<<0)
/// Whether a circuit is not able to be modified
#define SHELL_FLAG_CIRCUIT_UNMODIFIABLE (1<<5)

View File

@@ -51,6 +51,7 @@ GLOBAL_LIST_INIT(maintenance_loot, list(
/obj/item/airlock_painter = 1,
/obj/item/stack/cable_coil/random = 4,
/obj/item/stack/cable_coil/random/five = 6,
/obj/item/mod/construction/broken_core = 5,
/obj/item/stack/medical/suture = 1,
/obj/item/stack/rods/ten = 9,
/obj/item/stack/rods/twentyfive = 1,

View File

@@ -91,6 +91,8 @@ GLOBAL_LIST_EMPTY(radial_menus)
else
py_shift = 32
restrict_to_dir(NORTH) //I was going to parse screen loc here but that's more effort than it's worth.
else if(hudfix_method && AM.loc)
anchor = get_atom_on_turf(anchor)
//Sets defaults
//These assume 45 deg min_angle

View File

@@ -0,0 +1,48 @@
/// An AI controller for the MODsuit pathfinder module. It's activated by implant and attaches itself to the user.
/datum/ai_controller/mod
blackboard = list(
BB_MOD_TARGET,
BB_MOD_IMPLANT,
)
max_target_distance = MOD_AI_RANGE //a little spicy but its one specific item that summons it, and it doesnt run otherwise
ai_movement = /datum/ai_movement/jps
///ID card generated from the suit's required access. Used for pathing.
var/obj/item/card/id/advanced/id_card
/datum/ai_controller/mod/TryPossessPawn(atom/new_pawn)
if(!istype(new_pawn, /obj/item/mod/control))
return AI_CONTROLLER_INCOMPATIBLE
var/obj/item/mod/control/mod = new_pawn
id_card = new /obj/item/card/id/advanced/simple_bot()
if(length(mod.req_access))
id_card.set_access(mod.req_access)
return ..() //Run parent at end
/datum/ai_controller/mod/UnpossessPawn(destroy)
QDEL_NULL(id_card)
return ..() //Run parent at end
/datum/ai_controller/mod/SelectBehaviors(delta_time)
current_behaviors = list()
if(blackboard[BB_MOD_TARGET] && blackboard[BB_MOD_IMPLANT])
queue_behavior(/datum/ai_behavior/mod_attach)
/datum/ai_controller/mod/get_access()
return id_card
/datum/ai_behavior/mod_attach
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT|AI_BEHAVIOR_MOVE_AND_PERFORM
/datum/ai_behavior/mod_attach/perform(delta_time, datum/ai_controller/controller)
. = ..()
if(!controller.pawn.Adjacent(controller.blackboard[BB_MOD_TARGET]))
return
var/obj/item/implant/mod/implant = controller.blackboard[BB_MOD_IMPLANT]
implant.module.attach(controller.blackboard[BB_MOD_TARGET])
finish_action(controller, TRUE)
/datum/ai_behavior/mod_attach/finish_action(datum/ai_controller/controller, succeeded)
. = ..()
controller.blackboard[BB_MOD_TARGET] = null
var/obj/item/implant/mod/implant = controller.blackboard[BB_MOD_IMPLANT]
implant.end_recall(succeeded)

View File

@@ -554,6 +554,19 @@
subcategory = CAT_MISCELLANEOUS
category = CAT_MISCELLANEOUS
/datum/crafting_recipe/mod_core
name = "MOD core"
result = /obj/item/mod/construction/core
tool_behaviors = list(TOOL_SCREWDRIVER)
time = 10 SECONDS
reqs = list(/obj/item/stack/cable_coil = 5,
/obj/item/stack/rods = 2,
/obj/item/stack/sheet/glass = 1,
/obj/item/organ/heart = 1
)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISCELLANEOUS
//////////////
//Banners/////
//////////////

View File

@@ -369,9 +369,10 @@
//Tries to dump content
/datum/component/storage/proc/dump_content_at(atom/dest_object, mob/M)
var/atom/A = parent
var/atom/dump_destination = dest_object.get_dumping_location()
if(A.Adjacent(M) && dump_destination && M.Adjacent(dump_destination))
var/atom/dump_destination = get_dumping_location(dest_object)
if(M.CanReach(A) && dump_destination && M.CanReach(dump_destination))
if(check_locked(null, M, TRUE))
to_chat(M, "<span class='warning'>[parent] seems to be locked!</span>")
return FALSE
if(dump_destination.storage_contents_dump_act(src, M))
playsound(A, "rustle", 50, 1, -5)

View File

@@ -348,12 +348,21 @@
/datum/preset_holoimage/engineer/rig
outfit_type = /datum/outfit/job/engineer/gloved/rig
/datum/preset_holoimage/engineer/mod
outfit_type = /datum/outfit/job/engineer/mod
/datum/preset_holoimage/engineer/ce
outfit_type = /datum/outfit/job/ce
/datum/preset_holoimage/engineer/ce/mod
outfit_type = /datum/outfit/job/ce/mod
/datum/preset_holoimage/engineer/ce/rig
outfit_type = /datum/outfit/job/engineer/gloved/rig
/datum/preset_holoimage/engineer/atmos/mod
outfit_type = /datum/outfit/job/atmos/mod
/datum/preset_holoimage/engineer/atmos
outfit_type = /datum/outfit/job/atmos
@@ -449,6 +458,7 @@
SAY Oh, shit!
DELAY 10
PRESET /datum/preset_holoimage/engineer/atmos/rig
PRESET /datum/preset_holoimage/engineer/atmos/mod
LANGUAGE /datum/language/narsie
NAME Unknown
SAY RISE, MY LORD!!
@@ -456,6 +466,7 @@
LANGUAGE /datum/language/common
NAME Plastic
PRESET /datum/preset_holoimage/engineer/rig
PRESET /datum/preset_holoimage/engineer/mod
SAY Fuck, fuck, fuck!
DELAY 20
SAY It's loose! CALL THE FUCKING SHUTT-

View File

@@ -79,6 +79,10 @@
//Type path of item to go in left hand
var/r_hand = null
///ID of the slot containing a gas tank
var/internals_slot = null
/// Any clothing accessory item
var/accessory = null
@@ -140,6 +144,15 @@
//to be overridden for toggling internals, id binding, access etc
return
#define EQUIP_OUTFIT_ITEM(item_path, slot_name) if(##item_path) { \
H.equip_to_slot_or_del(SSwardrobe.provide_type(##item_path), ##slot_name, TRUE); \
var/obj/item/outfit_item = H.get_item_by_slot(##slot_name); \
if (outfit_item && outfit_item.type == ##item_path) { \
outfit_item.on_outfit_equip(H, visualsOnly, ##slot_name); \
} \
}
/**
* Equips all defined types and paths to the mob passed in
*
@@ -153,31 +166,32 @@
//Start with uniform,suit,backpack for additional slots
if(uniform)
H.equip_to_slot_or_del(new uniform(H), ITEM_SLOT_ICLOTHING, TRUE)
EQUIP_OUTFIT_ITEM(uniform, ITEM_SLOT_ICLOTHING)
if(suit)
H.equip_to_slot_or_del(new suit(H), ITEM_SLOT_OCLOTHING, TRUE)
if(back)
H.equip_to_slot_or_del(new back(H), ITEM_SLOT_BACK, TRUE)
EQUIP_OUTFIT_ITEM(suit, ITEM_SLOT_OCLOTHING)
if(belt)
H.equip_to_slot_or_del(new belt(H), ITEM_SLOT_BELT, TRUE)
EQUIP_OUTFIT_ITEM(belt, ITEM_SLOT_BELT)
if(gloves)
H.equip_to_slot_or_del(new gloves(H), ITEM_SLOT_GLOVES, TRUE)
EQUIP_OUTFIT_ITEM(gloves, ITEM_SLOT_GLOVES)
if(shoes)
H.equip_to_slot_or_del(new shoes(H), ITEM_SLOT_FEET, TRUE)
EQUIP_OUTFIT_ITEM(shoes, ITEM_SLOT_FEET)
if(head)
H.equip_to_slot_or_del(new head(H), ITEM_SLOT_HEAD, TRUE)
EQUIP_OUTFIT_ITEM(head, ITEM_SLOT_HEAD)
if(mask)
H.equip_to_slot_or_del(new mask(H), ITEM_SLOT_MASK, TRUE)
EQUIP_OUTFIT_ITEM(mask, ITEM_SLOT_MASK)
if(neck)
H.equip_to_slot_or_del(new neck(H), ITEM_SLOT_NECK, TRUE)
EQUIP_OUTFIT_ITEM(neck, ITEM_SLOT_NECK)
if(ears)
H.equip_to_slot_or_del(new ears(H), ITEM_SLOT_EARS, TRUE)
EQUIP_OUTFIT_ITEM(ears, ITEM_SLOT_EARS)
if(glasses)
H.equip_to_slot_or_del(new glasses(H), ITEM_SLOT_EYES, TRUE)
EQUIP_OUTFIT_ITEM(glasses, ITEM_SLOT_EYES)
if(back)
EQUIP_OUTFIT_ITEM(back, ITEM_SLOT_BACK)
if(id)
H.equip_to_slot_or_del(new id(H), ITEM_SLOT_ID, TRUE)
EQUIP_OUTFIT_ITEM(id, ITEM_SLOT_ID)
if(suit_store)
H.equip_to_slot_or_del(new suit_store(H), ITEM_SLOT_SUITSTORE, TRUE)
EQUIP_OUTFIT_ITEM(suit_store, ITEM_SLOT_SUITSTORE)
if(undershirt)
H.undershirt = initial(undershirt.name)
@@ -195,9 +209,9 @@
if(!visualsOnly) // Items in pockets or backpack don't show up on mob's icon.
if(l_pocket)
H.equip_to_slot_or_del(new l_pocket(H), ITEM_SLOT_LPOCKET, TRUE)
EQUIP_OUTFIT_ITEM(l_pocket, ITEM_SLOT_LPOCKET)
if(r_pocket)
H.equip_to_slot_or_del(new r_pocket(H), ITEM_SLOT_RPOCKET, TRUE)
EQUIP_OUTFIT_ITEM(r_pocket, ITEM_SLOT_RPOCKET)
if(box)
if(!backpack_contents)
@@ -211,11 +225,7 @@
if(!isnum(number))//Default to 1
number = 1
for(var/i in 1 to number)
H.equip_to_slot_or_del(new path(H), ITEM_SLOT_BACKPACK, TRUE)
if(!H.head && toggle_helmet && istype(H.wear_suit, /obj/item/clothing/suit/space/hardsuit))
var/obj/item/clothing/suit/space/hardsuit/HS = H.wear_suit
HS.ToggleHelmet()
EQUIP_OUTFIT_ITEM(path, ITEM_SLOT_BACKPACK)
post_equip(H, visualsOnly, preference_source)
@@ -232,6 +242,9 @@
H.update_body()
return TRUE
#undef EQUIP_OUTFIT_ITEM
/**
* Apply a fingerprint from the passed in human to all items in the outfit
*

57
code/datums/wires/mod.dm Normal file
View File

@@ -0,0 +1,57 @@
/datum/wires/mod
holder_type = /obj/item/mod/control
proper_name = "MOD control unit"
/datum/wires/mod/New(atom/holder)
wires = list(WIRE_HACK, WIRE_DISABLE, WIRE_SHOCK, WIRE_INTERFACE)
add_duds(2)
..()
/datum/wires/mod/interactable(mob/user)
if(!..())
return FALSE
var/obj/item/mod/control/mod = holder
return mod.open
/datum/wires/mod/get_status()
var/obj/item/mod/control/mod = holder
var/list/status = list()
status += "The orange light is [mod.seconds_electrified ? "on" : "off"]."
status += "The red light is [mod.malfunctioning ? "off" : "blinking"]."
status += "The green light is [mod.locked ? "on" : "off"]."
status += "The yellow light is [mod.interface_break ? "off" : "on"]."
return status
/datum/wires/mod/on_pulse(wire)
var/obj/item/mod/control/mod = holder
switch(wire)
if(WIRE_HACK)
mod.locked = !mod.locked
if(WIRE_DISABLE)
mod.malfunctioning = TRUE
if(WIRE_SHOCK)
mod.seconds_electrified = MACHINE_DEFAULT_ELECTRIFY_TIME
if(WIRE_INTERFACE)
mod.interface_break = !mod.interface_break
/datum/wires/mod/on_cut(wire, mend)
var/obj/item/mod/control/mod = holder
switch(wire)
if(WIRE_HACK)
if(!mend)
mod.req_access = list()
if(WIRE_DISABLE)
mod.malfunctioning = !mend
if(WIRE_SHOCK)
if(mend)
mod.seconds_electrified = MACHINE_NOT_ELECTRIFIED
else
mod.seconds_electrified = MACHINE_ELECTRIFIED_PERMANENT
if(WIRE_INTERFACE)
mod.interface_break = !mend
/datum/wires/mod/ui_act(action, params)
var/obj/item/mod/control/mod = holder
if(!issilicon(usr) && mod.seconds_electrified && mod.shock(usr))
return FALSE
return ..()

View File

@@ -911,7 +911,8 @@
user.active_storage.ui_show(user)
return TRUE
/atom/proc/get_dumping_location(obj/item/storage/source,mob/user)
///Get the best place to dump the items contained in the source storage item?
/atom/proc/get_dumping_location()
return null
//This proc is called on the location of an atom when the atom is Destroy()'d

View File

@@ -381,7 +381,7 @@
/obj/machinery/door/morgue
icon = 'icons/obj/doors/doormorgue.dmi'
/obj/machinery/door/get_dumping_location(obj/item/storage/source,mob/user)
/obj/machinery/door/get_dumping_location()
return null
/obj/machinery/door/proc/lock()

View File

@@ -1,6 +1,6 @@
/obj/machinery/recharge_station
name = "cyborg recharging station"
desc = "This device recharges cyborgs and resupplies them with materials."
name = "recharging station"
desc = "This device recharges energy dependent lifeforms, like cyborgs, ethereals and MODsuit users."
icon = 'icons/obj/objects.dmi'
icon_state = "borgcharger0"
density = FALSE

View File

@@ -10,11 +10,15 @@
var/obj/item/clothing/suit/space/suit = null
var/obj/item/clothing/head/helmet/space/helmet = null
var/obj/item/clothing/mask/mask = null
var/obj/item/mod/control/mod = null
var/obj/item/storage = null
var/suit_type = null
var/helmet_type = null
var/mask_type = null
/// What type of MOD the unit starts with when spawned.
var/mod_type = null
/// What type of additional item the unit starts with when spawned.
var/storage_type = null
state_open = FALSE
@@ -38,21 +42,50 @@
mask_type = /obj/item/clothing/mask/gas/sechailer
storage_type = /obj/item/tank/jetpack/oxygen/captain
/obj/machinery/suit_storage_unit/captainmod
mask_type = /obj/item/clothing/mask/gas/atmos/captain
storage_type = /obj/item/tank/jetpack/oxygen/captain
mod_type = /obj/item/mod/control/pre_equipped/magnate
/obj/machinery/suit_storage_unit/engine
suit_type = /obj/item/clothing/suit/space/hardsuit/engine
mask_type = /obj/item/clothing/mask/breath
storage_type= /obj/item/clothing/shoes/magboots
/obj/machinery/suit_storage_unit/enginemod
mask_type = /obj/item/clothing/mask/breath
mod_type = /obj/item/mod/control/pre_equipped/engineering
/obj/machinery/suit_storage_unit/atmos
suit_type = /obj/item/clothing/suit/space/hardsuit/engine/atmos
mask_type = /obj/item/clothing/mask/gas/atmos
storage_type = /obj/item/watertank/atmos
/obj/machinery/suit_storage_unit/atmosmod
mask_type = /obj/item/clothing/mask/gas/atmos
storage_type = /obj/item/watertank/atmos
mod_type = /obj/item/mod/control/pre_equipped/atmospheric
/obj/machinery/suit_storage_unit/ce
suit_type = /obj/item/clothing/suit/space/hardsuit/engine/elite
mask_type = /obj/item/clothing/mask/breath
storage_type= /obj/item/clothing/shoes/magboots/advance
/obj/machinery/suit_storage_unit/cemod
mask_type = /obj/item/clothing/mask/breath
storage_type = /obj/item/clothing/shoes/magboots/advance
mod_type = /obj/item/mod/control/pre_equipped/advanced
/obj/machinery/suit_storage_unit/security
suit_type = /obj/item/clothing/suit/space/hardsuit/security
mask_type = /obj/item/clothing/mask/gas/sechailer
storage_type = /obj/item/tank/jetpack/oxygen/security
/obj/machinery/suit_storage_unit/securitymod
mask_type = /obj/item/clothing/mask/gas/sechailer
mod_type = /obj/item/mod/control/pre_equipped/security
/obj/machinery/suit_storage_unit/hos
suit_type = /obj/item/clothing/suit/space/hardsuit/security/hos
mask_type = /obj/item/clothing/mask/gas/sechailer
@@ -63,6 +96,11 @@
mask_type = /obj/item/clothing/mask/gas
storage_type = /obj/item/watertank/atmos
/obj/machinery/suit_storage_unit/hosmod
mask_type = /obj/item/clothing/mask/gas/sechailer
storage_type = /obj/item/tank/internals/oxygen
mod_type = /obj/item/mod/control/pre_equipped/safeguard
/obj/machinery/suit_storage_unit/mining
suit_type = /obj/item/clothing/suit/hooded/explorer/standard
mask_type = /obj/item/clothing/mask/gas/explorer
@@ -71,6 +109,16 @@
suit_type = /obj/item/clothing/suit/space/hardsuit/mining
mask_type = /obj/item/clothing/mask/breath
/obj/machinery/suit_storage_unit/mining/evahos
suit_type = null
mask_type = /obj/item/clothing/mask/breath
mod_type = /obj/item/mod/control/pre_equipped/mining
/obj/machinery/suit_storage_unit/medicalmod
mask_type = /obj/item/clothing/mask/breath/medical
storage_type = /obj/item/tank/internals/oxygen
mod_type = /obj/item/mod/control/pre_equipped/medical
/obj/machinery/suit_storage_unit/cmo
suit_type = /obj/item/clothing/suit/space/hardsuit/medical
mask_type = /obj/item/clothing/mask/breath
@@ -81,15 +129,29 @@
helmet_type = /obj/item/clothing/head/helmet/space/eva/paramedic
mask_type = /obj/item/clothing/mask/breath
/obj/machinery/suit_storage_unit/cmomod
mask_type = /obj/item/clothing/mask/breath/medical
storage_type = /obj/item/tank/internals/oxygen
mod_type = /obj/item/mod/control/pre_equipped/rescue
/obj/machinery/suit_storage_unit/rd
suit_type = /obj/item/clothing/suit/space/hardsuit/rd
mask_type = /obj/item/clothing/mask/breath
/obj/machinery/suit_storage_unit/rdmod
mask_type = /obj/item/clothing/mask/breath
mod_type = /obj/item/mod/control/pre_equipped/research
/obj/machinery/suit_storage_unit/syndicate
suit_type = /obj/item/clothing/suit/space/hardsuit/syndi
mask_type = /obj/item/clothing/mask/gas/syndicate
storage_type = /obj/item/tank/jetpack/oxygen/harness
/obj/machinery/suit_storage_unit/syndicatemod
mask_type = /obj/item/clothing/mask/gas/syndicate
storage_type = /obj/item/tank/jetpack/oxygen/harness
mod_type = /obj/item/mod/control/pre_equipped/nuclear
/obj/machinery/suit_storage_unit/ert/command
suit_type = /obj/item/clothing/suit/space/hardsuit/ert
mask_type = /obj/item/clothing/mask/breath
@@ -129,6 +191,8 @@
helmet = new helmet_type(src)
if(mask_type)
mask = new mask_type(src)
if(mod_type)
mod = new mod_type(src)
if(storage_type)
storage = new storage_type(src)
update_icon()
@@ -137,6 +201,7 @@
QDEL_NULL(suit)
QDEL_NULL(helmet)
QDEL_NULL(mask)
QDEL_NULL(mod)
QDEL_NULL(storage)
return ..()
@@ -154,7 +219,7 @@
. += "broken"
else
. += "open"
if(suit)
if(suit || mod)
. += "suit"
if(helmet)
. += "helm"
@@ -175,6 +240,7 @@
helmet = null
suit = null
mask = null
mod = null
storage = null
occupant = null
@@ -241,6 +307,8 @@
qdel(suit) // Delete everything but the occupant.
mask = null
qdel(mask)
mod = null
qdel(mod)
storage = null
qdel(storage)
// The wires get damaged too.
@@ -262,6 +330,9 @@
if(mask)
things_to_clear += mask
things_to_clear += mask.GetAllContents()
if(mod)
things_to_clear += mod
things_to_clear += mod.get_all_contents()
if(storage)
things_to_clear += storage
things_to_clear += storage.GetAllContents()
@@ -279,13 +350,25 @@
if(occupant)
dump_contents()
/obj/machinery/suit_storage_unit/proc/shock(mob/user, prb)
if(!prob(prb))
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(5, 1, src)
s.start()
if(electrocute_mob(user, src, src, 1, TRUE))
return 1
/obj/machinery/suit_storage_unit/process(delta_time)
var/obj/item/stock_parts/cell/cell
if(suit)
if(!istype(suit))
return
if(!suit.cell)
return
cell = suit.cell
else if(mod)
if(!istype(mod))
return
if(!mod.cell)
return
cell = mod.cell
else
return
use_power(charge_rate * delta_time)
cell.give(charge_rate * delta_time)
/obj/machinery/suit_storage_unit/relaymove(mob/user)
if(locked)
@@ -353,6 +436,13 @@
if(!user.transferItemToLoc(I, src))
return
mask = I
else if(istype(I, /obj/item/mod/control))
if(mod)
to_chat(user, span_warning("The unit already contains a MOD!"))
return
if(!user.transferItemToLoc(I, src))
return
mod = I
else
if(storage)
to_chat(user, "<span class='warning'>The auxiliary storage compartment is full!</span>")

View File

@@ -1271,3 +1271,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
/obj/item/proc/update_action_buttons(status_only = FALSE, force = FALSE)
for(var/datum/action/current_action as anything in actions)
current_action.UpdateButtonIcon(status_only, force)
/// Special stuff you want to do when an outfit equips this item.
/obj/item/proc/on_outfit_equip(mob/living/carbon/human/outfit_wearer, visuals_only, item_slot)
return

View File

@@ -26,18 +26,22 @@
user.visible_message("<span class='suicide'>[user] is trying to upload [user.p_them()]self into [src]! That's not going to work out well!</span>")
return BRUTELOSS
/obj/item/aicard/afterattack(atom/target, mob/user, proximity)
. = ..()
if(!proximity || !target)
return
/obj/item/aicard/pre_attack(atom/target, mob/living/user, params)
if(AI) //AI is on the card, implies user wants to upload it.
log_combat(user, AI, "carded", src)
var/our_ai = AI
target.transfer_ai(AI_TRANS_FROM_CARD, user, AI, src)
else //No AI on the card, therefore the user wants to download one.
target.transfer_ai(AI_TRANS_TO_CARD, user, null, src)
if(AI)
log_combat(user, our_ai, "uploaded", src, "to [target].")
return TRUE
else //No AI on the card, therefore the user wants to download one.
target.transfer_ai(AI_TRANS_TO_CARD, user, null, src)
if(AI)
log_combat(user, AI, "carded", src)
update_icon() //Whatever happened, update the card's state (icon, name) to match.
return TRUE
update_appearance() //Whatever happened, update the card's state (icon, name) to match.
return ..()
/obj/item/aicard/update_icon()
cut_overlays()

View File

@@ -53,7 +53,13 @@
var/atom/movable/A = X
if(A == wielder)
continue
if(A && !A.anchored && !ishuman(X))
if(isliving(A))
var/mob/living/vortexed_mob = A
if(vortexed_mob.mob_negates_gravity())
continue
else
vortexed_mob.Paralyze(2 SECONDS)
if(!A.anchored && !isobserver(A))
step_towards(A,pull)
step_towards(A,pull)
step_towards(A,pull)

View File

@@ -5,9 +5,6 @@
w_class = WEIGHT_CLASS_NORMAL
var/component_type = /datum/component/storage/concrete
/obj/item/storage/get_dumping_location(obj/item/storage/source,mob/user)
return src
/obj/item/storage/Initialize(mapload)
. = ..()
PopulateContents()

View File

@@ -19,6 +19,25 @@
ion_trail = new
ion_trail.set_up(src)
/obj/item/tank/jetpack/Destroy()
QDEL_NULL(ion_trail)
return ..()
/obj/item/tank/jetpack/item_action_slot_check(slot)
if(slot == ITEM_SLOT_BACK)
return TRUE
/obj/item/tank/jetpack/equipped(mob/user, slot, initial)
. = ..()
if(on && slot != ITEM_SLOT_BACK)
turn_off(user)
/obj/item/tank/jetpack/dropped(mob/user, silent)
. = ..()
if(on)
turn_off(user)
/obj/item/tank/jetpack/populate_gas()
if(gas_type)
air_contents.set_moles(gas_type, ((6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C)))
@@ -53,6 +72,7 @@
icon_state = "[initial(icon_state)]-on"
ion_trail.start()
RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/move_react)
RegisterSignal(user, COMSIG_MOVABLE_SPACEMOVE, .proc/spacemove_react)
if(full_speed)
user.add_movespeed_modifier(/datum/movespeed_modifier/jetpack/fullspeed)
else
@@ -90,6 +110,13 @@
else
..()
/obj/item/tank/jetpack/proc/spacemove_react(mob/user, movement_dir)
SIGNAL_HANDLER
if(on && (movement_dir || stabilizers))
return COMSIG_MOVABLE_STOP_SPACEMOVE
/obj/item/tank/jetpack/improvised
name = "improvised jetpack"
desc = "A jetpack made from two air tanks, a fire extinguisher and some atmospherics equipment. It doesn't look like it can hold much."

View File

@@ -237,7 +237,7 @@
if(!anchored || current_size >= STAGE_FIVE)
step_towards(src,S)
/obj/get_dumping_location(datum/component/storage/source,mob/user)
/obj/get_dumping_location()
return get_turf(src)
/**

View File

@@ -133,7 +133,7 @@
new mineral(loc)
qdel(src)
/obj/structure/falsewall/get_dumping_location(obj/item/storage/source,mob/user)
/obj/structure/falsewall/get_dumping_location()
return null
/obj/structure/falsewall/examine_status(mob/user) //So you can't detect falsewalls by examine.

View File

@@ -273,7 +273,7 @@
C.add_delayedload(C.newavail() * 0.0375) // you can gain up to 3.5 via the 4x upgrades power is halved by the pole so thats 2x then 1X then .5X for 3.5x the 3 bounces shock.
return ..()
/obj/structure/grille/get_dumping_location(datum/component/storage/source,mob/user)
/obj/structure/grille/get_dumping_location()
return null
/obj/structure/grille/broken // Pre-broken grilles for map placement

View File

@@ -567,7 +567,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
take_damage(round(exposed_volume / 100), BURN, 0, 0)
..()
/obj/structure/window/get_dumping_location(obj/item/storage/source,mob/user)
/obj/structure/window/get_dumping_location()
return null
/obj/structure/window/CanAStarPass(obj/item/card/id/ID, to_dir, atom/movable/caller)

View File

@@ -278,7 +278,7 @@
if(.)
ChangeTurf(/turf/closed/wall/clockwork)
/turf/closed/wall/get_dumping_location(obj/item/storage/source, mob/user)
/turf/closed/wall/get_dumping_location()
return null
/turf/closed/wall/acid_act(acidpwr, acid_volume)

View File

@@ -238,3 +238,15 @@
contains = list(/obj/item/raw_anomaly_core/pyro)
crate_name = "raw pyro anomaly"
crate_type = /obj/structure/closet/crate/secure/science
/datum/supply_pack/science/mod_core
name = "MOD core Crate"
desc = "Three cores, perfect for any MODsuit construction! Naturally harvested™, of course."
cost = CARGO_CRATE_VALUE * 3
access = ACCESS_ROBOTICS
access_view = ACCESS_ROBOTICS
contains = list(/obj/item/mod/construction/core,
/obj/item/mod/construction/core,
/obj/item/mod/construction/core)
crate_name = "MOD core crate"
crate_type = /obj/structure/closet/crate/secure/science

View File

@@ -26,6 +26,7 @@
#include "code\__DEFINES\achievements.dm"
#include "code\__DEFINES\actionspeed_modifiers.dm"
#include "code\__DEFINES\admin.dm"
#include "code\__DEFINES\ai.dm"
#include "code\__DEFINES\antagonists.dm"
#include "code\__DEFINES\atmospherics.dm"
#include "code\__DEFINES\bitfields.dm"
@@ -80,6 +81,7 @@
#include "code\__DEFINES\menu.dm"
#include "code\__DEFINES\misc.dm"
#include "code\__DEFINES\mobs.dm"
#include "code\__DEFINES\mod.dm"
#include "code\__DEFINES\monkeys.dm"
#include "code\__DEFINES\move_force.dm"
#include "code\__DEFINES\movement.dm"
@@ -136,6 +138,7 @@
#include "code\__DEFINES\vote.dm"
#include "code\__DEFINES\vv.dm"
#include "code\__DEFINES\wall_dents.dm"
#include "code\__DEFINES\wiremod.dm"
#include "code\__DEFINES\wires.dm"
#include "code\__DEFINES\wounds.dm"
#include "code\__DEFINES\_flags\_flags.dm"
@@ -156,8 +159,11 @@
#include "code\__DEFINES\dcs\flags.dm"
#include "code\__DEFINES\dcs\helpers.dm"
#include "code\__DEFINES\dcs\signals.dm"
#include "code\__DEFINES\dcs\signals\signals_mod.dm"
#include "code\__DEFINES\dcs\signals\signals_subsystem.dm"
#include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_movable.dm"
#include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_movement.dm"
#include "code\__DEFINES\dcs\signals\signals_mob\signals_mob_carbon.dm"
#include "code\__DEFINES\dcs\signals\signals_mob\signals_mob_living.dm"
#include "code\__DEFINES\mapping\maploader.dm"
#include "code\__DEFINES\material\worth.dm"
@@ -500,6 +506,7 @@
#include "code\datums\achievements\misc_scores.dm"
#include "code\datums\achievements\skill_achievements.dm"
#include "code\datums\actions\beam_rifle.dm"
#include "code\datums\ai\objects\mod.dm"
#include "code\datums\announcers\_announcer.dm"
#include "code\datums\announcers\default_announcer.dm"
#include "code\datums\announcers\intern_announcer.dm"
@@ -807,6 +814,7 @@
#include "code\datums\wires\emitter.dm"
#include "code\datums\wires\explosive.dm"
#include "code\datums\wires\microwave.dm"
#include "code\datums\wires\mod.dm"
#include "code\datums\wires\mulebot.dm"
#include "code\datums\wires\particle_accelerator.dm"
#include "code\datums\wires\r_n_d.dm"