Thrusters [chassis.thrusters_active ?"en":"dis"]abled.")
-
-
/datum/action/innate/mecha/mech_defence_mode
name = "Toggle Defence Mode"
button_icon_state = "mech_defence_mode_off"
@@ -288,3 +277,18 @@
button_icon_state = "mech_phasing_[chassis.phasing ? "on" : "off"]"
chassis.occupant_message("En":"#f00\">Dis"]abled phasing.")
build_all_button_icons()
+
+//////////////////////////////////////// Equipment Actions ///////////////////////////////////////////////
+//Equipment-based actions like RCD mode selection
+
+/datum/action/innate/mecha/equipment
+ var/obj/item/mecha_parts/mecha_equipment/equipment
+
+/datum/action/innate/mecha/equipment/Grant(mob/living/L, obj/mecha/M, obj/item/mecha_parts/mecha_equipment/E)
+ if(E)
+ equipment = E
+ return ..()
+
+/datum/action/innate/mecha/equipment/Destroy()
+ equipment = null
+ return ..()
diff --git a/code/game/mecha/mecha_construction_paths.dm b/code/game/mecha/mecha_construction_paths.dm
index e0db9909f2f8..4d3e58fe4b07 100644
--- a/code/game/mecha/mecha_construction_paths.dm
+++ b/code/game/mecha/mecha_construction_paths.dm
@@ -536,166 +536,6 @@
user.visible_message("[user] unfastens the Gygax Armor Plates.", span_notice("You unfasten the Gygax Armor Plates."))
return TRUE
-/datum/component/construction/unordered/mecha_chassis/firefighter
- result = /datum/component/construction/mecha/firefighter
- steps = list(
- /obj/item/mecha_parts/part/ripley_torso,
- /obj/item/mecha_parts/part/ripley_left_arm,
- /obj/item/mecha_parts/part/ripley_right_arm,
- /obj/item/mecha_parts/part/ripley_left_leg,
- /obj/item/mecha_parts/part/ripley_right_leg,
- /obj/item/clothing/suit/fire
- )
-
-/datum/component/construction/mecha/firefighter
- result = /obj/mecha/working/ripley/firefighter
- base_icon = "fireripley"
-
- circuit_control = /obj/item/circuitboard/mecha/ripley/main
- circuit_periph = /obj/item/circuitboard/mecha/ripley/peripherals
-
- inner_plating = /obj/item/stack/sheet/plasteel
- inner_plating_amount = 5
-
-/datum/component/construction/mecha/firefighter/get_outer_plating_steps()
- return list(
- list(
- "key" = /obj/item/stack/sheet/plasteel,
- "amount" = 5,
- "back_key" = TOOL_WELDER,
- "desc" = "Internal armor is welded."
- ),
-
- list(
- "key" = /obj/item/stack/sheet/plasteel,
- "amount" = 5,
- "back_key" = TOOL_CROWBAR,
- "desc" = "External armor is being installed."
- ),
-
- list(
- "key" = TOOL_WRENCH,
- "back_key" = TOOL_CROWBAR,
- "desc" = "External armor is installed."
- ),
-
- list(
- "key" = TOOL_WELDER,
- "back_key" = TOOL_WRENCH,
- "desc" = "External armor is wrenched."
- ),
-)
-
-/datum/component/construction/mecha/firefighter/custom_action(obj/item/I, mob/living/user, diff)
- if(!..())
- return FALSE
-
- //TODO: better messages.
- switch(index)
- if(1)
- user.visible_message("[user] connects [parent] hydraulic systems", span_notice("You connect [parent] hydraulic systems."))
- if(2)
- if(diff==FORWARD)
- user.visible_message("[user] activates [parent] hydraulic systems.", span_notice("You activate [parent] hydraulic systems."))
- else
- user.visible_message("[user] disconnects [parent] hydraulic systems", span_notice("You disconnect [parent] hydraulic systems."))
- if(3)
- if(diff==FORWARD)
- user.visible_message("[user] adds the wiring to [parent].", span_notice("You add the wiring to [parent]."))
- else
- user.visible_message("[user] deactivates [parent] hydraulic systems.", span_notice("You deactivate [parent] hydraulic systems."))
- if(4)
- if(diff==FORWARD)
- user.visible_message("[user] adjusts the wiring of [parent].", span_notice("You adjust the wiring of [parent]."))
- else
- user.visible_message("[user] removes the wiring from [parent].", span_notice("You remove the wiring from [parent]."))
- if(5)
- if(diff==FORWARD)
- user.visible_message("[user] installs [I] into [parent].", span_notice("You install [I] into [parent]."))
- else
- user.visible_message("[user] disconnects the wiring of [parent].", span_notice("You disconnect the wiring of [parent]."))
- if(6)
- if(diff==FORWARD)
- user.visible_message("[user] secures the mainboard.", span_notice("You secure the mainboard."))
- else
- user.visible_message("[user] removes the central control module from [parent].", span_notice("You remove the central computer mainboard from [parent]."))
- if(7)
- if(diff==FORWARD)
- user.visible_message("[user] installs [I]into [parent].", span_notice("You install [I]into [parent]."))
- else
- user.visible_message("[user] unfastens the mainboard.", span_notice("You unfasten the mainboard."))
- if(8)
- if(diff==FORWARD)
- user.visible_message("[user] secures the peripherals control module.", span_notice("You secure the peripherals control module."))
- else
- user.visible_message("[user] removes the peripherals control module from [parent].", span_notice("You remove the peripherals control module from [parent]."))
- if(9)
- if(diff==FORWARD)
- user.visible_message("[user] installs [I] into [parent].", span_notice("You install [I] into [parent]."))
- else
- user.visible_message("[user] unfastens the peripherals control module.", span_notice("You unfasten the peripherals control module."))
- if(10)
- if(diff==FORWARD)
- user.visible_message("[user] secures the scanner module.", span_notice("You secure the scanner module."))
- else
- user.visible_message("[user] removes the scanner module from [parent].", span_notice("You remove the scanner module from [parent]."))
- if(11)
- if(diff==FORWARD)
- user.visible_message("[user] installs [I] to [parent].", span_notice("You install [I] to [parent]."))
- else
- user.visible_message("[user] unfastens the scanner module.", span_notice("You unfasten the scanner module."))
- if(12)
- if(diff==FORWARD)
- user.visible_message("[user] secures the capacitor.", span_notice("You secure the capacitor."))
- else
- user.visible_message("[user] removes the capacitor from [parent].", span_notice("You remove the capacitor from [parent]."))
- if(13)
- if(diff==FORWARD)
- user.visible_message("[user] installs [I] into [parent].", span_notice("You install [I] into [parent]."))
- else
- user.visible_message("[user] unfastens the capacitor.", span_notice("You unfasten the capacitor."))
- if(14)
- if(diff==FORWARD)
- user.visible_message("[user] secures the power cell.", span_notice("You secure the power cell."))
- else
- user.visible_message("[user] pries the power cell from [parent].", span_notice("You pry the power cell from [parent]."))
- if(15)
- if(diff==FORWARD)
- user.visible_message("[user] installs the internal armor layer to [parent].", span_notice("You install the internal armor layer to [parent]."))
- else
- user.visible_message("[user] unfastens the power cell.", span_notice("You unfasten the power cell."))
- if(16)
- if(diff==FORWARD)
- user.visible_message("[user] secures the internal armor layer.", span_notice("You secure the internal armor layer."))
- else
- user.visible_message("[user] pries internal armor layer from [parent].", span_notice("You pry internal armor layer from [parent]."))
- if(17)
- if(diff==FORWARD)
- user.visible_message("[user] welds the internal armor layer to [parent].", span_notice("You weld the internal armor layer to [parent]."))
- else
- user.visible_message("[user] unfastens the internal armor layer.", span_notice("You unfasten the internal armor layer."))
- if(18)
- if(diff==FORWARD)
- user.visible_message("[user] starts to install the external armor layer to [parent].", span_notice("You install the external armor layer to [parent]."))
- else
- user.visible_message("[user] cuts the internal armor layer from [parent].", span_notice("You cut the internal armor layer from [parent]."))
- if(19)
- if(diff==FORWARD)
- user.visible_message("[user] installs the external reinforced armor layer to [parent].", span_notice("You install the external reinforced armor layer to [parent]."))
- else
- user.visible_message("[user] removes the external armor from [parent].", span_notice("You remove the external armor from [parent]."))
- if(20)
- if(diff==FORWARD)
- user.visible_message("[user] secures the external armor layer.", span_notice("You secure the external reinforced armor layer."))
- else
- user.visible_message("[user] pries external armor layer from [parent].", span_notice("You pry external armor layer from [parent]."))
- if(21)
- if(diff==FORWARD)
- user.visible_message("[user] welds the external armor layer to [parent].", span_notice("You weld the external armor layer to [parent]."))
- else
- user.visible_message("[user] unfastens the external armor layer.", span_notice("You unfasten the external armor layer."))
- return TRUE
-
/datum/component/construction/unordered/mecha_chassis/clarke
result = /datum/component/construction/mecha/clarke
steps = list(
diff --git a/code/game/mecha/mecha_control_console.dm b/code/game/mecha/mecha_control_console.dm
index 70b4dd549bcb..b47a0c059768 100644
--- a/code/game/mecha/mecha_control_console.dm
+++ b/code/game/mecha/mecha_control_console.dm
@@ -27,7 +27,7 @@
var/obj/mecha/M = MT.chassis
var/list/mech_data = list(
name = M.name,
- integrity = round((M.obj_integrity / M.max_integrity) * 100),
+ integrity = round((M.get_integrity() / M.max_integrity) * 100),
charge = M.cell ? round(M.cell.percent()) : null,
airtank = M.internal_tank ? M.return_pressure() : null,
pilot = M.occupant,
@@ -88,7 +88,7 @@
var/cell_charge = chassis.get_charge()
var/answer = {"Name: [chassis.name]
- Integrity: [round((chassis.obj_integrity/chassis.max_integrity * 100), 0.01)]%
+ Integrity: [round((chassis.get_integrity()/chassis.max_integrity * 100), 0.01)]%
Cell Charge: [isnull(cell_charge) ? "Not Found":"[chassis.cell.percent()]%"]
Airtank: [chassis.internal_tank ? "[round(chassis.return_pressure(), 0.01)]" : "Not Equipped"] kPa
Pilot: [chassis.occupant || "None"]
diff --git a/code/game/mecha/mecha_defense.dm b/code/game/mecha/mecha_defense.dm
index ba6c833a217e..9794889c8631 100644
--- a/code/game/mecha/mecha_defense.dm
+++ b/code/game/mecha/mecha_defense.dm
@@ -8,7 +8,7 @@
/obj/mecha/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = TRUE, attack_dir, armour_penetration = 0)
. = ..()
- if(. && obj_integrity > 0)
+ if(. && atom_integrity > 0)
spark_system.start()
switch(damage_flag)
if(FIRE)
@@ -21,7 +21,7 @@
occupant_message(span_userdanger("Taking damage!"))
log_message("Took [damage_amount] points of damage. Damage type: [damage_type]", LOG_MECHA)
-/obj/mecha/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir)
+/obj/mecha/run_atom_armor(damage_amount, damage_type, damage_flag = 0, attack_dir)
. = ..()
if(!damage_amount)
return 0
@@ -211,6 +211,15 @@
if(istype(W, /obj/item/mecha_ammo))
ammo_resupply(W, user)
return
+
+ if(istype(W, /obj/item/stack) || istype(W, /obj/item/rcd_ammo) || istype(W, /obj/item/rcd_upgrade))
+ if(matter_resupply(W, user))
+ return
+
+ if(istype(W, /obj/item/mecha_parts))
+ var/obj/item/mecha_parts/P = W
+ P.try_attach_part(user, src)
+ return
if(W.GetID())
if(add_req_access || maint_access)
@@ -289,26 +298,21 @@
else if(W.tool_behaviour == TOOL_WELDER && user.a_intent != INTENT_HARM)
user.changeNext_move(CLICK_CD_MELEE)
- if(obj_integrity < max_integrity)
+ if(atom_integrity < max_integrity)
if(W.use_tool(src, user, 0, volume=50, amount=1))
if (internal_damage & MECHA_INT_TANK_BREACH)
clearInternalDamage(MECHA_INT_TANK_BREACH)
to_chat(user, span_notice("You repair the damaged gas tank."))
else
user.visible_message(span_notice("[user] repairs some damage to [name]."), span_notice("You repair some damage to [src]."))
- obj_integrity += min(10, max_integrity-obj_integrity)
- if(obj_integrity == max_integrity)
+ update_integrity(atom_integrity + min(10, max_integrity-atom_integrity))
+ if(atom_integrity == max_integrity)
to_chat(user, span_notice("It looks to be fully repaired now."))
return 1
else
to_chat(user, span_warning("The [name] is at full integrity!"))
return 1
- else if(istype(W, /obj/item/mecha_parts))
- var/obj/item/mecha_parts/P = W
- P.try_attach_part(user, src)
- return
-
else if(istype(W, /obj/item/airlock_scanner)) //yogs start
var/obj/item/airlock_scanner/S = W
S.show_access(src, user) //yogs end
@@ -345,16 +349,12 @@
target.reagents.add_reagent(/datum/reagent/toxin, force/2.5)
-/obj/mecha/mech_melee_attack(obj/mecha/M, equip_allowed)
- if(!has_charge(melee_energy_drain))
- return 0
- use_power(melee_energy_drain)
- if(M.damtype == BRUTE || M.damtype == BURN)
- log_combat(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])")
- . = ..()
+/obj/mecha/mech_melee_attack(obj/mecha/M, punch_force, equip_allowed = TRUE)
+ log_combat(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])")
+ return ..(M, punch_force / 2, equip_allowed)
/obj/mecha/proc/full_repair(charge_cell)
- obj_integrity = max_integrity
+ update_integrity(max_integrity)
if(cell && charge_cell)
cell.charge = cell.maxcharge
if(internal_damage & MECHA_INT_FIRE)
@@ -393,7 +393,7 @@
visual_effect_icon = ATTACK_EFFECT_MECHTOXIN
..()
-/obj/mecha/obj_destruction()
+/obj/mecha/atom_destruction()
if(wreckage)
var/mob/living/silicon/ai/AI
if(isAI(occupant))
diff --git a/code/game/mecha/mecha_parts.dm b/code/game/mecha/mecha_parts.dm
index 81f83e1c5f1f..0eed9e0d2e73 100644
--- a/code/game/mecha/mecha_parts.dm
+++ b/code/game/mecha/mecha_parts.dm
@@ -7,7 +7,7 @@
icon = 'icons/mecha/mech_construct.dmi'
icon_state = "blank"
w_class = WEIGHT_CLASS_GIGANTIC
- flags_1 = CONDUCT_1
+ flags_1 = CONDUCT_1 | RAD_NO_CONTAMINATE_1
/obj/item/mecha_parts/proc/try_attach_part(mob/user, obj/mecha/M) //For attaching parts to a finished mech
if(!user.transferItemToLoc(src, M))
@@ -187,11 +187,6 @@
desc = "A set of armor plates for the Durand. Built heavy to resist an incredible amount of brute force."
icon_state = "durand_armor"
-////////// Firefighter
-
-/obj/item/mecha_parts/chassis/firefighter
- name = "\improper Firefighter chassis"
- construct_type = /datum/component/construction/unordered/mecha_chassis/firefighter
////////// Clarke
diff --git a/code/game/mecha/mecha_topic.dm b/code/game/mecha/mecha_topic.dm
index 1dff7668054b..9eedcd525deb 100644
--- a/code/game/mecha/mecha_topic.dm
+++ b/code/game/mecha/mecha_topic.dm
@@ -69,7 +69,7 @@
/obj/mecha/proc/get_stats_part()
- var/integrity = obj_integrity/max_integrity*100
+ var/integrity = atom_integrity/max_integrity*100
var/cell_charge = get_charge()
var/datum/gas_mixture/int_tank_air = 0
var/tank_pressure = 0
@@ -100,7 +100,6 @@
Environment pressure: [environment_pressure>WARNING_HIGH_PRESSURE ? span_danger("[environment_pressure]"): environment_pressure]kPa
Environment temperature: [environment_temperature]°K|[environment_temperature - T0C]°C
[dna_lock?"DNA-locked:
[dna_lock] \[Reset\]
":""]
- [thrusters_action.owner ? "Thrusters: [thrusters_active ? "Enabled" : "Disabled"]
" : ""]
[defence_action.owner ? "Defence Mode: [defence_mode ? "Enabled" : "Disabled"]
" : ""]
[overload_action.owner ? "Leg Actuators Overload: [leg_overload_mode ? "Enabled" : "Disabled"]
" : ""]
[smoke_action.owner ? "Smoke: [smoke]
" : ""]
diff --git a/code/game/mecha/mecha_wreckage.dm b/code/game/mecha/mecha_wreckage.dm
index 034d32ab341c..2bf1de084b9c 100644
--- a/code/game/mecha/mecha_wreckage.dm
+++ b/code/game/mecha/mecha_wreckage.dm
@@ -206,11 +206,6 @@
icon_state = "ripley-broken"
orig_mecha = /obj/mecha/working/ripley
-/obj/structure/mecha_wreckage/ripley/mkii
- name = "\improper Ripley MK-II wreckage"
- icon_state = "ripleymkii-broken"
- orig_mecha = /obj/mecha/working/ripley/mkii
-
/obj/structure/mecha_wreckage/ripley/firefighter
name = "\improper Firefighter wreckage"
icon_state = "firefighter-broken"
@@ -250,4 +245,10 @@
/obj/structure/mecha_wreckage/sidewinder
name = "\improper Sidewinder wreckage"
icon_state = "sidewinder-broken"
+ desc = "It continues to twitch, as if barely alive."
orig_mecha = /obj/mecha/combat/sidewinder
+
+/obj/structure/mecha_wreckage/sidewinder/mamba
+ name = "\improper mamba wreckage"
+ icon_state = "mamba-broken"
+ orig_mecha = /obj/mecha/combat/sidewinder/mamba
diff --git a/code/game/mecha/medical/medical.dm b/code/game/mecha/medical/medical.dm
index d605c64a839b..c379795ff78a 100644
--- a/code/game/mecha/medical/medical.dm
+++ b/code/game/mecha/medical/medical.dm
@@ -1,19 +1,5 @@
/obj/mecha/medical
internals_req_access = list(ACCESS_MECH_SCIENCE, ACCESS_MECH_MEDICAL)
-
-/obj/mecha/medical/mechturn(direction)
- setDir(direction)
- playsound(src,'sound/mecha/mechmove01.ogg',40,1)
- return 1
-
-/obj/mecha/medical/mechstep(direction)
- var/result = step(src,direction)
- if(result)
- playsound(src,'sound/mecha/mechstep.ogg',25,1)
- return result
-
-/obj/mecha/medical/mechsteprand()
- var/result = step_rand(src)
- if(result)
- playsound(src,'sound/mecha/mechstep.ogg',25,1)
- return result
\ No newline at end of file
+ stepsound = 'sound/mecha/mechstep.ogg'
+ turnsound = 'sound/mecha/mechmove01.ogg'
+ pivot_step = TRUE
diff --git a/code/game/mecha/working/clarke.dm b/code/game/mecha/working/clarke.dm
index 21219c90f8aa..69dc1e31b3af 100644
--- a/code/game/mecha/working/clarke.dm
+++ b/code/game/mecha/working/clarke.dm
@@ -6,16 +6,17 @@
max_temperature = 65000
max_integrity = 200
step_in = 1.25
- fast_pressure_step_in = 1.25
- slow_pressure_step_in = 1.8
+ fast_pressure_step_in = 1.5
+ slow_pressure_step_in = 2
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
light_power = 7
deflect_chance = 10
- armor = list(MELEE = 20, BULLET = 10, LASER = 20, ENERGY = 0, BOMB = 60, BIO = 0, RAD = 70, FIRE = 100, ACID = 100)
+ flags_1 = HEAR_1 | RAD_PROTECT_CONTENTS_1 | RAD_NO_CONTAMINATE_1
+ armor = list(MELEE = 20, BULLET = 10, LASER = 20, ENERGY = 0, BOMB = 60, BIO = 0, RAD = 100, FIRE = 100, ACID = 100)
max_equip = 7
wreckage = /obj/structure/mecha_wreckage/clarke
enter_delay = 40
- canstrafe = FALSE
+ pivot_step = TRUE
/// Handles an internal ore box for Clarke
var/obj/structure/ore_box/box
omnidirectional_attacks = TRUE
@@ -50,6 +51,14 @@
var/mob/living/brain/B = M.brainmob
hud.show_to(B)
+/obj/mecha/working/clarke/domove(direction)
+ if(ISDIAGONALDIR(direction) && strafe)
+ if(EWCOMPONENT(dir))
+ direction &= ~(NORTH|SOUTH)
+ else if(NSCOMPONENT(dir))
+ direction &= ~(EAST|WEST)
+ return ..(direction)
+
//Ore Box Controls
///Special equipment for the Clarke mech, handles moving ore without giving the mech a hydraulic clamp and cargo compartment.
diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm
index 046ce62ff769..188555453b57 100644
--- a/code/game/mecha/working/ripley.dm
+++ b/code/game/mecha/working/ripley.dm
@@ -6,7 +6,6 @@
step_in = 1.5 //Move speed, lower is faster.
max_temperature = 20000
max_integrity = 200
- light_power = 7
deflect_chance = 15
armor = list(MELEE = 40, BULLET = 20, LASER = 10, ENERGY = 0, BOMB = 40, BIO = 0, RAD = 20, FIRE = 100, ACID = 100)
max_equip = 6
@@ -18,6 +17,9 @@
enclosed = FALSE //Normal ripley has an open cockpit design
enter_delay = 10 //can enter in a quarter of the time of other mechs
exit_delay = 10
+ /// Custom Ripley step and turning sounds (from TGMC)
+ stepsound = 'sound/mecha/powerloader_step.ogg'
+ turnsound = 'sound/mecha/powerloader_turn2.ogg'
opacity = FALSE //Ripley has a window
/obj/mecha/working/ripley/Move()
@@ -59,40 +61,33 @@
. = ..()
AddComponent(/datum/component/armor_plate,3,/obj/item/stack/sheet/animalhide/goliath_hide,list(MELEE = 10, BULLET = 5, LASER = 5))
-
-/obj/mecha/working/ripley/mkii
- desc = "Autonomous Power Loader Unit MK-II. This prototype Ripley is refitted with a pressurized cabin, trading its prior speed for atmospheric protection"
- name = "\improper APLU MK-II \"Ripley\""
- icon_state = "ripleymkii"
- fast_pressure_step_in = 1.75 //step_in while in low pressure conditions
- slow_pressure_step_in = 3 //step_in while in normal pressure conditions
- step_in = 3
- armor = list(MELEE = 40, BULLET = 20, LASER = 10, ENERGY = 0, BOMB = 40, BIO = 100, RAD = 55, FIRE = 100, ACID = 100)
- wreckage = /obj/structure/mecha_wreckage/ripley/mkii
- enclosed = TRUE
- enter_delay = 40
- silicon_icon_state = null
- opacity = TRUE
-
/obj/mecha/working/ripley/firefighter
- desc = "Autonomous Power Loader Unit MK-III. This model is refitted with a pressurized cabin and additional thermal protection."
- name = "\improper APLU MK-III \"Firefighter\""
+ desc = "Autonomous Power Loader Unit MK-II. This model is fitted with a pressurized cabin and thermal protection."
+ name = "\improper APLU MK-II \"Firefighter\""
icon_state = "firefighter"
max_temperature = 65000
max_integrity = 250
- fast_pressure_step_in = 2 //step_in while in low pressure conditions
- slow_pressure_step_in = 4 //step_in while in normal pressure conditions
- step_in = 4
+ fast_pressure_step_in = 1.75 //step_in while in low pressure conditions
+ slow_pressure_step_in = 3 //step_in while in normal pressure conditions
+ step_in = 3
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
- light_power = 7
- armor = list(MELEE = 40, BULLET = 30, LASER = 30, ENERGY = 0, BOMB = 60, BIO = 100, RAD = 70, FIRE = 100, ACID = 100)
- max_equip = 5 // More armor, less tools
+ flags_1 = HEAR_1 | RAD_PROTECT_CONTENTS_1 | RAD_NO_CONTAMINATE_1
+ armor = list(MELEE = 40, BULLET = 30, LASER = 30, ENERGY = 0, BOMB = 60, BIO = 100, RAD = 100, FIRE = 100, ACID = 100)
wreckage = /obj/structure/mecha_wreckage/ripley/firefighter
enclosed = TRUE
enter_delay = 40
silicon_icon_state = null
opacity = TRUE
+// maybe janitor ERTs could get this or something?
+/obj/mecha/working/ripley/janitorial/Initialize(mapload)
+ . = ..()
+ var/obj/item/mecha_parts/mecha_equipment/washer = new /obj/item/mecha_parts/mecha_equipment/weapon/pressure_washer
+ washer.attach(src)
+ var/obj/item/mecha_parts/mecha_equipment/big_mop = new /obj/item/mecha_parts/mecha_equipment/melee_weapon/mop
+ big_mop.attach(src)
+ var/obj/item/mecha_parts/mecha_equipment/swatter = new /obj/item/mecha_parts/mecha_equipment/melee_weapon/flyswatter
+ swatter.attach(src)
/obj/mecha/working/ripley/deathripley
desc = "OH SHIT IT'S THE DEATHSQUAD WE'RE ALL GONNA DIE"
@@ -134,10 +129,10 @@
/obj/mecha/working/ripley/mining
desc = "An old, dusty mining Ripley."
name = "\improper APLU \"Miner\""
- obj_integrity = 75 //Low starting health
/obj/mecha/working/ripley/mining/Initialize(mapload)
. = ..()
+ update_integrity(75) //Low starting health
if(cell)
cell.charge = FLOOR(cell.charge * 0.25, 1) //Starts at very low charge
if(prob(70)) //Maybe add a drill
diff --git a/code/game/objects/effects/alien_acid.dm b/code/game/objects/effects/alien_acid.dm
index 6d0ae81b5082..0f979ad1443b 100644
--- a/code/game/objects/effects/alien_acid.dm
+++ b/code/game/objects/effects/alien_acid.dm
@@ -23,6 +23,11 @@
pixel_x = target.pixel_x + rand(-4,4)
pixel_y = target.pixel_y + rand(-4,4)
+ var/static/list/loc_connections = list(
+ COMSIG_ATOM_ENTERED = PROC_REF(on_entered),
+ )
+ AddElement(/datum/element/connect_loc, loc_connections)
+
START_PROCESSING(SSobj, src)
@@ -52,8 +57,8 @@
qdel(src)
return 0
-/obj/effect/acid/Crossed(AM as mob|obj)
- . = ..()
+/obj/effect/acid/proc/on_entered(datum/source, atom/movable/AM, ...)
+
if(isliving(AM))
var/mob/living/L = AM
if(L.movement_type & FLYING)
diff --git a/code/game/objects/effects/anomalies.dm b/code/game/objects/effects/anomalies.dm
index 1aa541aa1b7e..da939af96234 100644
--- a/code/game/objects/effects/anomalies.dm
+++ b/code/game/objects/effects/anomalies.dm
@@ -109,6 +109,13 @@
density = FALSE
var/boing = 0
+/obj/effect/anomaly/grav/Initialize(mapload)
+ . = ..()
+ var/static/list/loc_connections = list(
+ COMSIG_ATOM_ENTERED = PROC_REF(on_entered),
+ )
+ AddElement(/datum/element/connect_loc, loc_connections)
+
/obj/effect/anomaly/grav/anomalyEffect()
..()
boing = 1
@@ -126,8 +133,7 @@
if(target && !target.stat)
O.throw_at(target, 5, 10)
-/obj/effect/anomaly/grav/Crossed(atom/movable/AM)
- . = ..()
+/obj/effect/anomaly/grav/proc/on_entered(datum/source, atom/movable/AM, ...)
gravShock(AM)
/obj/effect/anomaly/grav/Bump(atom/A)
@@ -171,6 +177,13 @@
/obj/effect/anomaly/flux/explosion
explosive = ANOMALY_FLUX_EXPLOSION
+/obj/effect/anomaly/flux/Initialize(mapload)
+ . = ..()
+ var/static/list/loc_connections = list(
+ COMSIG_ATOM_ENTERED = PROC_REF(on_entered),
+ )
+ AddElement(/datum/element/connect_loc, loc_connections)
+
/obj/effect/anomaly/flux/anomalyEffect(delta_time)
..()
canshock = 1
@@ -179,8 +192,7 @@
if(prob(delta_time * 2)) // shocks everyone nearby
tesla_zap(src, 5, shockdamage*500, TESLA_MOB_DAMAGE)
-/obj/effect/anomaly/flux/Crossed(atom/movable/AM)
- . = ..()
+/obj/effect/anomaly/flux/proc/on_entered(datum/source, atom/movable/AM, ...)
mobShock(AM)
/obj/effect/anomaly/flux/Bump(atom/A)
diff --git a/code/game/objects/effects/contraband.dm b/code/game/objects/effects/contraband.dm
index d0540c13aebf..6157d42765d9 100644
--- a/code/game/objects/effects/contraband.dm
+++ b/code/game/objects/effects/contraband.dm
@@ -670,6 +670,32 @@
desc = "This poster reminds employees to not panic in the unlikely event of an emergency."
icon_state = "poster37_legit" //36 is taken
+/obj/structure/sign/poster/official/nvs_gax
+ name = "NVS Gax 5th Anniversary"
+ desc = "This poster commemorates the 5th year of operation for the NVS Gax."
+ icon_state = "poster38_legit"
+
+/obj/structure/sign/poster/official/nvs_gax/attackby(obj/item/I, mob/user, params)
+ if(istype(I, /obj/item/toy/crayon/spraycan))
+ var/obj/item/toy/crayon/spraycan/spraycan = I
+ if(spraycan.is_capped)
+ to_chat(user, span_warning("Take the cap off first!"))
+ return ..()
+
+ if(spraycan.check_empty(user))
+ return ..()
+
+ name = "Smoke Gas"
+ desc = "A defaced poster recommending you to smoke some good weed."
+ icon_state = "smoke_gas"
+
+
+ if(spraycan.pre_noise || spraycan.post_noise)
+ playsound(user.loc, 'sound/effects/spray.ogg', 5, 1, 5)
+ user.visible_message("[user] livens up [src] with spray paint!", span_notice("You liven up [src] with spray paint."))
+ return
+ else ..()
+
/obj/item/wantedposterposter
name = "Wanted Poster Poster"
desc = "This piece of high-tech machinery prints out a poster on walls that it's used on."
diff --git a/code/game/objects/effects/countdown.dm b/code/game/objects/effects/countdown.dm
index f9a73eba6e5d..8e564c0029ff 100644
--- a/code/game/objects/effects/countdown.dm
+++ b/code/game/objects/effects/countdown.dm
@@ -113,7 +113,7 @@
var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = attached_to
if(!istype(G))
return
- else if(G.obj_integrity && !G.purpose_fulfilled)
+ else if(G.get_integrity() && !G.purpose_fulfilled)
return "[G.get_arrival_time(FALSE)]
"
/obj/effect/countdown/supermatter
diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm
index 6d408ecaed6d..a43e008b6b83 100644
--- a/code/game/objects/effects/decals/cleanable.dm
+++ b/code/game/objects/effects/decals/cleanable.dm
@@ -34,6 +34,10 @@
diseases_to_add += D
if(LAZYLEN(diseases_to_add))
AddComponent(/datum/component/infective, diseases_to_add)
+ var/static/list/loc_connections = list(
+ COMSIG_ATOM_ENTERED = PROC_REF(on_entered),
+ )
+ AddElement(/datum/element/connect_loc, loc_connections)
/obj/effect/decal/cleanable/proc/replace_decal(obj/effect/decal/cleanable/C) // Returns true if we should give up in favor of the pre-existing decal
if(mergeable_decal)
@@ -85,7 +89,7 @@
//This is on /cleanable because fuck this ancient mess
/obj/effect/decal/cleanable/proc/on_entered(datum/source, atom/movable/AM)
SIGNAL_HANDLER
- if(iscarbon(AM) && blood_state && bloodiness > 40)
+ if(iscarbon(AM) && blood_state && bloodiness > 40 && !HAS_TRAIT(AM, TRAIT_LIGHT_STEP))
SEND_SIGNAL(AM, COMSIG_STEP_ON_BLOOD, src)
update_icon()
diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm
index e686f9b57948..d885f080cab0 100644
--- a/code/game/objects/effects/decals/cleanable/humans.dm
+++ b/code/game/objects/effects/decals/cleanable/humans.dm
@@ -11,6 +11,7 @@
var/dryname = "dried blood" //when the blood lasts long enough, it becomes dry and gets a new name
var/drydesc = "Looks like it's been here a while. Eew." //as above
var/drytime = 0
+ var/footprint_sprite = null
/obj/effect/decal/cleanable/blood/Initialize(mapload)
. = ..()
@@ -130,7 +131,7 @@
/obj/effect/decal/cleanable/blood/gibs/ex_act(severity, target)
return
-/obj/effect/decal/cleanable/blood/gibs/Crossed(atom/movable/L)
+/obj/effect/decal/cleanable/blood/gibs/on_entered(datum/source, atom/movable/L)
if(isliving(L) && has_gravity(loc))
playsound(loc, 'sound/effects/gib_step.ogg', HAS_TRAIT(L, TRAIT_LIGHT_STEP) ? 20 : 50, TRUE)
. = ..()
@@ -205,9 +206,8 @@
/obj/effect/decal/cleanable/blood/footprints
name = "footprints"
icon = 'icons/effects/footprints.dmi'
- icon_state = "nothingwhatsoever"
desc = "WHOSE FOOTPRINTS ARE THESE?"
- icon_state = "blood1"
+ icon_state = "blood_shoes_enter"
random_icon_states = null
blood_state = BLOOD_STATE_HUMAN //the icon state to load images from
var/entered_dirs = 0
@@ -220,28 +220,72 @@
dryname = "dried footprints"
drydesc = "HMM... SOMEONE WAS HERE!"
+/obj/effect/decal/cleanable/blood/footprints/Initialize(mapload, footprint_sprite)
+ src.footprint_sprite = footprint_sprite
+ . = ..()
+ icon_state = "" //All of the footprint visuals come from overlays
+ if(mapload)
+ entered_dirs |= dir //Keep the same appearance as in the map editor
+ update_appearance(mapload ? (ALL) : (UPDATE_NAME | UPDATE_DESC))
+
+//Rotate all of the footprint directions too
+/obj/effect/decal/cleanable/blood/footprints/setDir(newdir)
+ if(dir == newdir)
+ return ..()
+
+ var/ang_change = dir2angle(newdir) - dir2angle(dir)
+ var/old_entered_dirs = entered_dirs
+ var/old_exited_dirs = exited_dirs
+ entered_dirs = 0
+ exited_dirs = 0
+
+ for(var/Ddir in GLOB.cardinals)
+ if(old_entered_dirs & Ddir)
+ entered_dirs |= angle2dir_cardinal(dir2angle(Ddir) + ang_change)
+ if(old_exited_dirs & Ddir)
+ exited_dirs |= angle2dir_cardinal(dir2angle(Ddir) + ang_change)
+
+ update_appearance()
+ return ..()
+
+/obj/effect/decal/cleanable/blood/footprints/update_name(updates)
+ switch(footprint_sprite)
+ if(FOOTPRINT_SPRITE_CLAWS)
+ name = "clawprints"
+ if(FOOTPRINT_SPRITE_SHOES)
+ name = "footprints"
+ if(FOOTPRINT_SPRITE_PAWS)
+ name = "pawprints"
+ dryname = "dried [name]"
+ return ..()
+
+/obj/effect/decal/cleanable/blood/footprints/update_desc(updates)
+ desc = "WHOSE [uppertext(name)] ARE THESE?"
+ return ..()
+
+/obj/effect/decal/cleanable/blood/footprints/update_icon()
+ . = ..()
+ alpha = min(BLOODY_FOOTPRINT_BASE_ALPHA + (255 - BLOODY_FOOTPRINT_BASE_ALPHA) * bloodiness / (BLOOD_ITEM_MAX / 2), 255)
+
/obj/effect/decal/cleanable/blood/footprints/update_overlays()
. = ..()
for(var/Ddir in GLOB.cardinals)
if(entered_dirs & Ddir)
- var/image/bloodstep_overlay = GLOB.bloody_footprints_cache["entered-[blood_state]-[Ddir]"]
+ var/image/bloodstep_overlay = GLOB.bloody_footprints_cache["entered-[footprint_sprite]-[blood_state]-[Ddir]"]
if(!bloodstep_overlay)
- GLOB.bloody_footprints_cache["entered-[blood_state]-[Ddir]"] = bloodstep_overlay = image(icon, "[blood_state]1", dir = Ddir)
+ GLOB.bloody_footprints_cache["entered-[footprint_sprite]-[blood_state]-[Ddir]"] = bloodstep_overlay = image(icon, "[blood_state]_[footprint_sprite]_enter", dir = Ddir)
. += bloodstep_overlay
if(exited_dirs & Ddir)
- var/image/bloodstep_overlay = GLOB.bloody_footprints_cache["exited-[blood_state]-[Ddir]"]
+ var/image/bloodstep_overlay = GLOB.bloody_footprints_cache["exited-[footprint_sprite]-[blood_state]-[Ddir]"]
if(!bloodstep_overlay)
- GLOB.bloody_footprints_cache["exited-[blood_state]-[Ddir]"] = bloodstep_overlay = image(icon, "[blood_state]2", dir = Ddir)
+ GLOB.bloody_footprints_cache["exited-[footprint_sprite]-[blood_state]-[Ddir]"] = bloodstep_overlay = image(icon, "[blood_state]_[footprint_sprite]_exit", dir = Ddir)
. += bloodstep_overlay
- alpha = min(BLOODY_FOOTPRINT_BASE_ALPHA + (255 - BLOODY_FOOTPRINT_BASE_ALPHA) * bloodiness / (BLOOD_ITEM_MAX / 2), 255)
-
-
/obj/effect/decal/cleanable/blood/footprints/examine(mob/user)
. = ..()
if((shoe_types.len + species_types.len) > 0)
- . += "You recognise the footprints as belonging to:"
+ . += "You recognise the [name] as belonging to:"
for(var/sole in shoe_types)
var/obj/item/clothing/item = sole
var/article = initial(item.gender) == PLURAL ? "Some" : "A"
@@ -251,14 +295,14 @@
if(species == "unknown")
. += "Some feet."
else if(species == "monkey")
- . += "[icon2html('icons/mob/monkey.dmi', user, "monkey1")] Some monkey feet."
+ . += "[icon2html('icons/mob/monkey.dmi', user, "monkey1")] Some monkey paws."
else if(species == "human")
. += "[icon2html('icons/mob/human_parts.dmi', user, "default_human_l_leg")] Some human feet."
else
. += "[icon2html('icons/mob/human_parts.dmi', user, "[species]_l_leg")] Some [species] feet."
-/obj/effect/decal/cleanable/blood/footprints/replace_decal(obj/effect/decal/cleanable/C)
- if(blood_state != C.blood_state) //We only replace footprints of the same type as us
+/obj/effect/decal/cleanable/blood/footprints/replace_decal(obj/effect/decal/cleanable/blood/blood_decal)
+ if(blood_state != blood_decal.blood_state || footprint_sprite != blood_decal.footprint_sprite) //We only replace footprints of the same type as us
return FALSE
return ..()
diff --git a/code/game/objects/effects/decals/cleanable/robots.dm b/code/game/objects/effects/decals/cleanable/robots.dm
index 7936b73ae440..52160c6f1313 100644
--- a/code/game/objects/effects/decals/cleanable/robots.dm
+++ b/code/game/objects/effects/decals/cleanable/robots.dm
@@ -79,3 +79,10 @@
/obj/effect/decal/cleanable/oil/slippery/Initialize(mapload)
. = ..()
AddComponent(/datum/component/slippery, 80, (NO_SLIP_WHEN_WALKING | SLIDE))
+
+/obj/effect/decal/cleanable/oil/synth
+ name = "circulation fluid"
+ desc = "It's a white and viscous fluid used by synthetic crewmembers."
+ color = "#e6e6e6"
+ icon_state = "synthfloor1"
+ random_icon_states = list("synthfloor1", "synthfloor2", "synthfloor3", "synthfloor4", "synthfloor5", "synthfloor6", "synthfloor7")
diff --git a/code/game/objects/effects/effect_system/effects_other.dm b/code/game/objects/effects/effect_system/effects_other.dm
index 81f3330f53cf..83583f844b3f 100644
--- a/code/game/objects/effects/effect_system/effects_other.dm
+++ b/code/game/objects/effects/effect_system/effects_other.dm
@@ -11,7 +11,7 @@
var/active = FALSE
var/allow_overlap = FALSE
var/auto_process = TRUE
- var/qdel_in_time = 10
+ var/qdel_in_time = 1 SECONDS
var/fadetype = "ion_fade"
var/fade = TRUE
var/nograv_required = FALSE
@@ -65,6 +65,16 @@
/datum/effect_system/trail_follow/steam
effect_type = /obj/effect/particle_effect/steam
+/datum/effect_system/trail_follow/sparks
+ effect_type = /obj/effect/particle_effect/sparks
+ nograv_required = TRUE
+ fade = FALSE
+
+/datum/effect_system/trail_follow/smoke
+ effect_type = /obj/effect/particle_effect/fluid/smoke/trail
+ nograv_required = TRUE
+ fade = FALSE
+
/obj/effect/particle_effect/ion_trails
name = "ion trails"
icon_state = "ion_trails"
@@ -76,7 +86,7 @@
/datum/effect_system/trail_follow/ion
effect_type = /obj/effect/particle_effect/ion_trails
nograv_required = TRUE
- qdel_in_time = 20
+ qdel_in_time = 2 SECONDS
/datum/effect_system/trail_follow/proc/set_dir(obj/effect/particle_effect/ion_trails/I)
I.setDir(holder.dir)
diff --git a/code/game/objects/effects/effect_system/fluid_spread/effects_foam.dm b/code/game/objects/effects/effect_system/fluid_spread/effects_foam.dm
index 52da421b47b4..f51946d1efb9 100644
--- a/code/game/objects/effects/effect_system/fluid_spread/effects_foam.dm
+++ b/code/game/objects/effects/effect_system/fluid_spread/effects_foam.dm
@@ -386,8 +386,10 @@
/// Atmos Backpack Resin, transparent, prevents atmos and filters the air
/obj/structure/foamedmetal/resin
name = "\improper ATMOS Resin"
- desc = "A lightweight, transparent resin used to suffocate fires, scrub the air of toxins, and restore the air to a safe temperature. It can be used as base to construct a wall."
+ desc = "A lightweight, transparent and passable resin used to suffocate fires, scrub the air of toxins, and restore the air to a safe temperature. It can be used as base to construct a wall."
opacity = FALSE
+ density = FALSE
+ can_atmos_pass = ATMOS_PASS_NO
icon_state = "atmos_resin"
alpha = 120
max_integrity = 10
@@ -395,6 +397,11 @@
/obj/structure/foamedmetal/resin/Initialize(mapload)
. = ..()
var/turf/open/location = loc
+ var/static/list/loc_connections = list(
+ COMSIG_ATOM_ENTERED = PROC_REF(on_entered),
+ COMSIG_ATOM_EXITED = PROC_REF(on_exited),
+ )
+ AddElement(/datum/element/connect_loc, loc_connections)
if(!istype(location))
return
@@ -422,3 +429,29 @@
potential_tinder.extinguish_mob()
for(var/obj/item/potential_tinder in location)
potential_tinder.extinguish()
+
+/obj/structure/foamedmetal/resin/proc/on_entered(datum/source, atom/movable/arrived)
+ SIGNAL_HANDLER
+
+ if(isliving(arrived)) //I guess living subtype is fine
+ var/mob/living/living = arrived
+ living.add_movespeed_modifier(MOVESPEED_ID_RESIN_FOAM, multiplicative_slowdown = 0.4)
+
+/obj/structure/foamedmetal/resin/proc/on_exited(datum/source, atom/movable/gone, direction)
+ if(isliving(gone))
+ var/mob/living/living = gone
+ var/turf/T = get_turf(src)
+ var/turf/them = get_step(T, direction)
+
+ for(var/obj/structure/foamedmetal/resin/S in them)
+ if(S.loc == living.loc) //No removing speed if has same loc
+ return
+
+ living.remove_movespeed_modifier(MOVESPEED_ID_RESIN_FOAM)
+
+/obj/structure/foamedmetal/resin/Destroy() //Make sure to remove the speed if the resin is destroyed while the mob is in it
+ var/turf/T = get_turf(src)
+ for(var/mob/living/living in T)
+ living.remove_movespeed_modifier(MOVESPEED_ID_RESIN_FOAM)
+
+ return ..()
diff --git a/code/game/objects/effects/effect_system/fluid_spread/effects_smoke.dm b/code/game/objects/effects/effect_system/fluid_spread/effects_smoke.dm
index 585fe1433621..f02dfc5396a7 100644
--- a/code/game/objects/effects/effect_system/fluid_spread/effects_smoke.dm
+++ b/code/game/objects/effects/effect_system/fluid_spread/effects_smoke.dm
@@ -156,6 +156,19 @@
/obj/effect/particle_effect/fluid/smoke/transparent
opacity = FALSE
+/// Special smoke used for the RCS thruster
+/obj/effect/particle_effect/fluid/smoke/trail
+ lifetime = 1 SECONDS
+ opacity = FALSE
+ alpha = 100
+
+/obj/effect/particle_effect/fluid/smoke/trail/Initialize(mapload, datum/fluid_group/group, ...)
+ . = ..()
+ var/matrix/start_transform = matrix(transform)/2
+ var/matrix/end_transform = matrix(transform)
+ transform = start_transform
+ animate(src, alpha = 0, transform = end_transform, time = lifetime)
+
/**
* A helper proc used to spawn small puffs of smoke.
*
diff --git a/code/game/objects/effects/effects.dm b/code/game/objects/effects/effects.dm
index 3b2bfd1de8bd..64a8731dddaa 100644
--- a/code/game/objects/effects/effects.dm
+++ b/code/game/objects/effects/effects.dm
@@ -5,6 +5,7 @@
icon = 'icons/effects/effects.dmi'
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF
move_resist = INFINITY
+ uses_integrity = FALSE
obj_flags = NONE
blocks_emissive = EMISSIVE_BLOCK_GENERIC
@@ -17,7 +18,7 @@
/obj/effect/acid_act()
return
-/obj/effect/mech_melee_attack(obj/mecha/M, equip_allowed)
+/obj/effect/mech_melee_attack(obj/mecha/M, punch_force, equip_allowed = TRUE)
return 0
/obj/effect/blob_act(obj/structure/blob/B)
diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm
index b1a080d6eb71..3124dfb4bc8d 100644
--- a/code/game/objects/effects/landmarks.dm
+++ b/code/game/objects/effects/landmarks.dm
@@ -193,6 +193,10 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark)
name = "Cyborg"
icon_state = "Cyborg"
+/obj/effect/landmark/start/synthetic
+ name = "Synthetic"
+ icon_state = "Cyborg"
+
//Department Security spawns
diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm
index 930959270c27..ebe2344f13bd 100644
--- a/code/game/objects/effects/mines.dm
+++ b/code/game/objects/effects/mines.dm
@@ -86,13 +86,23 @@
icon_state = "uglymine"
alpha = 30
var/triggered = 0
+ /// Can be set to FALSE if we want a short 'coming online' delay, then set to TRUE. Can still be set off by damage
+ var/armed = TRUE
var/smartmine = FALSE
var/disarm_time = 12 SECONDS
var/disarm_product = /obj/item/deployablemine // ie what drops when the mine is disarmed
+ /// Who's got their foot on the mine's pressure plate
+ /// Stepping on the mine will set this to the first mob who stepped over it
+ /// The mine will not detonate via movement unless the first mob steps off of it
+ var/datum/weakref/foot_on_mine
/obj/effect/mine/Initialize(mapload)
. = ..()
- layer = ABOVE_MOB_LAYER
+ var/static/list/loc_connections = list(
+ COMSIG_ATOM_ENTERED = PROC_REF(on_entered),
+ COMSIG_ATOM_EXITED = PROC_REF(on_exited),
+ )
+ AddElement(/datum/element/connect_loc, loc_connections)
/obj/effect/mine/attackby(obj/I, mob/user, params)
if(istype(I, /obj/item/multitool))
@@ -107,32 +117,16 @@
/obj/effect/mine/proc/mineEffect(mob/victim)
to_chat(victim, span_danger("*click*"))
-/obj/effect/mine/Crossed(AM as mob|obj)
- . = ..()
- if(isturf(loc))
- if(ismob(AM))
- var/mob/MM = AM
- if(!(MM.movement_type & FLYING))
- checksmartmine(AM)
- else
- if(istype(AM, /obj/projectile))
- return
- triggermine(AM)
-
-/obj/effect/mine/proc/checksmartmine(mob/target)
- if(smartmine && target && !HAS_TRAIT(target, TRAIT_MINDSHIELD))
- triggermine(target)
- else if(!smartmine)
- triggermine(target)
-
/obj/effect/mine/proc/triggermine(mob/victim)
if(triggered)
return
+ if(smartmine && victim && HAS_TRAIT(victim, TRAIT_MINDSHIELD))
+ return
visible_message(span_danger("[victim] sets off [icon2html(src, viewers(src))] [src]!"))
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(1, 0, src)
s.start()
- mineEffect(victim)
+ INVOKE_ASYNC(src, PROC_REF(mineEffect), victim)
triggered = 1
qdel(src)
@@ -257,7 +251,7 @@
/obj/effect/mine/pickup
name = "pickup"
- desc = "pick me up"
+ desc = "Pick me up."
icon = 'icons/effects/effects.dmi'
icon_state = "electricity2"
density = FALSE
@@ -360,3 +354,45 @@
/obj/effect/mine/creampie/mineEffect(mob/victim)
var/obj/item/reagent_containers/food/snacks/pie/cream/P = new /obj/item/reagent_containers/food/snacks/pie/cream(src)
P.splat(victim)
+
+/// Can this mine trigger on the passed movable?
+/obj/effect/mine/proc/can_trigger(atom/movable/on_who)
+ if(triggered || !isturf(loc) || iseffect(on_who))
+ return FALSE
+
+ var/mob/living/living_mob
+ if(ismob(on_who))
+ if(!isliving(on_who)) //no ghosties.
+ return FALSE
+ living_mob = on_who
+
+ if(living_mob?.incorporeal_move || (on_who.movement_type & MOVETYPES_NOT_TOUCHING_GROUND))
+ return foot_on_mine ? IS_WEAKREF_OF(on_who, foot_on_mine) : FALSE //Only go boom if their foot was on the mine PRIOR to flying/phasing. You fucked up, you live with the consequences.
+
+ return TRUE
+
+
+/obj/effect/mine/proc/on_entered(datum/source, atom/movable/arrived)
+ SIGNAL_HANDLER
+
+ if(!can_trigger(arrived))
+ return
+ // Someone already on it
+ if(foot_on_mine?.resolve())
+ return
+
+ foot_on_mine = WEAKREF(arrived)
+ visible_message(span_danger("[icon2html(src, viewers(src))] *click*"))
+ playsound(src, 'sound/machines/click.ogg', 60, TRUE)
+
+/obj/effect/mine/proc/on_exited(datum/source, atom/movable/gone)
+ // SIGNAL_HANDLER we're not ready for this
+
+ if(!can_trigger(gone))
+ return
+ // Check that the guy who's on it is stepping off
+ if(foot_on_mine && !IS_WEAKREF_OF(gone, foot_on_mine))
+ return
+
+ triggermine(gone)
+ foot_on_mine = null
diff --git a/code/game/objects/effects/spawners/lootdrop.dm b/code/game/objects/effects/spawners/lootdrop.dm
index 521feb5776fb..aefead875e86 100644
--- a/code/game/objects/effects/spawners/lootdrop.dm
+++ b/code/game/objects/effects/spawners/lootdrop.dm
@@ -713,7 +713,6 @@
name = "secure AI circuit board spawner"
loot = list(
/obj/item/circuitboard/computer/aiupload,
- /obj/item/circuitboard/computer/ai_upload_download,
/obj/item/circuitboard/computer/borgupload
)
diff --git a/code/game/objects/effects/spawners/mystery_box.dm b/code/game/objects/effects/spawners/mystery_box.dm
index c7a2ca6f18ba..46fbb2bfc32d 100644
--- a/code/game/objects/effects/spawners/mystery_box.dm
+++ b/code/game/objects/effects/spawners/mystery_box.dm
@@ -152,6 +152,7 @@
var/static/list/spooks = list('sound/hallucinations/growl1.ogg','sound/hallucinations/growl2.ogg','sound/hallucinations/growl3.ogg','sound/hallucinations/veryfar_noise.ogg','sound/hallucinations/wail.ogg')
armor = 20
speedmod = 1.6
+ changesource_flags = MIRROR_BADMIN //deliberate admin spawn only
var/heal_rate = 1
var/regen_cooldown = 0
diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm
index 08f70d4bd4af..c8d2c42821c7 100644
--- a/code/game/objects/effects/spiders.dm
+++ b/code/game/objects/effects/spiders.dm
@@ -14,7 +14,7 @@
playsound(loc, 'sound/items/welder.ogg', 100, 1)
-/obj/structure/spider/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir)
+/obj/structure/spider/run_atom_armor(damage_amount, damage_type, damage_flag = 0, attack_dir)
if(damage_flag == MELEE)
switch(damage_type)
if(BURN)
diff --git a/code/game/objects/effects/step_triggers.dm b/code/game/objects/effects/step_triggers.dm
index c430cdbd0307..0a2e15a5229e 100644
--- a/code/game/objects/effects/step_triggers.dm
+++ b/code/game/objects/effects/step_triggers.dm
@@ -7,11 +7,17 @@
invisibility = INVISIBILITY_ABSTRACT // nope cant see this shit
anchored = TRUE
+/obj/effect/step_trigger/Initialize(mapload)
+ . = ..()
+ var/static/list/loc_connections = list(
+ COMSIG_ATOM_ENTERED = PROC_REF(on_entered),
+ )
+ AddElement(/datum/element/connect_loc, loc_connections)
+
/obj/effect/step_trigger/proc/Trigger(atom/movable/A)
return 0
-/obj/effect/step_trigger/Crossed(H as mob|obj)
- ..()
+/obj/effect/step_trigger/proc/on_entered(datum/source, atom/movable/H, ...)
if(!H)
return
if(isobserver(H) && !affect_ghosts)
diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm
index 124ba550dfcf..3c7795a7f01c 100644
--- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm
+++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm
@@ -20,31 +20,31 @@
. = ..()
if(set_color)
color = set_color
- var/target_pixel_x = 0
- var/target_pixel_y = 0
+ var/target_pixel_x = pixel_x
+ var/target_pixel_y = pixel_y
switch(set_dir)
if(NORTH)
- target_pixel_y = 16
+ target_pixel_y += 16
if(SOUTH)
- target_pixel_y = -16
+ target_pixel_y += -16
layer = ABOVE_MOB_LAYER
if(EAST)
- target_pixel_x = 16
+ target_pixel_x += 16
if(WEST)
- target_pixel_x = -16
+ target_pixel_x += -16
if(NORTHEAST)
- target_pixel_x = 16
- target_pixel_y = 16
+ target_pixel_x += 16
+ target_pixel_y += 16
if(NORTHWEST)
- target_pixel_x = -16
- target_pixel_y = 16
+ target_pixel_x += -16
+ target_pixel_y += 16
if(SOUTHEAST)
- target_pixel_x = 16
- target_pixel_y = -16
+ target_pixel_x += 16
+ target_pixel_y += -16
layer = ABOVE_MOB_LAYER
if(SOUTHWEST)
- target_pixel_x = -16
- target_pixel_y = -16
+ target_pixel_x += -16
+ target_pixel_y += -16
layer = ABOVE_MOB_LAYER
animate(src, pixel_x = target_pixel_x, pixel_y = target_pixel_y, alpha = 0, time = duration)
@@ -71,14 +71,14 @@
switch(newdir)
if(NORTH)
layer = BELOW_MOB_LAYER
- pixel_x = rand(-3,3)
- pixel_y = rand(4,6)
+ pixel_x += rand(-3,3)
+ pixel_y += rand(4,6)
if(SOUTH)
- pixel_x = rand(-3,3)
- pixel_y = rand(-1,1)
+ pixel_x += rand(-3,3)
+ pixel_y += rand(-1,1)
else
- pixel_x = rand(-1,1)
- pixel_y = rand(-1,1)
+ pixel_x += rand(-1,1)
+ pixel_y += rand(-1,1)
..()
/obj/effect/temp_visual/dir_setting/firing_effect/energy
@@ -89,11 +89,20 @@
icon_state = "shieldsparkles"
duration = 0.3 SECONDS
-/obj/effect/temp_visual/dir_setting/firing_effect/mecha_swipe
+/obj/effect/temp_visual/dir_setting/firing_effect/sweep_attack
icon = 'icons/effects/96x96.dmi'
icon_state = "big_slash"
+ pixel_x = -32
+ pixel_y = -32
duration = 0.3 SECONDS
+/obj/effect/temp_visual/dir_setting/firing_effect/sweep_attack/semicircle
+ icon_state = "big_slash_180"
+
+/obj/effect/temp_visual/dir_setting/firing_effect/sweep_attack/full_circle
+ icon_state = "big_slash_360"
+ duration = 0.4 SECONDS
+
/obj/effect/temp_visual/dir_setting/ninja
name = "ninja shadow"
icon = 'icons/mob/mob.dmi'
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 0e1295fb2b88..8cba73d07b9e 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -8,6 +8,16 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
name = "item"
icon = 'icons/obj/misc.dmi'
blocks_emissive = EMISSIVE_BLOCK_GENERIC
+
+ /* !!!!!!!!!!!!!!! IMPORTANT !!!!!!!!!!!!!!
+
+ IF YOU ADD MORE ICON CRAP TO THIS
+ ENSURE YOU ALSO ADD THE NEW VARS TO CHAMELEON ITEM_ACTION'S update_item() PROC (/datum/action/item_action/chameleon/change/proc/update_item())
+ WASHING MASHINE'S dye_item() PROC (/obj/item/proc/dye_item())
+ AND ALSO TO THE CHANGELING PROFILE DISGUISE SYSTEMS (/datum/changeling_profile / /datum/antagonist/changeling/proc/create_profile() / /proc/changeling_transform())
+
+ !!!!!!!!!!!!!!! IMPORTANT !!!!!!!!!!!!!! */
+
///icon state name for inhand overlays
var/item_state = null
///Icon file for left hand inhand overlays
@@ -16,10 +26,21 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
var/righthand_file = 'icons/mob/inhands/items_righthand.dmi'
///Icon file for mob worn overlays.
- ///no var for state because it should *always* be the same as icon_state
var/icon/mob_overlay_icon
- //Forced mob worn layer instead of the standard preferred ssize.
+ ///Icon state for mob worn overlays, if null the normal icon_state will be used.
+ var/worn_icon_state
+ ///Icon state for the belt overlay, if null the normal icon_state will be used.
+ var/belt_icon_state
+ //Forced mob worn layer instead of the standard preferred size.
var/alternate_worn_layer
+ ///The config type to use for greyscaled worn sprites. Both this and greyscale_colors must be assigned to work.
+ var/greyscale_config_worn
+ ///The config type to use for greyscaled left inhand sprites. Both this and greyscale_colors must be assigned to work.
+ var/greyscale_config_inhand_left
+ ///The config type to use for greyscaled right inhand sprites. Both this and greyscale_colors must be assigned to work.
+ var/greyscale_config_inhand_right
+ ///The config type to use for greyscaled belt overlays. Both this and greyscale_colors must be assigned to work.
+ var/greyscale_config_belt
//Dimensions of the icon file used when this item is worn, eg: hats.dmi
//eg: 32x32 sprite, 64x64 sprite, etc.
@@ -162,6 +183,9 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
if (attack_verb)
attack_verb = typelist("attack_verb", attack_verb)
+ if(!greyscale_config && greyscale_colors && (greyscale_config_worn || greyscale_config_belt || greyscale_config_inhand_right || greyscale_config_inhand_left))
+ update_greyscale()
+
. = ..()
// Handle adding item associated actions
@@ -267,6 +291,27 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
/obj/item/proc/suicide_act(mob/user)
return
+/obj/item/set_greyscale(list/colors, new_config, new_worn_config, new_inhand_left, new_inhand_right)
+ if(new_worn_config)
+ greyscale_config_worn = new_worn_config
+ if(new_inhand_left)
+ greyscale_config_inhand_left = new_inhand_left
+ if(new_inhand_right)
+ greyscale_config_inhand_right = new_inhand_right
+ return ..()
+
+/// Checks if this atom uses the GAGS system and if so updates the worn and inhand icons
+/obj/item/update_greyscale()
+ . = ..()
+ if(!greyscale_colors)
+ return
+ if(greyscale_config_worn)
+ /*worn_icon*/mob_overlay_icon = SSgreyscale.GetColoredIconByType(greyscale_config_worn, greyscale_colors)
+ if(greyscale_config_inhand_left)
+ lefthand_file = SSgreyscale.GetColoredIconByType(greyscale_config_inhand_left, greyscale_colors)
+ if(greyscale_config_inhand_right)
+ righthand_file = SSgreyscale.GetColoredIconByType(greyscale_config_inhand_right, greyscale_colors)
+
/obj/item/proc/get_sharpness()
return sharpness
@@ -724,7 +769,10 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
return FALSE
/obj/item/proc/get_belt_overlay() //Returns the icon used for overlaying the object on a belt
- return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', icon_state)
+ var/icon_state_to_use = belt_icon_state || icon_state
+ if(greyscale_config_belt && greyscale_colors)
+ return mutable_appearance(SSgreyscale.GetColoredIconByType(greyscale_config_belt, greyscale_colors), icon_state_to_use)
+ return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', icon_state_to_use)
/obj/item/proc/update_slot_icon()
if(!ismob(loc))
@@ -797,7 +845,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
return ..()
return 0
-/obj/item/mech_melee_attack(obj/mecha/M, equip_allowed)
+/obj/item/mech_melee_attack(obj/mecha/M, punch_force, equip_allowed = TRUE)
return 0
/obj/item/deconstruct(disassembled = TRUE)
diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm
index f32892331598..f0ab2f890b99 100644
--- a/code/game/objects/items/RCD.dm
+++ b/code/game/objects/items/RCD.dm
@@ -1,6 +1,3 @@
-#define GLOW_MODE 3
-#define LIGHT_MODE 2
-#define REMOVE_MODE 1
/*
CONTAINS:
@@ -41,6 +38,7 @@ RLD
var/linked_switch_id = null //integer variable, the id for the assigned conveyor switch
var/obj/machinery/conveyor/last_placed
var/color_choice = null
+ var/silent = FALSE // does it make sound? (used for mime mech RCD)
/obj/item/construction/Initialize(mapload)
. = ..()
@@ -50,13 +48,20 @@ RLD
if(upgrade & RCD_UPGRADE_SILO_LINK)
silo_mats = AddComponent(/datum/component/remote_materials, "RCD", mapload, FALSE)
+/// Used for examining the RCD and for its UI
+/obj/item/construction/proc/get_silo_iron()
+ if(silo_link && silo_mats.mat_container && !silo_mats.on_hold())
+ return silo_mats.mat_container.get_material_amount(/datum/material/iron)/500
+ return FALSE
+
/obj/item/construction/examine(mob/user)
. = ..()
. += "It currently holds [matter]/[max_matter] matter-units."
if(upgrade & RCD_UPGRADE_SILO_LINK)
. += "Remote storage link state: [silo_link ? "[silo_mats.on_hold() ? "ON HOLD" : "ON"]" : "OFF"]."
- if(silo_link && silo_mats.mat_container && !silo_mats.on_hold())
- . += "Remote connection has iron in equivalent to [silo_mats.mat_container.get_material_amount(/datum/material/iron)/500] RCD unit\s." //1 matter for 1 floor tile, as 4 tiles are produced from 1 metal
+ var/iron = get_silo_iron()
+ if(iron)
+ . += "Remote connection has iron in equivalent to [iron] RCD unit\s." //1 matter for 1 floor tile, as 4 tiles are produced from 1 metal
/obj/item/construction/Destroy()
QDEL_NULL(spark_system)
@@ -90,13 +95,15 @@ RLD
upgrade |= rcd_up.upgrade
if((rcd_up.upgrade & RCD_UPGRADE_SILO_LINK) && !silo_mats)
silo_mats = AddComponent(/datum/component/remote_materials, "RCD", FALSE, FALSE)
- playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE)
+ if(!silent)
+ playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE)
qdel(rcd_up)
/// Inserts matter into the RCD allowing it to build
/obj/item/construction/proc/insert_matter(obj/O, mob/user)
if(iscyborg(user))
return FALSE
+
var/loaded = FALSE
if(istype(O, /obj/item/rcd_ammo))
var/obj/item/rcd_ammo/R = O
@@ -108,7 +115,8 @@ RLD
if(R.ammoamt <= 0)
qdel(R)
matter += load
- playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE)
+ if(!silent)
+ playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE)
loaded = TRUE
else if(istype(O, /obj/item/stack))
loaded = loadwithsheets(O, user)
@@ -127,17 +135,20 @@ RLD
var/amount_to_use = min(S.amount, maxsheets)
S.use(amount_to_use)
matter += value*amount_to_use
- playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE)
+ if(!silent)
+ playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE)
to_chat(user, span_notice("You insert [amount_to_use] [S.name] sheets into [src]. "))
return TRUE
to_chat(user, span_warning("You can't insert any more [S.name] sheets into [src]!"))
return FALSE
/obj/item/construction/proc/activate()
- playsound(src.loc, 'sound/items/deconstruct.ogg', 50, TRUE)
+ if(!silent)
+ playsound(src.loc, 'sound/items/deconstruct.ogg', 50, TRUE)
/obj/item/construction/attack_self(mob/user)
- playsound(src.loc, 'sound/effects/pop.ogg', 50, FALSE)
+ if(!silent)
+ playsound(src.loc, 'sound/effects/pop.ogg', 50, FALSE)
if(prob(20))
spark_system.start()
@@ -169,6 +180,39 @@ RLD
silo_mats.silo_log(src, "consume", -amount, "build", materials)
return TRUE
+/obj/item/construction/ui_data(mob/user)
+ var/list/data = list()
+
+ //matter in the rcd
+ var/total_matter = ((upgrade & RCD_UPGRADE_SILO_LINK) && silo_link) ? get_silo_iron() : matter
+ if(!total_matter)
+ total_matter = 0
+ data["matterLeft"] = total_matter
+
+ //silo details
+ data["silo_upgraded"] = !!(upgrade & RCD_UPGRADE_SILO_LINK)
+ data["silo_enabled"] = silo_link
+
+ return data
+
+///shared action for toggling silo link rcd,rld & plumbing
+/obj/item/construction/ui_act(action, list/params)
+ . = ..()
+ if(.)
+ return
+
+ if(action == "toggle_silo")
+ if(silo_mats)
+ if(!silo_mats.mat_container && !silo_link) // Allow them to turn off an invalid link
+ to_chat(usr, span_alert("No silo link detected. Connect to silo via multitool."))
+ return FALSE
+ silo_link = !silo_link
+ to_chat(usr, span_notice("You change [src]'s storage link state: [silo_link ? "ON" : "OFF"]."))
+ else
+ to_chat(usr, span_warning("[src] doesn't have remote storage connection."))
+ return TRUE
+ return FALSE
+
/obj/item/construction/proc/checkResource(amount, mob/user)
if(!silo_link || !silo_mats || !silo_mats.mat_container)
. = matter >= amount
@@ -213,6 +257,27 @@ RLD
return FALSE
return TRUE
+///each define maps to a variable used for construction in the RCD
+#define CONSTRUCTION_MODE "construction_mode"
+#define WINDOW_TYPE "window_type"
+#define WINDOW_GLASS "window_glass"
+#define WINDOW_SIZE "window_size"
+#define COMPUTER_DIR "computer_dir"
+#define FURNISH_TYPE "furnish_type"
+#define FURNISH_COST "furnish_cost"
+#define FURNISH_DELAY "furnish_delay"
+#define AIRLOCK_TYPE "airlock_type"
+#define CONVEYOR_TYPE "conveyor_type"
+
+///flags to be sent to UI
+#define TITLE "title"
+#define ICON "icon"
+
+///flags for creating icons shared by an entire category
+#define CATEGORY_ICON_STATE "category_icon_state"
+#define CATEGORY_ICON_SUFFIX "category_icon_suffix"
+#define TITLE_ICON "ICON=TITLE"
+
/obj/item/construction/rcd
name = "rapid-construction-device (RCD)"
icon = 'icons/obj/tools.dmi'
@@ -224,7 +289,104 @@ RLD
slot_flags = ITEM_SLOT_BELT
item_flags = NO_MAT_REDEMPTION | NOBLUDGEON
has_ammobar = TRUE
- var/mode = RCD_FLOORWALL
+
+ ///all stuff used by RCD for construction
+ var/static/list/root_categories = list(
+ //1ST ROOT CATEGORY
+ "Construction" = list( //Stuff you use to make & decorate areas
+ //Walls & Windows
+ "Structures" = list(
+ list(CONSTRUCTION_MODE = RCD_FLOORWALL, ICON = "wallfloor", TITLE = "Wall/Floor"),
+ list(CONSTRUCTION_MODE = RCD_DECONSTRUCT, ICON = "delete", TITLE = "Deconstruct"),
+ list(CONSTRUCTION_MODE = RCD_WINDOWGRILLE, WINDOW_TYPE = /obj/structure/window, WINDOW_GLASS = RCD_WINDOW_NORMAL, WINDOW_SIZE = RCD_WINDOW_DIRECTIONAL, ICON = "dirwindow", TITLE = "Directional Window"),
+ list(CONSTRUCTION_MODE = RCD_WINDOWGRILLE, WINDOW_TYPE = /obj/structure/window/fulltile, WINDOW_GLASS = RCD_WINDOW_NORMAL, WINDOW_SIZE = RCD_WINDOW_FULLTILE, ICON = "fullwindow", TITLE = "Full Tile Window"),
+ list(CONSTRUCTION_MODE = RCD_WINDOWGRILLE, WINDOW_TYPE = /obj/structure/window/reinforced, WINDOW_GLASS = RCD_WINDOW_REINFORCED, WINDOW_SIZE = RCD_WINDOW_DIRECTIONAL, ICON = "dirwindow_r", TITLE = "Directional Reinforced Window"),
+ list(CONSTRUCTION_MODE = RCD_WINDOWGRILLE, WINDOW_TYPE = /obj/structure/window/reinforced/fulltile, WINDOW_GLASS = RCD_WINDOW_REINFORCED, WINDOW_SIZE = RCD_WINDOW_FULLTILE, ICON = "fullwindow_r", TITLE = "Full Tile Reinforced Window"),
+ ),
+
+ //Computers & Machine Frames
+ "Machines" = list(
+ list(CONSTRUCTION_MODE = RCD_MACHINE, ICON = "box_1", TITLE = "Machine Frame"),
+ list(CONSTRUCTION_MODE = RCD_COMPUTER, COMPUTER_DIR = 1, ICON = "cnorth", TITLE = "Computer North"),
+ list(CONSTRUCTION_MODE = RCD_COMPUTER, COMPUTER_DIR = 2, ICON = "csouth", TITLE = "Computer South"),
+ list(CONSTRUCTION_MODE = RCD_COMPUTER, COMPUTER_DIR = 4, ICON = "ceast", TITLE = "Computer East"),
+ list(CONSTRUCTION_MODE = RCD_COMPUTER, COMPUTER_DIR = 8, ICON = "cwest", TITLE = "Computer West"),
+ ),
+
+ //Interior Design[construction_mode = RCD_FURNISHING is implied]
+ "Furniture" = list(
+ list(FURNISH_TYPE = /obj/structure/chair, FURNISH_COST = 8, FURNISH_DELAY = 10, ICON = "chair", TITLE = "Chair"),
+ list(FURNISH_TYPE = /obj/structure/chair/stool, FURNISH_COST = 8, FURNISH_DELAY = 10, ICON = "stool", TITLE = "Stool"),
+ list(FURNISH_TYPE = /obj/structure/table, FURNISH_COST = 16, FURNISH_DELAY = 20, ICON = "table",TITLE = "Table"),
+ list(FURNISH_TYPE = /obj/structure/table/glass, FURNISH_COST = 16, FURNISH_DELAY = 20, ICON = "glass_table", TITLE = "Glass Table"),
+ ),
+
+ //Conveyors & Switches
+ "Conveyors" = list(
+ list(CONSTRUCTION_MODE = RCD_CONVEYOR, ICON = "conveyor_construct", TITLE = "Conveyor Belt"),
+ list(CONSTRUCTION_MODE = RCD_SWITCH, ICON = "switch-off", TITLE = "Conveyor Switch"),
+ )
+ ),
+
+ //2ND ROOT CATEGORY[construction_mode = RCD_AIRLOCK is implied,"icon=closed"]
+ "Airlocks" = list( //used to seal/close areas
+ //Solid Airlocks[airlock_glass = FALSE is implied,no fill_closed overlay]
+ "Solid Airlocks" = list(
+ list(AIRLOCK_TYPE = /obj/machinery/door/airlock, TITLE = "Standard", CATEGORY_ICON_STATE = TITLE_ICON),
+ list(AIRLOCK_TYPE = /obj/machinery/door/airlock/public, TITLE = "Public"),
+ list(AIRLOCK_TYPE = /obj/machinery/door/airlock/engineering, TITLE = "Engineering"),
+ list(AIRLOCK_TYPE = /obj/machinery/door/airlock/atmos, TITLE = "Atmospherics"),
+ list(AIRLOCK_TYPE = /obj/machinery/door/airlock/security, TITLE = "Security"),
+ list(AIRLOCK_TYPE = /obj/machinery/door/airlock/command, TITLE = "Command"),
+ list(AIRLOCK_TYPE = /obj/machinery/door/airlock/medical, TITLE = "Medical"),
+ list(AIRLOCK_TYPE = /obj/machinery/door/airlock/research, TITLE = "Research"),
+ list(AIRLOCK_TYPE = /obj/machinery/door/airlock/freezer, TITLE = "Freezer"),
+ list(AIRLOCK_TYPE = /obj/machinery/door/airlock/virology, TITLE = "Virology"),
+ list(AIRLOCK_TYPE = /obj/machinery/door/airlock/mining, TITLE = "Mining"),
+ list(AIRLOCK_TYPE = /obj/machinery/door/airlock/maintenance, TITLE = "Maintenance"),
+ list(AIRLOCK_TYPE = /obj/machinery/door/airlock/external, TITLE = "External"),
+ list(AIRLOCK_TYPE = /obj/machinery/door/airlock/maintenance/external, TITLE = "External Maintenance"),
+ list(AIRLOCK_TYPE = /obj/machinery/door/airlock/hatch, TITLE = "Airtight Hatch"),
+ list(AIRLOCK_TYPE = /obj/machinery/door/airlock/maintenance_hatch, TITLE = "Maintenance Hatch"),
+ ),
+
+ //Glass Airlocks[airlock_glass = TRUE is implied,do fill_closed overlay]
+ "Glass Airlocks" = list(
+ list(AIRLOCK_TYPE = /obj/machinery/door/airlock/glass, TITLE = "Standard", CATEGORY_ICON_STATE = TITLE_ICON, CATEGORY_ICON_SUFFIX = "Glass"),
+ list(AIRLOCK_TYPE = /obj/machinery/door/airlock/public/glass, TITLE = "Public"),
+ list(AIRLOCK_TYPE = /obj/machinery/door/airlock/engineering/glass, TITLE = "Engineering"),
+ list(AIRLOCK_TYPE = /obj/machinery/door/airlock/atmos/glass, TITLE = "Atmospherics"),
+ list(AIRLOCK_TYPE = /obj/machinery/door/airlock/security/glass, TITLE = "Security"),
+ list(AIRLOCK_TYPE = /obj/machinery/door/airlock/command/glass, TITLE = "Command"),
+ list(AIRLOCK_TYPE = /obj/machinery/door/airlock/medical/glass, TITLE = "Medical"),
+ list(AIRLOCK_TYPE = /obj/machinery/door/airlock/research/glass, TITLE = "Research"),
+ list(AIRLOCK_TYPE = /obj/machinery/door/airlock/virology/glass, TITLE = "Virology"),
+ list(AIRLOCK_TYPE = /obj/machinery/door/airlock/mining/glass, TITLE = "Mining"),
+ list(AIRLOCK_TYPE = /obj/machinery/door/airlock/maintenance/glass, TITLE = "Maintenance"),
+ list(AIRLOCK_TYPE = /obj/machinery/door/airlock/external/glass, TITLE = "External"),
+ list(AIRLOCK_TYPE = /obj/machinery/door/airlock/maintenance/external/glass, TITLE = "External Maintenance"),
+ ),
+
+ //Window Doors[airlock_glass = TRUE is implied]
+ "Windoors" = list(
+ list(AIRLOCK_TYPE = /obj/machinery/door/window, ICON = "windoor", TITLE = "Windoor"),
+ list(AIRLOCK_TYPE = /obj/machinery/door/window/brigdoor, ICON = "secure_windoor", TITLE = "Secure Windoor"),
+ ),
+ ),
+
+ //3RD CATEGORY Airlock access,empty list cause airlock_electronics UI will be displayed when this tab is selected
+ "Airlock Access" = list()
+ )
+
+ ///english name for the design to check if it was selected or not
+ var/design_title = "Wall/Floor"
+ var/design_category = "Structures"
+ var/root_category = "Construction"
+ var/closed = FALSE
+ ///owner of this rcd. It can either be an construction console or an player
+ var/owner
+
+ var/construction_mode = RCD_FLOORWALL
var/ranged = FALSE
var/computer_dir = 1
var/airlock_type = /obj/machinery/door/airlock
@@ -244,7 +406,7 @@ RLD
var/obj/item/electronics/airlock/airlock_electronics
/obj/item/construction/rcd/suicide_act(mob/user)
- mode = RCD_FLOORWALL
+ construction_mode = RCD_FLOORWALL
if(!rcd_create(get_turf(user), user))
return SHAME
if(isfloorturf(get_turf(user)))
@@ -252,350 +414,39 @@ RLD
user.visible_message(span_suicide("[user] sets the RCD to 'Wall' and points it down [user.p_their()] throat! It looks like [user.p_theyre()] trying to commit suicide.."))
return (BRUTELOSS)
-/obj/item/construction/rcd/verb/toggle_window_glass_verb()
- set name = "RCD : Toggle Window Glass"
- set category = "Object"
- set src in view(1)
-
- if(!usr.canUseTopic(src, BE_CLOSE))
- return
-
- toggle_window_glass(usr)
-
-/obj/item/construction/rcd/verb/toggle_window_size_verb()
- set name = "RCD : Toggle Window Size"
- set category = "Object"
- set src in view(1)
-
- if(!usr.canUseTopic(src, BE_CLOSE))
- return
-
- toggle_window_size(usr)
-
-/obj/item/construction/rcd/proc/toggle_access(acc)
- if (acc == "all")
- conf_access = null
- else if(acc == "one")
- use_one_access = !use_one_access
- else
- var/req = text2num(acc)
-
- if (conf_access == null)
- conf_access = list()
-
- if (!(req in conf_access))
- conf_access += req
- else
- conf_access -= req
- if (!conf_access.len)
- conf_access = null
-
-/// Toggles the usage of reinforced or normal glass
-/obj/item/construction/rcd/proc/toggle_window_glass(mob/user)
- if (window_glass != RCD_WINDOW_REINFORCED)
- set_window_type(user, RCD_WINDOW_REINFORCED, window_size)
- return
- set_window_type(user, RCD_WINDOW_NORMAL, window_size)
-
-/// Toggles the usage of directional or full tile windows
-/obj/item/construction/rcd/proc/toggle_window_size(mob/user)
- if (window_size != RCD_WINDOW_DIRECTIONAL)
- set_window_type(user, window_glass, RCD_WINDOW_DIRECTIONAL)
- return
- set_window_type(user, window_glass, RCD_WINDOW_FULLTILE)
-
-/// Sets the window type to be created based on parameters
-/obj/item/construction/rcd/proc/set_window_type(mob/user, glass, size)
- window_glass = glass
- window_size = size
- if(window_glass == RCD_WINDOW_REINFORCED)
- if(window_size == RCD_WINDOW_DIRECTIONAL)
- window_type = /obj/structure/window/reinforced
- else
- window_type = /obj/structure/window/reinforced/fulltile
- else
- if(window_size == RCD_WINDOW_DIRECTIONAL)
- window_type = /obj/structure/window
- else
- window_type = /obj/structure/window/fulltile
-
- to_chat(user, span_notice("You change \the [src]'s window mode to [window_size] [window_glass] window."))
-
-/obj/item/construction/rcd/proc/toggle_silo_link(mob/user)
- if(silo_mats)
- if(!silo_mats.mat_container)
- to_chat(user, span_alert("No silo link detected. Connect to silo via multitool."))
- return FALSE
- silo_link = !silo_link
- to_chat(user, span_notice("You change \the [src]'s storage link state: [silo_link ? "ON" : "OFF"]."))
- else
- to_chat(user, span_warning("\the [src] doesn't have remote storage connection."))
-
-/obj/item/construction/rcd/proc/get_airlock_image(airlock_type)
- var/obj/machinery/door/airlock/proto = airlock_type
- var/ic = initial(proto.icon)
- var/mutable_appearance/MA = mutable_appearance(ic, "closed")
- if(!initial(proto.glass))
- MA.overlays += "fill_closed"
- //Not scaling these down to button size because they look horrible then, instead just bumping up radius.
- return MA
-
-/obj/item/construction/rcd/proc/change_computer_dir(mob/user)
- if(!user)
- return
- var/list/computer_dirs = list(
- "NORTH" = image(icon = 'icons/mob/radial.dmi', icon_state = "cnorth"),
- "EAST" = image(icon = 'icons/mob/radial.dmi', icon_state = "ceast"),
- "SOUTH" = image(icon = 'icons/mob/radial.dmi', icon_state = "csouth"),
- "WEST" = image(icon = 'icons/mob/radial.dmi', icon_state = "cwest")
- )
- var/computerdirs = show_radial_menu(user, src, computer_dirs, custom_check = CALLBACK(src, PROC_REF(check_menu), user), require_near = TRUE, tooltips = TRUE)
- if(!check_menu(user))
- return
- switch(computerdirs)
- if("NORTH")
- computer_dir = 1
- if("EAST")
- computer_dir = 4
- if("SOUTH")
- computer_dir = 2
- if("WEST")
- computer_dir = 8
-
-/**
- * Customizes RCD's airlock settings based on user's choices
- *
- * Arguments:
- * * user The mob that is choosing airlock settings
- * * remote_anchor The remote anchor for radial menus. If set, it will also remove proximity restrictions from the menus
- */
-/obj/item/construction/rcd/proc/change_airlock_setting(mob/user, remote_anchor)
- if(!user)
- return
-
- var/list/solid_or_glass_choices = list(
- "Solid" = get_airlock_image(/obj/machinery/door/airlock),
- "Glass" = get_airlock_image(/obj/machinery/door/airlock/glass),
- "Windoor" = image(icon = 'icons/mob/radial.dmi', icon_state = "windoor"),
- "Secure Windoor" = image(icon = 'icons/mob/radial.dmi', icon_state = "secure_windoor")
- )
-
- var/list/solid_choices = list(
- "Standard" = get_airlock_image(/obj/machinery/door/airlock),
- "Public" = get_airlock_image(/obj/machinery/door/airlock/public),
- "Engineering" = get_airlock_image(/obj/machinery/door/airlock/engineering),
- "Atmospherics" = get_airlock_image(/obj/machinery/door/airlock/atmos),
- "Security" = get_airlock_image(/obj/machinery/door/airlock/security),
- "Command" = get_airlock_image(/obj/machinery/door/airlock/command),
- "Medical" = get_airlock_image(/obj/machinery/door/airlock/medical),
- "Research" = get_airlock_image(/obj/machinery/door/airlock/research),
- "Freezer" = get_airlock_image(/obj/machinery/door/airlock/freezer),
- "Science" = get_airlock_image(/obj/machinery/door/airlock/science),
- "Virology" = get_airlock_image(/obj/machinery/door/airlock/virology),
- "Mining" = get_airlock_image(/obj/machinery/door/airlock/mining),
- "Maintenance" = get_airlock_image(/obj/machinery/door/airlock/maintenance),
- "External" = get_airlock_image(/obj/machinery/door/airlock/external),
- "External Maintenance" = get_airlock_image(/obj/machinery/door/airlock/maintenance/external),
- "Airtight Hatch" = get_airlock_image(/obj/machinery/door/airlock/hatch),
- "Maintenance Hatch" = get_airlock_image(/obj/machinery/door/airlock/maintenance_hatch)
- )
-
- var/list/glass_choices = list(
- "Standard" = get_airlock_image(/obj/machinery/door/airlock/glass),
- "Public" = get_airlock_image(/obj/machinery/door/airlock/public/glass),
- "Engineering" = get_airlock_image(/obj/machinery/door/airlock/engineering/glass),
- "Atmospherics" = get_airlock_image(/obj/machinery/door/airlock/atmos/glass),
- "Security" = get_airlock_image(/obj/machinery/door/airlock/security/glass),
- "Command" = get_airlock_image(/obj/machinery/door/airlock/command/glass),
- "Medical" = get_airlock_image(/obj/machinery/door/airlock/medical/glass),
- "Research" = get_airlock_image(/obj/machinery/door/airlock/research/glass),
- "Science" = get_airlock_image(/obj/machinery/door/airlock/science/glass),
- "Virology" = get_airlock_image(/obj/machinery/door/airlock/virology/glass),
- "Mining" = get_airlock_image(/obj/machinery/door/airlock/mining/glass),
- "Maintenance" = get_airlock_image(/obj/machinery/door/airlock/maintenance/glass),
- "External" = get_airlock_image(/obj/machinery/door/airlock/external/glass),
- "External Maintenance" = get_airlock_image(/obj/machinery/door/airlock/maintenance/external/glass)
- )
-
- var/airlockcat = show_radial_menu(user, remote_anchor || src, solid_or_glass_choices, custom_check = CALLBACK(src, PROC_REF(check_menu), user, remote_anchor), require_near = remote_anchor ? FALSE : TRUE, tooltips = TRUE)
- switch(airlockcat)
- if("Solid")
- if(advanced_airlock_setting == 1)
- var/airlockpaint = show_radial_menu(user, remote_anchor || src, solid_choices, radius = 42, custom_check = CALLBACK(src, PROC_REF(check_menu), user), require_near = remote_anchor ? FALSE : TRUE, tooltips = TRUE)
- switch(airlockpaint)
- if("Standard")
- airlock_type = /obj/machinery/door/airlock
- if("Public")
- airlock_type = /obj/machinery/door/airlock/public
- if("Engineering")
- airlock_type = /obj/machinery/door/airlock/engineering
- if("Atmospherics")
- airlock_type = /obj/machinery/door/airlock/atmos
- if("Security")
- airlock_type = /obj/machinery/door/airlock/security
- if("Command")
- airlock_type = /obj/machinery/door/airlock/command
- if("Medical")
- airlock_type = /obj/machinery/door/airlock/medical
- if("Research")
- airlock_type = /obj/machinery/door/airlock/research
- if("Freezer")
- airlock_type = /obj/machinery/door/airlock/freezer
- if("Science")
- airlock_type = /obj/machinery/door/airlock/science
- if("Virology")
- airlock_type = /obj/machinery/door/airlock/virology
- if("Mining")
- airlock_type = /obj/machinery/door/airlock/mining
- if("Maintenance")
- airlock_type = /obj/machinery/door/airlock/maintenance
- if("External")
- airlock_type = /obj/machinery/door/airlock/external
- if("External Maintenance")
- airlock_type = /obj/machinery/door/airlock/maintenance/external
- if("Airtight Hatch")
- airlock_type = /obj/machinery/door/airlock/hatch
- if("Maintenance Hatch")
- airlock_type = /obj/machinery/door/airlock/maintenance_hatch
- airlock_glass = FALSE
- else
- airlock_type = /obj/machinery/door/airlock
- airlock_glass = FALSE
-
- if("Glass")
- if(advanced_airlock_setting == 1)
- var/airlockpaint = show_radial_menu(user, remote_anchor || src, glass_choices, radius = 42, custom_check = CALLBACK(src, PROC_REF(check_menu), user), require_near = remote_anchor ? FALSE : TRUE, tooltips = TRUE)
- if(!check_menu(user))
- return
- switch(airlockpaint)
- if("Standard")
- airlock_type = /obj/machinery/door/airlock/glass
- if("Public")
- airlock_type = /obj/machinery/door/airlock/public/glass
- if("Engineering")
- airlock_type = /obj/machinery/door/airlock/engineering/glass
- if("Atmospherics")
- airlock_type = /obj/machinery/door/airlock/atmos/glass
- if("Security")
- airlock_type = /obj/machinery/door/airlock/security/glass
- if("Command")
- airlock_type = /obj/machinery/door/airlock/command/glass
- if("Medical")
- airlock_type = /obj/machinery/door/airlock/medical/glass
- if("Research")
- airlock_type = /obj/machinery/door/airlock/research/glass
- if("Science")
- airlock_type = /obj/machinery/door/airlock/science/glass
- if("Virology")
- airlock_type = /obj/machinery/door/airlock/virology/glass
- if("Mining")
- airlock_type = /obj/machinery/door/airlock/mining/glass
- if("Maintenance")
- airlock_type = /obj/machinery/door/airlock/maintenance/glass
- if("External")
- airlock_type = /obj/machinery/door/airlock/external/glass
- if("External Maintenance")
- airlock_type = /obj/machinery/door/airlock/maintenance/external/glass
- airlock_glass = TRUE
- else
- airlock_type = /obj/machinery/door/airlock/glass
- airlock_glass = TRUE
- if("Windoor")
- airlock_type = /obj/machinery/door/window
- airlock_glass = TRUE
- if("Secure Windoor")
- airlock_type = /obj/machinery/door/window/brigdoor
- airlock_glass = TRUE
- else
- airlock_type = /obj/machinery/door/airlock
- airlock_glass = FALSE
-
-/// Radial menu for choosing the object you want to be created with the furnishing mode
-/obj/item/construction/rcd/proc/change_furnishing_type(mob/user)
- if(!user)
- return
- var/static/list/choices = list(
- "Chair" = image(icon = 'icons/mob/radial.dmi', icon_state = "chair"),
- "Stool" = image(icon = 'icons/mob/radial.dmi', icon_state = "stool"),
- "Table" = image(icon = 'icons/mob/radial.dmi', icon_state = "table"),
- "Glass Table" = image(icon = 'icons/mob/radial.dmi', icon_state = "glass_table")
- )
- var/choice = show_radial_menu(user, src, choices, custom_check = CALLBACK(src, PROC_REF(check_menu), user), require_near = TRUE, tooltips = TRUE)
- if(!check_menu(user))
- return
- switch(choice)
- if("Chair")
- furnish_type = /obj/structure/chair
- furnish_cost = 8
- furnish_delay = 10
- if("Stool")
- furnish_type = /obj/structure/chair/stool
- furnish_cost = 8
- furnish_delay = 10
- if("Table")
- furnish_type = /obj/structure/table
- furnish_cost = 16
- furnish_delay = 20
- if("Glass Table")
- furnish_type = /obj/structure/table/glass
- furnish_cost = 16
- furnish_delay = 20
-
/obj/item/construction/rcd/proc/rcd_create(atom/A, mob/user)
var/list/rcd_results = A.rcd_vals(user, src)
if(!rcd_results)
return FALSE
var/delay = rcd_results["delay"] * delay_mod
- var/obj/effect/constructing_effect/rcd_effect = new(get_turf(A), delay, src.mode)
+ var/obj/effect/constructing_effect/rcd_effect = new(get_turf(A), delay, src.construction_mode)
+ var/datum/beam/rcd_beam
if(checkResource(rcd_results["cost"], user))
- if(do_after(user, delay, A))
+ if(!A.Adjacent(owner ? owner : user)) // ranged RCDs create beams
+ if(isatom(owner))
+ var/atom/owner_atom = owner
+ rcd_beam = owner_atom.Beam(A,icon_state="rped_upgrade",time=delay)
+ else
+ rcd_beam = Beam(A,icon_state="rped_upgrade",time=delay)
+ if(do_after(user, delay, (owner ? owner : A)))
if(checkResource(rcd_results["cost"], user))
if(A.rcd_act(user, src, rcd_results["mode"]))
rcd_effect.end_animation()
useResource(rcd_results["cost"], user)
activate()
- playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE)
+ if(!silent)
+ playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE)
return TRUE
+ if(rcd_beam)
+ qdel(rcd_beam)
qdel(rcd_effect)
return FALSE
-/obj/item/construction/rcd/proc/rcd_switch(atom/A, mob/user)
- var/cost = 1
- var/delay = 1
- var/obj/effect/constructing_effect/rcd_effect = new(get_turf(A), delay, src.mode)
- if(checkResource(cost, user))
- if(do_after(user, delay, A))
- if(checkResource(cost, user))
- rcd_effect.end_animation()
- useResource(cost, user)
- activate()
- playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
- new /obj/item/conveyor_switch_construct(A)
- qdel(rcd_effect)
-
-/obj/item/construction/rcd/proc/rcd_conveyor(atom/A, mob/user)
- var/delay = 5
- var/cost = 5
- var/obj/effect/constructing_effect/rcd_effect = new(get_turf(A), delay, src.mode)
- if(checkResource(cost, user))
- if(do_after(user, delay, target = A))
- if(checkResource(cost, user))
- rcd_effect.end_animation()
- useResource(cost, user)
- activate()
- playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
- var/cdir = get_dir(A, user)
- if (last_placed)
- cdir = get_dir(A, last_placed)
- if(cdir in GLOB.cardinals)
- last_placed.setDir(get_dir(last_placed, A))
- last_placed = new/obj/machinery/conveyor(A, cdir, linked_switch_id)
- qdel(rcd_effect)
-
/obj/item/construction/rcd/Initialize(mapload)
. = ..()
airlock_electronics = new(src)
airlock_electronics.name = "Access Control"
+ airlock_electronics.holder = src
GLOB.rcd_list += src
/obj/item/construction/rcd/Destroy()
@@ -603,127 +454,174 @@ RLD
GLOB.rcd_list -= src
. = ..()
-/obj/item/construction/rcd/attack_self(mob/user)
- ..()
- var/list/choices = list(
- "Airlock" = image(icon = 'icons/mob/radial.dmi', icon_state = "airlock"),
- "Deconstruct" = image(icon= 'icons/mob/radial.dmi', icon_state = "delete"),
- "Grilles & Windows" = image(icon = 'icons/mob/radial.dmi', icon_state = "grillewindow"),
- "Floors & Walls" = image(icon = 'icons/mob/radial.dmi', icon_state = "wallfloor")
+/obj/item/construction/rcd/ui_host(mob/user)
+ return owner || ..()
+
+/obj/item/construction/rcd/ui_interact(mob/user, datum/tgui/ui)
+ ui = SStgui.try_update_ui(user, src, ui)
+ if(!ui)
+ var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/rcd)
+ assets.send(user)
+ ui = new(user, src, "RapidConstructionDevice", name)
+ ui.open()
+
+/obj/item/construction/rcd/ui_static_data(mob/user)
+ return airlock_electronics.ui_static_data(user)
+
+/obj/item/construction/rcd/ui_assets(mob/user)
+ return list(
+ get_asset_datum(/datum/asset/spritesheet/rcd),
)
- if(upgrade & RCD_UPGRADE_FRAMES)
- choices += list(
- "Machine Frames" = image(icon = 'icons/mob/radial.dmi', icon_state = "machine"),
- "Computer Frames" = image(icon = 'icons/mob/radial.dmi', icon_state = "computer_dir"),
- )
- if(upgrade & RCD_UPGRADE_SILO_LINK)
- choices += list(
- "Silo Link" = image(icon = 'icons/obj/mining.dmi', icon_state = "silo"),
- )
- if(upgrade & RCD_UPGRADE_FURNISHING)
- choices += list(
- "Furnishing" = image(icon = 'icons/mob/radial.dmi', icon_state = "chair")
- )
- if(mode == RCD_AIRLOCK)
- choices += list(
- "Change Access" = image(icon = 'icons/mob/radial.dmi', icon_state = "access"),
- "Change Airlock Type" = image(icon = 'icons/mob/radial.dmi', icon_state = "airlocktype")
- )
- else if(mode == RCD_WINDOWGRILLE)
- choices += list(
- "Change Window Glass" = image(icon = 'icons/mob/radial.dmi', icon_state = "windowtype"),
- "Change Window Size" = image(icon = 'icons/mob/radial.dmi', icon_state = "windowsize")
- )
- else if(mode == RCD_FURNISHING)
- choices += list(
- "Change Furnishing Type" = image(icon = 'icons/mob/radial.dmi', icon_state = "chair")
- )
- if(upgrade & RCD_UPGRADE_CONVEYORS)
- choices += list(
- "Conveyor" = image(icon = 'icons/obj/recycling.dmi', icon_state = "conveyor_construct"),
- "Switch" = image(icon = 'icons/obj/recycling.dmi', icon_state = "switch-off")
- )
- var/choice = show_radial_menu(user, src, choices, custom_check = CALLBACK(src, PROC_REF(check_menu), user), require_near = TRUE, tooltips = TRUE)
- if(!check_menu(user))
+
+/obj/item/construction/rcd/ui_data(mob/user)
+ var/list/data = ..()
+
+ //main categories
+ data["selected_root"] = root_category
+ data["root_categories"] = list()
+ for(var/category in root_categories)
+ data["root_categories"] += category
+
+ //create the category list
+ data["selected_category"] = design_category
+ data["selected_design"] = design_title
+ data["categories"] = list()
+
+ var/category_icon_state
+ var/category_icon_suffix
+ for(var/list/sub_category as anything in root_categories[root_category])
+ var/list/target_category = root_categories[root_category][sub_category]
+ if(target_category.len == 0)
+ continue
+
+ //skip category if upgrades were not installed for these
+ if(sub_category == "Machines" && !(upgrade & RCD_UPGRADE_FRAMES))
+ continue
+ if(sub_category == "Furniture" && !(upgrade & RCD_UPGRADE_FURNISHING))
+ continue
+ if(sub_category == "Conveyors" && !(upgrade & RCD_UPGRADE_CONVEYORS))
+ continue
+ category_icon_state = ""
+ category_icon_suffix = ""
+
+ var/list/designs = list() //initialize all designs under this category
+ for(var/i in 1 to target_category.len)
+ var/list/design = target_category[i]
+
+ //check for special icon flags
+ if(design[CATEGORY_ICON_STATE] != null)
+ category_icon_state = design[CATEGORY_ICON_STATE]
+ if(design[CATEGORY_ICON_SUFFIX] != null)
+ category_icon_suffix = design[CATEGORY_ICON_SUFFIX]
+
+ //get icon or create it from pre defined flags
+ var/icon_state
+ if(design[ICON] != null)
+ icon_state = design[ICON]
+ else
+ icon_state = category_icon_state
+ if(icon_state == TITLE_ICON)
+ icon_state = design[TITLE]
+ icon_state = "[icon_state][category_icon_suffix]"
+
+ //sanitize them so you dont go insane when icon names contain spaces in them
+ icon_state = sanitize_css_class_name(icon_state)
+
+ designs += list(list("design_id" = i, TITLE = design[TITLE], ICON = icon_state))
+ data["categories"] += list(list("cat_name" = sub_category, "designs" = designs))
+
+ //merge airlock_electronics ui data with this
+ var/list/airlock_data = airlock_electronics.ui_data(user)
+ for(var/key in airlock_data)
+ data[key] = airlock_data[key]
+
+ return data
+
+
+/obj/item/construction/rcd/ui_act(action, params)
+ . = ..()
+ if(.)
return
- switch(choice)
- if("Floors & Walls")
- mode = RCD_FLOORWALL
- if("Airlock")
- mode = RCD_AIRLOCK
- if("Deconstruct")
- mode = RCD_DECONSTRUCT
- if("Grilles & Windows")
- mode = RCD_WINDOWGRILLE
- if("Machine Frames")
- mode = RCD_MACHINE
- if("Furnishing")
- mode = RCD_FURNISHING
- if("Computer Frames")
- mode = RCD_COMPUTER
- change_computer_dir(user)
- return
- if("Change Access")
- airlock_electronics.ui_interact(user)
- return
- if("Change Airlock Type")
- change_airlock_setting(user)
- return
- if("Change Window Glass")
- toggle_window_glass(user)
- return
- if("Change Window Size")
- toggle_window_size(user)
- return
- if("Change Furnishing Type")
- change_furnishing_type(user)
- return
- if("Silo Link")
- toggle_silo_link(user)
- return
- if("Conveyor")
- mode = RCD_CONVEYOR
- linked_switch_id = null
- last_placed = null
- if("Switch")
- mode = RCD_SWITCH
- else
- return
- playsound(src, 'sound/effects/pop.ogg', 50, FALSE)
- to_chat(user, span_notice("You change RCD's mode to '[choice]'."))
+
+ switch(action)
+ if("root_category")
+ var/new_root = params["root_category"]
+ if(root_categories[new_root] != null) //is a valid category
+ root_category = new_root
+
+ if("design")
+ var/category_name = params["category"]
+ var/index = params["index"]
+
+ var/list/root = root_categories[root_category]
+ if(root == null) //not a valid root
+ return TRUE
+ var/list/category = root[category_name]
+ if(category == null) //not a valid category
+ return TRUE
+ var/list/design = category[index]
+ if(design == null) //not a valid design
+ return TRUE
+
+ design_category = category_name
+ design_title = design["title"]
+
+ if(category_name == "Structures")
+ construction_mode = design[CONSTRUCTION_MODE]
+ if(design[WINDOW_TYPE] != null)
+ window_type = design[WINDOW_TYPE]
+ if(design[WINDOW_GLASS] != null)
+ window_glass = design[WINDOW_GLASS]
+ if(design[WINDOW_SIZE] != null)
+ window_size = design[WINDOW_SIZE]
+ else if(category_name == "Machines")
+ construction_mode = design[CONSTRUCTION_MODE]
+ if(design[COMPUTER_DIR] != null)
+ computer_dir = design[COMPUTER_DIR]
+ else if(category_name == "Furniture")
+ construction_mode = RCD_FURNISHING
+ furnish_type = design[FURNISH_TYPE]
+ furnish_cost = design[FURNISH_COST]
+ furnish_delay = design[FURNISH_DELAY]
+ else if(category_name == "Conveyors")
+ construction_mode = design[CONSTRUCTION_MODE]
+
+ if(root_category == "Airlocks")
+ construction_mode = RCD_AIRLOCK
+ airlock_glass = (category_name != "Solid AirLocks")
+ airlock_type = design[AIRLOCK_TYPE]
+ else
+ airlock_electronics.do_action(action, params)
+
+ return TRUE
+
+/obj/item/construction/rcd/attack_self(mob/user)
+ . = ..()
+ ui_interact(user)
/obj/item/construction/rcd/proc/target_check(atom/A, mob/user) // only returns true for stuff the device can actually work with
- if((isturf(A) && A.density && mode==RCD_DECONSTRUCT) || (isturf(A) && !A.density) || (istype(A, /obj/machinery/door/airlock) && mode==RCD_DECONSTRUCT) || istype(A, /obj/structure/grille) || (istype(A, /obj/structure/window) && mode==RCD_DECONSTRUCT) || istype(A, /obj/structure/girder))
+ if((isturf(A) && A.density && construction_mode==RCD_DECONSTRUCT) || (isturf(A) && !A.density) || (istype(A, /obj/machinery/door/airlock) && construction_mode==RCD_DECONSTRUCT) || istype(A, /obj/structure/grille) || (istype(A, /obj/structure/window) && construction_mode==RCD_DECONSTRUCT) || istype(A, /obj/structure/girder))
return TRUE
else
return FALSE
/obj/item/construction/rcd/afterattack(atom/A, mob/user, proximity)
. = ..()
- if (mode == RCD_CONVEYOR)
- if(!range_check(A, user) || !target_check(A,user) || istype(A, /obj/machinery/conveyor) || !isopenturf(A) || istype(A, /area/shuttle))
- to_chat(user, "Error! Invalid tile!")
- return
- if (!linked_switch_id)
- to_chat(user, "Error! [src] is not linked!")
- return
- if (get_turf(A) == get_turf(user))
- to_chat(user, "Cannot place conveyor below your feet!")
- return
- if(!proximity)
- return
- rcd_conveyor(A, user)
- if (mode == RCD_SWITCH)
- if(!range_check(A, user) || !target_check(A,user) || istype(A, /obj/item/conveyor_switch_construct) || !isopenturf(A) || istype(A, /area/shuttle))
- to_chat(user, "Error! Invalid tile!")
- return
- if(!proximity)
- return
- rcd_switch(A, user)
- else
- if(!prox_check(proximity))
- return
- rcd_create(A, user)
+ if(!prox_check(proximity) && !(ranged && range_check(A, user)))
+ return
+ if((upgrade & RCD_UPGRADE_CONVEYORS) && istype(A, /obj/machinery/conveyor_switch))
+ var/obj/machinery/conveyor_switch/C = A
+ linked_switch_id = C.id
+ balloon_alert(user, "linked")
+ return
+ rcd_create(A, user)
+
+/obj/item/construction/rcd/attackby(obj/item/I, mob/user, params)
+ . = ..()
+ if((upgrade & RCD_UPGRADE_CONVEYORS) && istype(I, /obj/item/conveyor_switch_construct))
+ var/obj/item/conveyor_switch_construct/C = I
+ linked_switch_id = C.id
+ balloon_alert(user, "linked")
/obj/item/construction/rcd/proc/detonate_pulse()
audible_message("[src] begins to vibrate and \
@@ -796,6 +694,23 @@ RLD
matter = 500
canRturf = TRUE
+#undef CONSTRUCTION_MODE
+#undef WINDOW_TYPE
+#undef WINDOW_GLASS
+#undef WINDOW_SIZE
+#undef COMPUTER_DIR
+#undef FURNISH_TYPE
+#undef FURNISH_COST
+#undef FURNISH_DELAY
+#undef AIRLOCK_TYPE
+
+#undef TITLE
+#undef ICON
+
+#undef CATEGORY_ICON_STATE
+#undef CATEGORY_ICON_SUFFIX
+#undef TITLE_ICON
+
/obj/item/rcd_ammo
name = "compressed matter cartridge"
desc = "Highly compressed matter for the RCD."
@@ -832,18 +747,43 @@ RLD
has_ammobar = FALSE
/obj/item/construction/rcd/arcd/afterattack(atom/A, mob/user)
- ..()
if(!range_check(A,user))
return
- if(target_check(A,user))
- user.Beam(A,icon_state="rped_upgrade",time=30)
- rcd_create(A,user)
-
+ return ..()
+/obj/item/construction/rcd/exosuit
+ name = "mounted RCD"
+ desc = "You're not supposed to see this!"
+ max_matter = 1000
+ matter = 0 // starts off empty, load materials into the mech itself
+ delay_mod = 0.5
+ ranged = TRUE
+ has_ammobar = FALSE // don't bother, you can't see it
+ item_flags = NO_MAT_REDEMPTION | DROPDEL | NOBLUDGEON
+ resistance_flags = INDESTRUCTIBLE | FIRE_PROOF | ACID_PROOF | UNACIDABLE // would be weird if it could somehow be destroyed inside the equipment item
+
+/obj/item/construction/rcd/exosuit/ui_state(mob/user)
+ return GLOB.pilot_state
+
+/obj/item/construction/rcd/exosuit/ui_status(mob/user)
+ if(!(owner && ismecha(owner)))
+ return UI_CLOSE
+ var/obj/mecha/gundam = owner
+ if(user != gundam.occupant)
+ return UI_CLOSE
+ if(!gundam.equipment_disabled && gundam.selected == loc)
+ return UI_INTERACTIVE
+ return UI_UPDATE
+
+/obj/item/construction/rcd/exosuit/mime
+ name = "silenced mounted RCD"
+ silent = TRUE
// RAPID LIGHTING DEVICE
-
+#define GLOW_MODE 3
+#define LIGHT_MODE 2
+#define REMOVE_MODE 1
/obj/item/construction/rld
name = "Rapid Lighting Device (RLD)"
@@ -854,10 +794,12 @@ RLD
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
matter = 200
max_matter = 200
+ slot_flags = ITEM_SLOT_BELT
+ ///it does not make sense why any of these should be installed
+ banned_upgrades = RCD_UPGRADE_FRAMES | RCD_UPGRADE_SIMPLE_CIRCUITS | RCD_UPGRADE_FURNISHING
+
var/matter_divisor = 35
var/mode = LIGHT_MODE
- slot_flags = ITEM_SLOT_BELT
- actions_types = list(/datum/action/item_action/pick_color)
var/wallcost = 10
var/floorcost = 15
@@ -868,35 +810,62 @@ RLD
var/floordelay = 10
var/decondelay = 15
-/obj/item/construction/rld/ui_action_click(mob/user, datum/action/A)
- if(istype(A, /datum/action/item_action/pick_color))
- color_choice = input(user,"","Choose Color",color_choice) as color
- else
- ..()
+ ///reference to thr original icons
+ var/list/original_options = list(
+ "Color Pick" = icon(icon = 'icons/mob/radial.dmi', icon_state = "omni"),
+ "Glow Stick" = icon(icon = 'icons/obj/lighting.dmi', icon_state = "glowstick"),
+ "Deconstruct" = icon(icon = 'icons/obj/tools.dmi', icon_state = "wrench"),
+ "Light Fixture" = icon(icon = 'icons/obj/lighting.dmi', icon_state = "ltube"),
+ )
+ ///will contain the original icons modified with the color choice
+ var/list/display_options = list()
+
+/obj/item/construction/rld/Initialize(mapload)
+ . = ..()
+ for(var/option in original_options)
+ display_options[option] = icon(original_options[option])
/obj/item/construction/rld/update_icon_state()
. = ..()
icon_state = "rld-[round(matter/35)]"
/obj/item/construction/rld/attack_self(mob/user)
- ..()
- switch(mode)
- if(REMOVE_MODE)
+ . = ..()
+
+ if((upgrade & RCD_UPGRADE_SILO_LINK) && display_options["Silo Link"] == null) //silo upgrade instaled but option was not updated then update it just one
+ display_options["Silo Link"] = icon(icon = 'icons/obj/mining.dmi', icon_state = "silo")
+ var/choice = show_radial_menu(user, src, display_options, custom_check = CALLBACK(src, PROC_REF(check_menu), user), require_near = TRUE, tooltips = TRUE)
+ if(!check_menu(user))
+ return
+ if(!choice)
+ return
+
+ switch(choice)
+ if("Light Fixture")
mode = LIGHT_MODE
to_chat(user, span_notice("You change RLD's mode to 'Permanent Light Construction'."))
- if(LIGHT_MODE)
+ if("Glow Stick")
mode = GLOW_MODE
to_chat(user, span_notice("You change RLD's mode to 'Light Launcher'."))
- if(GLOW_MODE)
+ if("Color Pick")
+ var/new_choice = input(user,"","Choose Color",color_choice) as color
+ if(new_choice == null)
+ return
+
+ var/list/new_rgb = ReadRGB(new_choice)
+ for(var/option in original_options)
+ if(option == "Color Pick" || option == "Deconstruct" || option == "Silo Link")
+ continue
+ var/icon/icon = icon(original_options[option])
+ icon.SetIntensity(new_rgb[1]/255, new_rgb[2]/255, new_rgb[3]/255) //apply new scale
+ display_options[option] = icon
+
+ color_choice = new_choice
+ if("Deconstruct")
mode = REMOVE_MODE
to_chat(user, span_notice("You change RLD's mode to 'Deconstruct'."))
-
-/obj/item/construction/rcd/attackby(obj/item/I, mob/user, params)
- ..()
- if(upgrade & RCD_UPGRADE_CONVEYORS && istype(I, /obj/item/conveyor_switch_construct))
- to_chat(user, "You link the switch to the [src].")
- var/obj/item/conveyor_switch_construct/C = I
- linked_switch_id = C.id
+ else
+ ui_act("toggle_silo", list())
/obj/item/construction/rld/proc/checkdupes(target)
. = list()
@@ -917,7 +886,8 @@ RLD
if(checkResource(deconcost, user))
to_chat(user, span_notice("You start deconstructing [A]..."))
user.Beam(A,icon_state="nzcrentrs_power",time=15)
- playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE)
+ if(!silent)
+ playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE)
if(do_after(user, decondelay, A))
if(!useResource(deconcost, user))
return FALSE
@@ -931,8 +901,9 @@ RLD
if(checkResource(floorcost, user))
to_chat(user, span_notice("You start building a wall light..."))
user.Beam(A,icon_state="nzcrentrs_power",time=15)
- playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE)
- playsound(src.loc, 'sound/effects/light_flicker.ogg', 50, FALSE)
+ if(!silent)
+ playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE)
+ playsound(src.loc, 'sound/effects/light_flicker.ogg', 50, FALSE)
if(do_after(user, floordelay, A))
if(!istype(W))
return FALSE
@@ -946,7 +917,8 @@ RLD
candidates += C
if(!candidates.len)
to_chat(user, span_warning("Valid target not found..."))
- playsound(src.loc, 'sound/misc/compiler-failure.ogg', 30, TRUE)
+ if(!silent)
+ playsound(src.loc, 'sound/misc/compiler-failure.ogg', 30, TRUE)
return FALSE
for(var/turf/open/O in candidates)
if(istype(O))
@@ -977,8 +949,9 @@ RLD
if(checkResource(floorcost, user))
to_chat(user, span_notice("You start building a floor light..."))
user.Beam(A,icon_state="light_beam",time=15)
- playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE)
- playsound(src.loc, 'sound/effects/light_flicker.ogg', 50, TRUE)
+ if(!silent)
+ playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE)
+ playsound(src.loc, 'sound/effects/light_flicker.ogg', 50, TRUE)
if(do_after(user, floordelay, A))
if(!istype(F))
return 0
diff --git a/code/game/objects/items/RPD.dm b/code/game/objects/items/RPD.dm
index a58fe204b090..12d3e9973540 100644
--- a/code/game/objects/items/RPD.dm
+++ b/code/game/objects/items/RPD.dm
@@ -241,6 +241,8 @@ GLOBAL_LIST_INIT(fluid_duct_recipes, list(
var/static/datum/pipe_info/first_plumbing
var/mode = BUILD_MODE | PAINT_MODE | DESTROY_MODE | WRENCH_MODE
var/locked = FALSE //wheter we can change categories. Useful for the plumber
+ /// The owner of this RCD. It can be a mech or a player.
+ var/owner
/obj/item/pipe_dispenser/Initialize(mapload)
. = ..()
@@ -287,6 +289,9 @@ GLOBAL_LIST_INIT(fluid_duct_recipes, list(
get_asset_datum(/datum/asset/spritesheet/pipes),
)
+/obj/item/pipe_dispenser/ui_host(mob/user)
+ return owner || ..()
+
/obj/item/pipe_dispenser/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
@@ -306,7 +311,7 @@ GLOBAL_LIST_INIT(fluid_duct_recipes, list(
"selected_color" = paint_color,
"paint_colors" = GLOB.pipe_paint_colors,
"mode" = mode,
- "locked" = locked
+ "locked" = locked,
)
var/list/recipes
@@ -330,10 +335,10 @@ GLOBAL_LIST_INIT(fluid_duct_recipes, list(
return data
/obj/item/pipe_dispenser/ui_act(action, params)
- if(..())
- return
- if(!usr.canUseTopic(src, BE_CLOSE))
+ . = ..()
+ if(.)
return
+
var/playeffect = TRUE
switch(action)
if("color")
@@ -568,6 +573,24 @@ GLOBAL_LIST_INIT(fluid_duct_recipes, list(
return
to_chat(source, span_notice("You set the layer to [piping_layer]."))
+/obj/item/pipe_dispenser/exosuit
+ name = "mounted pipe dispenser"
+ desc = "You shouldn't be seeing this!"
+ item_flags = NO_MAT_REDEMPTION | DROPDEL | NOBLUDGEON
+ resistance_flags = INDESTRUCTIBLE | FIRE_PROOF | ACID_PROOF | UNACIDABLE // would be weird if it could somehow be destroyed inside the equipment item
+
+/obj/item/pipe_dispenser/exosuit/ui_state(mob/user)
+ return GLOB.pilot_state
+
+// don't allow using this thing unless you're piloting the mech it's attached to
+/obj/item/pipe_dispenser/exosuit/can_interact(mob/user)
+ if(!(owner && ismecha(owner)))
+ return FALSE
+ var/obj/mecha/gundam = owner
+ if(user == gundam.occupant && !gundam.equipment_disabled && gundam.selected == loc)
+ return TRUE
+ return FALSE
+
/obj/item/pipe_dispenser/plumbing
name = "Plumberinator"
desc = "A crude device to rapidly plumb things."
diff --git a/code/game/objects/items/airlock_painter.dm b/code/game/objects/items/airlock_painter.dm
index d8f3fc908ca0..796735d2a727 100644
--- a/code/game/objects/items/airlock_painter.dm
+++ b/code/game/objects/items/airlock_painter.dm
@@ -439,7 +439,7 @@
* * target - The turf being painted to
*/
/obj/item/airlock_painter/decal/proc/paint_floor(turf/open/floor/target)
- target.AddElement(/datum/element/decal, 'icons/turf/decals.dmi', stored_decal_total, stored_dir, null, null, alpha, color, null, FALSE, null)
+ target.AddElement(/datum/element/decal, 'icons/turf/decals.dmi', stored_decal_total, stored_dir, null, null, default_alpha, color, null, FALSE, null)
/**
* Return the final icon_state for the given decal options
diff --git a/code/game/objects/items/bell.dm b/code/game/objects/items/bell.dm
index 7bb200f82249..f3b1b1d30467 100644
--- a/code/game/objects/items/bell.dm
+++ b/code/game/objects/items/bell.dm
@@ -1,6 +1,6 @@
/obj/item/deskbell
name = "desk bell"
- desc = "ding. ding."
+ desc = "Ding! Ding! Ding!"
icon = 'icons/obj/bell.dmi'
icon_state = "bell"
force = 5
diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm
index 02320aed0c12..2f07409a68e0 100644
--- a/code/game/objects/items/cards_ids.dm
+++ b/code/game/objects/items/cards_ids.dm
@@ -561,6 +561,10 @@ update_label("John Doe", "Clowny")
name = "[(!registered_name) ? "identification card" : "[registered_name]'s ID Card"][(!assignment) ? "" : " ([assignment])"]"
+//a card that can't register a bank account IC
+/obj/item/card/id/no_bank/AltClick(mob/living/user)
+ return FALSE
+
/obj/item/card/id/silver
name = "silver identification card"
desc = "A silver card which shows honour and dedication."
@@ -584,6 +588,27 @@ update_label("John Doe", "Clowny")
lefthand_file = 'icons/mob/inhands/equipment/idcards_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/idcards_righthand.dmi'
+/obj/item/card/id/synthetic
+ name = "synthetic identification card"
+ desc = "An integrated card that allows synthetic units access across the station."
+ icon_state = "id_silver"
+ item_state = "silver_id"
+ lefthand_file = 'icons/mob/inhands/equipment/idcards_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/equipment/idcards_righthand.dmi'
+ item_flags = DROPDEL
+ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
+
+/obj/item/card/id/synthetic/Initialize(mapload)
+ . = ..()
+ ADD_TRAIT(src, TRAIT_NODROP, SYNTHETIC_TRAIT)
+
+/obj/item/card/id/synthetic/GetAccess()
+ if(ishuman(loc))
+ var/mob/living/carbon/human/H = loc
+ if(H.mind)
+ return GLOB.synthetic_base_access + GLOB.synthetic_added_access
+ return list()
+
/obj/item/card/id/syndicate
name = "agent card"
access = list(ACCESS_MAINT_TUNNELS, ACCESS_SYNDICATE)
@@ -796,8 +821,8 @@ update_label("John Doe", "Clowny")
var/obj/structure/fireaxecabinet/bridge/spare/holder = loc
forceMove(holder.loc)
holder.spareid = null
- if(holder.obj_integrity > holder.integrity_failure) //we dont want to heal it by accident
- holder.take_damage(holder.obj_integrity - holder.integrity_failure, BURN, armour_penetration = 100) //we do a bit of trolling for being naughty
+ if(holder.get_integrity() > holder.integrity_failure) //we dont want to heal it by accident
+ holder.take_damage(holder.get_integrity() - holder.integrity_failure, BURN, armour_penetration = 100) //we do a bit of trolling for being naughty
else
holder.update_appearance(UPDATE_ICON) //update the icon anyway so it pops out
visible_message(span_danger("The heat of the temporary spare shatters the glass!"));
diff --git a/code/game/objects/items/circuitboards/circuitboard.dm b/code/game/objects/items/circuitboards/circuitboard.dm
index 73763cfbb5f2..79aa6f428cae 100644
--- a/code/game/objects/items/circuitboards/circuitboard.dm
+++ b/code/game/objects/items/circuitboards/circuitboard.dm
@@ -6,15 +6,21 @@
/obj/item/circuitboard
name = "circuit board"
icon = 'icons/obj/module.dmi'
- icon_state = "id_mod"
+ icon_state = "circuit_map"
item_state = "electronic"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
materials = list(/datum/material/glass=1000)
w_class = WEIGHT_CLASS_SMALL
grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/gold = 10)
+ greyscale_colors = CIRCUIT_COLOR_GENERIC
var/build_path = null
+/obj/item/circuitboard/Initialize(mapload)
+ if(icon_state == "circuit_map") // some circuitboards have cool custom sprites
+ set_greyscale(new_config = /datum/greyscale_config/circuit)
+ return ..()
+
/obj/item/circuitboard/proc/apply_default_parts(obj/machinery/M)
return
diff --git a/code/game/objects/items/circuitboards/computer_circuitboards.dm b/code/game/objects/items/circuitboards/computer_circuitboards.dm
index d29f7babb581..d2a196a1c8b3 100644
--- a/code/game/objects/items/circuitboards/computer_circuitboards.dm
+++ b/code/game/objects/items/circuitboards/computer_circuitboards.dm
@@ -2,12 +2,12 @@
/obj/item/circuitboard/computer/aiupload
name = "AI Upload (Computer Board)"
- icon_state = "command"
+ greyscale_colors = CIRCUIT_COLOR_COMMAND
build_path = /obj/machinery/computer/upload/ai
/obj/item/circuitboard/computer/borgupload
name = "Cyborg Upload (Computer Board)"
- icon_state = "command"
+ greyscale_colors = CIRCUIT_COLOR_COMMAND
build_path = /obj/machinery/computer/upload/borg
/obj/item/circuitboard/computer/bsa_control
@@ -16,7 +16,7 @@
/obj/item/circuitboard/computer/card
name = "ID Console (Computer Board)"
- icon_state = "command"
+ greyscale_colors = CIRCUIT_COLOR_COMMAND
build_path = /obj/machinery/computer/card
/obj/item/circuitboard/computer/card/centcom
@@ -42,30 +42,30 @@
/obj/item/circuitboard/computer/ai_ship
name = "AI Ship Shuttle (Computer Board)"
- icon_state = "command"
+ greyscale_colors = CIRCUIT_COLOR_COMMAND
build_path = /obj/machinery/computer/shuttle/ai_ship
//obj/item/circuitboard/computer/shield
// name = "Shield Control (Computer Board)"
-// icon_state = "command"
+// greyscale_colors = CIRCUIT_COLOR_COMMAND
// build_path = /obj/machinery/computer/stationshield
//Engineering
/obj/item/circuitboard/computer/apc_control
name = "\improper Power Flow Control Console (Computer Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/computer/apc_control
/obj/item/circuitboard/computer/atmos_alert
name = "Atmospheric Alert (Computer Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/computer/atmos_alert
/obj/item/circuitboard/computer/atmos_control
name = "Atmospheric Monitor (Computer Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/computer/atmos_control
/obj/item/circuitboard/computer/atmos_control/tank
@@ -106,94 +106,94 @@
/obj/item/circuitboard/computer/auxiliary_base
name = "Auxiliary Base Management Console (Computer Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/computer/auxiliary_base
/obj/item/circuitboard/computer/base_construction
name = "circuit board (Aux Mining Base Construction Console)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/computer/camera_advanced/base_construction
/obj/item/circuitboard/computer/comm_monitor
name = "Telecommunications Monitor (Computer Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/computer/telecomms/monitor
/obj/item/circuitboard/computer/comm_server
name = "Telecommunications Server Monitor (Computer Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/computer/telecomms/server
/obj/item/circuitboard/computer/communications
name = "Communications (Computer Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/computer/communications
/obj/item/circuitboard/computer/message_monitor
name = "Message Monitor (Computer Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/computer/message_monitor
/obj/item/circuitboard/computer/powermonitor
name = "Power Monitor (Computer Board)" //name fixed 250810
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/computer/monitor
/obj/item/circuitboard/computer/powermonitor/secret
name = "Outdated Power Monitor (Computer Board)" //Variant used on ruins to prevent them from showing up on PDA's.
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/computer/monitor/secret
/obj/item/circuitboard/computer/sat_control
name = "Satellite Network Control (Computer Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/computer/sat_control
/obj/item/circuitboard/computer/solar_control
name = "Solar Control (Computer Board)" //name fixed 250810
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/power/solar_control
/obj/item/circuitboard/computer/stationalert
name = "Station Alerts (Computer Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/computer/station_alert
/obj/item/circuitboard/computer/teleporter
name = "Teleporter (Computer Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/computer/teleporter
/obj/item/circuitboard/computer/turbine_computer
name = "Turbine Computer (Computer Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/computer/turbine_computer
/obj/item/circuitboard/computer/turbine_control
name = "Turbine control (Computer Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/computer/turbine_computer
//Generic
/obj/item/circuitboard/computer/arcade/amputation
name = "Mediborg's Amputation Adventure (Computer Board)"
- icon_state = "generic"
+ greyscale_colors = CIRCUIT_COLOR_GENERIC
build_path = /obj/machinery/computer/arcade/amputation
/obj/item/circuitboard/computer/arcade/battle
name = "Arcade Battle (Computer Board)"
- icon_state = "generic"
+ greyscale_colors = CIRCUIT_COLOR_GENERIC
build_path = /obj/machinery/computer/arcade/battle
/obj/item/circuitboard/computer/arcade/orion_trail
name = "Orion Trail (Computer Board)"
- icon_state = "generic"
+ greyscale_colors = CIRCUIT_COLOR_GENERIC
build_path = /obj/machinery/computer/arcade/orion_trail
/obj/item/circuitboard/computer/holodeck// Not going to let people get this, but it's just here for future
name = "Holodeck Control (Computer Board)"
- icon_state = "generic"
+ greyscale_colors = CIRCUIT_COLOR_GENERIC
build_path = /obj/machinery/computer/holodeck
/obj/item/circuitboard/computer/libraryconsole
@@ -215,32 +215,32 @@
/obj/item/circuitboard/computer/monastery_shuttle
name = "Monastery Shuttle (Computer Board)"
- icon_state = "generic"
+ greyscale_colors = CIRCUIT_COLOR_GENERIC
build_path = /obj/machinery/computer/shuttle/monastery_shuttle
/obj/item/circuitboard/computer/olddoor
name = "DoorMex (Computer Board)"
- icon_state = "generic"
+ greyscale_colors = CIRCUIT_COLOR_GENERIC
build_path = /obj/machinery/computer/pod/old
/obj/item/circuitboard/computer/pod
name = "Massdriver control (Computer Board)"
- icon_state = "generic"
+ greyscale_colors = CIRCUIT_COLOR_GENERIC
build_path = /obj/machinery/computer/pod
/obj/item/circuitboard/computer/slot_machine
name = "Slot Machine (Computer Board)"
- icon_state = "generic"
+ greyscale_colors = CIRCUIT_COLOR_GENERIC
build_path = /obj/machinery/computer/slot_machine
/obj/item/circuitboard/computer/swfdoor
name = "Magix (Computer Board)"
- icon_state = "generic"
+ greyscale_colors = CIRCUIT_COLOR_GENERIC
build_path = /obj/machinery/computer/pod/old/swf
/obj/item/circuitboard/computer/syndicate_shuttle
name = "Syndicate Shuttle (Computer Board)"
- icon_state = "generic"
+ greyscale_colors = CIRCUIT_COLOR_GENERIC
build_path = /obj/machinery/computer/shuttle/syndicate
var/challenge = FALSE
var/moved = FALSE
@@ -255,12 +255,12 @@
/obj/item/circuitboard/computer/syndicatedoor
name = "ProComp Executive (Computer Board)"
- icon_state = "generic"
+ greyscale_colors = CIRCUIT_COLOR_GENERIC
build_path = /obj/machinery/computer/pod/old/syndicate
/obj/item/circuitboard/computer/white_ship
name = "White Ship (Computer Board)"
- icon_state = "generic"
+ greyscale_colors = CIRCUIT_COLOR_GENERIC
build_path = /obj/machinery/computer/shuttle/white_ship
/obj/item/circuitboard/computer/white_ship/pod
@@ -275,80 +275,80 @@
/obj/item/circuitboard/computer/cloning
name = "Cloning (Computer Board)"
- icon_state = "medical"
+ greyscale_colors = CIRCUIT_COLOR_MEDICAL
build_path = /obj/machinery/computer/cloning
/obj/item/circuitboard/computer/crew
name = "Crew Monitoring Console (Computer Board)"
- icon_state = "medical"
+ greyscale_colors = CIRCUIT_COLOR_MEDICAL
build_path = /obj/machinery/computer/crew
/obj/item/circuitboard/computer/med_data
name = "Medical Records Console (Computer Board)"
- icon_state = "medical"
+ greyscale_colors = CIRCUIT_COLOR_MEDICAL
build_path = /obj/machinery/computer/med_data
/obj/item/circuitboard/computer/operating
name = "Operating Computer (Computer Board)"
- icon_state = "medical"
+ greyscale_colors = CIRCUIT_COLOR_MEDICAL
build_path = /obj/machinery/computer/operating
/obj/item/circuitboard/computer/pandemic
name = "PanD.E.M.I.C. 2200 (Computer Board)"
- icon_state = "medical"
+ greyscale_colors = CIRCUIT_COLOR_MEDICAL
build_path = /obj/machinery/computer/pandemic
/obj/item/circuitboard/computer/prototype_cloning
name = "Prototype Cloning (Computer Board)"
- icon_state = "medical"
+ greyscale_colors = CIRCUIT_COLOR_MEDICAL
build_path = /obj/machinery/computer/prototype_cloning
/obj/item/circuitboard/computer/scan_consolenew
name = "DNA Machine (Computer Board)"
- icon_state = "medical"
+ greyscale_colors = CIRCUIT_COLOR_MEDICAL
build_path = /obj/machinery/computer/scan_consolenew
//Science
/obj/item/circuitboard/computer/aifixer
name = "AI Integrity Restorer (Computer Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/computer/aifixer
/obj/item/circuitboard/computer/launchpad_console
name = "Launchpad Control Console (Computer Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/computer/launchpad
/obj/item/circuitboard/computer/mech_bay_power_console
name = "Mech Bay Power Control Console (Computer Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/computer/mech_bay_power_console
/obj/item/circuitboard/computer/mecha_control
name = "Exosuit Control Console (Computer Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/computer/mecha
/obj/item/circuitboard/computer/nanite_chamber_control
name = "Nanite Chamber Control (Computer Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/computer/nanite_chamber_control
/obj/item/circuitboard/computer/nanite_cloud_controller
name = "Nanite Cloud Control (Computer Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/computer/nanite_cloud_controller
/obj/item/circuitboard/computer/rdconsole
name = "R&D Console (Computer Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/computer/rdconsole/core
var/unlocked = FALSE
/obj/item/circuitboard/computer/rdconsole/ruin
name = "Experimental R&D Console (Computer Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/computer/rdconsole/nolock/ruin
/obj/item/circuitboard/computer/rdconsole/production
@@ -402,22 +402,22 @@
/obj/item/circuitboard/computer/rdservercontrol
name = "R&D Server Control (Computer Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/computer/rdservercontrol
/obj/item/circuitboard/computer/research
name = "Research Monitor (Computer Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/computer/security/research
/obj/item/circuitboard/computer/robotics
name = "Robotics Control (Computer Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/computer/robotics
/obj/item/circuitboard/computer/xenobiology
name = "Xenobiology Console (Computer Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/computer/camera_advanced/xenobio
/obj/item/circuitboard/computer/xenobiology/syndicateicemoon
@@ -432,71 +432,63 @@
name = "Shuttle Navigation Computer (Computer Board)"
build_path = /obj/machinery/computer/camera_advanced/shuttle_docker/custom
-/obj/item/circuitboard/computer/ai_upload_download
- name = "AI Control Console (Computer Board)"
- icon_state = "science"
- build_path = /obj/machinery/computer/ai_control_console
/obj/item/circuitboard/computer/ai_server_overview
name = "AI Server Overview Console (Computer Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/computer/ai_server_console
-/obj/item/circuitboard/computer/ai_resource_distribution
- name = "AI Resource Distribution Console (Computer Board)"
- icon_state = "science"
- build_path = /obj/machinery/computer/ai_resource_distribution
//Security
/obj/item/circuitboard/computer/labor_shuttle
name = "Labor Shuttle (Computer Board)"
- icon_state = "security"
+ greyscale_colors = CIRCUIT_COLOR_SECURITY
build_path = /obj/machinery/computer/shuttle/labor
/obj/item/circuitboard/computer/labor_shuttle/one_way
name = "Prisoner Shuttle Console (Computer Board)"
- icon_state = "security"
+ greyscale_colors = CIRCUIT_COLOR_SECURITY
build_path = /obj/machinery/computer/shuttle/labor/one_way
/obj/item/circuitboard/computer/gulag_teleporter_console
name = "Labor Camp teleporter console (Computer Board)"
- icon_state = "security"
+ greyscale_colors = CIRCUIT_COLOR_SECURITY
build_path = /obj/machinery/computer/gulag_teleporter_computer
/obj/item/circuitboard/computer/prisoner
name = "Prisoner Management Console (Computer Board)"
- icon_state = "security"
+ greyscale_colors = CIRCUIT_COLOR_SECURITY
build_path = /obj/machinery/computer/prisoner
/obj/item/circuitboard/computer/secure_data
name = "Security Records Console (Computer Board)"
- icon_state = "security"
+ greyscale_colors = CIRCUIT_COLOR_SECURITY
build_path = /obj/machinery/computer/secure_data
/obj/item/circuitboard/computer/warrant
name = "Security Warrant Viewer (Computer Board)"
- icon_state = "security"
+ greyscale_colors = CIRCUIT_COLOR_SECURITY
build_path = /obj/machinery/computer/warrant
/obj/item/circuitboard/computer/security
name = "Security Cameras (Computer Board)"
- icon_state = "security"
+ greyscale_colors = CIRCUIT_COLOR_SECURITY
build_path = /obj/machinery/computer/security
/obj/item/circuitboard/computer/security/labor
name = "Labor Security Cameras (Computer Board)"
- icon_state = "security"
+ greyscale_colors = CIRCUIT_COLOR_SECURITY
build_path = /obj/machinery/computer/security/labor
/obj/item/circuitboard/computer/security/hos
name = "HOS Security Cameras (Computer Board)"
- icon_state = "security"
+ greyscale_colors = CIRCUIT_COLOR_SECURITY
build_path = /obj/machinery/computer/security/hos
/obj/item/circuitboard/computer/security/qm
name = "QM Security Cameras (Computer Board)"
- icon_state = "supply"
+ greyscale_colors = CIRCUIT_COLOR_SUPPLY
build_path = /obj/machinery/computer/security/qm
//Service
@@ -505,12 +497,12 @@
/obj/item/circuitboard/computer/bounty
name = "Nanotrasen Bounty Console (Computer Board)"
- icon_state = "supply"
+ greyscale_colors = CIRCUIT_COLOR_SUPPLY
build_path = /obj/machinery/computer/bounty
/obj/item/circuitboard/computer/cargo
name = "Supply Console (Computer Board)"
- icon_state = "supply"
+ greyscale_colors = CIRCUIT_COLOR_SUPPLY
build_path = /obj/machinery/computer/cargo
var/contraband = FALSE
@@ -553,21 +545,21 @@
/obj/item/circuitboard/computer/ferry
name = "Transport Ferry (Computer Board)"
- icon_state = "supply"
+ greyscale_colors = CIRCUIT_COLOR_SUPPLY
build_path = /obj/machinery/computer/shuttle/ferry
/obj/item/circuitboard/computer/ferry/request
name = "Transport Ferry Console (Computer Board)"
- icon_state = "supply"
+ greyscale_colors = CIRCUIT_COLOR_SUPPLY
build_path = /obj/machinery/computer/shuttle/ferry/request
/obj/item/circuitboard/computer/mining
name = "Outpost Status Display (Computer Board)"
- icon_state = "supply"
+ greyscale_colors = CIRCUIT_COLOR_SUPPLY
build_path = /obj/machinery/computer/security/mining
/obj/item/circuitboard/computer/mining_shuttle
name = "Mining Shuttle (Computer Board)"
- icon_state = "supply"
+ greyscale_colors = CIRCUIT_COLOR_SUPPLY
build_path = /obj/machinery/computer/shuttle/mining
diff --git a/code/game/objects/items/circuitboards/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machine_circuitboards.dm
index baf533a0496d..9f73965fa137 100644
--- a/code/game/objects/items/circuitboards/machine_circuitboards.dm
+++ b/code/game/objects/items/circuitboards/machine_circuitboards.dm
@@ -2,7 +2,7 @@
/obj/item/circuitboard/machine/bsa/back
name = "Bluespace Artillery Generator (Machine Board)"
- icon_state = "command"
+ greyscale_colors = CIRCUIT_COLOR_COMMAND
build_path = /obj/machinery/bsa/back //No freebies!
req_components = list(
/obj/item/stock_parts/capacitor/quadratic = 5,
@@ -10,7 +10,7 @@
/obj/item/circuitboard/machine/bsa/front
name = "Bluespace Artillery Bore (Machine Board)"
- icon_state = "command"
+ greyscale_colors = CIRCUIT_COLOR_COMMAND
build_path = /obj/machinery/bsa/front
req_components = list(
/obj/item/stock_parts/manipulator/femto = 5,
@@ -18,7 +18,7 @@
/obj/item/circuitboard/machine/bsa/middle
name = "Bluespace Artillery Fusor (Machine Board)"
- icon_state = "command"
+ greyscale_colors = CIRCUIT_COLOR_COMMAND
build_path = /obj/machinery/bsa/middle
req_components = list(
/obj/item/stack/ore/bluespace_crystal = 20,
@@ -26,7 +26,7 @@
/obj/item/circuitboard/machine/dna_vault
name = "DNA Vault (Machine Board)"
- icon_state = "command"
+ greyscale_colors = CIRCUIT_COLOR_COMMAND
build_path = /obj/machinery/dna_vault //No freebies!
req_components = list(
/obj/item/stock_parts/capacitor/super = 5,
@@ -37,7 +37,7 @@
/obj/item/circuitboard/machine/announcement_system
name = "Announcement System (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/announcement_system
req_components = list(
/obj/item/stack/cable_coil = 2,
@@ -45,7 +45,7 @@
/obj/item/circuitboard/machine/igniter
name = "Floor Igniter (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/igniter
req_components = list(
/obj/item/stack/cable_coil = 2,
@@ -53,7 +53,7 @@
/obj/item/circuitboard/machine/autolathe
name = "Autolathe (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/autolathe
req_components = list(
/obj/item/stock_parts/matter_bin = 3,
@@ -62,7 +62,7 @@
/obj/item/circuitboard/machine/grounding_rod
name = "Grounding Rod (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/power/grounding_rod
req_components = list(/obj/item/stock_parts/capacitor = 1)
needs_anchored = FALSE
@@ -70,7 +70,7 @@
/obj/item/circuitboard/machine/telecomms/broadcaster
name = "Subspace Broadcaster (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/telecomms/broadcaster
req_components = list(
/obj/item/stock_parts/manipulator = 2,
@@ -81,7 +81,7 @@
/obj/item/circuitboard/machine/telecomms/bus
name = "Bus Mainframe (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/telecomms/bus
req_components = list(
/obj/item/stock_parts/manipulator = 2,
@@ -90,7 +90,7 @@
/obj/item/circuitboard/machine/telecomms/hub
name = "Hub Mainframe (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/telecomms/hub
req_components = list(
/obj/item/stock_parts/manipulator = 2,
@@ -99,7 +99,7 @@
/obj/item/circuitboard/machine/telecomms/message_server
name = "Messaging Server (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/telecomms/message_server
req_components = list(
/obj/item/stock_parts/manipulator = 2,
@@ -108,7 +108,7 @@
/obj/item/circuitboard/machine/telecomms/processor
name = "Processor Unit (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/telecomms/processor
req_components = list(
/obj/item/stock_parts/manipulator = 3,
@@ -120,7 +120,7 @@
/obj/item/circuitboard/machine/telecomms/receiver
name = "Subspace Receiver (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/telecomms/receiver
req_components = list(
/obj/item/stock_parts/subspace/ansible = 1,
@@ -130,7 +130,7 @@
/obj/item/circuitboard/machine/telecomms/relay
name = "Relay Mainframe (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/telecomms/relay
req_components = list(
/obj/item/stock_parts/manipulator = 2,
@@ -139,7 +139,7 @@
/obj/item/circuitboard/machine/telecomms/server
name = "Telecommunication Server (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/telecomms/server
req_components = list(
/obj/item/stock_parts/manipulator = 2,
@@ -148,7 +148,7 @@
/obj/item/circuitboard/machine/tesla_coil
name = "Tesla Controller (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
desc = "You can use a screwdriver to switch between Research and Power Generation."
build_path = /obj/machinery/power/tesla_coil
req_components = list(/obj/item/stock_parts/capacitor = 1)
@@ -156,16 +156,25 @@
/obj/item/circuitboard/machine/suit_storage_unit
name = "Suit Storage Unit (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/suit_storage_unit
req_components = list(
/obj/item/stock_parts/micro_laser = 5,
/obj/item/stack/cable_coil = 2,
/obj/item/stock_parts/manipulator = 5)
+/obj/item/circuitboard/machine/synth_pod
+ name = "Synthetic Storage Unit (Machine Board)"
+ icon_state = "engineering"
+ build_path = /obj/machinery/synth_pod
+ req_components = list(
+ /obj/item/stock_parts/micro_laser = 2,
+ /obj/item/stack/cable_coil = 2,
+ /obj/item/stock_parts/manipulator = 2)
+
/obj/item/circuitboard/machine/decontamination_unit
name = "Decontamination Storage Unit (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/decontamination_unit
req_components = list(
/obj/item/stock_parts/micro_laser = 5,
@@ -214,20 +223,20 @@
/obj/item/circuitboard/machine/cell_charger
name = "Cell Charger (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/cell_charger
req_components = list(/obj/item/stock_parts/capacitor = 1)
needs_anchored = FALSE
/obj/item/circuitboard/machine/circulator
name = "Circulator/Heat Exchanger (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/atmospherics/components/binary/circulator
req_components = list()
/obj/item/circuitboard/machine/emitter
name = "Emitter (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/power/emitter
req_components = list(
/obj/item/stock_parts/micro_laser = 1,
@@ -241,13 +250,13 @@
/obj/item/circuitboard/machine/generator
name = "Thermo-Electric Generator (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/power/generator
req_components = list()
/obj/item/circuitboard/machine/ntnet_relay
name = "NTNet Relay (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/ntnet_relay
req_components = list(
/obj/item/stack/cable_coil = 2,
@@ -255,7 +264,7 @@
/obj/item/circuitboard/machine/pacman
name = "PACMAN-type Generator (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/power/port_gen/pacman
req_components = list(
/obj/item/stock_parts/matter_bin = 1,
@@ -266,7 +275,7 @@
/obj/item/circuitboard/machine/pacman/super
name = "SUPERPACMAN-type Generator (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/power/port_gen/pacman/super
/obj/item/circuitboard/machine/pacman/mrs
@@ -275,7 +284,7 @@
/obj/item/circuitboard/machine/power_compressor
name = "Power Compressor (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/power/compressor
req_components = list(
/obj/item/stack/cable_coil = 5,
@@ -283,7 +292,7 @@
/obj/item/circuitboard/machine/power_turbine
name = "Power Turbine (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/power/turbine
req_components = list(
/obj/item/stack/cable_coil = 5,
@@ -291,12 +300,12 @@
/obj/item/circuitboard/machine/protolathe/department/engineering
name = "Departmental Protolathe (Machine Board) - Engineering"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/rnd/production/protolathe/department/engineering
/obj/item/circuitboard/machine/rad_collector
name = "Radiation Collector (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/power/rad_collector
req_components = list(
/obj/item/stack/cable_coil = 5,
@@ -308,7 +317,7 @@
/obj/item/circuitboard/machine/rtg
name = "RTG (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/power/rtg
req_components = list(
/obj/item/stack/cable_coil = 5,
@@ -327,14 +336,14 @@
/obj/item/circuitboard/machine/scanner_gate
name = "Scanner Gate (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/scanner_gate
req_components = list(
/obj/item/stock_parts/scanning_module = 3)
/obj/item/circuitboard/machine/smes
name = "SMES (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/power/smes
req_components = list(
/obj/item/stack/cable_coil = 5,
@@ -348,7 +357,7 @@
/obj/item/circuitboard/machine/teleporter_hub
name = "Teleporter Hub (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/teleport/hub
req_components = list(
/obj/item/stack/ore/bluespace_crystal = 3,
@@ -357,7 +366,7 @@
/obj/item/circuitboard/machine/teleporter_station
name = "Teleporter Station (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/teleport/station
req_components = list(
/obj/item/stack/ore/bluespace_crystal = 2,
@@ -367,7 +376,7 @@
/obj/item/circuitboard/machine/thermomachine
name = "Thermomachine (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/atmospherics/components/unary/thermomachine/freezer
var/pipe_layer = PIPING_LAYER_DEFAULT
req_components = list(
@@ -380,14 +389,14 @@
. = ..()
if(istype(I))
pipe_layer = (pipe_layer >= PIPING_LAYER_MAX) ? PIPING_LAYER_MIN : (pipe_layer + 1)
- to_chat(user, "You change the circuitboard to layer [pipe_layer].")
+ to_chat(user, span_notice("You change the circuitboard to layer [pipe_layer]."))
/obj/item/circuitboard/machine/thermomachine/examine()
. = ..()
. += "It is set to layer [pipe_layer]."
/obj/item/circuitboard/machine/crystallizer
name = "Crystallizer (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/atmospherics/components/binary/crystallizer
req_components = list(
/obj/item/stack/cable_coil = 10,
@@ -396,28 +405,28 @@
/obj/item/circuitboard/machine/HFR_fuel_input
name = "HFR Fuel Input (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/atmospherics/components/unary/hypertorus/fuel_input
req_components = list(
/obj/item/stack/sheet/plasteel = 5)
/obj/item/circuitboard/machine/HFR_waste_output
name = "HFR Waste Output (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/atmospherics/components/unary/hypertorus/waste_output
req_components = list(
/obj/item/stack/sheet/plasteel = 5)
/obj/item/circuitboard/machine/HFR_moderator_input
name = "HFR Moderator Input (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/atmospherics/components/unary/hypertorus/moderator_input
req_components = list(
/obj/item/stack/sheet/plasteel = 5)
/obj/item/circuitboard/machine/HFR_core
name = "HFR core (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/atmospherics/components/unary/hypertorus/core
req_components = list(
/obj/item/stack/cable_coil = 10,
@@ -426,14 +435,14 @@
/obj/item/circuitboard/machine/HFR_corner
name = "HFR Corner (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/hypertorus/corner
req_components = list(
/obj/item/stack/sheet/plasteel = 5)
/obj/item/circuitboard/machine/HFR_interface
name = "HFR Interface (Machine Board)"
- icon_state = "engineering"
+ greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/hypertorus/interface
req_components = list(
/obj/item/stack/cable_coil = 10,
@@ -444,7 +453,7 @@
/obj/item/circuitboard/machine/circuit_imprinter
name = "Circuit Imprinter (Machine Board)"
- icon_state = "generic"
+ greyscale_colors = CIRCUIT_COLOR_GENERIC
build_path = /obj/machinery/rnd/production/circuit_imprinter
req_components = list(
/obj/item/stock_parts/matter_bin = 1,
@@ -453,12 +462,12 @@
/obj/item/circuitboard/machine/circuit_imprinter/department
name = "Departmental Circuit Imprinter (Machine Board)"
- icon_state = "generic"
+ greyscale_colors = CIRCUIT_COLOR_GENERIC
build_path = /obj/machinery/rnd/production/circuit_imprinter/department
/obj/item/circuitboard/machine/holopad
name = "AI Holopad (Machine Board)"
- icon_state = "generic"
+ greyscale_colors = CIRCUIT_COLOR_GENERIC
build_path = /obj/machinery/holopad
req_components = list(/obj/item/stock_parts/capacitor = 1)
needs_anchored = FALSE //wew lad
@@ -484,7 +493,7 @@
/obj/item/circuitboard/machine/launchpad
name = "Bluespace Launchpad (Machine Board)"
- icon_state = "generic"
+ greyscale_colors = CIRCUIT_COLOR_GENERIC
build_path = /obj/machinery/launchpad
req_components = list(
/obj/item/stack/ore/bluespace_crystal = 1,
@@ -493,7 +502,7 @@
/obj/item/circuitboard/machine/paystand
name = "Pay Stand (Machine Board)"
- icon_state = "generic"
+ greyscale_colors = CIRCUIT_COLOR_GENERIC
build_path = /obj/machinery/paystand
var/cash_register = FALSE
req_components = list()
@@ -513,7 +522,7 @@
/obj/item/circuitboard/machine/ticketmachine
name = "Ticket Machine (Machine Board)"
- icon_state = "generic"
+ greyscale_colors = CIRCUIT_COLOR_GENERIC
desc = "You will also need a ticket machine remote to operate this."
build_path = /obj/machinery/ticket_machine
req_components = list(
@@ -522,7 +531,7 @@
/obj/item/circuitboard/machine/inspector_booth
name = "Inspector Booth (Machine Board)"
- icon_state = "generic"
+ greyscale_colors = CIRCUIT_COLOR_GENERIC
build_path = /obj/machinery/inspector_booth
req_components = list(
/obj/item/stock_parts/matter_bin = 1,
@@ -533,7 +542,7 @@
/obj/item/circuitboard/machine/protolathe
name = "Protolathe (Machine Board)"
- icon_state = "generic"
+ greyscale_colors = CIRCUIT_COLOR_GENERIC
build_path = /obj/machinery/rnd/production/protolathe
req_components = list(
/obj/item/stock_parts/matter_bin = 2,
@@ -542,7 +551,7 @@
/obj/item/circuitboard/machine/protolathe
name = "Protolathe (Machine Board)"
- icon_state = "generic"
+ greyscale_colors = CIRCUIT_COLOR_GENERIC
build_path = /obj/machinery/rnd/production/protolathe
req_components = list(
/obj/item/stock_parts/matter_bin = 2,
@@ -551,17 +560,17 @@
/obj/item/circuitboard/machine/protolathe/department
name = "Departmental Protolathe (Machine Board)"
- icon_state = "generic"
+ greyscale_colors = CIRCUIT_COLOR_GENERIC
build_path = /obj/machinery/rnd/production/protolathe/department
/obj/item/circuitboard/machine/protolathe/department
name = "Departmental Protolathe (Machine Board)"
- icon_state = "generic"
+ greyscale_colors = CIRCUIT_COLOR_GENERIC
build_path = /obj/machinery/rnd/production/protolathe/department
/obj/item/circuitboard/machine/reagentgrinder
name = "Machine Design (All-In-One Grinder)"
- icon_state = "generic"
+ greyscale_colors = CIRCUIT_COLOR_GENERIC
build_path = /obj/machinery/reagentgrinder/constructed
req_components = list(
/obj/item/stock_parts/manipulator = 1)
@@ -602,7 +611,7 @@
/obj/item/circuitboard/machine/space_heater
name = "Space Heater (Machine Board)"
- icon_state = "generic"
+ greyscale_colors = CIRCUIT_COLOR_GENERIC
build_path = /obj/machinery/space_heater
req_components = list(
/obj/item/stock_parts/micro_laser = 1,
@@ -612,7 +621,7 @@
/obj/item/circuitboard/machine/techfab
name = "\improper Techfab (Machine Board)"
- icon_state = "generic"
+ greyscale_colors = CIRCUIT_COLOR_GENERIC
build_path = /obj/machinery/rnd/production/techfab
req_components = list(
/obj/item/stock_parts/matter_bin = 2,
@@ -704,6 +713,14 @@
/obj/item/stack/sheet/glass = 1,
/obj/item/vending_refill/donksoft = 1)
+/obj/item/circuitboard/machine/vending/donksofttoyvendor/hugbox
+ name = "Donksoft Toy Vendor Lite (Machine Board)"
+ desc = "This one seems somehow less fun than usual..."
+ build_path = /obj/machinery/vending/donksofttoyvendor/hugbox
+ req_components = list(
+ /obj/item/stack/sheet/glass = 1,
+ /obj/item/vending_refill/donksoft = 1)
+
/obj/item/circuitboard/machine/vending/syndicatedonksofttoyvendor
name = "Syndicate Donksoft Toy Vendor (Machine Board)"
build_path = /obj/machinery/vending/toyliberationstation
@@ -715,7 +732,7 @@
/obj/item/circuitboard/machine/chem_dispenser
name = "Chem Dispenser (Machine Board)"
- icon_state = "medical"
+ greyscale_colors = CIRCUIT_COLOR_MEDICAL
build_path = /obj/machinery/chem_dispenser
req_components = list(
/obj/item/stock_parts/matter_bin = 2,
@@ -735,7 +752,7 @@
// yogs end
/obj/item/circuitboard/machine/chem_heater
name = "Chemical Heater (Machine Board)"
- icon_state = "medical"
+ greyscale_colors = CIRCUIT_COLOR_MEDICAL
build_path = /obj/machinery/chem_heater
req_components = list(
/obj/item/stock_parts/micro_laser = 1,
@@ -743,7 +760,7 @@
/obj/item/circuitboard/machine/chem_master
name = "ChemMaster 3000 (Machine Board)"
- icon_state = "medical"
+ greyscale_colors = CIRCUIT_COLOR_MEDICAL
build_path = /obj/machinery/chem_master
desc = "You can turn the \"mode selection\" dial using a screwdriver."
req_components = list(
@@ -769,7 +786,7 @@
/obj/item/circuitboard/machine/clonepod
name = "Clone Pod (Machine Board)"
- icon_state = "medical"
+ greyscale_colors = CIRCUIT_COLOR_MEDICAL
build_path = /obj/machinery/clonepod
req_components = list(
/obj/item/stack/cable_coil = 2,
@@ -780,12 +797,12 @@
/obj/item/circuitboard/machine/clonepod/experimental
name = "Experimental Clone Pod (Machine Board)"
- icon_state = "medical"
+ greyscale_colors = CIRCUIT_COLOR_MEDICAL
build_path = /obj/machinery/clonepod/experimental
/obj/item/circuitboard/machine/clonescanner
name = "Cloning Scanner (Machine Board)"
- icon_state = "medical"
+ greyscale_colors = CIRCUIT_COLOR_MEDICAL
build_path = /obj/machinery/dna_scannernew
req_components = list(
/obj/item/stock_parts/scanning_module = 1,
@@ -796,7 +813,7 @@
/obj/item/circuitboard/machine/cryo_tube
name = "Cryotube (Machine Board)"
- icon_state = "medical"
+ greyscale_colors = CIRCUIT_COLOR_MEDICAL
build_path = /obj/machinery/atmospherics/components/unary/cryo_cell
req_components = list(
/obj/item/stock_parts/matter_bin = 1,
@@ -805,20 +822,20 @@
/obj/item/circuitboard/machine/fat_sucker
name = "Lipid Extractor (Machine Board)"
- icon_state = "medical"
+ greyscale_colors = CIRCUIT_COLOR_MEDICAL
build_path = /obj/machinery/fat_sucker
req_components = list(/obj/item/stock_parts/micro_laser = 1,
/obj/item/kitchen/fork = 1)
/obj/item/circuitboard/machine/harvester
name = "Harvester (Machine Board)"
- icon_state = "medical"
+ greyscale_colors = CIRCUIT_COLOR_MEDICAL
build_path = /obj/machinery/harvester
req_components = list(/obj/item/stock_parts/micro_laser = 4)
/obj/item/circuitboard/machine/medical_kiosk
name = "Medical Kiosk (Machine Board)"
- icon_state = "medical"
+ greyscale_colors = CIRCUIT_COLOR_MEDICAL
build_path = /obj/machinery/medical_kiosk
var/custom_cost = 10
req_components = list(
@@ -842,7 +859,7 @@
/obj/item/circuitboard/machine/limbgrower
name = "Limb Grower (Machine Board)"
- icon_state = "medical"
+ greyscale_colors = CIRCUIT_COLOR_MEDICAL
build_path = /obj/machinery/limbgrower
req_components = list(
/obj/item/stock_parts/manipulator = 1,
@@ -851,12 +868,12 @@
/obj/item/circuitboard/machine/protolathe/department/medical
name = "Departmental Protolathe (Machine Board) - Medical"
- icon_state = "medical"
+ greyscale_colors = CIRCUIT_COLOR_MEDICAL
build_path = /obj/machinery/rnd/production/protolathe/department/medical
/obj/item/circuitboard/machine/sleeper
name = "Sleeper (Machine Board)"
- icon_state = "medical"
+ greyscale_colors = CIRCUIT_COLOR_MEDICAL
build_path = /obj/machinery/sleeper
req_components = list(
/obj/item/stock_parts/matter_bin = 1,
@@ -875,7 +892,7 @@
// yogs end
/obj/item/circuitboard/machine/smoke_machine
name = "Smoke Machine (Machine Board)"
- icon_state = "medical"
+ greyscale_colors = CIRCUIT_COLOR_MEDICAL
build_path = /obj/machinery/smoke_machine
req_components = list(
/obj/item/stock_parts/matter_bin = 2,
@@ -887,7 +904,7 @@
/obj/item/circuitboard/machine/stasis
name = "Lifeform Stasis Unit (Machine Board)"
- icon_state = "medical"
+ greyscale_colors = CIRCUIT_COLOR_MEDICAL
build_path = /obj/machinery/stasis
req_components = list(
/obj/item/stack/cable_coil = 3,
@@ -896,7 +913,7 @@
/obj/item/circuitboard/machine/techfab/department/medical
name = "\improper Departmental Techfab (Machine Board) - Medical"
- icon_state = "medical"
+ greyscale_colors = CIRCUIT_COLOR_MEDICAL
build_path = /obj/machinery/rnd/production/techfab/department/medical
/obj/item/circuitboard/machine/mindmachine_hub
@@ -922,17 +939,17 @@
/obj/item/circuitboard/machine/circuit_imprinter/department/science
name = "Departmental Circuit Imprinter - Science (Machine Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/rnd/production/circuit_imprinter/department/science
/obj/item/circuitboard/machine/circuit_imprinter/department/netmin
name = "Departmental Circuit Imprinter - Netmin (Machine Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/rnd/production/circuit_imprinter/department/netmin
/obj/item/circuitboard/machine/cyborgrecharger
name = "Cyborg Recharger (Machine Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/recharge_station
req_components = list(
/obj/item/stock_parts/capacitor = 2,
@@ -942,7 +959,7 @@
/obj/item/circuitboard/machine/destructive_analyzer
name = "Destructive Analyzer (Machine Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/rnd/destructive_analyzer
req_components = list(
/obj/item/stock_parts/scanning_module = 1,
@@ -951,7 +968,7 @@
/obj/item/circuitboard/machine/experimentor
name = "E.X.P.E.R.I-MENTOR (Machine Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/rnd/experimentor
req_components = list(
/obj/item/stock_parts/scanning_module = 1,
@@ -960,7 +977,7 @@
/obj/item/circuitboard/machine/mech_recharger
name = "Mechbay Recharger (Machine Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/mech_bay_recharge_port
req_components = list(
/obj/item/stack/cable_coil = 2,
@@ -968,7 +985,7 @@
/obj/item/circuitboard/machine/mechfab
name = "Exosuit Fabricator (Machine Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/mecha_part_fabricator
req_components = list(
/obj/item/stock_parts/matter_bin = 2,
@@ -978,7 +995,7 @@
/obj/item/circuitboard/machine/monkey_recycler
name = "Monkey Recycler (Machine Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/monkey_recycler
req_components = list(
/obj/item/stock_parts/matter_bin = 1,
@@ -987,7 +1004,7 @@
/obj/item/circuitboard/machine/nanite_chamber
name = "Nanite Chamber (Machine Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/nanite_chamber
req_components = list(
/obj/item/stock_parts/scanning_module = 2,
@@ -996,7 +1013,7 @@
/obj/item/circuitboard/machine/nanite_program_hub
name = "Nanite Program Hub (Machine Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/nanite_program_hub
req_components = list(
/obj/item/stock_parts/matter_bin = 1,
@@ -1004,7 +1021,7 @@
/obj/item/circuitboard/machine/nanite_programmer
name = "Nanite Programmer (Machine Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/nanite_programmer
req_components = list(
/obj/item/stock_parts/manipulator = 2,
@@ -1013,17 +1030,17 @@
/obj/item/circuitboard/machine/processor/slime
name = "Slime Processor (Machine Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/processor/slime
/obj/item/circuitboard/machine/protolathe/department/science
name = "Departmental Protolathe (Machine Board) - Science"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/rnd/production/protolathe/department/science
/obj/item/circuitboard/machine/public_nanite_chamber
name = "Public Nanite Chamber (Machine Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/public_nanite_chamber
var/cloud_id = 1
req_components = list(
@@ -1044,7 +1061,7 @@
/obj/item/circuitboard/machine/quantumpad
name = "Quantum Pad (Machine Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/quantumpad
req_components = list(
/obj/item/stack/ore/bluespace_crystal = 1,
@@ -1055,7 +1072,7 @@
/obj/item/circuitboard/machine/rdserver
name = "R&D Server (Machine Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/rnd/server
req_components = list(
/obj/item/stack/cable_coil = 2,
@@ -1063,12 +1080,12 @@
/obj/item/circuitboard/machine/techfab/department/science
name = "\improper Departmental Techfab (Machine Board) - Science"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/rnd/production/techfab/department/science
/obj/item/circuitboard/machine/server_cabinet
name = "Server Cabinet (Machine Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/ai/server_cabinet
req_components = list(
/obj/item/stock_parts/matter_bin = 2,
@@ -1076,14 +1093,35 @@
/obj/item/stack/sheet/glass = 2,
/obj/item/stack/cable_coil = 1)
+/obj/item/circuitboard/machine/networking_machine
+ name = "Networking Machine (Machine Board)"
+ icon_state = "science"
+ build_path = /obj/machinery/ai/networking
+ req_components = list(
+ /obj/item/stock_parts/matter_bin = 4,
+ /obj/item/stock_parts/capacitor = 2,
+ /obj/item/stock_parts/scanning_module = 4,
+ /obj/item/stack/sheet/glass = 4,
+ /obj/item/stack/cable_coil = 1)
+
+/obj/item/circuitboard/machine/subcontroller
+ name = "Subcontroller (Machine Board)"
+ icon_state = "science"
+ build_path = /obj/machinery/ai/master_subcontroller
+ req_components = list(
+ /obj/item/stock_parts/capacitor = 4,
+ /obj/item/stock_parts/scanning_module = 4,
+ /obj/item/stack/sheet/glass = 2,
+ /obj/item/stack/cable_coil = 1)
+
/obj/item/circuitboard/machine/ai_core_display
name = "AI Core Display (Machine Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/status_display/ai_core
/obj/item/circuitboard/machine/ai_data_core
name = "AI Data Core (Machine Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/ai/data_core
req_components = list(
/obj/item/stock_parts/capacitor = 4,
@@ -1094,7 +1132,7 @@
/obj/item/circuitboard/machine/rack_creator
name = "Rack Creator (Machine Board)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/rack_creator
req_components = list(
/obj/item/stock_parts/manipulator = 2,
@@ -1102,7 +1140,7 @@
/obj/item/circuitboard/machine/plort
name = "Machine Design (Plort Redemption Machine)"
- icon_state = "science"
+ greyscale_colors = CIRCUIT_COLOR_SCIENCE
build_path = /obj/machinery/plortrefinery
req_components = list(
/obj/item/stock_parts/manipulator = 3,
@@ -1112,31 +1150,31 @@
/obj/item/circuitboard/machine/protolathe/department/security
name = "Departmental Protolathe (Machine Board) - Security"
- icon_state = "security"
+ greyscale_colors = CIRCUIT_COLOR_SECURITY
build_path = /obj/machinery/rnd/production/protolathe/department/security
/obj/item/circuitboard/machine/recharger
name = "Weapon Recharger (Machine Board)"
- icon_state = "security"
+ greyscale_colors = CIRCUIT_COLOR_SECURITY
build_path = /obj/machinery/recharger
req_components = list(/obj/item/stock_parts/capacitor = 1)
needs_anchored = FALSE
/obj/item/circuitboard/machine/techfab/department/security
name = "\improper Departmental Techfab (Machine Board) - Security"
- icon_state = "security"
+ greyscale_colors = CIRCUIT_COLOR_SECURITY
build_path = /obj/machinery/rnd/production/techfab/department/security
/obj/item/circuitboard/machine/techfab/department/armory
name = "\improper Departmental Techfab (Machine Board) - Armory"
- icon_state = "security"
+ greyscale_colors = CIRCUIT_COLOR_SECURITY
build_path = /obj/machinery/rnd/production/techfab/department/armory
//Service
/obj/item/circuitboard/machine/biogenerator
name = "Biogenerator (Machine Board)"
- icon_state = "service"
+ greyscale_colors = CIRCUIT_COLOR_SERVICE
build_path = /obj/machinery/biogenerator
req_components = list(
/obj/item/stock_parts/matter_bin = 1,
@@ -1146,43 +1184,43 @@
/obj/item/circuitboard/machine/chem_dispenser/drinks
name = "Soda Dispenser (Machine Board)"
- icon_state = "service"
+ greyscale_colors = CIRCUIT_COLOR_SERVICE
build_path = /obj/machinery/chem_dispenser/drinks
/obj/item/circuitboard/machine/chem_dispenser/drinks/beer
name = "Booze Dispenser (Machine Board)"
- icon_state = "service"
+ greyscale_colors = CIRCUIT_COLOR_SERVICE
build_path = /obj/machinery/chem_dispenser/drinks/beer
/obj/item/circuitboard/machine/chem_master/condi
name = "CondiMaster 3000 (Machine Board)"
- icon_state = "service"
+ greyscale_colors = CIRCUIT_COLOR_SERVICE
build_path = /obj/machinery/chem_master/condimaster
/obj/item/circuitboard/machine/deep_fryer
name = "Deep Fryer (Machine Board)"
- icon_state = "service"
+ greyscale_colors = CIRCUIT_COLOR_SERVICE
build_path = /obj/machinery/deepfryer
req_components = list(/obj/item/stock_parts/micro_laser = 1)
needs_anchored = FALSE
/obj/item/circuitboard/machine/griddle
name = "Griddle (Machine Board)"
- icon_state = "service"
+ greyscale_colors = CIRCUIT_COLOR_SERVICE
build_path = /obj/machinery/griddle
req_components = list(/obj/item/stock_parts/micro_laser = 1)
needs_anchored = FALSE
/obj/item/circuitboard/machine/oven
name = "Oven (Machine Board)"
- icon_state = "service"
+ greyscale_colors = CIRCUIT_COLOR_SERVICE
build_path = /obj/machinery/oven
req_components = list(/obj/item/stock_parts/micro_laser = 1)
needs_anchored = FALSE
/obj/item/circuitboard/machine/dish_drive
name = "Dish Drive (Machine Board)"
- icon_state = "service"
+ greyscale_colors = CIRCUIT_COLOR_SERVICE
build_path = /obj/machinery/dish_drive
req_components = list(
/obj/item/stack/sheet/glass = 1,
@@ -1209,7 +1247,7 @@
/obj/item/circuitboard/machine/gibber
name = "Gibber (Machine Board)"
- icon_state = "service"
+ greyscale_colors = CIRCUIT_COLOR_SERVICE
build_path = /obj/machinery/gibber
req_components = list(
/obj/item/stock_parts/matter_bin = 1,
@@ -1218,7 +1256,7 @@
/obj/item/circuitboard/machine/hydroponics
name = "Hydroponics Tray (Machine Board)"
- icon_state = "service"
+ greyscale_colors = CIRCUIT_COLOR_SERVICE
build_path = /obj/machinery/hydroponics/constructable
req_components = list(
/obj/item/stock_parts/matter_bin = 2,
@@ -1228,7 +1266,7 @@
/obj/item/circuitboard/machine/microwave
name = "Microwave (Machine Board)"
- icon_state = "service"
+ greyscale_colors = CIRCUIT_COLOR_SERVICE
build_path = /obj/machinery/microwave
req_components = list(
/obj/item/stock_parts/micro_laser = 1,
@@ -1239,7 +1277,7 @@
/obj/item/circuitboard/machine/plantgenes
name = "Plant DNA Manipulator (Machine Board)"
- icon_state = "service"
+ greyscale_colors = CIRCUIT_COLOR_SERVICE
build_path = /obj/machinery/plantgenes
req_components = list(
/obj/item/stock_parts/manipulator = 1,
@@ -1249,7 +1287,7 @@
/obj/item/circuitboard/machine/processor
name = "Food Processor (Machine Board)"
- icon_state = "service"
+ greyscale_colors = CIRCUIT_COLOR_SERVICE
build_path = /obj/machinery/processor
req_components = list(
/obj/item/stock_parts/matter_bin = 1,
@@ -1271,12 +1309,12 @@
/obj/item/circuitboard/machine/protolathe/department/service
name = "Departmental Protolathe - Service (Machine Board)"
- icon_state = "service"
+ greyscale_colors = CIRCUIT_COLOR_SERVICE
build_path = /obj/machinery/rnd/production/protolathe/department/service
/obj/item/circuitboard/machine/recycler
name = "Recycler (Machine Board)"
- icon_state = "service"
+ greyscale_colors = CIRCUIT_COLOR_SERVICE
build_path = /obj/machinery/recycler
req_components = list(
/obj/item/stock_parts/matter_bin = 1,
@@ -1285,7 +1323,7 @@
/obj/item/circuitboard/machine/seed_extractor
name = "Seed Extractor (Machine Board)"
- icon_state = "service"
+ greyscale_colors = CIRCUIT_COLOR_SERVICE
build_path = /obj/machinery/seed_extractor
req_components = list(
/obj/item/stock_parts/matter_bin = 1,
@@ -1294,14 +1332,14 @@
/obj/item/circuitboard/machine/techfab/department/service
name = "\improper Departmental Techfab - Service (Machine Board)"
- icon_state = "service"
+ greyscale_colors = CIRCUIT_COLOR_SERVICE
build_path = /obj/machinery/rnd/production/techfab/department/service
//Supply
/obj/item/circuitboard/machine/mining_equipment_vendor
name = "Mining Equipment Vendor (Machine Board)"
- icon_state = "supply"
+ greyscale_colors = CIRCUIT_COLOR_SUPPLY
build_path = /obj/machinery/mineral/equipment_vendor
req_components = list(
/obj/item/stack/sheet/glass = 1,
@@ -1313,7 +1351,7 @@
/obj/item/circuitboard/machine/ore_redemption
name = "Ore Redemption (Machine Board)"
- icon_state = "supply"
+ greyscale_colors = CIRCUIT_COLOR_SUPPLY
build_path = /obj/machinery/mineral/ore_redemption
req_components = list(
/obj/item/stack/sheet/glass = 1,
@@ -1325,18 +1363,18 @@
/obj/item/circuitboard/machine/ore_silo
name = "Ore Silo (Machine Board)"
- icon_state = "supply"
+ greyscale_colors = CIRCUIT_COLOR_SUPPLY
build_path = /obj/machinery/ore_silo
req_components = list()
/obj/item/circuitboard/machine/protolathe/department/cargo
name = "Departmental Protolathe (Machine Board) - Cargo"
- icon_state = "supply"
+ greyscale_colors = CIRCUIT_COLOR_SUPPLY
build_path = /obj/machinery/rnd/production/protolathe/department/cargo
/obj/item/circuitboard/machine/stacking_machine
name = "Stacking Machine (Machine Board)"
- icon_state = "supply"
+ greyscale_colors = CIRCUIT_COLOR_SUPPLY
build_path = /obj/machinery/mineral/stacking_machine
req_components = list(
/obj/item/stock_parts/manipulator = 2,
@@ -1344,7 +1382,7 @@
/obj/item/circuitboard/machine/stacking_unit_console
name = "Stacking Machine Console (Machine Board)"
- icon_state = "supply"
+ greyscale_colors = CIRCUIT_COLOR_SUPPLY
build_path = /obj/machinery/mineral/stacking_unit_console
req_components = list(
/obj/item/stack/sheet/glass = 2,
@@ -1352,7 +1390,7 @@
/obj/item/circuitboard/machine/techfab/department/cargo
name = "\improper Departmental Techfab (Machine Board) - Cargo"
- icon_state = "supply"
+ greyscale_colors = CIRCUIT_COLOR_SUPPLY
build_path = /obj/machinery/rnd/production/techfab/department/cargo
//Misc
@@ -1388,7 +1426,7 @@
/obj/item/circuitboard/machine/electrolyzer
name = "Electrolyzer (Machine Board)"
- icon_state = "generic"
+ greyscale_colors = CIRCUIT_COLOR_GENERIC
build_path = /obj/machinery/electrolyzer
req_components = list(
/obj/item/stock_parts/micro_laser = 2,
diff --git a/code/game/objects/items/crab17.dm b/code/game/objects/items/crab17.dm
index f9f286a1dcc8..9f89ac1a8651 100644
--- a/code/game/objects/items/crab17.dm
+++ b/code/game/objects/items/crab17.dm
@@ -41,7 +41,7 @@
/obj/structure/checkoutmachine/examine(mob/living/user)
. = ..()
- . += span_info("Its integrated integrity meter reads: HEALTH: [obj_integrity].")
+ . += span_info("Its integrated integrity meter reads: HEALTH: [atom_integrity].")
/obj/structure/checkoutmachine/proc/check_if_finished()
for(var/i in accounts_to_rob)
diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm
index edd624f642e3..6e9311739504 100644
--- a/code/game/objects/items/devices/PDA/PDA.dm
+++ b/code/game/objects/items/devices/PDA/PDA.dm
@@ -28,8 +28,8 @@ GLOBAL_LIST_EMPTY(PDAs)
/obj/item/pda
- name = "\improper PDA"
- desc = "A portable microcomputer by Thinktronic Systems, LTD. Functionality determined by a preprogrammed ROM cartridge."
+ name = "\improper antique PDA"
+ desc = "An outdated, portable microcomputer developed by Thinktronic Systems, LTD. Functionality determined by a preprogrammed ROM cartridge."
icon = 'icons/obj/pda.dmi'
icon_state = "pda"
item_state = "electronic"
@@ -174,7 +174,7 @@ GLOBAL_LIST_EMPTY(PDAs)
inserted_item = null
/obj/item/pda/proc/update_label()
- name = "PDA-[owner] ([ownjob])" //Name generalisation
+ name = "\improper antique PDA-[owner] ([ownjob])" //Name generalisation
/obj/item/pda/GetAccess()
if(id)
diff --git a/code/game/objects/items/devices/PDA/PDA_types.dm b/code/game/objects/items/devices/PDA/PDA_types.dm
index 59f2a180b750..3294e545717a 100644
--- a/code/game/objects/items/devices/PDA/PDA_types.dm
+++ b/code/game/objects/items/devices/PDA/PDA_types.dm
@@ -1,10 +1,10 @@
//Clown PDA is slippery.
/obj/item/pda/clown
- name = "clown PDA"
+ name = "\improper antique clown PDA"
default_cartridge = /obj/item/cartridge/virus/clown
insert_type = /obj/item/toy/crayon/rainbow
icon_state = "pda-clown"
- desc = "A portable microcomputer by Thinktronic Systems, LTD. The surface is coated with polytetrafluoroethylene and banana drippings."
+ desc = "An outdated, portable microcomputer developed by Thinktronic Systems, LTD. The surface is coated with polytetrafluoroethylene and banana drippings."
ttone = "honk"
/obj/item/pda/clown/Initialize(mapload)
@@ -36,49 +36,49 @@
RegisterSignal(src, COMSIG_TABLET_CHECK_DETONATE, PROC_REF(pda_no_detonate))
/obj/item/pda/medical
- name = "medical PDA"
+ name = "\improper antique medical PDA"
default_cartridge = /obj/item/cartridge/medical
icon_state = "pda-medical"
/obj/item/pda/viro
- name = "virology PDA"
+ name = "\improper antique virology PDA"
default_cartridge = /obj/item/cartridge/medical
icon_state = "pda-virology"
/obj/item/pda/engineering
- name = "engineering PDA"
+ name = "\improper antique engineering PDA"
default_cartridge = /obj/item/cartridge/engineering
icon_state = "pda-engineer"
/obj/item/pda/security
- name = "security PDA"
+ name = "\improper antique security PDA"
default_cartridge = /obj/item/cartridge/security
icon_state = "pda-security"
/obj/item/pda/detective
- name = "detective PDA"
+ name = "\improper antique detective PDA"
default_cartridge = /obj/item/cartridge/detective
icon_state = "pda-detective"
/obj/item/pda/warden
- name = "warden PDA"
+ name = "\improper antique warden PDA"
default_cartridge = /obj/item/cartridge/security
icon_state = "pda-warden"
/obj/item/pda/janitor
- name = "janitor PDA"
+ name = "\improper antique janitor PDA"
default_cartridge = /obj/item/cartridge/janitor
icon_state = "pda-janitor"
ttone = "slip"
/obj/item/pda/toxins
- name = "scientist PDA"
+ name = "\improper antique scientist PDA"
default_cartridge = /obj/item/cartridge/signal/toxins
icon_state = "pda-science"
ttone = "boom"
/obj/item/pda/mime
- name = "mime PDA"
+ name = "\improper antique mime PDA"
default_cartridge = /obj/item/cartridge/virus/mime
insert_type = /obj/item/toy/crayon/mime
icon_state = "pda-mime"
@@ -90,33 +90,33 @@
icon_state = "pda-hop"
/obj/item/pda/heads/hop
- name = "head of personnel PDA"
+ name = "\improper antique head of personnel PDA"
default_cartridge = /obj/item/cartridge/hop
icon_state = "pda-hop"
/obj/item/pda/heads/hos
- name = "head of security PDA"
+ name = "\improper antique head of security PDA"
default_cartridge = /obj/item/cartridge/hos
icon_state = "pda-hos"
/obj/item/pda/heads/ce
- name = "chief engineer PDA"
+ name = "\improper antique chief engineer PDA"
default_cartridge = /obj/item/cartridge/ce
icon_state = "pda-ce"
/obj/item/pda/heads/cmo
- name = "chief medical officer PDA"
+ name = "\improper antique chief medical officer PDA"
default_cartridge = /obj/item/cartridge/cmo
icon_state = "pda-cmo"
/obj/item/pda/heads/rd
- name = "research director PDA"
+ name = "\improper antique research director PDA"
default_cartridge = /obj/item/cartridge/rd
insert_type = /obj/item/pen/fountain
icon_state = "pda-rd"
/obj/item/pda/captain
- name = "captain PDA"
+ name = "\improper antique captain PDA"
default_cartridge = /obj/item/cartridge/captain
insert_type = /obj/item/pen/fountain/captain
icon_state = "pda-captain"
@@ -126,90 +126,90 @@
RegisterSignal(src, COMSIG_TABLET_CHECK_DETONATE, PROC_REF(pda_no_detonate))
/obj/item/pda/cargo
- name = "cargo technician PDA"
+ name = "\improper antique cargo technician PDA"
default_cartridge = /obj/item/cartridge/quartermaster
icon_state = "pda-cargo"
/obj/item/pda/quartermaster
- name = "quartermaster PDA"
+ name = "\improper antique quartermaster PDA"
default_cartridge = /obj/item/cartridge/quartermaster
insert_type = /obj/item/pen/fountain
icon_state = "pda-qm"
/obj/item/pda/shaftminer
- name = "shaft miner PDA"
+ name = "\improper antique shaft miner PDA"
icon_state = "pda-miner"
/obj/item/pda/syndicate
default_cartridge = /obj/item/cartridge/virus/syndicate
icon_state = "pda-syndi"
- name = "military PDA"
+ name = "\improper antique military PDA"
owner = "John Doe"
hidden = 1
/obj/item/pda/chaplain
- name = "chaplain PDA"
+ name = "\improper antique chaplain PDA"
icon_state = "pda-chaplain"
ttone = "holy"
/obj/item/pda/lawyer
- name = "lawyer PDA"
+ name = "\improper antique lawyer PDA"
default_cartridge = /obj/item/cartridge/lawyer
insert_type = /obj/item/pen/fountain
icon_state = "pda-lawyer"
ttone = "objection"
/obj/item/pda/botanist
- name = "botanist PDA"
+ name = "\improper antique botanist PDA"
//default_cartridge = /obj/item/cartridge/botanist
icon_state = "pda-hydro"
/obj/item/pda/roboticist
- name = "roboticist PDA"
+ name = "\improper antique roboticist PDA"
icon_state = "pda-roboticist"
default_cartridge = /obj/item/cartridge/roboticist
/obj/item/pda/curator
- name = "curator PDA"
+ name = "\improper antique curator PDA"
icon_state = "pda-library"
icon_alert = "pda-r-library"
default_cartridge = /obj/item/cartridge/curator
insert_type = /obj/item/pen/fountain
- desc = "A portable microcomputer by Thinktronic Systems, LTD. This model is a WGW-11 series e-reader."
+ desc = "An outdated, portable microcomputer developed by Thinktronic Systems, LTD. This model is a WGW-11 series e-reader."
note = "Congratulations, your station has chosen the Thinktronic 5290 WGW-11 Series E-reader and Personal Data Assistant!"
silent = TRUE //Quiet in the library!
overlays_x_offset = -3
/obj/item/pda/clear
- name = "clear PDA"
+ name = "\improper antique clear PDA"
icon_state = "pda-clear"
- desc = "A portable microcomputer by Thinktronic Systems, LTD. This model is a special edition with a transparent case."
+ desc = "An outdated, portable microcomputer developed by Thinktronic Systems, LTD. This model is a special edition with a transparent case."
note = "Congratulations, you have chosen the Thinktronic 5230 Personal Data Assistant Deluxe Special Max Turbo Limited Edition!"
/obj/item/pda/artist
- name = "aesthetic PDA"
+ name = "\improper antique aesthetic PDA"
icon_state = "pda-artist"
/obj/item/pda/cook
- name = "cook PDA"
+ name = "\improper antique cook PDA"
icon_state = "pda-cook"
/obj/item/pda/bar
- name = "bartender PDA"
+ name = "\improper antique bartender PDA"
icon_state = "pda-bartender"
insert_type = /obj/item/pen/fountain
/obj/item/pda/atmos
- name = "atmospherics PDA"
+ name = "\improper antique atmospherics PDA"
default_cartridge = /obj/item/cartridge/atmos
icon_state = "pda-atmos"
/obj/item/pda/chemist
- name = "chemist PDA"
+ name = "\improper antique chemist PDA"
default_cartridge = /obj/item/cartridge/chemistry
icon_state = "pda-chemistry"
/obj/item/pda/geneticist
- name = "geneticist PDA"
+ name = "\improper antique geneticist PDA"
default_cartridge = /obj/item/cartridge/medical
icon_state = "pda-genetics"
diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm
index 6203c7ce1c86..1c2132a8e3a3 100644
--- a/code/game/objects/items/devices/PDA/cart.dm
+++ b/code/game/objects/items/devices/PDA/cart.dm
@@ -17,7 +17,7 @@
/obj/item/cartridge
name = "generic cartridge"
- desc = "A data cartridge for portable microcomputers."
+ desc = "A data cartridge for those old portable microcomputers."
icon = 'icons/obj/pda.dmi'
icon_state = "cart"
item_state = "electronic"
diff --git a/code/game/objects/items/devices/busterarm/busterharpoon.dm b/code/game/objects/items/devices/busterarm/busterharpoon.dm
new file mode 100644
index 000000000000..31a2a43f6ba6
--- /dev/null
+++ b/code/game/objects/items/devices/busterarm/busterharpoon.dm
@@ -0,0 +1,108 @@
+/datum/action/cooldown/buster/megabuster/megaharpoon
+ name = "gasharpoon"
+ desc = "Charge up your harpoon and ready it to be fired, if it makes contact with a person it will drag them to you and immobilize them."
+ cooldown_time = 10 SECONDS
+ button_icon_state = "harpoonhead"
+
+
+/obj/item/gun/magic/wire/harpoon
+ name = "Harpoon Head"
+ desc = "A harpoon head made of pure plasteel, hits like a freighter."
+ ammo_type = /obj/item/ammo_casing/magic/wire/harpoon
+ icon_state = "gasharpoon"
+ item_state = "chain"
+ lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi'
+ fire_sound = 'sound/weapons/batonextend.ogg'
+ max_charges = 1
+ item_flags = NEEDS_PERMIT | DROPDEL
+ force = 0
+ can_charge = FALSE
+
+/obj/item/ammo_casing/magic/wire/harpoon
+ name = "harpoon"
+ desc = "A harpoon."
+ projectile_type = /obj/projectile/wire/harpoon
+ caliber = CALIBER_HOOK
+ icon_state = "harpoonhead"
+
+/obj/projectile/wire/harpoon/fire(setAngle)
+ if(firer)
+ wire = firer.Beam(src, icon_state = "harpoonrope", time = INFINITY, maxdistance = INFINITY)
+ ..()
+
+/obj/projectile/wire/harpoon
+ name = "harpoon"
+ icon_state = "harpoonhead"
+ icon = 'icons/obj/lavaland/artefacts.dmi'
+ pass_flags = PASSTABLE
+ damage = 10
+ armour_penetration = 100
+ damage_type = BRUTE
+ nodamage = TRUE
+ range = 8
+ hitsound = 'sound/effects/splat.ogg'
+ immobilize = 1 SECONDS
+
+/obj/projectile/wire/harpoon/on_hit(atom/target)
+ var/mob/living/L = target
+ var/mob/living/carbon/human/H = firer
+ if(!L)
+ return
+ L.apply_status_effect(STATUS_EFFECT_EXPOSED_HARPOONED)
+ if(isobj(target)) // If it's an object
+ var/obj/item/I = target
+ if(!I?.anchored) // Give it to us if it's not anchored
+ I.throw_at(get_step_towards(H,I), 8, 2)
+ H.visible_message(span_danger("[I] is pulled by [H]'s harpoon!"))
+ if(istype(I, /obj/item/clothing/head))
+ H.equip_to_slot_if_possible(I, ITEM_SLOT_HEAD)
+ H.visible_message(span_danger("[H] pulls [I] onto [H.p_their()] head!"))
+ else
+ H.put_in_hands(I)
+ return
+ zip(H, target) // Pull us towards it if it's anchored
+ if(isliving(target)) // If it's somebody
+ H.swap_hand(0) //for the sake of throttling people you catch
+ var/turf/T = get_step(get_turf(H), H.dir)
+ var/turf/Q = get_turf(H)
+ var/obj/item/bodypart/limb_to_hit = L.get_bodypart(H.zone_selected)
+ var/armor = L.run_armor_check(limb_to_hit, MELEE, armour_penetration = 35)
+ if(!L.anchored) // Only pull them if they're unanchored
+ if(istype(H))
+ L.visible_message(span_danger("[L] is pulled by [H]'s harpoon!"),span_userdanger("A harpoon pierces you and pulls you towards [H]!"))
+ L.Immobilize(1.0 SECONDS)
+ if(T.density) // If we happen to be facing a wall after the wire snatches them
+ to_chat(H, span_warning("[H] catches [L] and throws [L.p_them()] against [T]!"))
+ to_chat(L, span_userdanger("[H] crushes you against [T]!"))
+ playsound(L,'sound/effects/pop_expl.ogg', 130, 1)
+ L.apply_damage(15, BRUTE, limb_to_hit, armor, wound_bonus=CANT_WOUND)
+ L.forceMove(Q)
+ return
+ // If we happen to be facing a dense object after the wire snatches them, like a table or window
+ for(var/obj/D in T.contents)
+ if(D.density == TRUE)
+ D.take_damage(50)
+ L.apply_damage(15, BRUTE, limb_to_hit, armor, wound_bonus=CANT_WOUND)
+ L.forceMove(Q)
+ to_chat(H, span_warning("[H] catches [L] throws [L.p_them()] against [D]!"))
+ playsound(L,'sound/effects/pop_expl.ogg', 20, 1)
+ return
+ L.forceMove(T)
+ if(iswallturf(target)) // If we hit a wall, pull us to it
+ var/turf/W = target
+ zip(H, W)
+
+/// Left buster-arm means megabuster goes in left hand -- I stole this from megabuster! -- cowbot93
+/datum/action/cooldown/buster/megabuster/megaharpoon/l/Activate()
+ var/obj/item/gun/magic/wire/harpoon/B = new()
+ owner.visible_message(span_userdanger("[owner]'s arm lets out a harrowing sound!"))
+ playsound(owner,'sound/weapons/bladeslice.ogg', 60, 1)
+ if(do_after(owner, 2 SECONDS, owner, timed_action_flags = IGNORE_USER_LOC_CHANGE))
+ if(!owner.put_in_l_hand(B))
+ to_chat(owner, span_warning("You can't do this with your left hand full!"))
+ else
+ owner.visible_message(span_danger("[owner]'s readies the harpoon to fire!"))
+ if(owner.active_hand_index % 2 == 0)
+ owner.swap_hand(0)
+ StartCooldown()
diff --git a/code/game/objects/items/devices/busterarm/gasharpoon.dm b/code/game/objects/items/devices/busterarm/gasharpoon.dm
new file mode 100644
index 000000000000..2889422101a0
--- /dev/null
+++ b/code/game/objects/items/devices/busterarm/gasharpoon.dm
@@ -0,0 +1,59 @@
+/obj/item/clothing/gloves/gasharpoon
+ name = "gasharpoon"
+ desc = "A metal gauntlet with a harpoon attatched, powered by gasoline and traditionally used by space-whalers."
+ ///reminder to channge all this -- I changed it :)
+ icon = 'icons/obj/traitor.dmi'
+ icon_state = "gasharpoon"
+ item_state = "gasharpoon"
+ lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi'
+ attack_verb = list("harpooned", "gouged", "pierced")
+ force = 10
+ throwforce = 10
+ throw_range = 7
+ strip_delay = 15 SECONDS
+ cold_protection = HANDS
+ heat_protection = HANDS
+ w_class = WEIGHT_CLASS_NORMAL
+ armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100, ELECTRIC = 100)
+ resistance_flags = FIRE_PROOF | ACID_PROOF
+ var/click_delay = 1.5
+
+
+/obj/item/clothing/gloves/gasharpoon/equipped(mob/user, slot)
+ . = ..()
+ if(slot & ITEM_SLOT_GLOVES)
+ RegisterSignal(user, COMSIG_HUMAN_EARLY_UNARMED_ATTACK, PROC_REF(power_harpoon))
+ var/datum/action/cooldown/buster/megabuster/megaharpoon/l/harpoon = new(user)
+ harpoon.Grant(user)
+
+/obj/item/clothing/gloves/gasharpoon/dropped(mob/user)
+ . = ..()
+ if(user.get_item_by_slot(ITEM_SLOT_GLOVES)==src)
+ UnregisterSignal(user, COMSIG_HUMAN_EARLY_UNARMED_ATTACK)
+ var/datum/action/cooldown/buster/megabuster/megaharpoon/l/harpoon = locate(/datum/action/cooldown/buster/megabuster/megaharpoon/l) in user.actions
+ if(harpoon)
+ harpoon.Remove(user)
+ return ..()
+
+
+/obj/item/clothing/gloves/gasharpoon/proc/power_harpoon(mob/living/user, atom/movable/target)
+ if(!user || user.a_intent!=INTENT_HARM || (!isliving(target) && !isobj(target)) || isitem(target))
+ return
+ do_attack(user, target, force * 2)
+ playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1)
+ target.visible_message(span_danger("[user]'s gasharpoon pierces through [target.name]!"))
+ return COMPONENT_NO_ATTACK_HAND
+
+/obj/item/clothing/gloves/gasharpoon/attack(mob/living/target, mob/living/user)
+ power_harpoon(user, target)
+
+/obj/item/clothing/gloves/gasharpoon/proc/do_attack(mob/living/user, atom/target, punch_force)
+ if(isliving(target))
+ var/mob/living/target_mob = target
+ target_mob.apply_damage(punch_force, BRUTE, wound_bonus = 30)
+ else if(isobj(target))
+ var/obj/target_obj = target
+ target_obj.take_damage(punch_force, BRUTE, MELEE, FALSE)
+ user.do_attack_animation(target, ATTACK_EFFECT_SLASH)
+ user.changeNext_move(CLICK_CD_MELEE * click_delay)
diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm
index 0ca05a5c32af..dd31e5b34328 100644
--- a/code/game/objects/items/devices/flashlight.dm
+++ b/code/game/objects/items/devices/flashlight.dm
@@ -492,6 +492,13 @@
light_range = 6 // luminosity when on
light_system = MOVABLE_LIGHT
+/obj/item/flashlight/lantern/pinapolantern
+ name = "pinap-o'-lantern"
+ desc = "It's a pineapple."
+ icon = 'yogstation/icons/obj/items.dmi'
+ icon_state = "pinapolantern"
+ item_state = "pinapolantern"
+
/obj/item/flashlight/lantern/heirloom_moth
name = "old lantern"
desc = "An old lantern that has seen plenty of use."
diff --git a/code/game/objects/items/devices/radio/encryptionkey.dm b/code/game/objects/items/devices/radio/encryptionkey.dm
index bd43da8ef7e8..95a0a72e29b5 100644
--- a/code/game/objects/items/devices/radio/encryptionkey.dm
+++ b/code/game/objects/items/devices/radio/encryptionkey.dm
@@ -124,6 +124,17 @@
icon_state = "srv_cypherkey"
channels = list(RADIO_CHANNEL_SERVICE = 1)
+/obj/item/encryptionkey/headset_synthetic
+ name = "synthetic radio encryption key"
+ icon_state = "rd_cypherkey"
+ channels = list(RADIO_CHANNEL_COMMAND = 1, RADIO_CHANNEL_ENGINEERING = 1, RADIO_CHANNEL_SCIENCE = 1, RADIO_CHANNEL_MEDICAL = 1, RADIO_CHANNEL_SUPPLY = 1, RADIO_CHANNEL_SERVICE = 1)
+ translate_binary = TRUE
+ item_flags = DROPDEL
+
+/obj/item/encryptionkey/headset_synthetic/Initialize(mapload)
+ . = ..()
+ ADD_TRAIT(src, TRAIT_NODROP, SYNTHETIC_TRAIT)
+
/obj/item/encryptionkey/headset_cent
name = "\improper CentCom radio encryption key"
icon_state = "cent_cypherkey"
diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm
index e1159a7dce30..c7906d086a7a 100644
--- a/code/game/objects/items/devices/radio/headset.dm
+++ b/code/game/objects/items/devices/radio/headset.dm
@@ -204,6 +204,23 @@
icon_state = "srv_headset"
keyslot = new /obj/item/encryptionkey/headset_service
+/obj/item/radio/headset/headset_synthetic
+ name = "synthetic radio headset"
+ desc = "Headset used by the onboard synthetic units. This one is integrated directly into the unit and is not possible to remove."
+ icon_state = "com_headset"
+ keyslot = new /obj/item/encryptionkey/headset_synthetic
+ item_flags = DROPDEL
+ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
+
+/obj/item/radio/headset/headset_synthetic/Initialize(mapload)
+ . = ..()
+ ADD_TRAIT(src, TRAIT_NODROP, SYNTHETIC_TRAIT)
+ ADD_TRAIT(src, TRAIT_EMPPROOF_CONTENTS, SYNTHETIC_TRAIT)
+ ADD_TRAIT(src, TRAIT_EMPPROOF_SELF, SYNTHETIC_TRAIT)
+
+/obj/item/radio/headset/headset_synthetic/attackby(obj/item/W, mob/user, params)
+ return FALSE
+
/obj/item/radio/headset/headset_cent
name = "\improper CentCom headset"
desc = "A headset used by the upper echelons of Nanotrasen."
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index cb5027fa300c..37dd346099a7 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -302,7 +302,7 @@ GLOBAL_LIST_INIT(channel_tokens, list(
// Okay, the signal was never processed, send a mundane broadcast.
signal.data["compression"] = 0
signal.transmission_method = TRANSMISSION_RADIO
- signal.levels = list(T.z)
+ signal.levels = SSmapping.get_connected_levels(T)
signal.broadcast()
/obj/item/radio/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, list/message_mods = list())
diff --git a/code/game/objects/items/devices/reverse_bear_trap.dm b/code/game/objects/items/devices/reverse_bear_trap.dm
index 30075a439631..1988bcc2512b 100644
--- a/code/game/objects/items/devices/reverse_bear_trap.dm
+++ b/code/game/objects/items/devices/reverse_bear_trap.dm
@@ -7,7 +7,6 @@
flags_1 = CONDUCT_1
resistance_flags = FIRE_PROOF | UNACIDABLE
w_class = WEIGHT_CLASS_NORMAL
- obj_integrity = 300
max_integrity = 300
item_state = "reverse_bear_trap"
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm
index 7a195a99be79..11e82c572af3 100644
--- a/code/game/objects/items/devices/transfer_valve.dm
+++ b/code/game/objects/items/devices/transfer_valve.dm
@@ -14,6 +14,13 @@
var/valve_open = FALSE
var/toggle = TRUE
+/obj/item/transfer_valve/Initialize(mapload)
+ . = ..()
+ var/static/list/loc_connections = list(
+ COMSIG_ATOM_ENTERED = PROC_REF(on_entered),
+ )
+ AddElement(/datum/element/connect_loc, loc_connections)
+
/obj/item/transfer_valve/Destroy()
attached_device = null
return ..()
@@ -70,8 +77,7 @@
if(attached_device)
attached_device.on_found(finder)
-/obj/item/transfer_valve/Crossed(atom/movable/AM as mob|obj)
- . = ..()
+/obj/item/transfer_valve/proc/on_entered(datum/source, atom/movable/AM, ...)
if(attached_device)
attached_device.Crossed(AM)
diff --git a/code/game/objects/items/dna_injector.dm b/code/game/objects/items/dna_injector.dm
index 2ec72419d8d2..be60945b4233 100644
--- a/code/game/objects/items/dna_injector.dm
+++ b/code/game/objects/items/dna_injector.dm
@@ -371,14 +371,6 @@
name = "\improper DNA injector (Anti-Paranoia)"
remove_mutations = list(PARANOIA)
-/obj/item/dnainjector/mindread
- name = "\improper DNA injector (Mindread)"
- add_mutations = list(MINDREAD)
-
-/obj/item/dnainjector/antimindread
- name = "\improper DNA injector (Anti-Mindread)"
- remove_mutations = list(MINDREAD)
-
/obj/item/dnainjector/radioactive
name = "\improper DNA injector (Radioactive)"
add_mutations = list(RADIOACTIVE)
diff --git a/code/game/objects/items/extinguisher.dm b/code/game/objects/items/extinguisher.dm
index 267803160ba5..44f789bb8735 100644
--- a/code/game/objects/items/extinguisher.dm
+++ b/code/game/objects/items/extinguisher.dm
@@ -89,7 +89,7 @@
else
return ..()
-/obj/item/extinguisher/attack_obj(obj/O, mob/living/user)
+/obj/item/extinguisher/attack_atom(obj/O, mob/living/user)
if(AttemptRefill(O, user))
refilling = TRUE
return FALSE
diff --git a/code/game/objects/items/flamethrower.dm b/code/game/objects/items/flamethrower.dm
index d7d7cf9ef2fc..0792c4085680 100644
--- a/code/game/objects/items/flamethrower.dm
+++ b/code/game/objects/items/flamethrower.dm
@@ -1,3 +1,6 @@
+/// How many joules of energy from reactions required to cause 1 damage
+#define JOULES_PER_DAMAGE 100000
+
/obj/item/flamethrower
name = "flamethrower"
desc = "You are a firestarter!"
@@ -54,7 +57,7 @@
if(M.is_holding(src))
location = M.loc
if(isturf(location)) //start a fire if possible
- igniter.flamethrower_process(location)
+ open_flame(igniter.heat)
/obj/item/flamethrower/update_overlays()
@@ -199,33 +202,21 @@
if(!istype(target))
return FALSE
- var/ratio_removed = 1
- if(!release_all)
- ratio_removed = min(ptank.distribute_pressure, ptank.air_contents.return_pressure()) / ptank.air_contents.return_pressure()
+ var/ratio_removed = min(ptank.distribute_pressure, ptank.air_contents.return_pressure()) / ptank.air_contents.return_pressure()
+
var/datum/gas_mixture/fuel_mix = ptank.air_contents.remove_ratio(ratio_removed)
+ var/datum/gas_mixture/turf_mix = target.return_air()
+
+ fuel_mix.merge(turf_mix.copy()) // copy air from the turf to do reactions with
+ fuel_mix.set_temperature(igniter.heat) // heat the contents
+
+ var/old_thermal_energy = fuel_mix.thermal_energy()
+ for(var/i in 1 to 10) // react a bunch of times on the target turf
+ if(!fuel_mix.react(target))
+ break // break the loop if it stops reacting
- // Return of the stimball flamethrower, wear radiation protection when using this or you're just as likely to die as your target
- if(fuel_mix.get_moles(GAS_PLASMA) >= NITRO_BALL_MOLES_REQUIRED && fuel_mix.get_moles(GAS_NITRIUM) >= NITRO_BALL_MOLES_REQUIRED && fuel_mix.get_moles(GAS_PLUOXIUM) >= NITRO_BALL_MOLES_REQUIRED)
- var/balls_shot = round(min(fuel_mix.get_moles(GAS_NITRIUM), fuel_mix.get_moles(GAS_PLUOXIUM), NITRO_BALL_MAX_REACT_RATE / NITRO_BALL_MOLES_REQUIRED))
- var/angular_increment = 360/balls_shot
- var/random_starting_angle = rand(0,360)
- for(var/i in 1 to balls_shot)
- target.fire_nuclear_particle((i*angular_increment+random_starting_angle))
- fuel_mix.adjust_moles(GAS_PLASMA, -balls_shot * NITRO_BALL_MOLES_REQUIRED) // No free extra damage for you, conservation of mass go brrrrr
-
- // Funny rad flamethrower go brrr
- if(fuel_mix.get_moles(GAS_TRITIUM)) // Tritium fires cause a bit of radiation
- radiation_pulse(target, min(fuel_mix.get_moles(GAS_TRITIUM), fuel_mix.get_moles(GAS_O2)/2) * FIRE_HYDROGEN_ENERGY_RELEASED / TRITIUM_BURN_RADIOACTIVITY_FACTOR)
-
- // 8 damage at 0.5 mole transfer or ~17 kPa release pressure
- // 16 damage at 1 mole transfer or ~35 kPa release pressure
- var/damage = fuel_mix.get_moles(GAS_PLASMA) * 16
- // harder to achieve than plasma
- damage += fuel_mix.get_moles(GAS_TRITIUM) * 24 // Lower damage than hydrogen, causes minor radiation
- damage += fuel_mix.get_moles(GAS_H2) * 32
- // Maximum damage restricted by the available oxygen, with a hard cap at 16
- var/datum/gas_mixture/turf_air = target.return_air()
- damage = min(damage, turf_air.get_moles(GAS_O2) + fuel_mix.get_moles(GAS_O2), max_damage) // capped by combined oxygen in the fuel mix and enviroment
+ // damage is based on the positive or negative energy of the reaction, with a cap
+ var/damage = min(abs(fuel_mix.thermal_energy() - old_thermal_energy) / JOULES_PER_DAMAGE, max_damage)
// If there's not enough fuel and/or oxygen to do more than 1 damage, shut itself off
if(damage < 1)
@@ -251,22 +242,40 @@
for(var/turf/T in turflist)
if(T == previousturf)
continue //so we don't burn the tile we be standin on
- for(var/obj/structure/blob/B in T)
+ var/cached_damage = 0
+
+ for(var/obj/structure/blob/blob in T)
// This is run before atmos checks because blob can be atmos blocking but we still want to hit them
// See /proc/default_ignite
- var/damage = process_fuel(T)
- if(!damage)
- break // Out of gas, stop running pointlessly
- B.take_damage(damage * 2, BURN, FIRE) // strong against blobs
+ if(!cached_damage)
+ cached_damage = process_fuel(T)
+ if(!lit)
+ break // stopped running, don't continue
+ if(QDELETED(blob))
+ continue
+ blob.take_damage(cached_damage * 2, BURN, FIRE) // strong against blobs
+
+ for(var/obj/structure/spacevine/vine in T)
+ // This is run before atmos checks because vines can be on top of a window or some other atmos-blocking structure
+ if(!cached_damage)
+ cached_damage = process_fuel(T)
+ if(!lit)
+ break // stopped running, don't continue
+ if(QDELETED(vine))
+ continue
+ vine.take_damage(cached_damage * 3, BURN, FIRE, TRUE) // very strong against vines
+
var/list/turfs_sharing_with_prev = previousturf.GetAtmosAdjacentTurfs(alldir=1)
if(!(T in turfs_sharing_with_prev))
break // Hit something that blocks atmos
- if(igniter)
- if(!igniter.ignite_turf(src,T))
- break // Out of gas, stop running pointlessly
- else
- if(!default_ignite(T))
- break // Out of gas, stop running pointlessly
+
+ if(!cached_damage)
+ cached_damage = process_fuel(T)
+ if(!lit)
+ break // stopped running, don't continue
+ if(!burn_atoms_on_turf(T, cached_damage))
+ break // Out of gas, stop running pointlessly
+
if(!sound_played) // play the sound once if we successfully ignite at least one thing
sound_played = TRUE
playsound(loc, pick(flame_sounds), 50, TRUE)
@@ -281,10 +290,9 @@
// /obj/structure/blob/normal
// Return value tells the parent whether to continue calculating the line
-/obj/item/flamethrower/proc/default_ignite(turf/target, release_all = FALSE)
- // do the fuel stuff
- var/damage = process_fuel(target, release_all)
- if(!damage)
+/obj/item/flamethrower/proc/burn_atoms_on_turf(turf/target, damage)
+ // no damage? don't continue
+ if(damage <= 0)
return FALSE
//Burn it
@@ -333,24 +341,17 @@
var/obj/projectile/P = hitby
if(damage && attack_type == PROJECTILE_ATTACK && P.damage_type != STAMINA && prob(5))
owner.visible_message(span_danger("\The [attack_text] hits the fueltank on [owner]'s [name], rupturing it! What a shot!"))
- var/target_turf = get_turf(owner)
- igniter.ignite_turf(src,target_turf, release_all = TRUE)
- qdel(ptank)
- return 1 //It hit the flamethrower, not them
-
-
-/obj/item/assembly/igniter/proc/flamethrower_process(turf/open/location)
- location.hotspot_expose(700,2)
-
-/obj/item/assembly/igniter/proc/ignite_turf(obj/item/flamethrower/F, turf/open/location, release_all = FALSE)
- return F.default_ignite(location, release_all)
+ var/turf/target_turf = get_turf(owner)
+ burn_atoms_on_turf(target_turf, process_fuel(target_turf))
+ return TRUE //It hit the flamethrower, not them
+ return ..()
///////////////////// Flamethrower as an energy weapon /////////////////////
// Currently used exclusively in /obj/item/gun/energy/printer/flamethrower
/obj/item/ammo_casing/energy/flamethrower
projectile_type = /obj/projectile/bullet/incendiary/flamethrower
select_name = "fire"
- fire_sound = null
+ fire_sound = 'sound/weapons/flamethrower1.ogg'
firing_effect_type = null
e_cost = 50
@@ -361,3 +362,5 @@
sharpness = SHARP_NONE
range = 6
penetration_flags = PENETRATE_OBJECTS | PENETRATE_MOBS
+
+#undef JOULES_PER_DAMAGE
diff --git a/code/game/objects/items/grenades/chem_grenade.dm b/code/game/objects/items/grenades/chem_grenade.dm
index 2423c687ef52..477af55a02f6 100644
--- a/code/game/objects/items/grenades/chem_grenade.dm
+++ b/code/game/objects/items/grenades/chem_grenade.dm
@@ -342,7 +342,7 @@
/obj/item/grenade/chem_grenade/radiation
name = "Rad Bomb"
- desc = "the best grenade to irridiate the fuck out of someone"
+ desc = "The best grenade to irradiate the fuck out of someone."
stage = GRENADE_READY
/obj/item/grenade/chem_grenade/radiation/Initialize(mapload)
diff --git a/code/game/objects/items/grenades/grenade.dm b/code/game/objects/items/grenades/grenade.dm
index 8d9552276130..220e526453d3 100644
--- a/code/game/objects/items/grenades/grenade.dm
+++ b/code/game/objects/items/grenades/grenade.dm
@@ -58,6 +58,9 @@
/obj/item/grenade/attack_self(mob/user)
if(!active)
if(clown_check(user))
+ if(HAS_TRAIT(user, TRAIT_NO_GRENADES))
+ to_chat(user, span_warning("You can't use grenades!"))
+ return
preprime(user)
/obj/item/grenade/proc/log_grenade(mob/user, turf/T)
diff --git a/code/game/objects/items/grenades/plastic.dm b/code/game/objects/items/grenades/plastic.dm
index 15e28fc95142..819a1ce6f000 100644
--- a/code/game/objects/items/grenades/plastic.dm
+++ b/code/game/objects/items/grenades/plastic.dm
@@ -25,6 +25,10 @@
. = ..()
ADD_TRAIT(src, TRAIT_EMPPROOF_CONTENTS, "innate_empproof")
plastic_overlay = mutable_appearance(icon, "[item_state]2", ABOVE_ALL_MOB_LAYER)
+ var/static/list/loc_connections = list(
+ COMSIG_ATOM_ENTERED = PROC_REF(on_entered),
+ )
+ AddElement(/datum/element/connect_loc, loc_connections)
/obj/item/grenade/plastic/Destroy()
qdel(nadeassembly)
@@ -80,8 +84,7 @@
/obj/item/grenade/plastic/receive_signal()
prime()
-/obj/item/grenade/plastic/Crossed(atom/movable/AM)
- . = ..()
+/obj/item/grenade/plastic/proc/on_entered(datum/source, atom/movable/AM, ...)
if(nadeassembly)
nadeassembly.Crossed(AM)
diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm
index c14723dd7e6c..18824aa5da65 100644
--- a/code/game/objects/items/handcuffs.dm
+++ b/code/game/objects/items/handcuffs.dm
@@ -268,7 +268,11 @@
/obj/item/restraints/legcuffs/beartrap/Initialize(mapload)
. = ..()
- update_appearance(UPDATE_ICON)
+ update_appearance()
+ var/static/list/loc_connections = list(
+ COMSIG_ATOM_ENTERED = PROC_REF(trap_stepped_on),
+ )
+ AddElement(/datum/element/connect_loc, loc_connections)
/obj/item/restraints/legcuffs/beartrap/update_icon_state()
. = ..()
@@ -310,6 +314,55 @@
update_appearance(UPDATE_ICON)
playsound(src, 'sound/effects/snap.ogg', 50, TRUE)
+/obj/item/restraints/legcuffs/beartrap/proc/trap_stepped_on(datum/source, atom/movable/entering, ...)
+ SIGNAL_HANDLER
+
+ spring_trap(entering)
+
+/**
+ * Tries to spring the trap on the target movable.
+ *
+ * This proc is safe to call without knowing if the target is valid or if the trap is armed.
+ *
+ * Does not trigger on tiny mobs.
+ * If ignore_movetypes is FALSE, does not trigger on floating / flying / etc. mobs.
+ */
+/obj/item/restraints/legcuffs/beartrap/proc/spring_trap(atom/movable/target, ignore_movetypes = FALSE)
+ if(!armed || !isturf(loc) || !isliving(target))
+ return
+
+ var/mob/living/victim = target
+ if(istype(victim.buckled, /obj/vehicle))
+ var/obj/vehicle/ridden_vehicle = victim.buckled
+ if(!ridden_vehicle.are_legs_exposed) //close the trap without injuring/trapping the rider if their legs are inside the vehicle at all times.
+ close_trap()
+ ridden_vehicle.visible_message(span_danger("[ridden_vehicle] triggers \the [src]."))
+ return
+
+ //don't close the trap if they're as small as a mouse
+ if(victim.mob_size <= MOB_SIZE_TINY)
+ return
+ if(!ignore_movetypes && (victim.movement_type & MOVETYPES_NOT_TOUCHING_GROUND))
+ return
+
+ close_trap()
+ if(ignore_movetypes)
+ victim.visible_message(span_danger("\The [src] ensnares [victim]!"), \
+ span_userdanger("\The [src] ensnares you!"))
+ else
+ victim.visible_message(span_danger("[victim] triggers \the [src]."), \
+ span_userdanger("You trigger \the [src]!"))
+ var/def_zone = BODY_ZONE_CHEST
+ if(iscarbon(victim) && victim.body_position == STANDING_UP)
+ var/mob/living/carbon/carbon_victim = victim
+ def_zone = pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
+ if(!carbon_victim.legcuffed && carbon_victim.num_legs >= 2) //beartrap can't cuff your leg if there's already a beartrap or legcuffs, or you don't have two legs.
+ INVOKE_ASYNC(carbon_victim, TYPE_PROC_REF(/mob/living/carbon, equip_to_slot), src, ITEM_SLOT_LEGCUFFED)
+ SSblackbox.record_feedback("tally", "handcuffs", 1, type)
+
+ victim.apply_damage(trap_damage, BRUTE, def_zone)
+
+
/obj/item/restraints/legcuffs/beartrap/Crossed(AM as mob|obj)
if(armed && isturf(loc))
if(isliving(AM))
diff --git a/code/game/objects/items/holy_armours.dm b/code/game/objects/items/holy_armours.dm
index d9124b65e11d..01cfdc254a3a 100644
--- a/code/game/objects/items/holy_armours.dm
+++ b/code/game/objects/items/holy_armours.dm
@@ -84,6 +84,7 @@
armor = list(MELEE = -15, BULLET = -10, LASER = -10, ENERGY = -5, BOMB = -5, BIO = -2, RAD = 0, FIRE = 0, ACID = 0)
slowdown = -0.1 //very statistically significant
flags_inv = null //doesn't actually visibly hide anything
+ clothing_flags = LARGE_WORN_ICON
worn_x_dimension = 64
worn_y_dimension = 64
dynamic_hair_suffix = ""
@@ -233,3 +234,208 @@
icon_state = "darktemplar-chaplain1"
item_state = "darktemplar-chaplain1"
armor = list(MELEE = 30, BULLET = 10, LASER = 15, ENERGY = 10, BOMB = 20, BIO = 60, RAD = 40, FIRE = 90, ACID = 80)
+
+/obj/item/storage/box/holy/flagelanteschains
+ name = "Flagenantes Kit"
+
+/obj/item/storage/box/holy/flagelanteschains/PopulateContents()
+ new /obj/item/clothing/suit/hooded/flagelantes_chains(src)
+
+/obj/item/clothing/suit/hooded/flagelantes_chains
+ name = "flagellant's chains"
+ desc = "Chains worn by those who wish to purify themselves through pain. They slow the wearer down initialy, but give divine haste the more pain they endure."
+ icon_state = "flagelantes_chains"
+ item_state = "flagelantes_chains"
+ armor = list(MELEE = -15, BULLET = -15, LASER = -15, ENERGY = -15, BOMB = -15, BIO = -15, RAD = 0, FIRE = 0, ACID = 0)
+ body_parts_covered = CHEST|GROIN|LEGS|ARMS
+ mutantrace_variation = MUTANTRACE_VARIATION //No leg squishing
+ resistance_flags = FIRE_PROOF | ACID_PROOF //No turning to ash/mush in the quest for pain
+ allowed = list(/obj/item/storage/book/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/tank/internals/ipc_coolant)
+ hoodtype = /obj/item/clothing/head/hooded/flagelantes_chains_hood
+ var/wrap = FALSE
+ var/obj/effect/abstract/particle_holder/flagelantes_effect
+ var/total_wounds
+ var/speed_message = FALSE
+ var/footstep = 1
+ var/footstep_max = 2
+
+/obj/item/clothing/suit/hooded/flagelantes_chains/equipped(mob/M, slot)
+ . = ..()
+ if(slot == ITEM_SLOT_OCLOTHING && iscarbon(M)) //Signals for sensing damage, healing, wounds, and movement
+ RegisterSignal(M, COMSIG_MOB_APPLY_DAMAGE, PROC_REF(handle_damage))
+ RegisterSignal(M, COMSIG_MOB_APPLY_HEALING, PROC_REF(on_heal))
+ RegisterSignal(M, COMSIG_CARBON_GAIN_WOUND, PROC_REF(handle_wound_add))
+ RegisterSignal(M, COMSIG_CARBON_LOSE_WOUND, PROC_REF(handle_wound_remove))
+ RegisterSignal(M, COMSIG_MOVABLE_MOVED, PROC_REF(on_mob_move))
+ else
+ UnregisterSignal(M, list(COMSIG_MOB_APPLY_DAMAGE, COMSIG_MOB_APPLY_HEALING, COMSIG_CARBON_GAIN_WOUND, COMSIG_CARBON_LOSE_WOUND, COMSIG_MOVABLE_MOVED))
+
+/obj/item/clothing/suit/hooded/flagelantes_chains/dropped(mob/M)
+ . = ..()
+ UnregisterSignal(M, list(COMSIG_MOB_APPLY_DAMAGE, COMSIG_MOB_APPLY_HEALING, COMSIG_CARBON_GAIN_WOUND, COMSIG_CARBON_LOSE_WOUND, COMSIG_MOVABLE_MOVED))
+ REMOVE_TRAIT(M, TRAIT_IGNOREDAMAGESLOWDOWN, type)
+ total_wounds = 0
+ slowdown = 0
+ if(flagelantes_effect)
+ QDEL_NULL(flagelantes_effect)
+
+/obj/item/clothing/suit/hooded/flagelantes_chains/ToggleHood() //So people can't just quickly wear it whenever they want to
+ var/mob/living/carbon/human/H = src.loc
+ if(wrap) //Make sure they're not already trying to wear it
+ to_chat(H, span_warning("You're already wrapping the chains around yourself!."))
+ return
+ else if(!suittoggled)
+ if(H.wear_suit != src)
+ to_chat(H, span_warning("You must be wearing [src] to put up the hood!"))
+ return
+ if(H.head)
+ to_chat(H, span_warning("You're already wearing something on your head!"))
+ return
+ to_chat(H, span_notice("You start wrapping the chains around yourself."))
+ H.visible_message(span_warning("[H] starts wrapping [src] around themselves!"))
+ playsound(get_turf(src), 'sound/spookoween/chain_rattling.ogg', 10, TRUE, -1)
+ wrap = TRUE
+ if(!do_after(H, 3 SECONDS, H))
+ wrap = FALSE
+ H.balloon_alert(H, "You were interupted!")
+ return //Stop it from completing if they move
+ if(ishuman(src.loc))
+ if(H.equip_to_slot_if_possible(hood,ITEM_SLOT_HEAD,0,0,1))
+ suittoggled = TRUE
+ src.icon_state = "[initial(icon_state)]_t"
+ H.update_inv_wear_suit()
+ for(var/X in actions)
+ var/datum/action/A = X
+ A.build_all_button_icons()
+ ADD_TRAIT(H, TRAIT_IGNOREDAMAGESLOWDOWN, type)// Ignore damage slowdown
+ change_slowdown(H, slowdown) //Change clothing slowdown based on damage
+ wrap = FALSE
+ else
+ RemoveHood()
+ REMOVE_TRAIT(H, TRAIT_IGNOREDAMAGESLOWDOWN, type)
+ total_wounds = 0
+ slowdown = 0
+ if(flagelantes_effect)
+ QDEL_NULL(flagelantes_effect)
+
+/obj/item/clothing/suit/hooded/flagelantes_chains/proc/handle_damage(mob/living/carbon/human/H, damage, damagetype, def_zone)
+
+ SIGNAL_HANDLER
+
+ if(suittoggled) //Make sure it only checks when the hood is up
+ change_slowdown(H, slowdown) //Change speed when damaged
+
+/obj/item/clothing/suit/hooded/flagelantes_chains/proc/on_heal(mob/living/carbon/human/H, amount, damtype)
+
+ SIGNAL_HANDLER
+
+ if(suittoggled) //Make sure it only checks when the hood is up
+ change_slowdown(H, slowdown) //Change speed when healed
+
+/obj/item/clothing/suit/hooded/flagelantes_chains/proc/handle_wound_add(mob/living/carbon/human/H, datum/wound/W, obj/item/bodypart/L)
+
+ SIGNAL_HANDLER
+
+ if(suittoggled) //Make sure it only checks when the hood is up
+ change_slowdown(H, slowdown) //Change speed when gaining a wound
+
+
+/obj/item/clothing/suit/hooded/flagelantes_chains/proc/handle_wound_remove(mob/living/carbon/human/H, datum/wound/W, obj/item/bodypart/L)
+
+ SIGNAL_HANDLER
+
+ if(suittoggled) //Make sure it only checks when the hood is up
+ change_slowdown(H, slowdown) //Change speed when losing a wound
+
+/obj/item/clothing/suit/hooded/flagelantes_chains/proc/change_slowdown(mob/living/carbon/human/H, starting_slowdown)
+ var/health_percent = H.health / H.maxHealth
+ var/final_slowdown = 0
+
+ total_wounds = length(H.all_wounds) //Thanks Molti, Baimo, and Bibby
+
+ if(total_wounds < 0)
+ total_wounds = 0
+
+ switch(total_wounds) //Change slowdown based on wounds
+ if(1)
+ final_slowdown += -0.1
+ if(2)
+ final_slowdown += -0.2
+ if(3 to INFINITY) //Max of three wounds for slowdown calculation
+ final_slowdown += -0.4
+
+ switch(health_percent) //Change slowdown based on health
+ if(0.90 to INFINITY)
+ final_slowdown += 1
+ if(0.80 to 0.89)
+ final_slowdown += 0.5
+ if(0.50 to 0.79)
+ final_slowdown += 0
+ if(0.30 to 0.49)
+ final_slowdown += -0.2
+ if(0.10 to 0.29)
+ final_slowdown += -0.4
+ if(0 to 0.9)
+ final_slowdown += -0.6
+
+ slowdown = final_slowdown //set slowdown
+
+ if(slowdown == -1) //Alert the user and those around that they've achieved MAXIMUM OVERDRIVE
+ if(!speed_message)
+ to_chat(H, span_notice("You feel yourself grow closer to the divine as your sins seep out of the chains!."))
+ H.visible_message(span_warning("[H] starts sweating profusely!"))
+ speed_message = TRUE
+ else
+ speed_message = FALSE
+
+ appearance_change(H, slowdown) //Add particles depending on slowdown
+
+ change_footstep(slowdown) //Change occurance of chain noise
+
+ if(slowdown > starting_slowdown) //Show bubble alert based on starting and new slowdown
+ H.balloon_alert(H, "You slow down!")
+ else if(slowdown < starting_slowdown)
+ H.balloon_alert(H, "You speed up!")
+
+/obj/item/clothing/suit/hooded/flagelantes_chains/proc/appearance_change(mob/living/carbon/human/H, slowdown)
+ switch(slowdown)
+ if(-0.9 to 1)
+ if(flagelantes_effect)
+ QDEL_NULL(flagelantes_effect) //Remove particle effect
+ if(-INFINITY to -1)
+ if(!flagelantes_effect)
+ flagelantes_effect = new(H, /particles/droplets)
+ flagelantes_effect.color = "#a41c1c"
+
+/obj/item/clothing/suit/hooded/flagelantes_chains/proc/change_footstep(slowdown) //So the chain sounds are not spammed at higher speeds
+ switch(slowdown)
+ if(0 to 1)
+ footstep_max = 2
+ if(-0.3 to -0.1)
+ footstep_max = 3
+ if(-0.9 to -0.4)
+ footstep_max = 4
+ if(-INFINITY to -1)
+ footstep_max = 5
+
+/obj/item/clothing/suit/hooded/flagelantes_chains/proc/on_mob_move()
+ var/mob/living/carbon/human/H = loc
+ if(!istype(H) || H.wear_suit != src)
+ return
+ if(footstep > footstep_max)
+ playsound(src, 'sound/weapons/chainhit.ogg', 3, 1)
+ footstep = 0
+ else
+ footstep++
+
+/obj/item/clothing/head/hooded/flagelantes_chains_hood
+ name = "flagellant's hood"
+ desc = "A hood worn by flagellants to hide their face."
+ icon = 'icons/obj/clothing/hats/hats.dmi'
+ mob_overlay_icon = 'icons/mob/clothing/head/head.dmi'
+ icon_state = "flagelantes_chains_hood"
+ item_state = "flagelantes_chains_hood"
+ armor = list(MELEE = -15, BULLET = -15, LASER = -15, ENERGY = -15, BOMB = -15, BIO = -15, RAD = 0, FIRE = 0, ACID = 0)
+ body_parts_covered = HEAD
+ flags_inv = HIDEEARS|HIDEEYES|HIDEFACE|HIDEFACIALHAIR|HIDEHAIR|HIDEMASK
+ resistance_flags = FIRE_PROOF | ACID_PROOF
diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm
index 593983b469fc..3cf8adbfd8f2 100644
--- a/code/game/objects/items/holy_weapons.dm
+++ b/code/game/objects/items/holy_weapons.dm
@@ -147,6 +147,10 @@
menutab = MENU_WEAPON
additional_desc = "An exceptionally large sword, capable of occasionally deflecting blows."
+/obj/item/nullrod/claymore/Initialize(mapload)
+ . = ..()
+ AddComponent(/datum/component/cleave_attack)
+
/obj/item/nullrod/claymore/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(attack_type == PROJECTILE_ATTACK)
final_block_chance = 0 //Don't bring a sword to a gunfight
@@ -359,6 +363,10 @@
menutab = MENU_WEAPON
additional_desc = "The weapon of choice for a devout monk. Block incoming blows while striking weak points until your opponent is too exhausted to continue."
+/obj/item/nullrod/bostaff/Initialize(mapload)
+ . = ..()
+ AddComponent(/datum/component/cleave_attack, arc_size=180)
+
/obj/item/nullrod/bostaff/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(attack_type == PROJECTILE_ATTACK)
final_block_chance = 0 //Don't bring a stick to a gunfight
@@ -610,6 +618,7 @@
. = ..()
ADD_TRAIT(src, TRAIT_NODROP, HAND_REPLACEMENT_TRAIT)
AddComponent(/datum/component/butchering, 30, 100, 0, hitsound)
+ AddComponent(/datum/component/cleave_attack)
/obj/item/nullrod/armblade
name = "dark blessing"
@@ -633,6 +642,7 @@
. = ..()
ADD_TRAIT(src, TRAIT_NODROP, HAND_REPLACEMENT_TRAIT)
AddComponent(/datum/component/butchering, 80, 70)
+ AddComponent(/datum/component/cleave_attack)
/obj/item/nullrod/armblade/tentacle
name = "unholy blessing"
@@ -852,7 +862,7 @@
C.regenerate_icons()
/obj/item/nullrod/staff/worn_overlays(isinhands)
- . = list()
+ . = ..()
if(isinhands)
. += mutable_appearance('icons/effects/effects.dmi', shield_icon, MOB_LAYER + 0.01)
@@ -1033,7 +1043,6 @@ it also swaps back if it gets thrown into the chaplain, but the chaplain catches
w_class = WEIGHT_CLASS_BULKY
slot_flags = ITEM_SLOT_BACK|ITEM_SLOT_BELT
var/possessed = FALSE
- var/walking = FALSE //check to tell if they're flying around or not
var/mob/living/simple_animal/shade/soul //when they're just a blade (stored inside the blade at all times)
var/mob/living/simple_animal/nullrod/blade //when they're flying around (blade stored inside them (soul is inside that blade))
var/mob/living/owner //the person with the recall spell
@@ -1041,6 +1050,10 @@ it also swaps back if it gets thrown into the chaplain, but the chaplain catches
menutab = MENU_MISC
additional_desc = "You feel an unwoken presence in this one."
+/obj/item/nullrod/talking/Initialize(mapload)
+ . = ..()
+ AddComponent(/datum/component/cleave_attack)
+
/obj/item/nullrod/talking/relaymove(mob/user)
return //stops buckled message spam for the ghost.
@@ -1101,12 +1114,13 @@ it also swaps back if it gets thrown into the chaplain, but the chaplain catches
visible_message("[src] smacks [owner] in the face as [owner.p_they()] try to catch it with [owner.p_their()] hands full!")
else if(possessed && soul)
transform = initial(transform)//to reset rotation for when it drops to the ground
- blade = new /mob/living/simple_animal/nullrod(get_turf(src))
- blade.sword = src
- blade.fully_replace_character_name(null, soul.name)
+ if(!blade)
+ blade = new(get_turf(src))
+ blade.sword = src
+ blade.fully_replace_character_name(null, soul.name)
forceMove(blade)//just hide it in here for now
- soul.mind.transfer_to(blade)
- walking = TRUE
+ if(soul?.mind)
+ soul.mind.transfer_to(blade)
else
. = ..()
@@ -1132,18 +1146,22 @@ it also swaps back if it gets thrown into the chaplain, but the chaplain catches
return ..()
/datum/action/cooldown/spell/recall_nullrod/cast(mob/living/carbon/user)
- if(sword)
- if(sword.walking)
- sword.blade.throw_at(user, 20, 3) //remember, sword is the item, blade is the mob
- else
- if(ismob(sword.loc))
- var/mob/holder = sword.loc //rip it out of the thief's hands first
- if(holder != user)
- to_chat(holder, "you feel [sword] ripped out of your hands by an unseen force.")
- holder.dropItemToGround(sword)
- sword.throw_at(user, 20, 3)
. = ..()
+ if(!sword)
+ return
+
+ if(sword.blade)
+ sword.blade.throw_at(user, 20, 3) //remember, sword is the item, blade is the mob
+ return
+ if(ismob(sword.loc))
+ var/mob/holder = sword.loc //rip it out of the thief's hands first
+ if(holder != user)
+ to_chat(holder, "you feel [sword] ripped out of your hands by an unseen force.")
+ holder.dropItemToGround(sword)
+ sword.throw_at(user, 20, 3)
+
+//the mob
/mob/living/simple_animal/nullrod
name = "Shade"
real_name = "Shade"
@@ -1187,9 +1205,9 @@ it also swaps back if it gets thrown into the chaplain, but the chaplain catches
/mob/living/simple_animal/nullrod/death()
if(sword)
visible_message("[src] lowers to the ground as it's power wanes!")
- mind.transfer_to(sword.soul)
+ if(mind)
+ mind.transfer_to(sword.soul)
sword.forceMove(get_turf(src))
- sword.walking = FALSE
qdel(src)
/mob/living/simple_animal/nullrod/canSuicide()
@@ -1199,8 +1217,8 @@ it also swaps back if it gets thrown into the chaplain, but the chaplain catches
if(!sword.owner || M != sword.owner)//let the chaplain pick it up in one hit
return ..()
sword.owner.put_in_active_hand(sword)
- mind.transfer_to(sword.soul)
- sword.walking = FALSE
+ if(mind)
+ mind.transfer_to(sword.soul)
visible_message("[sword.owner] grabs [src] by the hilt.")
qdel(src)
@@ -1210,8 +1228,8 @@ it also swaps back if it gets thrown into the chaplain, but the chaplain catches
var/mob/living/target = hit_atom
if(sword?.owner && target == sword.owner)
var/caught = sword.owner.put_in_hands(sword)
- mind.transfer_to(sword.soul)
- sword.walking = FALSE
+ if(mind)
+ mind.transfer_to(sword.soul)
qdel(src)
if(caught)
visible_message("[sword.owner] catches the flying blade out of the air!")
@@ -1336,6 +1354,10 @@ it also swaps back if it gets thrown into the chaplain, but the chaplain catches
menutab = MENU_MISC //banish it from being associated with proper weapons
additional_desc = "Hey, God here. Asking you to pick literally anything else as your implement of justice."
+/obj/item/nullrod/sord/Initialize(mapload)
+ . = ..()
+ AddComponent(/datum/component/cleave_attack) // i guess???
+
//NOT CHAPLAIN SPAWNABLE
/obj/item/nullrod/talking/chainsword
name = "possessed chainsaw sword"
diff --git a/code/game/objects/items/inducer.dm b/code/game/objects/items/inducer.dm
index 9db5e9347a2a..e59488570965 100644
--- a/code/game/objects/items/inducer.dm
+++ b/code/game/objects/items/inducer.dm
@@ -33,7 +33,7 @@
if(cell && !(. & EMP_PROTECT_CONTENTS))
cell.emp_act(severity)
-/obj/item/inducer/attack_obj(obj/O, mob/living/carbon/user)
+/obj/item/inducer/attack_atom(obj/O, mob/living/carbon/user)
if(user.a_intent == INTENT_HARM)
return ..()
diff --git a/code/game/objects/items/mail.dm b/code/game/objects/items/mail.dm
index 575d61c42ea0..167d5e56af85 100644
--- a/code/game/objects/items/mail.dm
+++ b/code/game/objects/items/mail.dm
@@ -148,13 +148,14 @@
recipient_ref = WEAKREF(recipient)
var/mob/living/body = recipient.current
- var/list/goodies = generic_goodies
+ var/list/goodies = generic_goodies.Copy()
var/datum/job/this_job = SSjob.GetJob(recipient.assigned_role)
if(this_job)
if(this_job.paycheck_department && department_colors[this_job.paycheck_department])
color = department_colors[this_job.paycheck_department]
var/list/job_goodies = this_job.get_mail_goodies()
+ job_goodies = job_goodies.Copy()
if(LAZYLEN(job_goodies))
// certain roles and jobs (prisoner) do not receive generic gifts.
if(this_job.exclusive_mail_goodies)
@@ -168,7 +169,7 @@
if(goodies[item] <= 0) //remove everything with a weight below 0
goodies -= item
- if(!goodies) //if everything was removed for some reason
+ if(!length(goodies)) //if everything was removed for some reason
return FALSE
for(var/iterator in 1 to goodie_count)
@@ -239,6 +240,8 @@
var/datum/job/this_job = SSjob.GetJob(human.mind.assigned_role)
if(!this_job || this_job.faction != "Station")
continue
+ if(is_synth(human))
+ continue
mail_recipients += human.mind
@@ -281,7 +284,7 @@
desc = "A bag for letters, envelopes, and other postage."
icon = 'icons/obj/library.dmi'
icon_state = "bookbag"
- //worn_icon_state = "bookbag"
+ worn_icon_state = "bookbag"
resistance_flags = FLAMMABLE
/obj/item/storage/bag/mail/Initialize(mapload)
@@ -377,4 +380,3 @@
debug_info += " - [initial(goodie.name)]: [goodie_weight] ([(goodie_weight / job_goodies_weight) * 100]%)\n"
to_chat(src, examine_block(debug_info))
-
diff --git a/code/game/objects/items/manuals.dm b/code/game/objects/items/manuals.dm
index 0b41e021e48e..b5f37de5e195 100644
--- a/code/game/objects/items/manuals.dm
+++ b/code/game/objects/items/manuals.dm
@@ -10,7 +10,7 @@
/obj/item/book/manual/ripley_build_and_repair
name = "APLU \"Ripley\" Construction and Operation Manual"
icon_state ="book"
- author = "Weyland-Yutani Corp"
+ author = "Sano-Waltfield Industries"
title = "APLU \"Ripley\" Construction and Operation Manual"
dat = {"
@@ -24,7 +24,7 @@