Name: [active1.fields["name"]] \
ID: [active1.fields["id"]] \n \
+ Entity Classification: [active1.fields["brain_type"]] \n \
Sex: [active1.fields["sex"]] \n"
if ((istype(src.active2, /datum/data/record) && data_core.medical.Find(src.active2)))
dat += "Gender identity: [active2.fields["id_gender"]] "
diff --git a/code/game/machinery/computer/prisoner.dm b/code/game/machinery/computer/prisoner.dm
index e8fe96ae6c..3d0235fab9 100644
--- a/code/game/machinery/computer/prisoner.dm
+++ b/code/game/machinery/computer/prisoner.dm
@@ -2,7 +2,6 @@
/obj/machinery/computer/prisoner
name = "prisoner management console"
- icon = 'icons/obj/computer.dmi'
icon_keyboard = "security_key"
icon_screen = "explosive"
light_color = "#a91515"
diff --git a/code/game/machinery/computer/prisonshuttle.dm b/code/game/machinery/computer/prisonshuttle.dm
index 1c54fb0f4c..8c435f5845 100644
--- a/code/game/machinery/computer/prisonshuttle.dm
+++ b/code/game/machinery/computer/prisonshuttle.dm
@@ -12,7 +12,6 @@ var/prison_shuttle_timeleft = 0
/obj/machinery/computer/prison_shuttle
name = "prison shuttle control console"
- icon = 'icons/obj/computer.dmi'
icon_keyboard = "security_key"
icon_screen = "syndishuttle"
light_color = "#00ffff"
diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm
index ca56ce168d..4d29a56b89 100644
--- a/code/game/machinery/computer/robot.dm
+++ b/code/game/machinery/computer/robot.dm
@@ -1,7 +1,6 @@
/obj/machinery/computer/robotics
name = "robotics control console"
desc = "Used to remotely lockdown or detonate linked cyborgs."
- icon = 'icons/obj/computer.dmi'
icon_keyboard = "tech_key"
icon_screen = "robot"
light_color = "#a97faa"
diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm
index 54c94d8684..465884b2ca 100644
--- a/code/game/machinery/computer/security.dm
+++ b/code/game/machinery/computer/security.dm
@@ -127,6 +127,7 @@
dat += text(" \
Name: [active1.fields["name"]] \
ID: [active1.fields["id"]] \n \
+ Entity Classification: [active1.fields["brain_type"]] \n \
Sex: [active1.fields["sex"]] \n \
Age: [active1.fields["age"]] \n \
Rank: [active1.fields["rank"]] \n \
@@ -612,5 +613,4 @@ What a mess.*/
..(severity)
/obj/machinery/computer/secure_data/detective_computer
- icon = 'icons/obj/computer.dmi'
icon_state = "messyfiles"
diff --git a/code/game/machinery/computer/skills.dm b/code/game/machinery/computer/skills.dm
index 1a67778fdf..bd9c66dbae 100644
--- a/code/game/machinery/computer/skills.dm
+++ b/code/game/machinery/computer/skills.dm
@@ -93,6 +93,7 @@
dat += text(" \
Name: [active1.fields["name"]] \
ID: [active1.fields["id"]] \n \
+ Entity Classification: [active1.fields["brain_type"]] \n \
Sex: [active1.fields["sex"]] \n \
Age: [active1.fields["age"]] \n \
Rank: [active1.fields["rank"]] \n \
diff --git a/code/game/machinery/computer/specops_shuttle.dm b/code/game/machinery/computer/specops_shuttle.dm
index cb0f8a5552..0a337f4df8 100644
--- a/code/game/machinery/computer/specops_shuttle.dm
+++ b/code/game/machinery/computer/specops_shuttle.dm
@@ -13,7 +13,6 @@ var/specops_shuttle_timeleft = 0
/obj/machinery/computer/specops_shuttle
name = "special operations shuttle control console"
- icon = 'icons/obj/computer.dmi'
icon_keyboard = "security_key"
icon_screen = "syndishuttle"
light_color = "#00ffff"
diff --git a/code/game/machinery/computer/supply.dm b/code/game/machinery/computer/supply.dm
index d390a7f163..4bcc43bbec 100644
--- a/code/game/machinery/computer/supply.dm
+++ b/code/game/machinery/computer/supply.dm
@@ -1,6 +1,5 @@
/obj/machinery/computer/supplycomp
name = "supply control console"
- icon = 'icons/obj/computer.dmi'
icon_keyboard = "tech_key"
icon_screen = "supply"
light_color = "#b88b2e"
@@ -13,7 +12,6 @@
/obj/machinery/computer/ordercomp
name = "supply ordering console"
- icon = 'icons/obj/computer.dmi'
icon_screen = "request"
circuit = /obj/item/weapon/circuitboard/ordercomp
var/temp = null
diff --git a/code/game/machinery/computer/syndicate_specops_shuttle.dm b/code/game/machinery/computer/syndicate_specops_shuttle.dm
index d36f03b525..ba7193b69b 100644
--- a/code/game/machinery/computer/syndicate_specops_shuttle.dm
+++ b/code/game/machinery/computer/syndicate_specops_shuttle.dm
@@ -12,7 +12,6 @@ var/syndicate_elite_shuttle_timeleft = 0
/obj/machinery/computer/syndicate_elite_shuttle
name = "elite syndicate squad shuttle control console"
- icon = 'icons/obj/computer.dmi'
icon_keyboard = "syndie_key"
icon_screen = "syndishuttle"
light_color = "#00ffff"
diff --git a/code/game/machinery/computer3/computers/medical.dm b/code/game/machinery/computer3/computers/medical.dm
index 57a662db46..bb4228397d 100644
--- a/code/game/machinery/computer3/computers/medical.dm
+++ b/code/game/machinery/computer3/computers/medical.dm
@@ -95,6 +95,7 @@
dat += "Name: [active1.fields["name"]] \
ID: [active1.fields["id"]] \n \
+ Entity Classification: [active1.fields["brain_type"]] \n \
Sex: [active1.fields["sex"]] \n \
Age: [active1.fields["age"]] \n \
Fingerprint: [active1.fields["fingerprint"]] \n \
diff --git a/code/game/machinery/computer3/computers/security.dm b/code/game/machinery/computer3/computers/security.dm
index a314bed273..6b77a274bf 100644
--- a/code/game/machinery/computer3/computers/security.dm
+++ b/code/game/machinery/computer3/computers/security.dm
@@ -134,6 +134,7 @@
dat += text(" \
Name: [active1.fields["name"]] \
ID: [active1.fields["id"]] \n \
+ Entity Classification: [active1.fields["brain_type"]] \n \
Sex: [active1.fields["sex"]] \n \
Age: [active1.fields["age"]] \n \
Rank: [active1.fields["rank"]] \n \
diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm
index d1ab11e706..5d0f707ae8 100644
--- a/code/game/machinery/cryo.dm
+++ b/code/game/machinery/cryo.dm
@@ -96,7 +96,7 @@
occupantData["name"] = occupant.name
occupantData["stat"] = occupant.stat
occupantData["health"] = occupant.health
- occupantData["maxHealth"] = occupant.maxHealth
+ occupantData["maxHealth"] = occupant.getMaxHealth()
occupantData["minHealth"] = config.health_threshold_dead
occupantData["bruteLoss"] = occupant.getBruteLoss()
occupantData["oxyLoss"] = occupant.getOxyLoss()
diff --git a/code/game/machinery/doors/blast_door.dm b/code/game/machinery/doors/blast_door.dm
index 209e3bb228..3d899377cc 100644
--- a/code/game/machinery/doors/blast_door.dm
+++ b/code/game/machinery/doors/blast_door.dm
@@ -12,6 +12,7 @@
desc = "That looks like it doesn't open easily."
icon = 'icons/obj/doors/rapid_pdoor.dmi'
icon_state = null
+ min_force = 20 //minimum amount of force needed to damage the door with a melee weapon
// Icon states for different shutter types. Simply change this instead of rewriting the update_icon proc.
var/icon_state_open = null
@@ -78,7 +79,10 @@
// Proc: force_toggle()
// Parameters: None
// Description: Opens or closes the door, depending on current state. No checks are done inside this proc.
-/obj/machinery/door/blast/proc/force_toggle()
+/obj/machinery/door/blast/proc/force_toggle(var/forced = 0, mob/user as mob)
+ if (forced)
+ playsound(src.loc, 'sound/machines/airlock_creaking.ogg', 100, 1)
+
if(src.density)
src.force_open()
else
@@ -91,7 +95,7 @@
/obj/machinery/door/blast/attackby(obj/item/weapon/C as obj, mob/user as mob)
src.add_fingerprint(user)
if(istype(C, /obj/item/weapon)) // For reasons unknown, sometimes C is actually not what it is advertised as, like a mob.
- if(C.pry == 1) // Can we pry it open with something, like a crowbar/fireaxe/lingblade?
+ if(C.pry == 1 && (user.a_intent != I_HURT || (stat & BROKEN))) // Can we pry it open with something, like a crowbar/fireaxe/lingblade?
if(istype(C,/obj/item/weapon/material/twohanded/fireaxe)) // Fireaxes need to be in both hands to pry.
var/obj/item/weapon/material/twohanded/fireaxe/F = C
if(!F.wielded)
@@ -100,7 +104,8 @@
// If we're at this point, it's a fireaxe in both hands or something else that doesn't care for twohanding.
if(((stat & NOPOWER) || (stat & BROKEN)) && !( src.operating ))
- force_toggle()
+ force_toggle(1, user)
+
else
usr << "[src]'s motors resist your effort."
return
@@ -123,15 +128,33 @@
usr << "You don't have enough sheets to repair this! You need at least [amt] sheets."
+ else if(src.density)
+ var/obj/item/weapon/W = C
+ user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
+ if(W.damtype == BRUTE || W.damtype == BURN)
+ user.do_attack_animation(src)
+ if(W.force < min_force)
+ user.visible_message("\The [user] hits \the [src] with \the [W] with no visible effect.")
+ else
+ user.visible_message("\The [user] forcefully strikes \the [src] with \the [W]!")
+ playsound(src.loc, hitsound, 100, 1)
+ take_damage(W.force*0.35) //it's a blast door, it should take a while. -Luke
+ return
+
// Proc: open()
// Parameters: None
// Description: Opens the door. Does necessary checks. Automatically closes if autoclose is true
-/obj/machinery/door/blast/open()
- if (src.operating || (stat & BROKEN || stat & NOPOWER))
- return
- force_open()
- if(autoclose)
+/obj/machinery/door/blast/open(var/forced = 0)
+ if(forced)
+ force_open()
+ return 1
+ else
+ if (src.operating || (stat & BROKEN || stat & NOPOWER))
+ return 1
+ force_open()
+
+ if(autoclose && src.operating && !(stat & BROKEN || stat & NOPOWER))
spawn(150)
close()
return 1
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index dd8e868d8a..0f4d541b6d 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -314,6 +314,8 @@
/obj/machinery/door/examine(mob/user)
. = ..()
+ if(src.health <= 0)
+ user << "\The [src] is broken!"
if(src.health < src.maxhealth / 4)
user << "\The [src] looks like it's about to break!"
else if(src.health < src.maxhealth / 2)
diff --git a/code/game/machinery/kitchen/smartfridge.dm b/code/game/machinery/kitchen/smartfridge.dm
index ae48142b4d..a18edbc5fa 100644
--- a/code/game/machinery/kitchen/smartfridge.dm
+++ b/code/game/machinery/kitchen/smartfridge.dm
@@ -78,7 +78,7 @@
C.traits = new()
C.nameVar = "grey"
I.add_product(C)
-
+
/obj/machinery/smartfridge/secure/medbay
name = "\improper Refrigerated Medicine Storage"
@@ -139,6 +139,7 @@
icon_state = "drying_rack"
icon_on = "drying_rack_on"
icon_off = "drying_rack"
+ icon_panel = "drying_rack-panel"
/obj/machinery/smartfridge/drying_rack/accept_check(var/obj/item/O as obj)
if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/))
@@ -260,7 +261,7 @@
locked = -1
user << "You short out the product lock on [src]."
return 1
-
+
/obj/machinery/smartfridge/proc/stock(obj/item/O)
var/hasRecord = FALSE //Check to see if this passes or not.
for(var/datum/stored_item/I in item_records)
@@ -273,7 +274,7 @@
item.add_product(O)
item_records.Add(item)
nanomanager.update_uis(src)
-
+
/obj/machinery/smartfridge/proc/vend(datum/stored_item/I)
I.get_product(get_turf(src))
nanomanager.update_uis(src)
@@ -357,7 +358,7 @@
if (!throw_item)
continue
break
-
+
if(!throw_item)
return 0
spawn(0)
diff --git a/code/game/mecha/mecha_control_console.dm b/code/game/mecha/mecha_control_console.dm
index a6da9bfa00..00a0654cc1 100644
--- a/code/game/mecha/mecha_control_console.dm
+++ b/code/game/mecha/mecha_control_console.dm
@@ -1,6 +1,5 @@
/obj/machinery/computer/mecha
name = "Exosuit Control"
- icon = 'icons/obj/computer.dmi'
icon_keyboard = "rd_key"
icon_screen = "mecha"
light_color = "#a97faa"
diff --git a/code/game/mecha/medical/odysseus.dm b/code/game/mecha/medical/odysseus.dm
index 967c03252f..6aec830c89 100644
--- a/code/game/mecha/medical/odysseus.dm
+++ b/code/game/mecha/medical/odysseus.dm
@@ -95,7 +95,7 @@
holder.icon_state = "hudhealth-100"
C.images += holder
else
- holder.icon_state = RoundHealth((patient.health-config.health_threshold_crit)/(patient.maxHealth-config.health_threshold_crit)*100)
+ holder.icon_state = RoundHealth((patient.health-config.health_threshold_crit)/(patient.getMaxHealth()-config.health_threshold_crit)*100)
C.images += holder
holder = patient.hud_list[STATUS_HUD]
diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm
index 7950200137..f456a95d73 100644
--- a/code/game/objects/buckling.dm
+++ b/code/game/objects/buckling.dm
@@ -74,7 +74,12 @@
add_fingerprint(user)
unbuckle_mob()
- if(buckle_mob(M))
+ //can't buckle unless you share locs so try to move M to the obj.
+ if(M.loc != src.loc)
+ step_towards(M, src)
+
+ . = buckle_mob(M)
+ if(.)
if(M == user)
M.visible_message(\
"[M.name] buckles themselves to [src].",\
diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm
index 1450fa94ce..b4ba67e4c2 100644
--- a/code/game/objects/items/bodybag.dm
+++ b/code/game/objects/items/bodybag.dm
@@ -86,6 +86,12 @@
qdel(src)
return
+/obj/structure/closet/body_bag/relaymove(mob/user,direction)
+ if(src.loc != get_turf(src))
+ src.loc.relaymove(user,direction)
+ else
+ ..()
+
/obj/structure/closet/body_bag/proc/get_occupants()
var/list/occupants = list()
for(var/mob/living/carbon/human/H in contents)
diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm
index d1a5b63e82..632f9afdfd 100644
--- a/code/game/objects/items/devices/flash.dm
+++ b/code/game/objects/items/devices/flash.dm
@@ -92,8 +92,8 @@
flash_strength *= H.species.flash_mod
if(flash_strength > 0)
- H.confused = max(H.confused, flash_strength + 5)
- H.eye_blind = max(H.eye_blind, flash_strength)
+ H.Confuse(flash_strength + 5)
+ H.Blind(flash_strength)
H.eye_blurry = max(H.eye_blurry, flash_strength + 5)
H.flash_eyes()
H.adjustHalLoss(halloss_per_flash * (flash_strength / 5)) // Should take four flashes to stun.
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index 1bd7f9349a..74d9a4b8ed 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -65,10 +65,12 @@ var/global/list/default_medbay_channels = list(
..()
wires = new(src)
internal_channels = default_internal_channels.Copy()
+ listening_objects += src
/obj/item/device/radio/Destroy()
qdel(wires)
wires = null
+ listening_objects -= src
if(radio_controller)
radio_controller.remove_object(src, frequency)
for (var/ch_name in channels)
@@ -474,7 +476,6 @@ var/global/list/default_medbay_channels = list(
/obj/item/device/radio/hear_talk(mob/M as mob, msg, var/verb = "says", var/datum/language/speaking = null)
-
if (broadcasting)
if(get_dist(src, M) <= canhear_range)
talk_into(M, msg,null,verb,speaking)
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 243d301289..5d883784aa 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -69,7 +69,7 @@ REAGENT SCANNER
user.show_message("Analyzing Results for [M]:")
user.show_message("Overall Status: dead")
else
- user.show_message("Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "dead" : "[round((M.health/M.maxHealth)*100) ]% healthy"]")
+ user.show_message("Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "dead" : "[round((M.health/M.getMaxHealth())*100) ]% healthy"]")
user.show_message(" Key: Suffocation/Toxin/Burns/Brute", 1)
user.show_message(" Damage Specifics: [OX] - [TX] - [BU] - [BR]")
user.show_message("Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1)
diff --git a/code/game/objects/items/weapons/RSF.dm b/code/game/objects/items/weapons/RSF.dm
index 10a847b469..d404b5cd44 100644
--- a/code/game/objects/items/weapons/RSF.dm
+++ b/code/game/objects/items/weapons/RSF.dm
@@ -39,7 +39,7 @@ RSF
playsound(src.loc, 'sound/effects/pop.ogg', 50, 0)
if (mode == 1)
mode = 2
- user << "Changed dispensing mode to 'Drinking Glass'"
+ user << "Changed dispensing mode to 'Drinking Glass:Pint'"
return
if (mode == 2)
mode = 3
@@ -82,7 +82,7 @@ RSF
product = new /obj/item/clothing/mask/smokable/cigarette()
used_energy = 10
if(2)
- product = new /obj/item/weapon/reagent_containers/food/drinks/glass2()
+ product = new /obj/item/weapon/reagent_containers/food/drinks/glass2/pint()
used_energy = 50
if(3)
product = new /obj/item/weapon/paper()
diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm
index 76c4f9e768..ee2d2f2c57 100644
--- a/code/game/objects/items/weapons/cigs_lighters.dm
+++ b/code/game/objects/items/weapons/cigs_lighters.dm
@@ -399,21 +399,6 @@ CIGARETTE PACKETS ARE IN FANCY.DM
..()
name = "empty [initial(name)]"
-/obj/item/clothing/mask/smokable/pipe/light(var/flavor_text = "[usr] lights the [name].")
- if(!src.lit && src.smoketime)
- src.lit = 1
- damtype = "fire"
- icon_state = icon_on
- item_state = icon_on
- var/turf/T = get_turf(src)
- T.visible_message(flavor_text)
- processing_objects.Add(src)
- if(ismob(loc))
- var/mob/living/M = loc
- M.update_inv_wear_mask(0)
- M.update_inv_l_hand(0)
- M.update_inv_r_hand(1)
-
/obj/item/clothing/mask/smokable/pipe/attack_self(mob/user as mob)
if(lit == 1)
if(user.a_intent == I_HURT)
diff --git a/code/game/objects/items/weapons/implants/implantcircuits.dm b/code/game/objects/items/weapons/implants/implantcircuits.dm
index cf55cbd706..db24be3c0a 100644
--- a/code/game/objects/items/weapons/implants/implantcircuits.dm
+++ b/code/game/objects/items/weapons/implants/implantcircuits.dm
@@ -38,7 +38,10 @@
IC.examine(user)
/obj/item/weapon/implant/integrated_circuit/attackby(var/obj/item/O, var/mob/user)
- if(istype(O, /obj/item/weapon/crowbar) || istype(O, /obj/item/device/integrated_electronics) || istype(O, /obj/item/integrated_circuit) || istype(O, /obj/item/weapon/screwdriver) )
+ if(istype(O, /obj/item/weapon/crowbar) || istype(O, /obj/item/device/integrated_electronics) || istype(O, /obj/item/integrated_circuit) || istype(O, /obj/item/weapon/screwdriver) || istype(O, /obj/item/weapon/cell/device) )
IC.attackby(O, user)
else
- ..()
\ No newline at end of file
+ ..()
+
+/obj/item/weapon/implant/integrated_circuit/attack_self(mob/user)
+ IC.attack_self(user)
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/material/material_armor.dm b/code/game/objects/items/weapons/material/material_armor.dm
new file mode 100644
index 0000000000..1041fb5d1f
--- /dev/null
+++ b/code/game/objects/items/weapons/material/material_armor.dm
@@ -0,0 +1,263 @@
+#define MATERIAL_ARMOR_COEFFICENT 0.05
+/*
+SEE code/modules/materials/materials.dm FOR DETAILS ON INHERITED DATUM.
+This class of armor takes armor and appearance data from a material "datum".
+They are also fragile based on material data and many can break/smash apart when hit.
+
+Materials has a var called protectiveness which plays a major factor in how good it is for armor.
+With the coefficent being 0.05, this is how strong different levels of protectiveness are (for melee)
+For bullets and lasers, material hardness and reflectivity also play a major role, respectively.
+
+
+Protectiveness | Armor %
+ 0 = 0%
+ 5 = 20%
+ 10 = 33%
+ 15 = 42%
+ 20 = 50%
+ 25 = 55%
+ 30 = 60%
+ 40 = 66%
+ 50 = 71%
+ 60 = 75%
+ 70 = 77%
+ 80 = 80%
+*/
+
+
+// Putting these at /clothing/ level saves a lot of code duplication in armor/helmets/gauntlets/etc
+/obj/item/clothing
+ var/material/material = null // Why isn't this a datum?
+ var/applies_material_color = TRUE
+ var/unbreakable = FALSE
+ var/default_material = null // Set this to something else if you want material attributes on init.
+ var/material_armor_modifer = 1 // Adjust if you want seperate types of armor made from the same material to have different protectiveness (e.g. makeshift vs real armor)
+
+/obj/item/clothing/New(var/newloc, var/material_key)
+ ..(newloc)
+ if(!material_key)
+ material_key = default_material
+ if(material_key) // May still be null if a material was not specified as a default.
+ set_material(material_key)
+
+/obj/item/clothing/Destroy()
+ processing_objects -= src
+ ..()
+
+/obj/item/clothing/get_material()
+ return material
+
+// Debating if this should be made an /obj/item/ proc.
+/obj/item/clothing/proc/set_material(var/new_material)
+ material = get_material_by_name(new_material)
+ if(!material)
+ qdel(src)
+ else
+ name = "[material.display_name] [initial(name)]"
+ health = round(material.integrity/10)
+ if(applies_material_color)
+ color = material.icon_colour
+ if(material.products_need_process())
+ processing_objects |= src
+ update_armor()
+
+// This is called when someone wearing the object gets hit in some form (melee, bullet_act(), etc).
+// Note that this cannot change if someone gets hurt, as it merely reacts to being hit.
+/obj/item/clothing/proc/clothing_impact(var/obj/source, var/damage)
+ if(material && damage)
+ material_impact(source, damage)
+
+/obj/item/clothing/proc/material_impact(var/obj/source, var/damage)
+ if(!material || unbreakable)
+ return
+
+ if(istype(source, /obj/item/projectile))
+ var/obj/item/projectile/P = source
+ if(P.pass_flags & PASSGLASS)
+ if(material.opacity - 0.3 <= 0)
+ return // Lasers ignore 'fully' transparent material.
+
+ if(material.is_brittle())
+ health = 0
+ else if(!prob(material.hardness))
+ health--
+
+ if(health <= 0)
+ shatter()
+
+/obj/item/clothing/proc/shatter()
+ if(!material)
+ return
+ var/turf/T = get_turf(src)
+ T.visible_message("\The [src] [material.destruction_desc]!")
+ if(istype(loc, /mob/living))
+ var/mob/living/M = loc
+ M.drop_from_inventory(src)
+ if(material.shard_type == SHARD_SHARD) // Wearing glass armor is a bad idea.
+ var/obj/item/weapon/material/shard/S = material.place_shard(T)
+ M.embed(S)
+
+ playsound(src, "shatter", 70, 1)
+ qdel(src)
+
+// Might be best to make ablative vests a material armor using a new material to cut down on this copypaste.
+/obj/item/clothing/suit/armor/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
+ if(!material) // No point checking for reflection.
+ return ..()
+
+ if(material.reflectivity)
+ if(istype(damage_source, /obj/item/projectile/energy) || istype(damage_source, /obj/item/projectile/beam))
+ var/obj/item/projectile/P = damage_source
+
+ if(P.reflected) // Can't reflect twice
+ return ..()
+
+ var/reflectchance = (40 * material.reflectivity) - round(damage/3)
+ reflectchance *= material_armor_modifer
+ if(!(def_zone in list(BP_TORSO, BP_GROIN)))
+ reflectchance /= 2
+ if(P.starting && prob(reflectchance))
+ visible_message("\The [user]'s [src.name] reflects [attack_text]!")
+
+ // Find a turf near or on the original location to bounce to
+ var/new_x = P.starting.x + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
+ var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
+ var/turf/curloc = get_turf(user)
+
+ // redirect the projectile
+ P.redirect(new_x, new_y, curloc, user)
+ P.reflected = 1
+
+ return PROJECTILE_CONTINUE // complete projectile permutation
+
+/proc/calculate_material_armor(amount)
+ var/result = 1 - MATERIAL_ARMOR_COEFFICENT * amount / (1 + MATERIAL_ARMOR_COEFFICENT * abs(amount))
+ result = result * 100
+ result = abs(result - 100)
+ return round(result)
+
+
+/obj/item/clothing/proc/update_armor()
+ if(material)
+ var/melee_armor = 0, bullet_armor = 0, laser_armor = 0, energy_armor = 0, bomb_armor = 0
+
+ melee_armor = calculate_material_armor(material.protectiveness * material_armor_modifer)
+
+ bullet_armor = calculate_material_armor((material.protectiveness * (material.hardness / 100) * material_armor_modifer) * 0.7)
+
+ laser_armor = calculate_material_armor((material.protectiveness * (material.reflectivity + 1) * material_armor_modifer) * 0.7)
+ if(material.opacity != 1)
+ laser_armor *= max(material.opacity - 0.3, 0) // Glass and such has an opacity of 0.3, but lasers should go through glass armor entirely.
+
+ energy_armor = calculate_material_armor((material.protectiveness * material_armor_modifer) * 0.4)
+
+ bomb_armor = calculate_material_armor((material.protectiveness * material_armor_modifer) * 0.5)
+
+ // Makes sure the numbers stay capped.
+ for(var/number in list(melee_armor, bullet_armor, laser_armor, energy_armor, bomb_armor))
+ number = between(0, number, 100)
+
+ armor["melee"] = melee_armor
+ armor["bullet"] = bullet_armor
+ armor["laser"] = laser_armor
+ armor["energy"] = energy_armor
+ armor["bomb"] = bomb_armor
+
+ if(!isnull(material.conductivity))
+ siemens_coefficient = between(0, material.conductivity / 10, 10)
+ slowdown = between(0, round(material.weight / 10, 0.1), 6)
+
+/obj/item/clothing/suit/armor/material
+ name = "armor"
+ default_material = DEFAULT_WALL_MATERIAL
+
+/obj/item/clothing/suit/armor/material/makeshift
+ name = "sheet armor"
+ desc = "This appears to be two 'sheets' of a material held together by cable. If the sheets are strong, this could be rather protective."
+ icon_state = "material_armor_makeshift"
+
+/obj/item/clothing/suit/armor/material/makeshift/durasteel
+ default_material = "durasteel"
+
+/obj/item/clothing/suit/armor/material/makeshift/glass
+ default_material = "glass"
+
+// Used to craft sheet armor, and possibly other things in the Future(tm).
+/obj/item/weapon/material/armor_plating
+ name = "armor plating"
+ desc = "A sheet designed to protect something."
+ icon = 'icons/obj/items.dmi'
+ icon_state = "armor_plate"
+ unbreakable = TRUE
+ force_divisor = 0.05 // Really bad as a weapon.
+ thrown_force_divisor = 0.2
+ var/wired = FALSE
+
+/obj/item/weapon/material/armor_plating/attackby(var/obj/O, mob/user)
+ if(istype(O, /obj/item/stack/cable_coil))
+ var/obj/item/stack/cable_coil/S = O
+ if(wired)
+ to_chat(user, "This already has enough wires on it.")
+ return
+ if(S.use(20))
+ to_chat(user, "You attach several wires to \the [src]. Now it needs another plate.")
+ wired = TRUE
+ icon_state = "[initial(icon_state)]_wired"
+ return
+ else
+ to_chat(user, "You need more wire for that.")
+ return
+ if(istype(O, /obj/item/weapon/material/armor_plating))
+ var/obj/item/weapon/material/armor_plating/second_plate = O
+ if(!wired && !second_plate.wired)
+ to_chat(user, "You need something to hold the two pieces of plating together.")
+ return
+ if(second_plate.material != src.material)
+ to_chat(user, "Both plates need to be the same type of material.")
+ return
+ user.drop_from_inventory(src)
+ user.drop_from_inventory(second_plate)
+ var/obj/item/clothing/suit/armor/material/makeshift/new_armor = new(null, src.material.name)
+ user.put_in_hands(new_armor)
+ qdel(second_plate)
+ qdel(src)
+ else
+ ..()
+
+
+// Used to craft the makeshift helmet
+/obj/item/clothing/head/helmet/bucket
+ name = "bucket"
+ desc = "It's a bucket with a large hole cut into it. You could wear it on your head and look really stupid."
+ flags_inv = HIDEEARS|HIDEEYES|BLOCKHAIR
+ icon_state = "bucket"
+ armor = list(melee = 5, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0)
+
+/obj/item/clothing/head/helmet/bucket/attackby(var/obj/O, mob/user)
+ if(istype(O, /obj/item/stack/material))
+ var/obj/item/stack/material/S = O
+ if(S.use(2))
+ to_chat(user, "You apply some [S.material.use_name] to \the [src]. Hopefully it'll make the makeshift helmet stronger.")
+ var/obj/item/clothing/head/helmet/material/makeshift/helmet = new(null, S.material.name)
+ user.put_in_hands(helmet)
+ user.drop_from_inventory(src)
+ qdel(src)
+ return
+ else
+ to_chat(user, "You don't have enough material to build a helmet!")
+ else
+ ..()
+
+/obj/item/clothing/head/helmet/material
+ name = "helmet"
+ flags_inv = HIDEEARS|HIDEEYES|BLOCKHAIR
+ default_material = DEFAULT_WALL_MATERIAL
+
+/obj/item/clothing/head/helmet/material/makeshift
+ name = "bucket"
+ desc = "A bucket with plating applied to the outside. Very crude, but could potentially be rather protective, if \
+ it was plated with something strong."
+ icon_state = "material_armor_makeshift"
+
+/obj/item/clothing/head/helmet/material/makeshift/durasteel
+ default_material = "durasteel"
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/permits.dm b/code/game/objects/items/weapons/permits.dm
index bb0ebfdd0c..8008959460 100644
--- a/code/game/objects/items/weapons/permits.dm
+++ b/code/game/objects/items/weapons/permits.dm
@@ -32,4 +32,9 @@
/obj/item/weapon/permit/gun/bar
name = "bar shotgun permit"
- desc = "A card indicating that the owner is allowed to carry a shotgun in the bar."
\ No newline at end of file
+ desc = "A card indicating that the owner is allowed to carry a shotgun in the bar."
+
+/obj/item/weapon/permit/drone
+ name = "drone identification card"
+ desc = "A card issued by the EIO, indicating that the owner is a Drone Intelligence. Drones are mandated to carry this card within SolGov space, by law."
+ icon_state = "drone"
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/policetape.dm b/code/game/objects/items/weapons/policetape.dm
index a9f2a15dea..9b4cb3ca9b 100644
--- a/code/game/objects/items/weapons/policetape.dm
+++ b/code/game/objects/items/weapons/policetape.dm
@@ -2,12 +2,12 @@
/obj/item/taperoll
name = "tape roll"
icon = 'icons/policetape.dmi'
- icon_state = "rollstart"
+ icon_state = "tape"
w_class = ITEMSIZE_SMALL
var/turf/start
var/turf/end
var/tape_type = /obj/item/tape
- var/icon_base
+ var/icon_base = "tape"
var/apply_tape = FALSE
@@ -33,7 +33,7 @@ var/list/tape_roll_applications = list()
var/lifted = 0
var/crumpled = 0
var/tape_dir = 0
- var/icon_base
+ var/icon_base = "tape"
/obj/item/tape/update_icon()
//Possible directional bitflags: 0 (AIRLOCK), 1 (NORTH), 2 (SOUTH), 4 (EAST), 8 (WEST), 3 (VERTICAL), 12 (HORIZONTAL)
@@ -60,22 +60,20 @@ var/list/tape_roll_applications = list()
/obj/item/taperoll/police
name = "police tape"
desc = "A roll of police tape used to block off crime scenes from the public."
- icon_state = "police"
tape_type = /obj/item/tape/police
- icon_base = "police"
+ color = COLOR_RED_LIGHT
/obj/item/tape/police
name = "police tape"
desc = "A length of police tape. Do not cross."
req_access = list(access_security)
- icon_base = "police"
+ color = COLOR_RED_LIGHT
/obj/item/taperoll/engineering
name = "engineering tape"
desc = "A roll of engineering tape used to block off working areas from the public."
- icon_state = "engineering"
tape_type = /obj/item/tape/engineering
- icon_base = "engineering"
+ color = COLOR_YELLOW
/obj/item/taperoll/engineering/applied
apply_tape = TRUE
@@ -84,28 +82,31 @@ var/list/tape_roll_applications = list()
name = "engineering tape"
desc = "A length of engineering tape. Better not cross it."
req_one_access = list(access_engine,access_atmospherics)
- icon_base = "engineering"
+ color = COLOR_YELLOW
/obj/item/taperoll/atmos
name = "atmospherics tape"
desc = "A roll of atmospherics tape used to block off working areas from the public."
- icon_state = "atmos"
tape_type = /obj/item/tape/atmos
- icon_base = "atmos"
+ color = COLOR_DEEP_SKY_BLUE
/obj/item/tape/atmos
name = "atmospherics tape"
desc = "A length of atmospherics tape. Better not cross it."
req_one_access = list(access_engine,access_atmospherics)
- icon_base = "atmos"
+ color = COLOR_DEEP_SKY_BLUE
/obj/item/taperoll/update_icon()
overlays.Cut()
+ var/image/overlay = image(icon = src.icon)
+ overlay.appearance_flags = RESET_COLOR
if(ismob(loc))
if(!start)
- overlays += "start"
+ overlay.icon_state = "start"
else
- overlays += "stop"
+ overlay.icon_state = "stop"
+ overlays += overlay
+
/obj/item/taperoll/dropped(mob/user)
update_icon()
diff --git a/code/game/objects/items/weapons/tape.dm b/code/game/objects/items/weapons/tape.dm
index b6fc2f4251..04e5aa909b 100644
--- a/code/game/objects/items/weapons/tape.dm
+++ b/code/game/objects/items/weapons/tape.dm
@@ -163,6 +163,15 @@
overlays = null
qdel(src)
+/obj/item/weapon/ducttape/attackby(var/obj/item/I, var/mob/user)
+ if(!(istype(src, /obj/item/weapon/handcuffs/cable/tape) || istype(src, /obj/item/clothing/mask/muzzle/tape)))
+ return ..()
+ else
+ user.drop_from_inventory(I)
+ I.loc = src
+ qdel(I)
+ to_chat(user, "You place \the [I] back into \the [src].")
+
/obj/item/weapon/ducttape/afterattack(var/A, mob/user, flag, params)
if(!in_range(user, A) || istype(A, /obj/machinery/door) || !stuck)
diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm
index 1080e1b8fb..8c4067187f 100644
--- a/code/game/objects/items/weapons/tools.dm
+++ b/code/game/objects/items/weapons/tools.dm
@@ -401,7 +401,7 @@
user.sdisabilities |= BLIND
else if (E.damage >= E.min_bruised_damage)
user << "You go blind!"
- user.eye_blind = 5
+ user.Blind(5)
user.eye_blurry = 5
user.disabilities |= NEARSIGHTED
spawn(100)
diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm
index eb6e2c2a77..34fb77f9f0 100644
--- a/code/game/objects/structures/morgue.dm
+++ b/code/game/objects/structures/morgue.dm
@@ -77,34 +77,44 @@
return
return
+
/obj/structure/morgue/attack_hand(mob/user as mob)
if (src.connected)
- for(var/atom/movable/A as mob|obj in src.connected.loc)
- if (!( A.anchored ))
- A.forceMove(src)
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
- qdel(src.connected)
- src.connected = null
+ close()
else
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
- src.connected = new /obj/structure/m_tray( src.loc )
- step(src.connected, src.dir)
- src.connected.layer = OBJ_LAYER
- var/turf/T = get_step(src, src.dir)
- if (T.contents.Find(src.connected))
- src.connected.connected = src
- src.icon_state = "morgue0"
- for(var/atom/movable/A as mob|obj in src)
- A.forceMove(src.connected.loc)
- src.connected.icon_state = "morguet"
- src.connected.set_dir(src.dir)
- else
- qdel(src.connected)
- src.connected = null
+ open()
src.add_fingerprint(user)
update()
return
+
+/obj/structure/morgue/proc/close()
+ for(var/atom/movable/A as mob|obj in src.connected.loc)
+ if (!( A.anchored ))
+ A.forceMove(src)
+ playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ qdel(src.connected)
+ src.connected = null
+
+
+/obj/structure/morgue/proc/open()
+ playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
+ src.connected = new /obj/structure/m_tray( src.loc )
+ step(src.connected, src.dir)
+ src.connected.layer = OBJ_LAYER
+ var/turf/T = get_step(src, src.dir)
+ if (T.contents.Find(src.connected))
+ src.connected.connected = src
+ src.icon_state = "morgue0"
+ for(var/atom/movable/A as mob|obj in src)
+ A.forceMove(src.connected.loc)
+ src.connected.icon_state = "morguet"
+ src.connected.set_dir(src.dir)
+ else
+ qdel(src.connected)
+ src.connected = null
+
+
/obj/structure/morgue/attackby(P as obj, mob/user as mob)
if (istype(P, /obj/item/weapon/pen))
var/t = input(user, "What would you like the label to be?", text("[]", src.name), null) as text
@@ -123,21 +133,8 @@
/obj/structure/morgue/relaymove(mob/user as mob)
if (user.stat)
return
- src.connected = new /obj/structure/m_tray( src.loc )
- step(src.connected, EAST)
- src.connected.layer = OBJ_LAYER
- var/turf/T = get_step(src, EAST)
- if (T.contents.Find(src.connected))
- src.connected.connected = src
- src.icon_state = "morgue0"
- for(var/atom/movable/A as mob|obj in src)
- A.forceMove(src.connected.loc)
- src.connected.icon_state = "morguet"
- else
- qdel(src.connected)
- src.connected = null
- return
-
+ if (user in src.occupants)
+ open()
/*
* Morgue tray
diff --git a/code/game/turfs/flooring/flooring.dm b/code/game/turfs/flooring/flooring.dm
index 779f76fc93..2170ea3019 100644
--- a/code/game/turfs/flooring/flooring.dm
+++ b/code/game/turfs/flooring/flooring.dm
@@ -37,6 +37,7 @@ var/list/flooring_types
var/descriptor = "tiles"
var/flags
var/can_paint
+ var/list/footstep_sounds = list() // key=species name, value = list of soundss
/decl/flooring/grass
name = "grass"
@@ -90,6 +91,12 @@ var/list/flooring_types
build_type = /obj/item/stack/tile/carpet
damage_temperature = T0C+200
flags = TURF_HAS_EDGES | TURF_HAS_CORNERS | TURF_REMOVE_CROWBAR | TURF_CAN_BURN
+ footstep_sounds = list("human" = list(
+ 'sound/effects/footstep/carpet1.ogg',
+ 'sound/effects/footstep/carpet2.ogg',
+ 'sound/effects/footstep/carpet3.ogg',
+ 'sound/effects/footstep/carpet4.ogg',
+ 'sound/effects/footstep/carpet5.ogg'))
/decl/flooring/carpet/blue
name = "carpet"
@@ -107,6 +114,12 @@ var/list/flooring_types
flags = TURF_REMOVE_CROWBAR | TURF_CAN_BREAK | TURF_CAN_BURN
build_type = /obj/item/stack/tile/floor
can_paint = 1
+ footstep_sounds = list("human" = list(
+ 'sound/effects/footstep/floor1.ogg',
+ 'sound/effects/footstep/floor2.ogg',
+ 'sound/effects/footstep/floor3.ogg',
+ 'sound/effects/footstep/floor4.ogg',
+ 'sound/effects/footstep/floor5.ogg'))
/decl/flooring/linoleum
name = "linoleum"
@@ -193,6 +206,12 @@ var/list/flooring_types
descriptor = "planks"
build_type = /obj/item/stack/tile/wood
flags = TURF_CAN_BREAK | TURF_IS_FRAGILE | TURF_REMOVE_SCREWDRIVER
+ footstep_sounds = list("human" = list(
+ 'sound/effects/footstep/wood1.ogg',
+ 'sound/effects/footstep/wood2.ogg',
+ 'sound/effects/footstep/wood3.ogg',
+ 'sound/effects/footstep/wood4.ogg',
+ 'sound/effects/footstep/wood5.ogg'))
/decl/flooring/reinforced
name = "reinforced floor"
diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm
index 3a7c1afdf0..336a34b2fe 100644
--- a/code/game/turfs/simulated/floor.dm
+++ b/code/game/turfs/simulated/floor.dm
@@ -13,6 +13,12 @@
var/base_desc = "The naked hull."
var/base_icon = 'icons/turf/flooring/plating.dmi'
var/base_icon_state = "plating"
+ var/static/list/base_footstep_sounds = list("human" = list(
+ 'sound/effects/footstep/plating1.ogg',
+ 'sound/effects/footstep/plating2.ogg',
+ 'sound/effects/footstep/plating3.ogg',
+ 'sound/effects/footstep/plating4.ogg',
+ 'sound/effects/footstep/plating5.ogg'))
// Flooring data.
var/flooring_override
@@ -33,10 +39,13 @@
floortype = initial_flooring
if(floortype)
set_flooring(get_flooring_data(floortype))
+ else
+ footstep_sounds = base_footstep_sounds
/turf/simulated/floor/proc/set_flooring(var/decl/flooring/newflooring)
make_plating(defer_icon_update = 1)
flooring = newflooring
+ footstep_sounds = newflooring.footstep_sounds
update_icon(1)
levelupdate()
@@ -53,6 +62,7 @@
desc = base_desc
icon = base_icon
icon_state = base_icon_state
+ footstep_sounds = base_footstep_sounds
if(flooring)
if(flooring.build_type && place_product)
diff --git a/code/game/turfs/simulated/outdoors/outdoors.dm b/code/game/turfs/simulated/outdoors/outdoors.dm
index da69406157..75c7e68083 100644
--- a/code/game/turfs/simulated/outdoors/outdoors.dm
+++ b/code/game/turfs/simulated/outdoors/outdoors.dm
@@ -31,17 +31,19 @@ var/list/outdoor_turfs = list()
/turf/simulated/floor/Destroy()
if(outdoors)
- outdoor_turfs.Remove(src)
+ planet_controller.unallocateTurf(src)
..()
-/turf/simulated/floor/proc/update_icon_edge()
+/turf/simulated/proc/update_icon_edge()
if(edge_blending_priority)
for(var/checkdir in cardinal)
var/turf/simulated/T = get_step(src, checkdir)
if(istype(T) && T.edge_blending_priority && edge_blending_priority < T.edge_blending_priority && icon_state != T.icon_state)
var/cache_key = "[T.get_edge_icon_state()]-[checkdir]"
if(!turf_edge_cache[cache_key])
- turf_edge_cache[cache_key] = image(icon = 'icons/turf/outdoors_edge.dmi', icon_state = "[T.get_edge_icon_state()]-edge", dir = checkdir)
+ var/image/I = image(icon = 'icons/turf/outdoors_edge.dmi', icon_state = "[T.get_edge_icon_state()]-edge", dir = checkdir)
+ I.plane = 0
+ turf_edge_cache[cache_key] = I
overlays += turf_edge_cache[cache_key]
/turf/simulated/proc/get_edge_icon_state()
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 028223ef26..3f2e0064f2 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -26,6 +26,8 @@
var/movement_cost = 0 // How much the turf slows down movement, if any.
+ var/list/footstep_sounds = null
+
/turf/New()
..()
for(var/atom/movable/AM as mob|obj in src)
@@ -145,6 +147,9 @@ var/const/enterloopsanity = 100
else if(!is_space())
M.inertia_dir = 0
M.make_floating(0)
+ if(isliving(M))
+ var/mob/living/L = M
+ L.handle_footstep(src)
..()
var/objects = 0
if(A && (A.flags & PROXMOVE))
diff --git a/code/game/turfs/unsimulated/planetary.dm b/code/game/turfs/unsimulated/planetary.dm
index ce4ffa44c0..7d9159d04a 100644
--- a/code/game/turfs/unsimulated/planetary.dm
+++ b/code/game/turfs/unsimulated/planetary.dm
@@ -27,6 +27,15 @@ var/list/planetary_walls = list()
planetary_walls.Remove(src)
..()
+/turf/unsimulated/wall/planetary/proc/set_temperature(var/new_temperature)
+ if(new_temperature == temperature)
+ return
+ temperature = new_temperature
+ // Force ZAS to reconsider our connections because our temperature has changed
+ if(connections)
+ connections.erase_all()
+ air_master.mark_for_update(src)
+
// Normal station/earth air.
/turf/unsimulated/wall/planetary/normal
oxygen = MOLES_O2STANDARD
@@ -55,3 +64,4 @@ var/list/planetary_walls = list()
oxygen = MOLES_O2STANDARD
nitrogen = MOLES_N2STANDARD
temperature = 310.92 // About 37.7C / 100F
+
diff --git a/code/game/verbs/suicide.dm b/code/game/verbs/suicide.dm
index ec84ee4232..6e23d74bbb 100644
--- a/code/game/verbs/suicide.dm
+++ b/code/game/verbs/suicide.dm
@@ -127,7 +127,7 @@
suiciding = 1
viewers(src) << "[src] is powering down. It looks like \he's trying to commit suicide."
//put em at -175
- adjustOxyLoss(max(maxHealth * 2 - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0))
+ adjustOxyLoss(max(getMaxHealth() * 2 - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0))
updatehealth()
/mob/living/silicon/robot/verb/suicide()
@@ -147,7 +147,7 @@
suiciding = 1
viewers(src) << "[src] is powering down. It looks like \he's trying to commit suicide."
//put em at -175
- adjustOxyLoss(max(maxHealth * 2 - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0))
+ adjustOxyLoss(max(getMaxHealth() * 2 - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0))
updatehealth()
/mob/living/silicon/pai/verb/suicide()
diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm
index ffea7b7fab..099aa43978 100644
--- a/code/modules/clothing/chameleon.dm
+++ b/code/modules/clothing/chameleon.dm
@@ -408,6 +408,7 @@
projectile_type = /obj/item/projectile/chameleon
charge_meter = 0
charge_cost = 48 //uses next to no power, since it's just holograms
+ battery_lock = 1
var/obj/item/projectile/copy_projectile
var/global/list/gun_choices
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index 16501464c6..f3f4cc855a 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -347,7 +347,9 @@
body_parts_covered = FACE|EYES
sprite_sheets = list(
"Teshari" = 'icons/mob/species/seromi/masks.dmi',
- "Vox" = 'icons/mob/species/vox/masks.dmi'
+ "Vox" = 'icons/mob/species/vox/masks.dmi',
+ "Tajara" = 'icons/mob/species/tajaran/mask.dmi',
+ "Unathi" = 'icons/mob/species/unathi/mask.dmi'
)
var/voicechange = 0
diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm
index 137cab1a01..9e27f5c73d 100644
--- a/code/modules/clothing/glasses/glasses.dm
+++ b/code/modules/clothing/glasses/glasses.dm
@@ -402,7 +402,7 @@ BLIND // can't see anything
var/mob/living/carbon/human/M = src.loc
M << "\red The Optical Thermal Scanner overloads and blinds you!"
if(M.glasses == src)
- M.eye_blind = 3
+ M.Blind(3)
M.eye_blurry = 5
// Don't cure being nearsighted
if(!(M.disabilities & NEARSIGHTED))
diff --git a/code/modules/clothing/masks/boxing.dm b/code/modules/clothing/masks/boxing.dm
index 978a5c13e6..5a311c5172 100644
--- a/code/modules/clothing/masks/boxing.dm
+++ b/code/modules/clothing/masks/boxing.dm
@@ -6,10 +6,6 @@
flags_inv = HIDEFACE|BLOCKHAIR
body_parts_covered = FACE|HEAD
w_class = ITEMSIZE_SMALL
- sprite_sheets = list(
- "Tajara" = 'icons/mob/species/tajaran/mask.dmi',
- "Unathi" = 'icons/mob/species/unathi/mask.dmi',
- )
/obj/item/clothing/mask/balaclava/tactical
name = "green balaclava"
@@ -18,10 +14,6 @@
item_state_slots = list(slot_r_hand_str = "bandgreen", slot_l_hand_str = "bandgreen")
flags_inv = HIDEFACE|BLOCKHAIR
w_class = ITEMSIZE_SMALL
- sprite_sheets = list(
- "Tajara" = 'icons/mob/species/tajaran/mask.dmi',
- "Unathi" = 'icons/mob/species/unathi/mask.dmi',
- )
/obj/item/clothing/mask/luchador
name = "Luchador Mask"
diff --git a/code/modules/clothing/spacesuits/alien.dm b/code/modules/clothing/spacesuits/alien.dm
index ff0f8ae077..e23c3c0c26 100644
--- a/code/modules/clothing/spacesuits/alien.dm
+++ b/code/modules/clothing/spacesuits/alien.dm
@@ -34,7 +34,7 @@
item_flags = STOPPRESSUREDAMAGE | THICKMATERIAL | PHORONGUARD
allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs,/obj/item/weapon/tank)
phoronproof = 1
- slowdown = 2
+ slowdown = 0.5
armor = list(melee = 60, bullet = 50, laser = 40,energy = 15, bomb = 30, bio = 100, rad = 50)
siemens_coefficient = 0.2
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm
index d08726371a..f090312320 100644
--- a/code/modules/clothing/suits/armor.dm
+++ b/code/modules/clothing/suits/armor.dm
@@ -80,6 +80,9 @@
if(istype(damage_source, /obj/item/projectile/energy) || istype(damage_source, /obj/item/projectile/beam))
var/obj/item/projectile/P = damage_source
+ if(P.reflected) // Can't reflect twice
+ return ..()
+
var/reflectchance = 40 - round(damage/3)
if(!(def_zone in list(BP_TORSO, BP_GROIN)))
reflectchance /= 2
diff --git a/code/modules/clothing/under/accessories/holster.dm b/code/modules/clothing/under/accessories/holster.dm
index d9dc2f2e54..a68605ff91 100644
--- a/code/modules/clothing/under/accessories/holster.dm
+++ b/code/modules/clothing/under/accessories/holster.dm
@@ -76,10 +76,12 @@
/obj/item/clothing/accessory/holster/on_attached(obj/item/clothing/under/S, mob/user as mob)
..()
- has_suit.verbs += /obj/item/clothing/accessory/holster/verb/holster_verb
+ if(has_suit)
+ has_suit.verbs += /obj/item/clothing/accessory/holster/verb/holster_verb
/obj/item/clothing/accessory/holster/on_removed(mob/user as mob)
- has_suit.verbs -= /obj/item/clothing/accessory/holster/verb/holster_verb
+ if(has_suit)
+ has_suit.verbs -= /obj/item/clothing/accessory/holster/verb/holster_verb
..()
//For the holster hotkey
diff --git a/code/modules/events/carp_migration.dm b/code/modules/events/carp_migration.dm
index e09c062ab0..d0f9a8165c 100644
--- a/code/modules/events/carp_migration.dm
+++ b/code/modules/events/carp_migration.dm
@@ -41,9 +41,11 @@
i++
/datum/event/carp_migration/end()
- for(var/mob/living/simple_animal/hostile/carp/C in spawned_carp)
- if(!C.stat)
- var/turf/T = get_turf(C)
- if(istype(T, /turf/space))
- if(!prob(25))
- qdel(C)
\ No newline at end of file
+ spawn(0)
+ for(var/mob/living/simple_animal/hostile/C in spawned_carp)
+ if(!C.stat)
+ var/turf/T = get_turf(C)
+ if(istype(T, /turf/space))
+ if(prob(75))
+ qdel(C)
+ sleep(1)
\ No newline at end of file
diff --git a/code/modules/genetics/side_effects.dm b/code/modules/genetics/side_effects.dm
index dcb5b4e499..f3a9efb6d2 100644
--- a/code/modules/genetics/side_effects.dm
+++ b/code/modules/genetics/side_effects.dm
@@ -72,7 +72,7 @@
finish(mob/living/carbon/human/H)
if(!H.reagents.has_reagent("anti_toxin"))
- H.confused += 100
+ H.Confuse(100)
proc/trigger_side_effect(mob/living/carbon/human/H)
spawn
diff --git a/code/modules/integrated_electronics/_defines.dm b/code/modules/integrated_electronics/_defines.dm
index c404f61581..7089c19d51 100644
--- a/code/modules/integrated_electronics/_defines.dm
+++ b/code/modules/integrated_electronics/_defines.dm
@@ -8,7 +8,7 @@
#define IC_SPAWN_DEFAULT 1 // If the circuit comes in the default circuit box.
#define IC_SPAWN_RESEARCH 2 // If the circuit design will be autogenerated for RnD.
-#define IC_FORMAT_STRING "\"
+#define IC_FORMAT_STRING "\"
#define IC_FORMAT_NUMBER "\"
#define IC_FORMAT_REF "\["
#define IC_FORMAT_LIST "\]"
diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm
index 88b804f80a..5c49e1817c 100644
--- a/code/modules/integrated_electronics/core/assemblies.dm
+++ b/code/modules/integrated_electronics/core/assemblies.dm
@@ -107,6 +107,7 @@
for(var/obj/item/integrated_circuit/circuit in contents)
HTML += "[circuit.name] | "
HTML += "\[Rename\] | "
+ HTML += "\[Scan with Debugger\] | "
if(circuit.removable)
HTML += "\[Remove\]"
HTML += " "
@@ -223,9 +224,10 @@
if(proximity)
var/scanned = FALSE
for(var/obj/item/integrated_circuit/input/sensor/S in contents)
- S.set_pin_data(IC_OUTPUT, 1, weakref(target))
- S.check_then_do_work()
- scanned = TRUE
+// S.set_pin_data(IC_OUTPUT, 1, weakref(target))
+// S.check_then_do_work()
+ if(S.scan(target))
+ scanned = TRUE
if(scanned)
visible_message("\The [user] waves \the [src] around [target].")
diff --git a/code/modules/integrated_electronics/core/integrated_circuit.dm b/code/modules/integrated_electronics/core/integrated_circuit.dm
index 87bb4cd182..1593297734 100644
--- a/code/modules/integrated_electronics/core/integrated_circuit.dm
+++ b/code/modules/integrated_electronics/core/integrated_circuit.dm
@@ -6,6 +6,7 @@ a creative player the means to solve many problems. Circuits are held inside an
/obj/item/integrated_circuit/examine(mob/user)
. = ..()
external_examine(user)
+ interact(user)
// This should be used when someone is examining while the case is opened.
/obj/item/integrated_circuit/proc/internal_examine(mob/user)
@@ -86,16 +87,14 @@ a creative player the means to solve many problems. Circuits are held inside an
var/HTML = list()
HTML += "[src.name]"
HTML += ""
- HTML += " "
+ HTML += ""
HTML += " \[Refresh\] | "
HTML += "\[Rename\] | "
+ HTML += "\[Scan with Debugger\] | "
HTML += "\[Remove\] "
HTML += ""
- //HTML += ""
- //HTML += ""
- //HTML += ""
HTML += ""
HTML += ""
HTML += ""
@@ -212,6 +211,16 @@ a creative player the means to solve many problems. Circuits are held inside an
if(href_list["rename"])
rename_component(usr)
+ if(href_list["scan"])
+ if(istype(held_item, /obj/item/device/integrated_electronics/debugger))
+ var/obj/item/device/integrated_electronics/debugger/D = held_item
+ if(D.accepting_refs)
+ D.afterattack(src, usr, TRUE)
+ else
+ to_chat(usr, "The Debugger's 'ref scanner' needs to be on.")
+ else
+ to_chat(usr, "You need a Debugger set to 'ref' mode to do that.")
+
if(href_list["autopulse"])
if(autopulse != -1)
autopulse = !autopulse
@@ -260,10 +269,10 @@ a creative player the means to solve many problems. Circuits are held inside an
return TRUE // Battery has enough.
return FALSE // Not enough power.
-/obj/item/integrated_circuit/proc/check_then_do_work()
+/obj/item/integrated_circuit/proc/check_then_do_work(var/ignore_power = FALSE)
if(world.time < next_use) // All intergrated circuits have an internal cooldown, to protect from spam.
return
- if(power_draw_per_use)
+ if(power_draw_per_use && !ignore_power)
if(!check_power())
power_fail()
return
diff --git a/code/modules/integrated_electronics/core/tools.dm b/code/modules/integrated_electronics/core/tools.dm
index 8220162be7..a875917441 100644
--- a/code/modules/integrated_electronics/core/tools.dm
+++ b/code/modules/integrated_electronics/core/tools.dm
@@ -160,7 +160,7 @@
data_to_show = A.name
to_chat(user, "You write '[data_to_write ? data_to_show : "NULL"]' to the '[io]' pin of \the [io.holder].")
else if(io.io_type == PULSE_CHANNEL)
- io.holder.check_then_do_work()
+ io.holder.check_then_do_work(ignore_power = TRUE)
to_chat(user, "You pulse \the [io.holder]'s [io].")
io.holder.interact(user) // This is to update the UI.
diff --git a/code/modules/integrated_electronics/subtypes/arithmetic.dm b/code/modules/integrated_electronics/subtypes/arithmetic.dm
index c6134f9bd1..059c699e50 100644
--- a/code/modules/integrated_electronics/subtypes/arithmetic.dm
+++ b/code/modules/integrated_electronics/subtypes/arithmetic.dm
@@ -1,9 +1,18 @@
//These circuits do simple math.
/obj/item/integrated_circuit/arithmetic
complexity = 1
- inputs = list("A","B","C","D","E","F","G","H")
- outputs = list("result")
- activators = list("compute")
+ inputs = list(
+ "\ A",
+ "\ B",
+ "\ C",
+ "\ D",
+ "\ E",
+ "\ F",
+ "\ G",
+ "\ H"
+ )
+ outputs = list("\ result")
+ activators = list("\ compute", "\ on computed")
category_text = "Arithmetic"
autopulse = 1
power_draw_per_use = 5 // Math is pretty cheap.
@@ -30,9 +39,9 @@
if(isnum(I.data))
result = result + I.data
- for(var/datum/integrated_io/output/O in outputs)
- O.data = result
- O.push_data()
+ set_pin_data(IC_OUTPUT, 1, result)
+ push_data()
+ activate_pin(2)
// -Subtracting- //
@@ -58,9 +67,9 @@
if(isnum(I.data))
result = result - I.data
- for(var/datum/integrated_io/output/O in outputs)
- O.data = result
- O.push_data()
+ set_pin_data(IC_OUTPUT, 1, result)
+ push_data()
+ activate_pin(2)
// *Multiply* //
@@ -86,9 +95,9 @@
if(isnum(I.data))
result = result * I.data
- for(var/datum/integrated_io/output/O in outputs)
- O.data = result
- O.push_data()
+ set_pin_data(IC_OUTPUT, 1, result)
+ push_data()
+ activate_pin(2)
// /Division/ //
@@ -114,9 +123,9 @@
if(isnum(I.data) && I.data != 0) //No runtimes here.
result = result / I.data
- for(var/datum/integrated_io/output/O in outputs)
- O.data = result
- O.push_data()
+ set_pin_data(IC_OUTPUT, 1, result)
+ push_data()
+ activate_pin(2)
//^ Exponent ^//
@@ -134,9 +143,9 @@
if(isnum(A.data) && isnum(B.data))
result = A.data ** B.data
- for(var/datum/integrated_io/output/O in outputs)
- O.data = result
- O.push_data()
+ set_pin_data(IC_OUTPUT, 1, result)
+ push_data()
+ activate_pin(2)
// +-Sign-+ //
@@ -159,9 +168,9 @@
else
result = 0
- for(var/datum/integrated_io/output/O in outputs)
- O.data = result
- O.push_data()
+ set_pin_data(IC_OUTPUT, 1, result)
+ push_data()
+ activate_pin(2)
// Round //
@@ -183,9 +192,9 @@
else
result = round(A.data)
- for(var/datum/integrated_io/output/O in outputs)
- O.data = result
- O.push_data()
+ set_pin_data(IC_OUTPUT, 1, result)
+ push_data()
+ activate_pin(2)
// Absolute //
@@ -204,9 +213,9 @@
if(isnum(I.data))
result = abs(I.data)
- for(var/datum/integrated_io/output/O in outputs)
- O.data = result
- O.push_data()
+ set_pin_data(IC_OUTPUT, 1, result)
+ push_data()
+ activate_pin(2)
// Averaging //
@@ -229,9 +238,9 @@
if(inputs_used)
result = result / inputs_used
- for(var/datum/integrated_io/output/O in outputs)
- O.data = result
- O.push_data()
+ set_pin_data(IC_OUTPUT, 1, result)
+ push_data()
+ activate_pin(2)
// Pi, because why the hell not? //
/obj/item/integrated_circuit/arithmetic/pi
@@ -242,9 +251,9 @@
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/arithmetic/pi/do_work()
- var/datum/integrated_io/output/O = outputs[1]
- O.data = 3.14159
- O.push_data()
+ set_pin_data(IC_OUTPUT, 1, 3.14159)
+ push_data()
+ activate_pin(2)
// Random //
/obj/item/integrated_circuit/arithmetic/random
@@ -253,20 +262,20 @@
extended_desc = "'Inclusive' means that the upper bound is included in the range of numbers, e.g. L = 1 and H = 3 will allow \
for outputs of 1, 2, or 3. H being the higher number is not strictly required."
icon_state = "random"
- inputs = list("L","H")
+ inputs = list("\ L","\ H")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/arithmetic/random/do_work()
var/result = 0
- var/datum/integrated_io/L = inputs[1]
- var/datum/integrated_io/H = inputs[2]
+ var/L = get_pin_data(IC_INPUT, 1)
+ var/H = get_pin_data(IC_INPUT, 2)
- if(isnum(L.data) && isnum(H.data))
- result = rand(L.data, H.data)
+ if(isnum(L) && isnum(H))
+ result = rand(L, H)
- for(var/datum/integrated_io/output/O in outputs)
- O.data = result
- O.push_data()
+ set_pin_data(IC_OUTPUT, 1, result)
+ push_data()
+ activate_pin(2)
// Square Root //
@@ -274,7 +283,7 @@
name = "square root circuit"
desc = "This outputs the square root of a number you put in."
icon_state = "square_root"
- inputs = list("A")
+ inputs = list("\ A")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/arithmetic/square_root/do_work()
@@ -284,9 +293,9 @@
if(isnum(I.data))
result = sqrt(I.data)
- for(var/datum/integrated_io/output/O in outputs)
- O.data = result
- O.push_data()
+ set_pin_data(IC_OUTPUT, 1, result)
+ push_data()
+ activate_pin(2)
// % Modulo % //
@@ -294,17 +303,17 @@
name = "modulo circuit"
desc = "Gets the remainder of A / B."
icon_state = "modulo"
- inputs = list("A", "B")
+ inputs = list("\ A", "\ B")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/arithmetic/modulo/do_work()
var/result = 0
- var/datum/integrated_io/input/A = inputs[1]
- var/datum/integrated_io/input/B = inputs[2]
- if(isnum(A.data) && isnum(B.data) && B.data != 0)
- result = A.data % B.data
+ var/A = get_pin_data(IC_INPUT, 1)
+ var/B = get_pin_data(IC_INPUT, 2)
+ if(isnum(A) && isnum(B) && B != 0)
+ result = A % B
- for(var/datum/integrated_io/output/O in outputs)
- O.data = result
- O.push_data()
+ set_pin_data(IC_OUTPUT, 1, result)
+ push_data()
+ activate_pin(2)
diff --git a/code/modules/integrated_electronics/subtypes/converters.dm b/code/modules/integrated_electronics/subtypes/converters.dm
index 9e04e24db5..431faa241f 100644
--- a/code/modules/integrated_electronics/subtypes/converters.dm
+++ b/code/modules/integrated_electronics/subtypes/converters.dm
@@ -3,7 +3,7 @@
complexity = 2
inputs = list("input")
outputs = list("output")
- activators = list("convert")
+ activators = list("\ convert", "\ on convert")
category_text = "Converter"
autopulse = 1
power_draw_per_use = 10
@@ -16,89 +16,113 @@
name = "number to string"
desc = "This circuit can convert a number variable into a string."
icon_state = "num-string"
+ inputs = list("\ input")
+ outputs = list("\ output")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/converter/num2text/do_work()
var/result = null
- var/datum/integrated_io/incoming = inputs[1]
- var/datum/integrated_io/outgoing = outputs[1]
- if(incoming.data && isnum(incoming.data))
- result = num2text(incoming.data)
+ pull_data()
+ var/incoming = get_pin_data(IC_INPUT, 1)
+ if(incoming && isnum(incoming))
+ result = num2text(incoming)
- outgoing.data = result
- outgoing.push_data()
+ set_pin_data(IC_OUTPUT, 1, result)
+ push_data()
+ activate_pin(2)
/obj/item/integrated_circuit/converter/text2num
name = "string to number"
desc = "This circuit can convert a string variable into a number."
icon_state = "string-num"
+ inputs = list("\ input")
+ outputs = list("\ output")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/converter/text2num/do_work()
var/result = null
- var/datum/integrated_io/incoming = inputs[1]
- var/datum/integrated_io/outgoing = outputs[1]
- if(incoming.data && istext(incoming.data))
- result = text2num(incoming.data)
+ pull_data()
+ var/incoming = get_pin_data(IC_INPUT, 1)
+ if(incoming && istext(incoming))
+ result = text2num(incoming)
- outgoing.data = result
- outgoing.push_data()
+ set_pin_data(IC_OUTPUT, 1, result)
+ push_data()
+ activate_pin(2)
/obj/item/integrated_circuit/converter/ref2text
name = "reference to string"
desc = "This circuit can convert a reference to something else to a string, specifically the name of that reference."
icon_state = "ref-string"
+ inputs = list("\[ input")
+ outputs = list("\ output")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/converter/ref2text/do_work()
var/result = null
- var/datum/integrated_io/incoming = inputs[1]
- var/datum/integrated_io/outgoing = outputs[1]
- var/atom/A = incoming.data_as_type(/atom)
- result = A && A.name
+ pull_data()
+ var/atom/A = get_pin_data(IC_INPUT, 1)
+ if(A && istype(A))
+ result = A.name
- outgoing.data = result
- outgoing.push_data()
+ set_pin_data(IC_OUTPUT, 1, result)
+ push_data()
+ activate_pin(2)
/obj/item/integrated_circuit/converter/lowercase
name = "lowercase string converter"
desc = "this will cause a string to come out in all lowercase."
icon_state = "lowercase"
+ inputs = list("\ input")
+ outputs = list("\ output")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/converter/lowercase/do_work()
var/result = null
- var/datum/integrated_io/incoming = inputs[1]
- var/datum/integrated_io/outgoing = outputs[1]
- if(incoming.data && istext(incoming.data))
- result = lowertext(incoming.data)
+ pull_data()
+ var/incoming = get_pin_data(IC_INPUT, 1)
+ if(incoming && istext(incoming))
+ result = lowertext(incoming)
- outgoing.data = result
- outgoing.push_data()
+ set_pin_data(IC_OUTPUT, 1, result)
+ push_data()
+ activate_pin(2)
/obj/item/integrated_circuit/converter/uppercase
name = "uppercase string converter"
desc = "THIS WILL CAUSE A STRING TO COME OUT IN ALL UPPERCASE."
icon_state = "uppercase"
+ inputs = list("\ input")
+ outputs = list("\ output")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/converter/uppercase/do_work()
var/result = null
- var/datum/integrated_io/incoming = inputs[1]
- var/datum/integrated_io/outgoing = outputs[1]
- if(incoming.data && istext(incoming.data))
- result = uppertext(incoming.data)
+ pull_data()
+ var/incoming = get_pin_data(IC_INPUT, 1)
+ if(incoming && istext(incoming))
+ result = uppertext(incoming)
- outgoing.data = result
- outgoing.push_data()
+ set_pin_data(IC_OUTPUT, 1, result)
+ push_data()
+ activate_pin(2)
/obj/item/integrated_circuit/converter/concatenatior
name = "concatenatior"
- desc = "This joins many strings together to get one big string."
+ desc = "This joins many strings or numbers together to get one big string."
complexity = 4
- inputs = list("A","B","C","D","E","F","G","H")
- outputs = list("result")
- activators = list("concatenate")
+ inputs = list(
+ "\ A",
+ "\ B",
+ "\ C",
+ "\ D",
+ "\ E",
+ "\ F",
+ "\ G",
+ "\ H"
+ )
+ outputs = list("\ result")
+ activators = list("\ concatenate", "\ on concatenated")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/converter/concatenatior/do_work()
@@ -107,70 +131,70 @@
I.pull_data()
if(istext(I.data))
result = result + I.data
+ else if(!isnull(I.data) && num2text(I.data))
+ result = result + num2text(I.data)
var/datum/integrated_io/outgoing = outputs[1]
outgoing.data = result
outgoing.push_data()
+ activate_pin(2)
/obj/item/integrated_circuit/converter/radians2degrees
name = "radians to degrees converter"
desc = "Converts radians to degrees."
- inputs = list("radian")
- outputs = list("degrees")
+ inputs = list("\ radian")
+ outputs = list("\ degrees")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/converter/radians2degrees/do_work()
var/result = null
- var/datum/integrated_io/incoming = inputs[1]
- var/datum/integrated_io/outgoing = outputs[1]
- incoming.pull_data()
- if(incoming.data && isnum(incoming.data))
- result = ToDegrees(incoming.data)
+ pull_data()
+ var/incoming = get_pin_data(IC_INPUT, 1)
+ if(incoming && isnum(incoming))
+ result = ToDegrees(incoming)
- outgoing.data = result
- outgoing.push_data()
+ set_pin_data(IC_OUTPUT, 1, result)
+ push_data()
+ activate_pin(2)
/obj/item/integrated_circuit/converter/degrees2radians
name = "degrees to radians converter"
desc = "Converts degrees to radians."
- inputs = list("degrees")
- outputs = list("radians")
+ inputs = list("\ degrees")
+ outputs = list("\ radians")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/converter/degrees2radians/do_work()
var/result = null
- var/datum/integrated_io/incoming = inputs[1]
- var/datum/integrated_io/outgoing = outputs[1]
- incoming.pull_data()
- if(incoming.data && isnum(incoming.data))
- result = ToRadians(incoming.data)
+ pull_data()
+ var/incoming = get_pin_data(IC_INPUT, 1)
+ if(incoming && isnum(incoming))
+ result = ToRadians(incoming)
- outgoing.data = result
- outgoing.push_data()
+ set_pin_data(IC_OUTPUT, 1, result)
+ push_data()
+ activate_pin(2)
/obj/item/integrated_circuit/converter/abs_to_rel_coords
name = "abs to rel coordinate converter"
desc = "Easily convert absolute coordinates to relative coordinates with this."
complexity = 4
- inputs = list("X1 (abs)", "Y1 (abs)", "X2 (abs)", "Y2 (abs)")
- outputs = list("X (rel)", "Y (rel)")
- activators = list("compute rel coordinates")
+ inputs = list("\ X1", "\ Y1", "\ X2", "\ Y2")
+ outputs = list("\ X", "\ Y")
+ activators = list("\ compute rel coordinates", "\ on convert")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/converter/abs_to_rel_coords/do_work()
- var/datum/integrated_io/x1 = inputs[1]
- var/datum/integrated_io/y1 = inputs[2]
+ var/x1 = get_pin_data(IC_INPUT, 1)
+ var/y1 = get_pin_data(IC_INPUT, 2)
- var/datum/integrated_io/x2 = inputs[3]
- var/datum/integrated_io/y2 = inputs[4]
+ var/x2 = get_pin_data(IC_INPUT, 3)
+ var/y2 = get_pin_data(IC_INPUT, 4)
- var/datum/integrated_io/result_x = outputs[1]
- var/datum/integrated_io/result_y = outputs[2]
+ if(x1 && y1 && x2 && y2)
+ set_pin_data(IC_OUTPUT, 1, x1 - x2)
+ set_pin_data(IC_OUTPUT, 2, y1 - y2)
- if(x1.data && y1.data && x2.data && y2.data)
- result_x.data = x1.data - x2.data
- result_y.data = y1.data - y2.data
-
- for(var/datum/integrated_io/output/O in outputs)
- O.push_data()
\ No newline at end of file
+ push_data()
+ activate_pin(2)
\ No newline at end of file
diff --git a/code/modules/integrated_electronics/subtypes/input_output.dm b/code/modules/integrated_electronics/subtypes/input_output.dm
index baa5738d4e..456fae889f 100644
--- a/code/modules/integrated_electronics/subtypes/input_output.dm
+++ b/code/modules/integrated_electronics/subtypes/input_output.dm
@@ -14,28 +14,27 @@
can_be_asked_input = 1
inputs = list()
outputs = list()
- activators = list("on pressed")
+ activators = list("\ on pressed")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/input/button/ask_for_input(mob/user) //Bit misleading name for this specific use.
- var/datum/integrated_io/A = activators[1]
- if(A.linked.len)
- for(var/datum/integrated_io/activate/target in A.linked)
- target.holder.check_then_do_work()
to_chat(user, "You press the button labeled '[src.name]'.")
+ activate_pin(1)
/obj/item/integrated_circuit/input/toggle_button
name = "toggle button"
desc = "It toggles on, off, on, off..."
icon_state = "toggle_button"
complexity = 1
+ can_be_asked_input = 1
inputs = list()
- outputs = list("on" = 0)
- activators = list("on toggle")
+ outputs = list("\ on" = 0)
+ activators = list("\ on toggle")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/input/toggle_button/ask_for_input(mob/user) // Ditto.
set_pin_data(IC_OUTPUT, 1, !get_pin_data(IC_OUTPUT, 1))
+ push_data()
activate_pin(1)
to_chat(user, "You toggle the button labeled '[src.name]' [get_pin_data(IC_OUTPUT, 1) ? "on" : "off"].")
@@ -46,19 +45,17 @@
complexity = 2
can_be_asked_input = 1
inputs = list()
- outputs = list("number entered")
- activators = list("on entered")
+ outputs = list("\ number entered")
+ activators = list("\ on entered")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
power_draw_per_use = 4
/obj/item/integrated_circuit/input/numberpad/ask_for_input(mob/user)
var/new_input = input(user, "Enter a number, please.","Number pad") as null|num
if(isnum(new_input) && CanInteract(user, physical_state))
- var/datum/integrated_io/O = outputs[1]
- O.data = new_input
- O.push_data()
- var/datum/integrated_io/A = activators[1]
- A.push_data()
+ set_pin_data(IC_OUTPUT, 1, new_input)
+ push_data()
+ activate_pin(1)
/obj/item/integrated_circuit/input/textpad
name = "text pad"
@@ -67,49 +64,43 @@
complexity = 2
can_be_asked_input = 1
inputs = list()
- outputs = list("string entered")
- activators = list("on entered")
+ outputs = list("\ string entered")
+ activators = list("\ on entered")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
power_draw_per_use = 4
/obj/item/integrated_circuit/input/textpad/ask_for_input(mob/user)
var/new_input = input(user, "Enter some words, please.","Number pad") as null|text
if(istext(new_input) && CanInteract(user, physical_state))
- var/datum/integrated_io/O = outputs[1]
- O.data = new_input
- O.push_data()
- var/datum/integrated_io/A = activators[1]
- A.push_data()
+ set_pin_data(IC_OUTPUT, 1, new_input)
+ push_data()
+ activate_pin(1)
/obj/item/integrated_circuit/input/med_scanner
name = "integrated medical analyser"
desc = "A very small version of the common medical analyser. This allows the machine to know how healthy someone is."
icon_state = "medscan"
complexity = 4
- inputs = list("target ref")
- outputs = list("total health %", "total missing health")
- activators = list("scan")
+ inputs = list("\][ target")
+ outputs = list("\ total health %", "\ total missing health")
+ activators = list("\ scan", "\ on scanned")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
power_draw_per_use = 40
/obj/item/integrated_circuit/input/med_scanner/do_work()
- var/datum/integrated_io/I = inputs[1]
- var/mob/living/carbon/human/H = I.data_as_type(/mob/living/carbon/human)
+ var/mob/living/carbon/human/H = get_pin_data_as_type(IC_INPUT, 1, /mob/living/carbon/human)
if(!istype(H)) //Invalid input
return
if(H.Adjacent(get_turf(src))) // Like normal analysers, it can't be used at range.
- var/total_health = round(H.health/H.maxHealth, 0.1)*100
- var/missing_health = H.maxHealth - H.health
+ var/total_health = round(H.health/H.getMaxHealth(), 0.1)*100
+ var/missing_health = H.getMaxHealth() - H.health
- var/datum/integrated_io/total = outputs[1]
- var/datum/integrated_io/missing = outputs[2]
+ set_pin_data(IC_OUTPUT, 1, total_health)
+ set_pin_data(IC_OUTPUT, 2, missing_health)
- total.data = total_health
- missing.data = missing_health
-
- for(var/datum/integrated_io/output/O in outputs)
- O.push_data()
+ push_data()
+ activate_pin(2)
/obj/item/integrated_circuit/input/adv_med_scanner
name = "integrated advanced medical analyser"
@@ -117,48 +108,39 @@
This type is much more precise, allowing the machine to know much more about the target than a normal analyzer."
icon_state = "medscan_adv"
complexity = 12
- inputs = list("target ref")
+ inputs = list("\][ target")
outputs = list(
- "total health %",
- "total missing health",
- "brute damage",
- "burn damage",
- "tox damage",
- "oxy damage",
- "clone damage"
+ "\ total health %",
+ "\ total missing health",
+ "\ brute damage",
+ "\ burn damage",
+ "\ tox damage",
+ "\ oxy damage",
+ "\ clone damage"
)
- activators = list("scan")
+ activators = list("\ scan", "\ on scanned")
spawn_flags = IC_SPAWN_RESEARCH
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 4)
power_draw_per_use = 80
/obj/item/integrated_circuit/input/adv_med_scanner/do_work()
- var/datum/integrated_io/I = inputs[1]
- var/mob/living/carbon/human/H = I.data_as_type(/mob/living/carbon/human)
+ var/mob/living/carbon/human/H = get_pin_data_as_type(IC_INPUT, 1, /mob/living/carbon/human)
if(!istype(H)) //Invalid input
return
if(H.Adjacent(get_turf(src))) // Like normal analysers, it can't be used at range.
- var/total_health = round(H.health/H.maxHealth, 0.1)*100
- var/missing_health = H.maxHealth - H.health
+ var/total_health = round(H.health/H.getMaxHealth(), 0.1)*100
+ var/missing_health = H.getMaxHealth() - H.health
- var/datum/integrated_io/total = outputs[1]
- var/datum/integrated_io/missing = outputs[2]
- var/datum/integrated_io/brute = outputs[3]
- var/datum/integrated_io/burn = outputs[4]
- var/datum/integrated_io/tox = outputs[5]
- var/datum/integrated_io/oxy = outputs[6]
- var/datum/integrated_io/clone = outputs[7]
+ set_pin_data(IC_OUTPUT, 1, total_health)
+ set_pin_data(IC_OUTPUT, 2, missing_health)
+ set_pin_data(IC_OUTPUT, 3, H.getBruteLoss())
+ set_pin_data(IC_OUTPUT, 4, H.getFireLoss())
+ set_pin_data(IC_OUTPUT, 5, H.getToxLoss())
+ set_pin_data(IC_OUTPUT, 6, H.getOxyLoss())
+ set_pin_data(IC_OUTPUT, 7, H.getCloneLoss())
- total.data = total_health
- missing.data = missing_health
- brute.data = H.getBruteLoss()
- burn.data = H.getFireLoss()
- tox.data = H.getToxLoss()
- oxy.data = H.getOxyLoss()
- clone.data = H.getCloneLoss()
-
- for(var/datum/integrated_io/output/O in outputs)
- O.push_data()
+ push_data()
+ activate_pin(2)
/obj/item/integrated_circuit/input/local_locator
name = "local locator"
@@ -222,9 +204,9 @@
Meaning the default frequency is expressed as 1457, not 145.7. To send a signal, pulse the 'send signal' activator pin."
icon_state = "signal"
complexity = 4
- inputs = list("frequency","code")
+ inputs = list("\ frequency","\ code")
outputs = list()
- activators = list("send signal","on signal received")
+ activators = list("\ send signal","\ on signal sent", "\ on signal received")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNET = 2)
power_draw_idle = 5
@@ -237,11 +219,9 @@
/obj/item/integrated_circuit/input/signaler/initialize()
..()
set_frequency(frequency)
- var/datum/integrated_io/new_freq = inputs[1]
- var/datum/integrated_io/new_code = inputs[2]
// Set the pins so when someone sees them, they won't show as null
- new_freq.data = frequency
- new_code.data = code
+ set_pin_data(IC_INPUT, 1, frequency)
+ set_pin_data(IC_INPUT, 2, code)
/obj/item/integrated_circuit/input/signaler/Destroy()
if(radio_controller)
@@ -250,12 +230,12 @@
. = ..()
/obj/item/integrated_circuit/input/signaler/on_data_written()
- var/datum/integrated_io/new_freq = inputs[1]
- var/datum/integrated_io/new_code = inputs[2]
- if(isnum(new_freq.data) && new_freq.data > 0)
- set_frequency(new_freq.data)
- if(isnum(new_code.data))
- code = new_code.data
+ var/new_freq = get_pin_data(IC_INPUT, 1)
+ var/new_code = get_pin_data(IC_INPUT, 2)
+ if(isnum(new_freq) && new_freq > 0)
+ set_frequency(new_freq)
+ if(isnum(new_code))
+ code = new_code
/obj/item/integrated_circuit/input/signaler/do_work() // Sends a signal.
@@ -267,6 +247,7 @@
signal.encryption = code
signal.data["message"] = "ACTIVATE"
radio_connection.post_signal(src, signal)
+ activate_pin(2)
/obj/item/integrated_circuit/input/signaler/proc/set_frequency(new_frequency)
if(!frequency)
@@ -280,11 +261,11 @@
radio_connection = radio_controller.add_object(src, frequency, RADIO_CHAT)
/obj/item/integrated_circuit/input/signaler/receive_signal(datum/signal/signal)
- var/datum/integrated_io/new_code = inputs[2]
+ var/new_code = get_pin_data(IC_INPUT, 2)
var/code = 0
- if(isnum(new_code.data))
- code = new_code.data
+ if(isnum(new_code))
+ code = new_code
if(!signal)
return 0
if(signal.encryption != code)
@@ -292,8 +273,7 @@
if(signal.source == src) // Don't trigger ourselves.
return 0
- var/datum/integrated_io/A = activators[2]
- A.push_data()
+ activate_pin(3)
for(var/mob/O in hearers(1, get_turf(src)))
O.show_message(text("\icon[] *beep* *beep*", src), 3, "*beep* *beep*", 2)
@@ -306,9 +286,9 @@
will pulse whatever's connected to it. Pulsing the first activation pin will send a message."
icon_state = "signal"
complexity = 4
- inputs = list("target EPv2 address", "data to send", "secondary text")
- outputs = list("address received", "data received", "secondary text received")
- activators = list("send data", "on data received")
+ inputs = list("\ target EPv2 address", "\ data to send", "\ secondary text")
+ outputs = list("\ address received", "\ data received", "\ secondary text received")
+ activators = list("\ send data", "\ on data received")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNET = 2, TECH_BLUESPACE = 2)
power_draw_per_use = 50
@@ -318,7 +298,7 @@
..()
exonet = new(src)
exonet.make_address("EPv2_circuit-\ref[src]")
- desc += "] This circuit's EPv2 address is: [exonet.address]."
+ desc += " This circuit's EPv2 address is: [exonet.address]"
/obj/item/integrated_circuit/input/EPv2/Destroy()
if(exonet)
@@ -327,64 +307,60 @@
..()
/obj/item/integrated_circuit/input/EPv2/do_work()
- var/datum/integrated_io/target_address = inputs[1]
- var/datum/integrated_io/message = inputs[2]
- var/datum/integrated_io/text = inputs[3]
- if(istext(target_address.data))
- exonet.send_message(target_address.data, message.data, text.data)
+ var/target_address = get_pin_data(IC_INPUT, 1)
+ var/message = get_pin_data(IC_INPUT, 2)
+ var/text = get_pin_data(IC_INPUT, 3)
+
+ if(target_address && istext(target_address))
+ exonet.send_message(target_address, message, text)
/obj/item/integrated_circuit/input/receive_exonet_message(var/atom/origin_atom, var/origin_address, var/message, var/text)
- var/datum/integrated_io/message_received = outputs[1]
- var/datum/integrated_io/data_received = outputs[2]
- var/datum/integrated_io/text_received = outputs[3]
+ set_pin_data(IC_OUTPUT, 1, origin_address)
+ set_pin_data(IC_OUTPUT, 2, message)
+ set_pin_data(IC_OUTPUT, 3, text)
- var/datum/integrated_io/A = activators[2]
- A.push_data()
-
- message_received.write_data_to_pin(origin_address)
- data_received.write_data_to_pin(message)
- text_received.write_data_to_pin(text)
-
- for(var/datum/integrated_io/output/O in outputs)
- O.push_data()
+ push_data()
+ activate_pin(2)
//This circuit gives information on where the machine is.
/obj/item/integrated_circuit/input/gps
name = "global positioning system"
desc = "This allows you to easily know the position of a machine containing this device."
+ extended_desc = "The GPS's coordinates it gives is absolute, not relative."
icon_state = "gps"
complexity = 4
inputs = list()
- outputs = list("X (abs)", "Y (abs)")
- activators = list("get coordinates")
+ outputs = list("\ X", "\ Y")
+ activators = list("\ get coordinates", "\ on get coordinates")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
power_draw_per_use = 30
/obj/item/integrated_circuit/input/gps/do_work()
var/turf/T = get_turf(src)
- var/datum/integrated_io/result_x = outputs[1]
- var/datum/integrated_io/result_y = outputs[2]
- result_x.data = null
- result_y.data = null
+ set_pin_data(IC_OUTPUT, 1, null)
+ set_pin_data(IC_OUTPUT, 2, null)
if(!T)
return
- result_x.data = T.x
- result_y.data = T.y
+ set_pin_data(IC_OUTPUT, 1, T.x)
+ set_pin_data(IC_OUTPUT, 2, T.y)
- for(var/datum/integrated_io/output/O in outputs)
- O.push_data()
+ push_data()
+ activate_pin(2)
/obj/item/integrated_circuit/input/microphone
name = "microphone"
desc = "Useful for spying on people or for voice activated machines."
+ extended_desc = "This will automatically translate most languages it hears to Galactic Common. \
+ The first activation pin is always pulsed when the circuit hears someone talk, while the second one \
+ is only triggered if it hears someone speaking a language other than Galactic Common."
icon_state = "recorder"
complexity = 8
inputs = list()
- outputs = list("speaker \", "message \")
- activators = list("on message received")
+ outputs = list("\ speaker", "\ message")
+ activators = list("\ on message received", "\ on translation")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
power_draw_per_use = 15
@@ -397,42 +373,45 @@
..()
/obj/item/integrated_circuit/input/microphone/hear_talk(mob/living/M, msg, var/verb="says", datum/language/speaking=null)
- var/datum/integrated_io/V = outputs[1]
- var/datum/integrated_io/O = outputs[2]
- var/datum/integrated_io/A = activators[1]
+ var/translated = FALSE
if(M && msg)
if(speaking)
if(!speaking.machine_understands)
msg = speaking.scramble(msg)
- V.data = M.GetVoice()
- O.data = msg
- A.push_data()
+ if(!istype(speaking, /datum/language/common))
+ translated = TRUE
+ set_pin_data(IC_OUTPUT, 1, M.GetVoice())
+ set_pin_data(IC_OUTPUT, 2, msg)
- for(var/datum/integrated_io/output/out in outputs)
- out.push_data()
-
- A.push_data()
+ push_data()
+ activate_pin(1)
+ if(translated)
+ activate_pin(2)
/obj/item/integrated_circuit/input/sensor
name = "sensor"
desc = "Scans and obtains a reference for any objects or persons near you. All you need to do is shove the machine in their face."
+ extended_desc = "If 'ignore storage' pin is set to 1, the sensor will disregard scanning various storage containers such as backpacks."
icon_state = "recorder"
complexity = 12
- inputs = list()
- outputs = list("scanned ref \[")
- activators = list("on scanned")
+ inputs = list("\ ignore storage" = 1)
+ outputs = list("\][ scanned")
+ activators = list("\ on scanned")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
power_draw_per_use = 120
-/obj/item/integrated_circuit/input/sensor/do_work()
- // Because this gets called by attack(), all this needs to do is pulse the activator.
- for(var/datum/integrated_io/output/O in outputs)
- O.push_data()
- var/datum/integrated_io/activate/A = activators[1]
- A.push_data()
+/obj/item/integrated_circuit/input/sensor/proc/scan(var/atom/A)
+ var/ignore_bags = get_pin_data(IC_INPUT, 1)
+ if(ignore_bags)
+ if(istype(A, /obj/item/weapon/storage))
+ return FALSE
+ set_pin_data(IC_OUTPUT, 1, weakref(A))
+ push_data()
+ activate_pin(1)
+ return TRUE
/obj/item/integrated_circuit/output
category_text = "Output"
@@ -441,9 +420,9 @@
name = "small screen"
desc = "This small screen can display a single piece of data, when the machine is examined closely."
icon_state = "screen"
- inputs = list("displayed data")
+ inputs = list("\ displayed data")
outputs = list()
- activators = list("load data")
+ activators = list("\ load data")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
power_draw_per_use = 10
autopulse = 1
@@ -497,7 +476,7 @@
complexity = 4
inputs = list()
outputs = list()
- activators = list("toggle light")
+ activators = list("\ toggle light")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
var/light_toggled = 0
var/light_brightness = 3
@@ -519,18 +498,18 @@
power_draw_idle = light_toggled ? light_brightness * 2 : 0
/obj/item/integrated_circuit/output/light/advanced/update_lighting()
- var/datum/integrated_io/R = inputs[1]
- var/datum/integrated_io/G = inputs[2]
- var/datum/integrated_io/B = inputs[3]
- var/datum/integrated_io/brightness = inputs[4]
+ var/R = get_pin_data(IC_INPUT, 1)
+ var/G = get_pin_data(IC_INPUT, 2)
+ var/B = get_pin_data(IC_INPUT, 3)
+ var/brightness = get_pin_data(IC_INPUT, 4)
- if(isnum(R.data) && isnum(G.data) && isnum(B.data) && isnum(brightness.data))
- R.data = Clamp(R.data, 0, 255)
- G.data = Clamp(G.data, 0, 255)
- B.data = Clamp(B.data, 0, 255)
- brightness.data = Clamp(brightness.data, 0, 6)
- light_rgb = rgb(R.data, G.data, B.data)
- light_brightness = brightness.data
+ if(isnum(R) && isnum(G) && isnum(B) && isnum(brightness))
+ R = Clamp(R, 0, 255)
+ G = Clamp(G, 0, 255)
+ B = Clamp(B, 0, 255)
+ brightness = Clamp(brightness, 0, 6)
+ light_rgb = rgb(R, G, B)
+ light_brightness = brightness
..()
@@ -544,10 +523,10 @@
icon_state = "light_adv"
complexity = 8
inputs = list(
- "R",
- "G",
- "B",
- "Brightness"
+ "\ R",
+ "\ G",
+ "\ B",
+ "\ Brightness"
)
outputs = list()
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
@@ -563,9 +542,9 @@
complexity = 8
cooldown_per_use = 4 SECONDS
inputs = list(
- "sound ID",
- "volume",
- "frequency"
+ "\ sound ID",
+ "\ volume",
+ "\ frequency"
)
outputs = list()
activators = list("play sound")
diff --git a/code/modules/integrated_electronics/subtypes/logic.dm b/code/modules/integrated_electronics/subtypes/logic.dm
index beb44bf535..759b1586eb 100644
--- a/code/modules/integrated_electronics/subtypes/logic.dm
+++ b/code/modules/integrated_electronics/subtypes/logic.dm
@@ -4,7 +4,7 @@
extended_desc = "Logic circuits will treat a null, 0, and a \"\" string value as FALSE and anything else as TRUE."
complexity = 3
outputs = list("result")
- activators = list("compare", "on true result", "on false result")
+ activators = list("\ compare", "\ on true result", "\ on false result")
category_text = "Logic"
autopulse = 1
power_draw_per_use = 1
@@ -14,19 +14,17 @@
check_then_do_work()
/obj/item/integrated_circuit/logic/do_work()
- var/datum/integrated_io/O = outputs[1]
- var/datum/integrated_io/T = activators[2]
- var/datum/integrated_io/F = activators[3]
- O.push_data()
- if(O.data)
- T.push_data()
+ push_data()
+ if(get_pin_data(IC_INPUT, 1))
+ activate_pin(1)
else
- F.push_data()
+ activate_pin(2)
/obj/item/integrated_circuit/logic/binary
- inputs = list("A","B")
+ inputs = list("\ A","\ B")
/obj/item/integrated_circuit/logic/binary/do_work()
+ pull_data()
var/datum/integrated_io/A = inputs[1]
var/datum/integrated_io/B = inputs[2]
var/datum/integrated_io/O = outputs[1]
@@ -37,9 +35,10 @@
return FALSE
/obj/item/integrated_circuit/logic/unary
- inputs = list("A")
+ inputs = list("\ A")
/obj/item/integrated_circuit/logic/unary/do_work()
+ pull_data()
var/datum/integrated_io/A = inputs[1]
var/datum/integrated_io/O = outputs[1]
O.data = do_check(A) ? TRUE : FALSE
diff --git a/code/modules/integrated_electronics/subtypes/manipulation.dm b/code/modules/integrated_electronics/subtypes/manipulation.dm
index 65bae751e0..4ee5145179 100644
--- a/code/modules/integrated_electronics/subtypes/manipulation.dm
+++ b/code/modules/integrated_electronics/subtypes/manipulation.dm
@@ -11,12 +11,12 @@
complexity = 20
w_class = ITEMSIZE_NORMAL
inputs = list(
- "target X rel",
- "target Y rel"
+ "\ target X rel",
+ "\ target Y rel"
)
outputs = list()
activators = list(
- "fire"
+ "\ fire"
)
var/obj/item/weapon/gun/installed_gun = null
spawn_flags = IC_SPAWN_RESEARCH
diff --git a/code/modules/integrated_electronics/subtypes/power.dm b/code/modules/integrated_electronics/subtypes/power.dm
index 7b3256e06b..3480a83a4a 100644
--- a/code/modules/integrated_electronics/subtypes/power.dm
+++ b/code/modules/integrated_electronics/subtypes/power.dm
@@ -11,9 +11,9 @@
some power is lost due to ineffiency."
w_class = ITEMSIZE_SMALL
complexity = 16
- inputs = list("target ref")
- outputs = list("target cell charge", "target cell max charge", "target cell percentage")
- activators = list("transmit")
+ inputs = list("\][ target")
+ outputs = list("\ target cell charge", "\ target cell max charge", "\ target cell percentage")
+ activators = list("\ transmit")
spawn_flags = IC_SPAWN_RESEARCH
origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_POWER = 4, TECH_MAGNET = 3)
power_draw_per_use = 500 // Inefficency has to come from somewhere.
diff --git a/code/modules/integrated_electronics/subtypes/reagents.dm b/code/modules/integrated_electronics/subtypes/reagents.dm
index e4bd5c15a3..e3b69d31cd 100644
--- a/code/modules/integrated_electronics/subtypes/reagents.dm
+++ b/code/modules/integrated_electronics/subtypes/reagents.dm
@@ -43,39 +43,39 @@
flags = OPENCONTAINER
complexity = 20
cooldown_per_use = 6 SECONDS
- inputs = list("target ref", "injection amount" = 5)
+ inputs = list("\][ target", "\ injection amount" = 5)
outputs = list()
- activators = list("inject")
+ activators = list("\ inject")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
volume = 30
power_draw_per_use = 15
/obj/item/integrated_circuit/reagent/injector/proc/inject_amount()
- var/datum/integrated_io/amount = inputs[2]
- if(isnum(amount.data))
- return Clamp(amount.data, 0, 30)
+ var/amount = get_pin_data(IC_INPUT, 2)
+ if(isnum(amount))
+ return Clamp(amount, 0, 30)
/obj/item/integrated_circuit/reagent/injector/do_work()
set waitfor = 0 // Don't sleep in a proc that is called by a processor without this set, otherwise it'll delay the entire thing
- var/datum/integrated_io/target = inputs[1]
- var/atom/movable/AM = target.data_as_type(/atom/movable)
+ var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
if(!istype(AM)) //Invalid input
return
if(!reagents.total_volume) // Empty
return
if(AM.can_be_injected_by(src))
if(isliving(AM))
+ var/mob/living/L = AM
var/turf/T = get_turf(AM)
- T.visible_message("[src] is trying to inject [AM]!")
+ T.visible_message("[src] is trying to inject [L]!")
sleep(3 SECONDS)
- if(!AM.can_be_injected_by(src))
+ if(!L.can_be_injected_by(src))
return
var/contained = reagents.get_reagents()
- var/trans = reagents.trans_to_mob(target, inject_amount(), CHEM_BLOOD)
- log_debug("[src] injected \the [AM] with [trans]u of [contained].") //VOREStation Edit - I don't care THAT much.
+ var/trans = reagents.trans_to_mob(L, inject_amount(), CHEM_BLOOD)
+ message_admins("[src] injected \the [L] with [trans]u of [contained].")
to_chat(AM, "You feel a tiny prick!")
- visible_message("[src] injects [AM]!")
+ visible_message("[src] injects [L]!")
else
reagents.trans_to(AM, inject_amount())
@@ -88,9 +88,9 @@
outside the machine if it is next to the machine. Note that this cannot be used on entities."
flags = OPENCONTAINER
complexity = 8
- inputs = list("source ref", "target ref", "injection amount" = 10)
+ inputs = list("\][ source", "\][ target", "\ injection amount" = 10)
outputs = list()
- activators = list("transfer reagents")
+ activators = list("\ transfer reagents", "\ on transfer")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
var/transfer_amount = 10
@@ -103,10 +103,9 @@
transfer_amount = amount.data
/obj/item/integrated_circuit/reagent/pump/do_work()
- var/datum/integrated_io/A = inputs[1]
- var/datum/integrated_io/B = inputs[2]
- var/atom/movable/source = A.data_as_type(/atom/movable)
- var/atom/movable/target = B.data_as_type(/atom/movable)
+ var/atom/movable/source = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
+ var/atom/movable/target = get_pin_data_as_type(IC_INPUT, 2, /atom/movable)
+
if(!istype(source) || !istype(target)) //Invalid input
return
var/turf/T = get_turf(src)
@@ -117,10 +116,11 @@
return
if(!source.is_open_container() || !target.is_open_container())
return
- if(!source.reagents.get_free_space() || !target.reagents.get_free_space())
+ if(!target.reagents.get_free_space())
return
source.reagents.trans_to(target, transfer_amount)
+ activate_pin(2)
/obj/item/integrated_circuit/reagent/storage
name = "reagent storage"
diff --git a/code/modules/integrated_electronics/subtypes/smart.dm b/code/modules/integrated_electronics/subtypes/smart.dm
index c159522e97..a90a3f57a3 100644
--- a/code/modules/integrated_electronics/subtypes/smart.dm
+++ b/code/modules/integrated_electronics/subtypes/smart.dm
@@ -8,17 +8,16 @@
cannot see the target, it will not be able to calculate the correct direction."
icon_state = "numberpad"
complexity = 25
- inputs = list("target ref")
- outputs = list("dir")
- activators = list("calculate dir")
+ inputs = list("\][ target")
+ outputs = list("\ dir")
+ activators = list("\ calculate dir", "\ on calculated")
spawn_flags = IC_SPAWN_RESEARCH
origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 5)
power_draw_per_use = 40
/obj/item/integrated_circuit/smart/basic_pathfinder/do_work()
var/datum/integrated_io/I = inputs[1]
- var/datum/integrated_io/O = outputs[1]
- O.data = null
+ set_pin_data(IC_OUTPUT, 1, null)
if(!isweakref(I.data))
return
@@ -28,6 +27,6 @@
if(!(A in view(get_turf(src))))
return // Can't see the target.
var/desired_dir = get_dir(get_turf(src), A)
- if(desired_dir)
- O.data = desired_dir
- O.push_data()
\ No newline at end of file
+
+ set_pin_data(IC_OUTPUT, 1, desired_dir)
+ push_data()
\ No newline at end of file
diff --git a/code/modules/integrated_electronics/subtypes/time.dm b/code/modules/integrated_electronics/subtypes/time.dm
index 72766c0c48..322ee2f9e0 100644
--- a/code/modules/integrated_electronics/subtypes/time.dm
+++ b/code/modules/integrated_electronics/subtypes/time.dm
@@ -12,16 +12,15 @@
This circuit is set to send a pulse after a delay of two seconds."
icon_state = "delay-20"
var/delay = 2 SECONDS
- activators = list("incoming pulse","outgoing pulse")
+ activators = list("\ incoming","\ outgoing")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
power_draw_per_use = 2
/obj/item/integrated_circuit/time/delay/do_work()
set waitfor = 0 // Don't sleep in a proc that is called by a processor. It'll delay the entire thing
- var/datum/integrated_io/out_pulse = activators[2]
sleep(delay)
- out_pulse.push_data()
+ activate_pin(2)
/obj/item/integrated_circuit/time/delay/five_sec
name = "five-sec delay circuit"
@@ -60,14 +59,13 @@
desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \
This circuit's delay can be customized, between 1/10th of a second to one hour. The delay is updated upon receiving a pulse."
icon_state = "delay"
- inputs = list("delay time")
+ inputs = list("\ delay time")
spawn_flags = IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/time/delay/custom/do_work()
- var/datum/integrated_io/delay_input = inputs[1]
- if(delay_input.data && isnum(delay_input.data) )
- var/new_delay = min(delay_input.data, 1)
- new_delay = max(new_delay, 36000) //An hour.
+ var/delay_input = get_pin_data(IC_INPUT, 1)
+ if(delay_input && isnum(delay_input) )
+ var/new_delay = between(1, delay_input, 36000) //An hour.
delay = new_delay
..()
@@ -80,8 +78,8 @@
var/ticks_to_pulse = 4
var/ticks_completed = 0
var/is_running = FALSE
- inputs = list("enable ticking")
- activators = list("outgoing pulse")
+ inputs = list("\ enable ticking" = 0)
+ activators = list("\ outgoing pulse")
spawn_flags = IC_SPAWN_RESEARCH
power_draw_per_use = 4
@@ -91,8 +89,8 @@
. = ..()
/obj/item/integrated_circuit/time/ticker/on_data_written()
- var/datum/integrated_io/do_tick = inputs[1]
- if(do_tick.data && !is_running)
+ var/do_tick = get_pin_data(IC_INPUT, 1)
+ if(do_tick && !is_running)
is_running = TRUE
processing_objects |= src
else if(is_running)
@@ -108,8 +106,7 @@
ticks_completed -= ticks_to_pulse
else
ticks_completed = 0
- var/datum/integrated_io/pulser = activators[1]
- pulser.push_data()
+ activate_pin(1)
/obj/item/integrated_circuit/time/ticker/fast
name = "fast ticker"
@@ -134,20 +131,16 @@
desc = "Tells you what the local time is, specific to your station or planet."
icon_state = "clock"
inputs = list()
- outputs = list("time (string)", "hours (number)", "minutes (number)", "seconds (number)")
+ outputs = list("\ time", "\ hours", "\ minutes", "\ seconds")
+ activators = list("\ get time","\ on time got")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
power_draw_per_use = 4
/obj/item/integrated_circuit/time/clock/do_work()
- var/datum/integrated_io/time = outputs[1]
- var/datum/integrated_io/hour = outputs[2]
- var/datum/integrated_io/min = outputs[3]
- var/datum/integrated_io/sec = outputs[4]
+ set_pin_data(IC_OUTPUT, 1, time2text(station_time_in_ticks, "hh:mm:ss") )
+ set_pin_data(IC_OUTPUT, 2, text2num(time2text(station_time_in_ticks, "hh") ) )
+ set_pin_data(IC_OUTPUT, 3, text2num(time2text(station_time_in_ticks, "mm") ) )
+ set_pin_data(IC_OUTPUT, 4, text2num(time2text(station_time_in_ticks, "ss") ) )
- time.data = time2text(station_time_in_ticks, "hh:mm:ss")
- hour.data = text2num(time2text(station_time_in_ticks, "hh"))
- min.data = text2num(time2text(station_time_in_ticks, "mm"))
- sec.data = text2num(time2text(station_time_in_ticks, "ss"))
-
- for(var/datum/integrated_io/output/O in outputs)
- O.push_data()
\ No newline at end of file
+ push_data()
+ activate_pin(2)
\ No newline at end of file
diff --git a/code/modules/integrated_electronics/subtypes/trig.dm b/code/modules/integrated_electronics/subtypes/trig.dm
index b1a19f4a40..72d779b621 100644
--- a/code/modules/integrated_electronics/subtypes/trig.dm
+++ b/code/modules/integrated_electronics/subtypes/trig.dm
@@ -1,9 +1,18 @@
//These circuits do not-so-simple math.
/obj/item/integrated_circuit/trig
complexity = 1
- inputs = list("A","B","C","D","E","F","G","H")
- outputs = list("result")
- activators = list("compute")
+ inputs = list(
+ "\ A",
+ "\ B",
+ "\ C",
+ "\ D",
+ "\ E",
+ "\ F",
+ "\ G",
+ "\ H"
+ )
+ outputs = list("\ result")
+ activators = list("\ compute", "\ on computed")
category_text = "Trig"
extended_desc = "Input and output are in degrees."
autopulse = 1
@@ -19,19 +28,19 @@
name = "sin circuit"
desc = "Has nothing to do with evil, unless you consider trigonometry to be evil. Outputs the sine of A."
icon_state = "sine"
- inputs = list("A")
+ inputs = list("\ A")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/trig/sine/do_work()
+ pull_data()
var/result = null
- var/datum/integrated_io/input/A = inputs[1]
- A.pull_data()
- if(isnum(A.data))
- result = sin(A.data)
+ var/A = get_pin_data(IC_INPUT, 1)
+ if(isnum(A))
+ result = sin(A)
- var/datum/integrated_io/output/O = outputs[1]
- O.data = result
- O.push_data()
+ set_pin_data(IC_OUTPUT, 1, result)
+ push_data()
+ activate_pin(2)
// Cosine //
@@ -39,19 +48,19 @@
name = "cos circuit"
desc = "Outputs the cosine of A."
icon_state = "cosine"
- inputs = list("A")
+ inputs = list("\ A")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/trig/cosine/do_work()
+ pull_data()
var/result = null
- var/datum/integrated_io/input/A = inputs[1]
- A.pull_data()
- if(isnum(A.data))
- result = cos(A.data)
+ var/A = get_pin_data(IC_INPUT, 1)
+ if(isnum(A))
+ result = cos(A)
- var/datum/integrated_io/output/O = outputs[1]
- O.data = result
- O.push_data()
+ set_pin_data(IC_OUTPUT, 1, result)
+ push_data()
+ activate_pin(2)
// Tangent //
@@ -59,19 +68,19 @@
name = "tan circuit"
desc = "Outputs the tangent of A. Guaranteed to not go on a tangent about its existance."
icon_state = "tangent"
- inputs = list("A")
+ inputs = list("\ A")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/trig/tangent/do_work()
+ pull_data()
var/result = null
- var/datum/integrated_io/input/A = inputs[1]
- A.pull_data()
- if(isnum(A.data))
- result = Tan(A.data)
+ var/A = get_pin_data(IC_INPUT, 1)
+ if(isnum(A))
+ result = Tan(A)
- var/datum/integrated_io/output/O = outputs[1]
- O.data = result
- O.push_data()
+ set_pin_data(IC_OUTPUT, 1, result)
+ push_data()
+ activate_pin(2)
// Cosecant //
@@ -79,19 +88,19 @@
name = "csc circuit"
desc = "Outputs the cosecant of A."
icon_state = "cosecant"
- inputs = list("A")
+ inputs = list("\ A")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/trig/cosecant/do_work()
+ pull_data()
var/result = null
- var/datum/integrated_io/input/A = inputs[1]
- A.pull_data()
- if(isnum(A.data))
- result = Csc(A.data)
+ var/A = get_pin_data(IC_INPUT, 1)
+ if(isnum(A))
+ result = Csc(A)
- var/datum/integrated_io/output/O = outputs[1]
- O.data = result
- O.push_data()
+ set_pin_data(IC_OUTPUT, 1, result)
+ push_data()
+ activate_pin(2)
// Secant //
@@ -100,19 +109,19 @@
name = "sec circuit"
desc = "Outputs the secant of A. Has nothing to do with the security department."
icon_state = "secant"
- inputs = list("A")
+ inputs = list("\ A")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/trig/secant/do_work()
+ pull_data()
var/result = null
- var/datum/integrated_io/input/A = inputs[1]
- A.pull_data()
- if(isnum(A.data))
- result = Sec(A.data)
+ var/A = get_pin_data(IC_INPUT, 1)
+ if(isnum(A))
+ result = Sec(A)
- var/datum/integrated_io/output/O = outputs[1]
- O.data = result
- O.push_data()
+ set_pin_data(IC_OUTPUT, 1, result)
+ push_data()
+ activate_pin(2)
// Cotangent //
@@ -121,16 +130,16 @@
name = "cot circuit"
desc = "Outputs the cotangent of A."
icon_state = "cotangent"
- inputs = list("A")
+ inputs = list("\ A")
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/trig/cotangent/do_work()
+ pull_data()
var/result = null
- var/datum/integrated_io/input/A = inputs[1]
- A.pull_data()
- if(isnum(A.data))
- result = Cot(A.data)
+ var/A = get_pin_data(IC_INPUT, 1)
+ if(isnum(A))
+ result = Cot(A)
- var/datum/integrated_io/output/O = outputs[1]
- O.data = result
- O.push_data()
\ No newline at end of file
+ set_pin_data(IC_OUTPUT, 1, result)
+ push_data()
+ activate_pin(2)
\ No newline at end of file
diff --git a/code/modules/lore_codex/lore_data/species.dm b/code/modules/lore_codex/lore_data/species.dm
index fa8c6d9615..54d72e0718 100644
--- a/code/modules/lore_codex/lore_data/species.dm
+++ b/code/modules/lore_codex/lore_data/species.dm
@@ -38,16 +38,11 @@
/datum/lore/codex/page/unathi
name = "Unathi"
- data = "The author wishes to apologize to the reader, as they currently lack enough knowledge of the Unathi to write about them, as they are \
- rather rare inside Vir." // Replace this when Anewbe finishes the lizard rewrite.
- /*
- data = "Raging in from Moghes, the Unathi are a race of tall, reptilian humanoids that possess both crocodile-like and serpent-like features. \
- They are a proud, warlike species that favors honor and strength, their home, Moghes, is a desert planet but was once believed to be full of life. \
- Of all the currently known sentient species, the Unathi are the most unequal in gender with females tending to be property of the males. Most Unathi \
- outside of Moghes tend to be exiles however, and with influence of other species the gender difference is not nearly as pronounced. Unathi were \
- humanity's second contact, and despite their aggressive nature, seem to get along well enough with humanity, though are often considered to be \
- 'second-class' citizens and are rarely seen in jobs other than where muscle is needed." // This probably needs to be updated.
- */
+ data = "The Unathi are a race of tall, reptilian humanoids that possess a blend of serpentine features reminiscent of crocodiles. \
+ They are a proud, religious species that favors honor and strength, and originate from the desert planet of Moghes. \
+ The Unathi follow a religious code known as the Unity, and they carry this with them on their travels. \
+ Unathi once fought a serious war against SolGov, and as a result are often considered to be second-class citizens, \
+ rarely seen in jobs that don't require a little muscle."
/datum/lore/codex/page/tajaran
name = "Tajaran"
diff --git a/code/modules/materials/material_recipes.dm b/code/modules/materials/material_recipes.dm
index 11f6021c75..68fb129108 100644
--- a/code/modules/materials/material_recipes.dm
+++ b/code/modules/materials/material_recipes.dm
@@ -10,6 +10,7 @@
recipes += new/datum/stack_recipe("[display_name] baseball bat", /obj/item/weapon/material/twohanded/baseballbat, 10, time = 20, one_per_turf = 0, on_floor = 1, supplied_material = "[name]")
recipes += new/datum/stack_recipe("[display_name] ashtray", /obj/item/weapon/material/ashtray, 2, one_per_turf = 1, on_floor = 1, supplied_material = "[name]")
recipes += new/datum/stack_recipe("[display_name] spoon", /obj/item/weapon/material/kitchen/utensil/spoon/plastic, 1, on_floor = 1, supplied_material = "[name]")
+ recipes += new/datum/stack_recipe("[display_name] armor plate", /obj/item/weapon/material/armor_plating, 1, time = 20, on_floor = 1, supplied_material = "[name]")
if(integrity>=50)
recipes += new/datum/stack_recipe("[display_name] door", /obj/structure/simple_door, 10, one_per_turf = 1, on_floor = 1, supplied_material = "[name]")
diff --git a/code/modules/materials/materials.dm b/code/modules/materials/materials.dm
index 66dde62a17..921b28d733 100644
--- a/code/modules/materials/materials.dm
+++ b/code/modules/materials/materials.dm
@@ -90,10 +90,12 @@ var/list/name_to_material
var/ignition_point // K, point at which the material catches on fire.
var/melting_point = 1800 // K, walls will take damage if they're next to a fire hotter than this
var/integrity = 150 // General-use HP value for products.
+ var/protectiveness = 10 // How well this material works as armor. Higher numbers are better, diminishing returns applies.
var/opacity = 1 // Is the material transparent? 0.5< makes transparent walls/doors.
- var/reflectivity = 0 // How reflective to light is the material? Currently used for laser defense.
+ var/reflectivity = 0 // How reflective to light is the material? Currently used for laser reflection and defense.
var/explosion_resistance = 5 // Only used by walls currently.
var/conductive = 1 // Objects with this var add CONDUCTS to flags on spawn.
+ var/conductivity = null // How conductive the material is. Iron acts as the baseline, at 10.
var/list/composite_material // If set, object matter var will be a list containing these values.
// Placeholder vars for the time being, todo properly integrate windows/light tiles/rods.
@@ -103,7 +105,7 @@ var/list/name_to_material
var/list/window_options = list()
// Damage values.
- var/hardness = 60 // Prob of wall destruction by hulk, used for edge damage in weapons.
+ var/hardness = 60 // Prob of wall destruction by hulk, used for edge damage in weapons. Also used for bullet protection in armor.
var/weight = 20 // Determines blunt damage/throwforce for weapons.
// Noise when someone is faceplanted onto a table made of this material.
@@ -236,6 +238,7 @@ var/list/name_to_material
icon_colour = "#00FFE1"
opacity = 0.4
reflectivity = 0.6
+ conductivity = 1
shard_type = SHARD_SHARD
tableslam_noise = 'sound/effects/Glasshit.ogg'
hardness = 100
@@ -247,6 +250,7 @@ var/list/name_to_material
icon_colour = "#EDD12F"
weight = 24
hardness = 40
+ conductivity = 41
stack_origin_tech = list(TECH_MATERIAL = 4)
sheet_singular_name = "ingot"
sheet_plural_name = "ingots"
@@ -261,6 +265,7 @@ var/list/name_to_material
icon_colour = "#D1E6E3"
weight = 22
hardness = 50
+ conductivity = 63
stack_origin_tech = list(TECH_MATERIAL = 3)
sheet_singular_name = "ingot"
sheet_plural_name = "ingots"
@@ -304,6 +309,8 @@ var/list/name_to_material
shard_type = SHARD_STONE_PIECE
weight = 22
hardness = 55
+ protectiveness = 5 // 20%
+ conductivity = 5
door_icon_base = "stone"
sheet_singular_name = "brick"
sheet_plural_name = "bricks"
@@ -320,6 +327,8 @@ var/list/name_to_material
name = DEFAULT_WALL_MATERIAL
stack_type = /obj/item/stack/material/steel
integrity = 150
+ conductivity = 11 // Assuming this is carbon steel, it would actually be slightly less conductive than iron, but lets ignore that.
+ protectiveness = 10 // 33%
icon_base = "solid"
icon_reinf = "reinf_over"
icon_colour = "#666666"
@@ -355,6 +364,8 @@ var/list/name_to_material
explosion_resistance = 25
hardness = 80
weight = 23
+ protectiveness = 20 // 50%
+ conductivity = 13 // For the purposes of balance.
stack_origin_tech = list(TECH_MATERIAL = 2)
composite_material = list(DEFAULT_WALL_MATERIAL = SHEET_MATERIAL_AMOUNT, "platinum" = SHEET_MATERIAL_AMOUNT) //todo
@@ -370,6 +381,7 @@ var/list/name_to_material
explosion_resistance = 75
hardness = 100
weight = 28
+ protectiveness = 60 // 75%
reflectivity = 0.7 // Not a perfect mirror, but close.
stack_origin_tech = list(TECH_MATERIAL = 8)
composite_material = list("plasteel" = SHEET_MATERIAL_AMOUNT, "diamond" = SHEET_MATERIAL_AMOUNT) //shrug
@@ -377,6 +389,7 @@ var/list/name_to_material
/material/plasteel/titanium
name = "titanium"
stack_type = null
+ conductivity = 2.38
icon_base = "metal"
door_icon_base = "metal"
icon_colour = "#D1E6E3"
@@ -393,6 +406,8 @@ var/list/name_to_material
tableslam_noise = 'sound/effects/Glasshit.ogg'
hardness = 30
weight = 15
+ protectiveness = 0 // 0%
+ conductivity = 1 // Glass shards don't conduct.
door_icon_base = "stone"
destruction_desc = "shatters"
window_options = list("One Direction" = 1, "Full Window" = 4, "Windoor" = 2)
@@ -526,6 +541,8 @@ var/list/name_to_material
icon_colour = "#CCCCCC"
hardness = 10
weight = 12
+ protectiveness = 5 // 20%
+ conductivity = 2 // For the sake of material armor diversity, we're gonna pretend this plastic is a good insulator.
melting_point = T0C+371 //assuming heat resistant plastic
stack_origin_tech = list(TECH_MATERIAL = 3)
@@ -556,12 +573,14 @@ var/list/name_to_material
stack_type = /obj/item/stack/material/mhydrogen
icon_colour = "#E6C5DE"
stack_origin_tech = list(TECH_MATERIAL = 6, TECH_POWER = 6, TECH_MAGNET = 5)
+ conductivity = 100
/material/platinum
name = "platinum"
stack_type = /obj/item/stack/material/platinum
icon_colour = "#9999FF"
weight = 27
+ conductivity = 9.43
stack_origin_tech = list(TECH_MATERIAL = 2)
sheet_singular_name = "ingot"
sheet_plural_name = "ingots"
@@ -571,6 +590,7 @@ var/list/name_to_material
stack_type = /obj/item/stack/material/iron
icon_colour = "#5C5454"
weight = 22
+ conductivity = 10
sheet_singular_name = "ingot"
sheet_plural_name = "ingots"
@@ -585,6 +605,7 @@ var/list/name_to_material
explosion_resistance = 200 // Hull plating.
hardness = 500
weight = 500
+ protectiveness = 80 // 80%
// Likewise.
/material/alienalloy/elevatorium
@@ -603,6 +624,8 @@ var/list/name_to_material
shard_can_repair = 0 // you can't weld splinters back into planks
hardness = 15
weight = 18
+ protectiveness = 8 // 28%
+ conductivity = 1
melting_point = T0C+300 //okay, not melting in this case, but hot enough to destroy wood
ignition_point = T0C+288
stack_origin_tech = list(TECH_MATERIAL = 1, TECH_BIO = 1)
@@ -634,6 +657,7 @@ var/list/name_to_material
icon_colour = "#AAAAAA"
hardness = 1
weight = 1
+ protectiveness = 0 // 0%
ignition_point = T0C+232 //"the temperature at which book-paper catches fire, and burns." close enough
melting_point = T0C+232 //temperature at which cardboard walls would be destroyed
stack_origin_tech = list(TECH_MATERIAL = 1)
@@ -650,6 +674,7 @@ var/list/name_to_material
integrity = 1
hardness = 1
weight = 1
+ protectiveness = 0 // 0%
stack_origin_tech = list(TECH_MATERIAL = 1)
melting_point = T0C+1
destruction_desc = "crumples"
@@ -662,6 +687,7 @@ var/list/name_to_material
door_icon_base = "wood"
ignition_point = T0C+232
melting_point = T0C+300
+ protectiveness = 1 // 4%
flags = MATERIAL_PADDING
/material/cult
@@ -695,6 +721,7 @@ var/list/name_to_material
flags = MATERIAL_PADDING
ignition_point = T0C+300
melting_point = T0C+300
+ protectiveness = 3 // 13%
/material/carpet
name = "carpet"
@@ -706,6 +733,7 @@ var/list/name_to_material
melting_point = T0C+300
sheet_singular_name = "tile"
sheet_plural_name = "tiles"
+ protectiveness = 1 // 4%
/material/cotton
name = "cotton"
@@ -714,7 +742,9 @@ var/list/name_to_material
flags = MATERIAL_PADDING
ignition_point = T0C+232
melting_point = T0C+300
+ protectiveness = 1 // 4%
+// This all needs to be OOP'd and use inheritence if its ever used in the future.
/material/cloth_teal
name = "teal"
display_name ="teal"
@@ -723,6 +753,7 @@ var/list/name_to_material
flags = MATERIAL_PADDING
ignition_point = T0C+232
melting_point = T0C+300
+ protectiveness = 1 // 4%
/material/cloth_black
name = "black"
@@ -732,6 +763,7 @@ var/list/name_to_material
flags = MATERIAL_PADDING
ignition_point = T0C+232
melting_point = T0C+300
+ protectiveness = 1 // 4%
/material/cloth_green
name = "green"
@@ -741,6 +773,7 @@ var/list/name_to_material
flags = MATERIAL_PADDING
ignition_point = T0C+232
melting_point = T0C+300
+ protectiveness = 1 // 4%
/material/cloth_puple
name = "purple"
@@ -750,6 +783,7 @@ var/list/name_to_material
flags = MATERIAL_PADDING
ignition_point = T0C+232
melting_point = T0C+300
+ protectiveness = 1 // 4%
/material/cloth_blue
name = "blue"
@@ -759,6 +793,7 @@ var/list/name_to_material
flags = MATERIAL_PADDING
ignition_point = T0C+232
melting_point = T0C+300
+ protectiveness = 1 // 4%
/material/cloth_beige
name = "beige"
@@ -768,6 +803,7 @@ var/list/name_to_material
flags = MATERIAL_PADDING
ignition_point = T0C+232
melting_point = T0C+300
+ protectiveness = 1 // 4%
/material/cloth_lime
name = "lime"
@@ -777,6 +813,7 @@ var/list/name_to_material
flags = MATERIAL_PADDING
ignition_point = T0C+232
melting_point = T0C+300
+ protectiveness = 1 // 4%
/material/toy_foam
name = "foam"
@@ -787,4 +824,5 @@ var/list/name_to_material
melting_point = T0C+300
icon_colour = "#ff9900"
hardness = 1
- weight = 1
\ No newline at end of file
+ weight = 1
+ protectiveness = 0 // 0%
\ No newline at end of file
diff --git a/code/modules/mining/ore.dm b/code/modules/mining/ore.dm
index 128dc17332..e531e5208f 100644
--- a/code/modules/mining/ore.dm
+++ b/code/modules/mining/ore.dm
@@ -37,7 +37,7 @@
var/mob/living/carbon/human/H = hit_atom
if(istype(H) && H.has_eyes() && prob(85))
H << "Some of \the [src] gets in your eyes!"
- H.eye_blind += 5
+ H.Blind(5)
H.eye_blurry += 10
spawn(1)
if(istype(loc, /turf/)) qdel(src)
diff --git a/code/modules/mob/language/station.dm b/code/modules/mob/language/station.dm
index 85942fcb4e..b1411f2fae 100644
--- a/code/modules/mob/language/station.dm
+++ b/code/modules/mob/language/station.dm
@@ -24,7 +24,7 @@
/datum/language/unathi
name = LANGUAGE_UNATHI
- desc = "The common language of Moghes, composed of sibilant hisses and rattles. Spoken natively by Unathi."
+ desc = "The common language of the Moghes Hegemony, composed of sibilant hisses and rattles. Spoken natively by Unathi."
speech_verb = "hisses"
ask_verb = "hisses"
exclaim_verb = "roars"
diff --git a/code/modules/mob/living/bot/bot.dm b/code/modules/mob/living/bot/bot.dm
index 8c61b68a3e..873934c0c7 100644
--- a/code/modules/mob/living/bot/bot.dm
+++ b/code/modules/mob/living/bot/bot.dm
@@ -70,10 +70,10 @@
/mob/living/bot/updatehealth()
if(status_flags & GODMODE)
- health = maxHealth
+ health = getMaxHealth()
stat = CONSCIOUS
else
- health = maxHealth - getFireLoss() - getBruteLoss()
+ health = getMaxHealth() - getFireLoss() - getBruteLoss()
oxyloss = 0
toxloss = 0
cloneloss = 0
@@ -104,9 +104,9 @@
user << "You need to unlock the controls first."
return
else if(istype(O, /obj/item/weapon/weldingtool))
- if(health < maxHealth)
+ if(health < getMaxHealth())
if(open)
- health = min(maxHealth, health + 10)
+ health = min(getMaxHealth(), health + 10)
user.visible_message("[user] repairs [src].","You repair [src].")
else
user << "Unable to repair with the maintenance panel closed."
@@ -224,7 +224,7 @@
/mob/living/bot/proc/getPatrolTurf()
var/minDist = INFINITY
var/obj/machinery/navbeacon/targ = locate() in get_turf(src)
-
+
if(!targ)
for(var/obj/machinery/navbeacon/N in navbeacons)
if(!N.codes["patrol"])
diff --git a/code/modules/mob/living/carbon/alien/life.dm b/code/modules/mob/living/carbon/alien/life.dm
index a7764d3d1d..fd48b912a0 100644
--- a/code/modules/mob/living/carbon/alien/life.dm
+++ b/code/modules/mob/living/carbon/alien/life.dm
@@ -73,11 +73,11 @@
// Eyes and blindness.
if(!has_eyes())
- eye_blind = 1
+ SetBlinded(1)
blinded = 1
eye_blurry = 1
else if(eye_blind)
- eye_blind = max(eye_blind-1,0)
+ AdjustBlinded(-1)
blinded = 1
else if(eye_blurry)
eye_blurry = max(eye_blurry-1, 0)
diff --git a/code/modules/mob/living/carbon/brain/life.dm b/code/modules/mob/living/carbon/brain/life.dm
index 3f41f21ce5..bac50b1e62 100644
--- a/code/modules/mob/living/carbon/brain/life.dm
+++ b/code/modules/mob/living/carbon/brain/life.dm
@@ -76,7 +76,7 @@
if(ingested) ingested.metabolize()
if(bloodstr) bloodstr.metabolize()
- confused = max(0, confused - 1)
+ AdjustConfused(-1)
// decrement dizziness counter, clamped to 0
if(resting)
dizziness = max(0, dizziness - 5)
@@ -110,7 +110,7 @@
if(31 to INFINITY)
emp_damage = 30//Let's not overdo it
if(21 to 30)//High level of EMP damage, unable to see, hear, or speak
- eye_blind = 1
+ SetBlinded(1)
blinded = 1
ear_deaf = 1
silent = 1
@@ -123,7 +123,7 @@
if(20)
alert = 0
blinded = 0
- eye_blind = 0
+ SetBlinded(0)
ear_deaf = 0
silent = 0
emp_damage -= 1
diff --git a/code/modules/mob/living/carbon/give.dm b/code/modules/mob/living/carbon/give.dm
index 6370380b29..58c26a56e2 100644
--- a/code/modules/mob/living/carbon/give.dm
+++ b/code/modules/mob/living/carbon/give.dm
@@ -1,11 +1,11 @@
-/mob/living/carbon/human/verb/give(var/mob/living/target in view(1)-usr)
+/mob/living/carbon/human/verb/give(var/mob/living/carbon/target in view(1)-usr)
set category = "IC"
set name = "Give"
// TODO : Change to incapacitated() on merge.
- if(src.stat || src.lying || src.resting || src.buckled)
+ if(src.stat || src.lying || src.resting || src.handcuffed)
return
- if(!istype(target) || target.stat || target.lying || target.resting || target.buckled || target.client == null)
+ if(!istype(target) || target.stat || target.lying || target.resting || target.handcuffed || target.client == null)
return
var/obj/item/I = src.get_active_hand()
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index de58677c81..e6865ef51e 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -94,6 +94,7 @@
if(mind.changeling)
stat("Chemical Storage", mind.changeling.chem_charges)
stat("Genetic Damage Time", mind.changeling.geneticdamage)
+ stat("Re-Adaptations", "[mind.changeling.readapts]/[mind.changeling.max_readapts]")
/mob/living/carbon/human/ex_act(severity)
if(!blinded)
@@ -1518,3 +1519,11 @@
/mob/living/carbon/human/is_muzzled()
return (wear_mask && (istype(wear_mask, /obj/item/clothing/mask/muzzle) || istype(src.wear_mask, /obj/item/weapon/grenade)))
+// Called by job_controller. Makes drones start with a permit, might be useful for other people later too.
+/mob/living/carbon/human/equip_post_job()
+ var/braintype = get_FBP_type()
+ if(braintype == FBP_DRONE)
+ var/turf/T = get_turf(src)
+ var/obj/item/weapon/permit/drone/permit = new(T)
+ permit.set_name(real_name)
+ equip_to_appropriate_slot(permit) // If for some reason it can't find room, it'll still be on the floor.
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm
index fa3d19ebab..02d85bbcfa 100644
--- a/code/modules/mob/living/carbon/human/human_damage.dm
+++ b/code/modules/mob/living/carbon/human/human_damage.dm
@@ -2,7 +2,7 @@
/mob/living/carbon/human/updatehealth()
if(status_flags & GODMODE)
- health = maxHealth
+ health = getMaxHealth()
stat = CONSCIOUS
return
@@ -14,10 +14,10 @@
total_brute += O.brute_dam
total_burn += O.burn_dam
- health = maxHealth - getOxyLoss() - getToxLoss() - getCloneLoss() - total_burn - total_brute
+ health = getMaxHealth() - getOxyLoss() - getToxLoss() - getCloneLoss() - total_burn - total_brute
//TODO: fix husking
- if( ((maxHealth - total_burn) < config.health_threshold_dead) && stat == DEAD)
+ if( ((getMaxHealth() - total_burn) < config.health_threshold_dead) && stat == DEAD)
ChangeToHusk()
return
@@ -42,7 +42,7 @@
if(should_have_organ("brain"))
var/obj/item/organ/internal/brain/sponge = internal_organs_by_name["brain"]
if(sponge)
- sponge.damage = min(max(amount, 0),(maxHealth*2))
+ sponge.damage = min(max(amount, 0),(getMaxHealth()*2))
brainloss = sponge.damage
else
brainloss = 200
@@ -56,7 +56,7 @@
if(should_have_organ("brain"))
var/obj/item/organ/internal/brain/sponge = internal_organs_by_name["brain"]
if(sponge)
- brainloss = min(sponge.damage,maxHealth*2)
+ brainloss = min(sponge.damage,getMaxHealth()*2)
else
brainloss = 200
else
@@ -99,16 +99,32 @@
/mob/living/carbon/human/adjustBruteLoss(var/amount)
amount = amount*species.brute_mod
if(amount > 0)
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.incoming_damage_percent))
+ amount *= M.incoming_damage_percent
+ if(!isnull(M.incoming_brute_damage_percent))
+ amount *= M.incoming_brute_damage_percent
take_overall_damage(amount, 0)
else
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.incoming_healing_percent))
+ amount *= M.incoming_healing_percent
heal_overall_damage(-amount, 0)
BITSET(hud_updateflag, HEALTH_HUD)
/mob/living/carbon/human/adjustFireLoss(var/amount)
amount = amount*species.burn_mod
if(amount > 0)
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.incoming_damage_percent))
+ amount *= M.incoming_damage_percent
+ if(!isnull(M.incoming_fire_damage_percent))
+ amount *= M.incoming_fire_damage_percent
take_overall_damage(0, amount)
else
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.incoming_healing_percent))
+ amount *= M.incoming_healing_percent
heal_overall_damage(0, -amount)
BITSET(hud_updateflag, HEALTH_HUD)
@@ -118,8 +134,16 @@
var/obj/item/organ/external/O = get_organ(organ_name)
if(amount > 0)
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.incoming_damage_percent))
+ amount *= M.incoming_damage_percent
+ if(!isnull(M.incoming_brute_damage_percent))
+ amount *= M.incoming_brute_damage_percent
O.take_damage(amount, 0, sharp=is_sharp(damage_source), edge=has_edge(damage_source), used_weapon=damage_source)
else
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.incoming_healing_percent))
+ amount *= M.incoming_healing_percent
//if you don't want to heal robot organs, they you will have to check that yourself before using this proc.
O.heal_damage(-amount, 0, internal=0, robo_repair=(O.robotic >= ORGAN_ROBOT))
@@ -131,8 +155,16 @@
var/obj/item/organ/external/O = get_organ(organ_name)
if(amount > 0)
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.incoming_damage_percent))
+ amount *= M.incoming_damage_percent
+ if(!isnull(M.incoming_fire_damage_percent))
+ amount *= M.incoming_fire_damage_percent
O.take_damage(0, amount, sharp=is_sharp(damage_source), edge=has_edge(damage_source), used_weapon=damage_source)
else
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.incoming_healing_percent))
+ amount *= M.incoming_healing_percent
//if you don't want to heal robot organs, they you will have to check that yourself before using this proc.
O.heal_damage(0, -amount, internal=0, robo_repair=(O.robotic >= ORGAN_ROBOT))
@@ -400,11 +432,25 @@ This function restores all organs.
if(BRUTE)
damageoverlaytemp = 20
damage = damage*species.brute_mod
+
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.incoming_damage_percent))
+ damage *= M.incoming_damage_percent
+ if(!isnull(M.incoming_brute_damage_percent))
+ damage *= M.incoming_brute_damage_percent
+
if(organ.take_damage(damage, 0, sharp, edge, used_weapon))
UpdateDamageIcon()
if(BURN)
damageoverlaytemp = 20
damage = damage*species.burn_mod
+
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.incoming_damage_percent))
+ damage *= M.incoming_damage_percent
+ if(!isnull(M.incoming_brute_damage_percent))
+ damage *= M.incoming_fire_damage_percent
+
if(organ.take_damage(0, damage, sharp, edge, used_weapon))
UpdateDamageIcon()
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 86bbdebc15..61b13316b8 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -27,6 +27,11 @@ emp_act
if(!P.nodamage)
organ.add_autopsy_data("[P.name]", P.damage)
+ // Tell clothing we're wearing that it got hit by a bullet/laser/etc
+ var/list/clothing = get_clothing_list_organ(organ)
+ for(var/obj/item/clothing/C in clothing)
+ C.clothing_impact(P, P.damage)
+
//Shrapnel
if(P.can_embed())
var/armor = getarmor_organ(organ, "bullet")
@@ -130,6 +135,15 @@ emp_act
return siemens_coefficient
+// Returns a list of clothing that is currently covering def_zone.
+/mob/living/carbon/human/proc/get_clothing_list_organ(var/obj/item/organ/external/def_zone, var/type)
+ var/list/results = list()
+ var/list/clothing_items = list(head, wear_mask, wear_suit, w_uniform, gloves, shoes)
+ for(var/obj/item/clothing/C in clothing_items)
+ if(istype(C) && (C.body_parts_covered & def_zone.body_part))
+ results.Add(C)
+ return results
+
//this proc returns the armour value for a particular external organ.
/mob/living/carbon/human/proc/getarmor_organ(var/obj/item/organ/external/def_zone, var/type)
if(!type || !def_zone) return 0
@@ -231,10 +245,6 @@ emp_act
var/soaked = get_armor_soak(hit_zone, "melee", I.armor_penetration)
- if(soaked >= effective_force)
- src << "Your armor absorbs the force of [I.name]!"
- return
-
var/blocked = run_armor_check(hit_zone, "melee", I.armor_penetration, "Your armor has protected your [affecting.name].", "Your armor has softened the blow to your [affecting.name].")
standard_weapon_hit_effects(I, user, effective_force, blocked, soaked, hit_zone)
@@ -246,9 +256,14 @@ emp_act
if(!affecting)
return 0
- if(soaked >= effective_force)
- return 0
+ // Allow clothing to respond to being hit.
+ // This is done up here so that clothing damage occurs even if fully blocked.
+ var/list/clothing = get_clothing_list_organ(affecting)
+ for(var/obj/item/clothing/C in clothing)
+ C.clothing_impact(I, effective_force)
+ if(soaked >= round(effective_force*0.8))
+ effective_force -= round(effective_force*0.8)
// Handle striking to cripple.
if(user.a_intent == I_DISARM)
effective_force *= 0.5 //reduced effective force...
@@ -309,12 +324,15 @@ emp_act
return 1
/mob/living/carbon/human/proc/attack_joint(var/obj/item/organ/external/organ, var/obj/item/W, var/effective_force, var/dislocate_mult, var/blocked, var/soaked)
- if(!organ || (organ.dislocated == 2) || (organ.dislocated == -1) || blocked >= 100 || soaked > effective_force)
+ if(!organ || (organ.dislocated == 2) || (organ.dislocated == -1) || blocked >= 100)
return 0
if(W.damtype != BRUTE)
return 0
+ if(soaked >= round(effective_force*0.8))
+ effective_force -= round(effective_force*0.8)
+
//want the dislocation chance to be such that the limb is expected to dislocate after dealing a fraction of the damage needed to break the limb
var/dislocate_chance = effective_force/(dislocate_mult * organ.min_broken_damage * config.organ_health_multiplier)*100
if(prob(dislocate_chance * (100 - blocked)/100))
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 34f5f44015..5e35d29599 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -95,3 +95,5 @@
mob_swap_flags = ~HEAVY
var/identifying_gender // In case the human identifies as another gender than it's biological
+
+ var/step_count = 0 // Track how many footsteps have been taken to know when to play footstep sounds
diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm
index 7682f675b0..cb49001d3c 100644
--- a/code/modules/mob/living/carbon/human/human_helpers.dm
+++ b/code/modules/mob/living/carbon/human/human_helpers.dm
@@ -90,6 +90,24 @@
return 0
+// Returns a string based on what kind of brain the FBP has.
+/mob/living/carbon/human/proc/get_FBP_type()
+ if(!isSynthetic())
+ return FBP_NONE
+ var/obj/item/organ/internal/brain/B
+ B = internal_organs_by_name[O_BRAIN]
+ if(B) // Incase we lost our brain for some reason, like if we got decapped.
+ if(istype(B, /obj/item/organ/internal/mmi_holder))
+ var/obj/item/organ/internal/mmi_holder/mmi_holder = B
+ if(istype(mmi_holder.stored_mmi, /obj/item/device/mmi/digital/posibrain))
+ return FBP_POSI
+ else if(istype(mmi_holder.stored_mmi, /obj/item/device/mmi/digital/robot))
+ return FBP_DRONE
+ else if(istype(mmi_holder.stored_mmi, /obj/item/device/mmi)) // This needs to come last because inheritence.
+ return FBP_CYBORG
+
+ return FBP_NONE
+
#undef HUMAN_EATING_NO_ISSUE
#undef HUMAN_EATING_NO_MOUTH
#undef HUMAN_EATING_BLOCKED_MOUTH
diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm
index aa4dd28c3b..29289d34b6 100644
--- a/code/modules/mob/living/carbon/human/human_movement.dm
+++ b/code/modules/mob/living/carbon/human/human_movement.dm
@@ -15,7 +15,11 @@
if(force_max_speed)
return -3 // Returning -1 will actually result in a slowdown for Teshari.
- var/health_deficiency = (maxHealth - health)
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.slowdown))
+ tally += M.slowdown
+
+ var/health_deficiency = (getMaxHealth() - health)
if(health_deficiency >= 40) tally += (health_deficiency / 25)
if(can_feel_pain())
@@ -146,3 +150,36 @@
prob_slip = round(prob_slip)
return(prob_slip)
+
+// Handle footstep sounds
+/mob/living/carbon/human/handle_footstep(var/turf/T)
+ if(!config.footstep_volume || !T.footstep_sounds || !T.footstep_sounds.len)
+ return
+ // Future Upgrades - Multi species support
+ var/list/footstep_sounds = T.footstep_sounds["human"]
+ if(!footstep_sounds)
+ return
+
+ var/S = pick(footstep_sounds)
+ if(!S) return
+
+ // Only play every other step while running
+ if(m_intent == "run" && step_count++ % 2 == 0)
+ return
+
+ var/volume = config.footstep_volume
+ // Reduce volume while walking or barefoot
+ if(!shoes || m_intent != "run")
+ volume *= 0.5
+
+ if(!has_organ(BP_L_FOOT) && !has_organ(BP_R_FOOT))
+ return // no feet = no footsteps
+
+ if(buckled || lying || throwing)
+ return // people flying, lying down or sitting do not step
+
+ if(!has_gravity(src) && prob(75))
+ return // Far less likely to make noise in no gravity
+
+ playsound(T, S, volume, FALSE)
+ return
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index a44b1e8351..3ae084dc4f 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -971,18 +971,18 @@
vision = internal_organs_by_name[species.vision_organ]
if(!species.vision_organ) // Presumably if a species has no vision organs, they see via some other means.
- eye_blind = 0
+ SetBlinded(0)
blinded = 0
eye_blurry = 0
else if(!vision || vision.is_broken()) // Vision organs cut out or broken? Permablind.
- eye_blind = 1
+ SetBlinded(1)
blinded = 1
eye_blurry = 1
else //You have the requisite organs
if(sdisabilities & BLIND) // Disabled-blind, doesn't get better on its own
blinded = 1
else if(eye_blind) // Blindness, heals slowly over time
- eye_blind = max(eye_blind-1,0)
+ AdjustBlinded(-1)
blinded = 1
else if(istype(glasses, /obj/item/clothing/glasses/sunglasses/blindfold)) //resting your eyes with a blindfold heals blurry eyes faster
eye_blurry = max(eye_blurry-3, 0)
@@ -1542,7 +1542,7 @@
if(stat == DEAD)
holder.icon_state = "-100" // X_X
else
- holder.icon_state = RoundHealth((health-config.health_threshold_crit)/(maxHealth-config.health_threshold_crit)*100)
+ holder.icon_state = RoundHealth((health-config.health_threshold_crit)/(getMaxHealth()-config.health_threshold_crit)*100)
hud_list[HEALTH_HUD] = holder
if (BITTEST(hud_updateflag, LIFE_HUD))
diff --git a/code/modules/mob/living/carbon/human/species/station/station.dm b/code/modules/mob/living/carbon/human/species/station/station.dm
index 7a0181b167..07876d1985 100644
--- a/code/modules/mob/living/carbon/human/species/station/station.dm
+++ b/code/modules/mob/living/carbon/human/species/station/station.dm
@@ -36,6 +36,8 @@
slowdown = 0.5
brute_mod = 0.9
burn_mod = 0.9
+ metabolic_rate = 0.85
+ item_slowdown_halved = 1
num_alternate_languages = 3
secondary_langs = list(LANGUAGE_UNATHI)
name_language = LANGUAGE_UNATHI
@@ -62,11 +64,36 @@
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
flesh_color = "#34AF10"
-
- //reagent_tag = IS_UNATHI //VOREStation Removal
+ blood_color = "#b3cbc3"
base_color = "#066000"
- //heat_discomfort_level = 295 //VOREStation Removal
+ //reagent_tag = IS_UNATHI //VOREStation Edit
+
+ has_limbs = list(
+ BP_TORSO = list("path" = /obj/item/organ/external/chest/unathi),
+ BP_GROIN = list("path" = /obj/item/organ/external/groin/unathi),
+ BP_HEAD = list("path" = /obj/item/organ/external/head/unathi),
+ BP_L_ARM = list("path" = /obj/item/organ/external/arm),
+ BP_R_ARM = list("path" = /obj/item/organ/external/arm/right),
+ BP_L_LEG = list("path" = /obj/item/organ/external/leg),
+ BP_R_LEG = list("path" = /obj/item/organ/external/leg/right),
+ BP_L_HAND = list("path" = /obj/item/organ/external/hand),
+ BP_R_HAND = list("path" = /obj/item/organ/external/hand/right),
+ BP_L_FOOT = list("path" = /obj/item/organ/external/foot),
+ BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right)
+ )
+
+ //No kidneys or appendix
+ has_organ = list(
+ O_HEART = /obj/item/organ/internal/heart/unathi,
+ O_LUNGS = /obj/item/organ/internal/lungs/unathi,
+ O_LIVER = /obj/item/organ/internal/liver/unathi,
+ O_BRAIN = /obj/item/organ/internal/brain/unathi,
+ O_EYES = /obj/item/organ/internal/eyes,
+ )
+
+
+ //heat_discomfort_level = 295 //VOREStation Edit
heat_discomfort_strings = list(
"You feel soothingly warm.",
"You feel the heat sink into your bones.",
diff --git a/code/modules/mob/living/carbon/metroid/life.dm b/code/modules/mob/living/carbon/metroid/life.dm
index 7bbc4110dd..0f393a9417 100644
--- a/code/modules/mob/living/carbon/metroid/life.dm
+++ b/code/modules/mob/living/carbon/metroid/life.dm
@@ -80,7 +80,7 @@
src.blinded = null
- health = maxHealth - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss())
+ health = getMaxHealth() - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss())
if(health < 0 && stat != DEAD)
death()
@@ -118,7 +118,7 @@
if (src.stuttering) src.stuttering = 0
if (src.eye_blind)
- src.eye_blind = 0
+ SetBlinded(0)
src.blinded = 1
if (src.ear_deaf > 0) src.ear_deaf = 0
diff --git a/code/modules/mob/living/carbon/metroid/metroid.dm b/code/modules/mob/living/carbon/metroid/metroid.dm
index 3c0bfbdbad..5fdea4a0e6 100644
--- a/code/modules/mob/living/carbon/metroid/metroid.dm
+++ b/code/modules/mob/living/carbon/metroid/metroid.dm
@@ -81,7 +81,7 @@
var/tally = 0
- var/health_deficiency = (maxHealth - health)
+ var/health_deficiency = (getMaxHealth() - health)
if(health_deficiency >= 30) tally += (health_deficiency / 25)
if (bodytemperature < 183.222)
@@ -146,7 +146,7 @@
..()
statpanel("Status")
- stat(null, "Health: [round((health / maxHealth) * 100)]%")
+ stat(null, "Health: [round((health / getMaxHealth()) * 100)]%")
stat(null, "Intent: [a_intent]")
if (client.statpanel == "Status")
diff --git a/code/modules/mob/living/carbon/metroid/powers.dm b/code/modules/mob/living/carbon/metroid/powers.dm
index 933596ef5e..9e20d49a44 100644
--- a/code/modules/mob/living/carbon/metroid/powers.dm
+++ b/code/modules/mob/living/carbon/metroid/powers.dm
@@ -21,7 +21,7 @@
return "I cannot feed on other slimes..."
if (!Adjacent(M))
return "This subject is too far away..."
- if (istype(M, /mob/living/carbon) && M.getCloneLoss() >= M.maxHealth * 1.5 || istype(M, /mob/living/simple_animal) && M.stat == DEAD)
+ if (istype(M, /mob/living/carbon) && M.getCloneLoss() >= M.getMaxHealth() * 1.5 || istype(M, /mob/living/simple_animal) && M.stat == DEAD)
return "This subject does not have an edible life energy..."
for(var/mob/living/carbon/slime/met in view())
if(met.Victim == M && met != src)
diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm
index 552319e6fe..0fa139c36f 100644
--- a/code/modules/mob/living/damage_procs.dm
+++ b/code/modules/mob/living/damage_procs.dm
@@ -11,10 +11,13 @@
/mob/living/proc/apply_damage(var/damage = 0,var/damagetype = BRUTE, var/def_zone = null, var/blocked = 0, var/soaked = 0, var/used_weapon = null, var/sharp = 0, var/edge = 0)
if(Debug2)
world.log << "## DEBUG: apply_damage() was called on [src], with [damage] damage, and an armor value of [blocked]."
- if(!damage || (blocked >= 100) || soaked >= damage)
+ if(!damage || (blocked >= 100))
return 0
if(soaked)
- damage -= soaked
+ if(soaked >= round(damage*0.8))
+ damage -= round(damage*0.8)
+ else
+ damage -= soaked
blocked = (100-blocked)/100
switch(damagetype)
if(BRUTE)
diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm
index 3e707b7c4c..c24f5b7236 100644
--- a/code/modules/mob/living/life.dm
+++ b/code/modules/mob/living/life.dm
@@ -10,6 +10,8 @@
return
var/datum/gas_mixture/environment = loc.return_air()
+ handle_modifiers() // Do this early since it might affect other things later.
+
if(stat != DEAD)
//Breathing, if applicable
handle_breathing()
@@ -150,9 +152,9 @@
/mob/living/proc/handle_disabilities()
//Eyes
if(sdisabilities & BLIND || stat) //blindness from disability or unconsciousness doesn't get better on its own
- eye_blind = max(eye_blind, 1)
+ SetBlinded(1)
else if(eye_blind) //blindness, heals slowly over time
- eye_blind = max(eye_blind-1,0)
+ AdjustBlinded(-1)
else if(eye_blurry) //blurry eyes heal slowly
eye_blurry = max(eye_blurry-1, 0)
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index a077319edc..dafeb2d37d 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -163,9 +163,9 @@ default behaviour is:
/mob/living/verb/succumb()
set hidden = 1
- if ((src.health < 0 && src.health > (5-src.maxHealth))) // Health below Zero but above 5-away-from-death, as before, but variable
- src.adjustOxyLoss(src.health + src.maxHealth * 2) // Deal 2x health in OxyLoss damage, as before but variable.
- src.health = src.maxHealth - src.getOxyLoss() - src.getToxLoss() - src.getFireLoss() - src.getBruteLoss()
+ if ((src.health < 0 && src.health > (5-src.getMaxHealth()))) // Health below Zero but above 5-away-from-death, as before, but variable
+ src.adjustOxyLoss(src.health + src.getMaxHealth() * 2) // Deal 2x health in OxyLoss damage, as before but variable.
+ src.health = src.getMaxHealth() - src.getOxyLoss() - src.getToxLoss() - src.getFireLoss() - src.getBruteLoss()
src << "\blue You have given up life and succumbed to death."
@@ -174,7 +174,7 @@ default behaviour is:
health = 100
stat = CONSCIOUS
else
- health = maxHealth - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss() - getCloneLoss() - halloss
+ health = getMaxHealth() - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss() - getCloneLoss() - halloss
//This proc is used for mobs which are affected by pressure to calculate the amount of pressure that actually
@@ -236,14 +236,38 @@ default behaviour is:
/mob/living/proc/adjustBruteLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
- bruteloss = min(max(bruteloss + amount, 0),(maxHealth*2))
+
+ if(amount > 0)
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.incoming_damage_percent))
+ amount *= M.incoming_damage_percent
+ if(!isnull(M.incoming_brute_damage_percent))
+ amount *= M.incoming_brute_damage_percent
+ else if(amount < 0)
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.incoming_healing_percent))
+ amount *= M.incoming_healing_percent
+
+ bruteloss = min(max(bruteloss + amount, 0),(getMaxHealth()*2))
/mob/living/proc/getOxyLoss()
return oxyloss
/mob/living/proc/adjustOxyLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
- oxyloss = min(max(oxyloss + amount, 0),(maxHealth*2))
+
+ if(amount > 0)
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.incoming_damage_percent))
+ amount *= M.incoming_damage_percent
+ if(!isnull(M.incoming_oxy_damage_percent))
+ amount *= M.incoming_oxy_damage_percent
+ else if(amount < 0)
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.incoming_healing_percent))
+ amount *= M.incoming_healing_percent
+
+ oxyloss = min(max(oxyloss + amount, 0),(getMaxHealth()*2))
/mob/living/proc/setOxyLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
@@ -254,7 +278,19 @@ default behaviour is:
/mob/living/proc/adjustToxLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
- toxloss = min(max(toxloss + amount, 0),(maxHealth*2))
+
+ if(amount > 0)
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.incoming_damage_percent))
+ amount *= M.incoming_damage_percent
+ if(!isnull(M.incoming_tox_damage_percent))
+ amount *= M.incoming_tox_damage_percent
+ else if(amount < 0)
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.incoming_healing_percent))
+ amount *= M.incoming_healing_percent
+
+ toxloss = min(max(toxloss + amount, 0),(getMaxHealth()*2))
/mob/living/proc/setToxLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
@@ -268,14 +304,37 @@ default behaviour is:
/mob/living/proc/adjustFireLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
- fireloss = min(max(fireloss + amount, 0),(maxHealth*2))
+ if(amount > 0)
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.incoming_damage_percent))
+ amount *= M.incoming_damage_percent
+ if(!isnull(M.incoming_fire_damage_percent))
+ amount *= M.incoming_fire_damage_percent
+ else if(amount < 0)
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.incoming_healing_percent))
+ amount *= M.incoming_healing_percent
+
+ fireloss = min(max(fireloss + amount, 0),(getMaxHealth()*2))
/mob/living/proc/getCloneLoss()
return cloneloss
/mob/living/proc/adjustCloneLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
- cloneloss = min(max(cloneloss + amount, 0),(maxHealth*2))
+
+ if(amount > 0)
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.incoming_damage_percent))
+ amount *= M.incoming_damage_percent
+ if(!isnull(M.incoming_clone_damage_percent))
+ amount *= M.incoming_clone_damage_percent
+ else if(amount < 0)
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.incoming_healing_percent))
+ amount *= M.incoming_healing_percent
+
+ cloneloss = min(max(cloneloss + amount, 0),(getMaxHealth()*2))
/mob/living/proc/setCloneLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
@@ -286,7 +345,7 @@ default behaviour is:
/mob/living/proc/adjustBrainLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
- brainloss = min(max(brainloss + amount, 0),(maxHealth*2))
+ brainloss = min(max(brainloss + amount, 0),(getMaxHealth()*2))
/mob/living/proc/setBrainLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
@@ -297,18 +356,117 @@ default behaviour is:
/mob/living/proc/adjustHalLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
- halloss = min(max(halloss + amount, 0),(maxHealth*2))
+ if(amount > 0)
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.incoming_damage_percent))
+ amount *= M.incoming_damage_percent
+ if(!isnull(M.incoming_hal_damage_percent))
+ amount *= M.incoming_hal_damage_percent
+ if(!isnull(M.disable_duration_percent))
+ amount *= M.incoming_hal_damage_percent
+ else if(amount < 0)
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.incoming_healing_percent))
+ amount *= M.incoming_healing_percent
+ halloss = min(max(halloss + amount, 0),(getMaxHealth()*2))
/mob/living/proc/setHalLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
halloss = amount
+// Use this to get a mob's max health whenever possible. Reading maxHealth directly will give inaccurate results if any modifiers exist.
/mob/living/proc/getMaxHealth()
- return maxHealth
+ var/result = maxHealth
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.max_health_flat))
+ result += M.max_health_flat
+ // Second loop is so we can get all the flat adjustments first before multiplying, otherwise the result will be different.
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.max_health_percent))
+ result *= M.max_health_percent
+ return result
/mob/living/proc/setMaxHealth(var/newMaxHealth)
maxHealth = newMaxHealth
+/mob/living/Stun(amount)
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.disable_duration_percent))
+ amount = round(amount * M.disable_duration_percent)
+ ..(amount)
+
+/mob/living/AdjustStunned(amount)
+ if(amount > 0)
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.disable_duration_percent))
+ amount = round(amount * M.disable_duration_percent)
+ ..(amount)
+
+/mob/living/Weaken(amount)
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.disable_duration_percent))
+ amount = round(amount * M.disable_duration_percent)
+ ..(amount)
+
+/mob/living/AdjustWeakened(amount)
+ if(amount > 0)
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.disable_duration_percent))
+ amount = round(amount * M.disable_duration_percent)
+ ..(amount)
+
+/mob/living/Paralyse(amount)
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.disable_duration_percent))
+ amount = round(amount * M.disable_duration_percent)
+ ..(amount)
+
+/mob/living/AdjustParalysis(amount)
+ if(amount > 0)
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.disable_duration_percent))
+ amount = round(amount * M.disable_duration_percent)
+ ..(amount)
+
+/mob/living/Sleeping(amount)
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.disable_duration_percent))
+ amount = round(amount * M.disable_duration_percent)
+ ..(amount)
+
+/mob/living/AdjustSleeping(amount)
+ if(amount > 0)
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.disable_duration_percent))
+ amount = round(amount * M.disable_duration_percent)
+ ..(amount)
+
+/mob/living/Confuse(amount)
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.disable_duration_percent))
+ amount = round(amount * M.disable_duration_percent)
+ ..(amount)
+
+/mob/living/AdjustConfused(amount)
+ if(amount > 0)
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.disable_duration_percent))
+ amount = round(amount * M.disable_duration_percent)
+ ..(amount)
+
+/mob/living/Blind(amount)
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.disable_duration_percent))
+ amount = round(amount * M.disable_duration_percent)
+ ..(amount)
+
+/mob/living/AdjustBlinded(amount)
+ if(amount > 0)
+ for(var/datum/modifier/M in modifiers)
+ if(!isnull(M.disable_duration_percent))
+ amount = round(amount * M.disable_duration_percent)
+ ..(amount)
+
// ++++ROCKDTBEN++++ MOB PROCS //END
/mob/proc/get_contents()
@@ -446,7 +604,7 @@ default behaviour is:
// fix blindness and deafness
blinded = 0
- eye_blind = 0
+ SetBlinded(0)
eye_blurry = 0
ear_deaf = 0
ear_damage = 0
@@ -585,6 +743,9 @@ default behaviour is:
for(var/mob/living/carbon/slime/M in view(1,src))
M.UpdateFeed(src)
+/mob/living/proc/handle_footstep(turf/T)
+ return FALSE
+
/mob/living/verb/resist()
set name = "Resist"
set category = "IC"
@@ -821,3 +982,7 @@ default behaviour is:
if(isSynthetic())
return FALSE
return TRUE
+
+// Called by job_controller.
+/mob/living/proc/equip_post_job()
+ return
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 8a49ed8922..b60ff078a3 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -107,6 +107,11 @@
var/absorb = run_armor_check(def_zone, P.check_armour, P.armor_penetration)
var/proj_sharp = is_sharp(P)
var/proj_edge = has_edge(P)
+
+ if ((proj_sharp || proj_edge) && (soaked >= round(P.damage*0.8)))
+ proj_sharp = 0
+ proj_edge = 0
+
if ((proj_sharp || proj_edge) && prob(getarmor(def_zone, P.check_armour)))
proj_sharp = 0
proj_edge = 0
@@ -167,13 +172,11 @@
var/soaked = get_armor_soak(hit_zone, "melee")
var/blocked = run_armor_check(hit_zone, "melee")
- //If the armor absorbs all of the damage, skip the damage calculation and the blood
- if(!(soaked > effective_force))
- standard_weapon_hit_effects(I, user, effective_force, blocked, soaked, hit_zone)
+ standard_weapon_hit_effects(I, user, effective_force, blocked, soaked, hit_zone)
- if(I.damtype == BRUTE && prob(33)) // Added blood for whacking non-humans too
- var/turf/simulated/location = get_turf(src)
- if(istype(location)) location.add_blood_floor(src)
+ if(I.damtype == BRUTE && prob(33)) // Added blood for whacking non-humans too
+ var/turf/simulated/location = get_turf(src)
+ if(istype(location)) location.add_blood_floor(src)
return blocked
@@ -186,13 +189,14 @@
if(HULK in user.mutations)
effective_force *= 2
- //Armor soak
- if(soaked >= effective_force)
- return 0
-
//Apply weapon damage
var/weapon_sharp = is_sharp(I)
var/weapon_edge = has_edge(I)
+
+ if(getsoak(hit_zone, "melee",) - (I.armor_penetration/5) > round(effective_force*0.8)) //soaking a hit turns sharp attacks into blunt ones
+ weapon_sharp = 0
+ weapon_edge = 0
+
if(prob(max(getarmor(hit_zone, "melee") - I.armor_penetration, 0))) //melee armour provides a chance to turn sharp/edge weapon attacks into blunt ones
weapon_sharp = 0
weapon_edge = 0
@@ -251,7 +255,7 @@
if(!O || !src) return
if(O.sharp) //Projectile is suitable for pinning.
- if(soaked >= throw_damage) //Don't embed if it didn't actually damage
+ if(soaked >= round(throw_damage*0.8))
return
//Handles embedding for non-humans and simple_animals.
diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm
index e6b7f2979d..d8913e7b5b 100644
--- a/code/modules/mob/living/living_defines.dm
+++ b/code/modules/mob/living/living_defines.dm
@@ -2,7 +2,7 @@
see_invisible = SEE_INVISIBLE_LIVING
//Health and life related vars
- var/maxHealth = 100 //Maximum health that should be possible.
+ var/maxHealth = 100 //Maximum health that should be possible. Avoid adjusting this if you can, and instead use modifiers datums.
var/health = 100 //A mob's health
var/hud_updateflag = 0
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_console.dm b/code/modules/mob/living/silicon/robot/drone/drone_console.dm
index 349f27114b..8c12226e3d 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_console.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_console.dm
@@ -1,7 +1,6 @@
/obj/machinery/computer/drone_control
name = "Maintenance Drone Control"
desc = "Used to monitor the station's drone population and the assembler that services them."
- icon = 'icons/obj/computer.dmi'
icon_keyboard = "power_key"
icon_screen = "power"
req_access = list(access_engine_equip)
diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm
index 9dacf9924c..a9464c595e 100644
--- a/code/modules/mob/living/silicon/robot/life.dm
+++ b/code/modules/mob/living/silicon/robot/life.dm
@@ -98,7 +98,7 @@
else //Not stunned.
src.stat = 0
- confused = max(0, confused - 1)
+ AdjustConfused(-1)
else //Dead.
src.blinded = 1
@@ -107,7 +107,7 @@
if (src.stuttering) src.stuttering--
if (src.eye_blind)
- src.eye_blind--
+ src.AdjustBlinded(-1)
src.blinded = 1
if (src.ear_deaf > 0) src.ear_deaf--
diff --git a/code/modules/mob/living/silicon/robot/robot_damage.dm b/code/modules/mob/living/silicon/robot/robot_damage.dm
index 1b051e029f..58a81ca7a7 100644
--- a/code/modules/mob/living/silicon/robot/robot_damage.dm
+++ b/code/modules/mob/living/silicon/robot/robot_damage.dm
@@ -1,9 +1,9 @@
/mob/living/silicon/robot/updatehealth()
if(status_flags & GODMODE)
- health = maxHealth
+ health = getMaxHealth()
stat = CONSCIOUS
return
- health = maxHealth - (getBruteLoss() + getFireLoss())
+ health = getMaxHealth() - (getBruteLoss() + getFireLoss())
return
/mob/living/silicon/robot/getBruteLoss()
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index 738e996967..40b1852528 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -63,16 +63,16 @@
switch(severity)
if(1)
src.take_organ_damage(0,20,emp=1)
- confused = (min(confused + 5, 30))
+ Confuse(5)
if(2)
src.take_organ_damage(0,15,emp=1)
- confused = (min(confused + 4, 30))
+ Confuse(4)
if(3)
src.take_organ_damage(0,10,emp=1)
- confused = (min(confused + 3, 30))
+ Confuse(3)
if(4)
src.take_organ_damage(0,5,emp=1)
- confused = (min(confused + 2, 30))
+ Confuse(2)
flash_eyes(affect_silicon = 1)
src << "*BZZZT*"
src << "Warning: Electromagnetic pulse detected."
@@ -148,7 +148,7 @@
// this function shows the health of the AI in the Status panel
/mob/living/silicon/proc/show_system_integrity()
if(!src.stat)
- stat(null, text("System integrity: [round((health/maxHealth)*100)]%"))
+ stat(null, text("System integrity: [round((health/getMaxHealth())*100)]%"))
else
stat(null, text("Systems nonfunctional"))
diff --git a/code/modules/mob/living/simple_animal/aliens/drone.dm b/code/modules/mob/living/simple_animal/aliens/drone.dm
index 3d1ae1bd02..06de6b4d14 100644
--- a/code/modules/mob/living/simple_animal/aliens/drone.dm
+++ b/code/modules/mob/living/simple_animal/aliens/drone.dm
@@ -17,7 +17,7 @@
response_help = "pokes"
response_disarm = "gently pushes aside"
response_harm = "hits"
-
+
a_intent = I_HURT
ranged = 1
rapid = 1
@@ -99,16 +99,16 @@
src.visible_message("\red \icon[src] [src] suddenly lights up, and additional targetting vanes slide into place.")
hostile = 1
- if(health / maxHealth > 0.9)
+ if(health / getMaxHealth() > 0.9)
icon_state = "drone3"
explode_chance = 0
- else if(health / maxHealth > 0.7)
+ else if(health / getMaxHealth() > 0.7)
icon_state = "drone2"
explode_chance = 0
- else if(health / maxHealth > 0.5)
+ else if(health / getMaxHealth() > 0.5)
icon_state = "drone1"
explode_chance = 0.5
- else if(health / maxHealth > 0.3)
+ else if(health / getMaxHealth() > 0.3)
icon_state = "drone0"
explode_chance = 5
else if(health > 0)
diff --git a/code/modules/mob/living/simple_animal/animals/spiderbot.dm b/code/modules/mob/living/simple_animal/animals/spiderbot.dm
index 1bb202d1a0..95b7e81a17 100644
--- a/code/modules/mob/living/simple_animal/animals/spiderbot.dm
+++ b/code/modules/mob/living/simple_animal/animals/spiderbot.dm
@@ -95,10 +95,10 @@
if (istype(O, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = O
if (WT.remove_fuel(0))
- if(health < maxHealth)
+ if(health < getMaxHealth())
health += pick(1,1,1,2,2,3)
- if(health > maxHealth)
- health = maxHealth
+ if(health > getMaxHealth())
+ health = getMaxHealth()
add_fingerprint(user)
src.visible_message("\The [user] has spot-welded some of the damage to \the [src]!")
else
diff --git a/code/modules/mob/living/simple_animal/constructs/constructs.dm b/code/modules/mob/living/simple_animal/constructs/constructs.dm
index c24100476c..1cc1a85108 100644
--- a/code/modules/mob/living/simple_animal/constructs/constructs.dm
+++ b/code/modules/mob/living/simple_animal/constructs/constructs.dm
@@ -57,7 +57,7 @@
/mob/living/simple_animal/construct/attack_generic(var/mob/user)
if(istype(user, /mob/living/simple_animal/construct/builder))
- if(health < maxHealth)
+ if(health < getMaxHealth())
adjustBruteLoss(-5)
user.visible_message("\The [user] mends some of \the [src]'s wounds.")
else
@@ -68,9 +68,9 @@
/mob/living/simple_animal/construct/examine(mob/user)
..(user)
var/msg = "*---------*\nThis is \icon[src] \a [src]!\n"
- if (src.health < src.maxHealth)
+ if (src.health < src.getMaxHealth())
msg += ""
- if (src.health >= src.maxHealth/2)
+ if (src.health >= src.getMaxHealth()/2)
msg += "It looks slightly dented.\n"
else
msg += "It looks severely dented!\n"
diff --git a/code/modules/mob/living/simple_animal/constructs/soulstone.dm b/code/modules/mob/living/simple_animal/constructs/soulstone.dm
index 05087c4036..7b5e77f5c3 100644
--- a/code/modules/mob/living/simple_animal/constructs/soulstone.dm
+++ b/code/modules/mob/living/simple_animal/constructs/soulstone.dm
@@ -170,7 +170,7 @@
T.forceMove(src) //put shade in stone
T.status_flags |= GODMODE
T.canmove = 0
- T.health = T.maxHealth
+ T.health = T.getMaxHealth()
src.icon_state = "soulstone2"
T << "Your soul has been recaptured by the soul stone, its arcane energies are reknitting your ethereal form"
diff --git a/code/modules/mob/living/simple_animal/humanoids/mechamobs.dm b/code/modules/mob/living/simple_animal/humanoids/mechamobs.dm
index 79f389821e..ae700d60b7 100644
--- a/code/modules/mob/living/simple_animal/humanoids/mechamobs.dm
+++ b/code/modules/mob/living/simple_animal/humanoids/mechamobs.dm
@@ -75,7 +75,7 @@
/mob/living/simple_animal/hostile/mecha/Life()
. = ..()
if(!.) return
- if((health < maxHealth*0.3) && prob(10))
+ if((health < getMaxHealth()*0.3) && prob(10))
sparks.start()
/mob/living/simple_animal/hostile/mecha/bullet_act()
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index af20f04201..3ad6260813 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -234,8 +234,8 @@
density = 1
//Overhealth
- else if(health > maxHealth)
- health = maxHealth
+ else if(health > getMaxHealth())
+ health = getMaxHealth()
/mob/living/simple_animal/update_icon()
..()
@@ -534,7 +534,7 @@
if(istype(O, /obj/item/stack/medical))
if(stat != DEAD)
var/obj/item/stack/medical/MED = O
- if(health < maxHealth)
+ if(health < getMaxHealth())
if(MED.amount >= 1)
adjustBruteLoss(-MED.heal_brute)
MED.amount -= 1
@@ -602,7 +602,7 @@
..()
if(statpanel("Status") && show_stat_health)
- stat(null, "Health: [round((health / maxHealth) * 100)]%")
+ stat(null, "Health: [round((health / getMaxHealth()) * 100)]%")
/mob/living/simple_animal/lay_down()
..()
@@ -645,10 +645,10 @@
adjustBruteLoss(30)
/mob/living/simple_animal/adjustBruteLoss(damage)
- health = Clamp(health - damage, 0, maxHealth)
+ health = Clamp(health - damage, 0, getMaxHealth())
/mob/living/simple_animal/adjustFireLoss(damage)
- health = Clamp(health - damage, 0, maxHealth)
+ health = Clamp(health - damage, 0, getMaxHealth())
// Check target_mob if worthy of attack (i.e. check if they are dead or empty mecha)
/mob/living/simple_animal/proc/SA_attackable(target_mob)
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index ab53d6466c..1d8ddceedd 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -805,6 +805,30 @@
sleeping = max(sleeping + amount,0)
return
+/mob/proc/Confuse(amount)
+ confused = max(max(confused,amount),0)
+ return
+
+/mob/proc/SetConfused(amount)
+ confused = max(amount,0)
+ return
+
+/mob/proc/AdjustConfused(amount)
+ confused = max(confused + amount,0)
+ return
+
+/mob/proc/Blind(amount)
+ eye_blind = max(max(eye_blind,amount),0)
+ return
+
+/mob/proc/SetBlinded(amount)
+ eye_blind = max(amount,0)
+ return
+
+/mob/proc/AdjustBlinded(amount)
+ eye_blind = max(eye_blind + amount,0)
+ return
+
/mob/proc/Resting(amount)
facing_dir = null
resting = max(max(resting,amount),0)
diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm
index f3cd084ffa..80f68b979d 100644
--- a/code/modules/mob/mob_grab.dm
+++ b/code/modules/mob/mob_grab.dm
@@ -170,7 +170,7 @@
if(announce)
assailant.visible_message("[assailant] covers [affecting]'s eyes!")
if(affecting.eye_blind < 3)
- affecting.eye_blind = 3
+ affecting.Blind(3)
/obj/item/weapon/grab/attack_self()
return s_click(hud)
diff --git a/code/modules/mob/modifiers.dm b/code/modules/mob/modifiers.dm
new file mode 100644
index 0000000000..6ba148916e
--- /dev/null
+++ b/code/modules/mob/modifiers.dm
@@ -0,0 +1,106 @@
+// This is a datum that tells the mob that something is affecting them.
+// The advantage of using this datum verses just setting a variable on the mob directly, is that there is no risk of two different procs overwriting
+// each other, or other weirdness. An excellent example is adjusting max health.
+
+/datum/modifier
+ var/name = null // Mostly used to organize, might show up on the UI in the Future(tm)
+ var/desc = null // Ditto.
+ var/icon_state = null // See above.
+ var/mob/living/holder = null // The mob that this datum is affecting.
+ var/expire_at = null // world.time when holder's Life() will remove the datum. If null, it lasts forever or until it gets deleted by something else.
+ var/on_created_text = null // Text to show to holder upon being created.
+ var/on_expired_text = null // Text to show to holder when it expires.
+ var/hidden = FALSE // If true, it will not show up on the HUD in the Future(tm)
+ var/stacks = MODIFIER_STACK_FORBID // If true, attempts to add a second instance of this type will refresh expire_at instead.
+ var/flags = 0 // Flags for the modifier, see mobs.dm defines for more details.
+
+ // Now for all the different effects.
+ // Percentage modifiers are expressed as a multipler. (e.g. +25% damage should be written as 1.25)
+ var/max_health_flat // Adjusts max health by a flat (e.g. +20) amount. Note this is added to base health.
+ var/max_health_percent // Adjusts max health by a percentage (e.g. -30%).
+ var/disable_duration_percent // Adjusts duration of 'disables' (stun, weaken, paralyze, confusion, sleep, halloss, etc) Setting to 0 will grant immunity.
+ var/incoming_damage_percent // Adjusts all incoming damage.
+ var/incoming_brute_damage_percent // Only affects bruteloss.
+ var/incoming_fire_damage_percent // Only affects fireloss.
+ var/incoming_tox_damage_percent // Only affects toxloss.
+ var/incoming_oxy_damage_percent // Only affects oxyloss.
+ var/incoming_clone_damage_percent // Only affects cloneloss.
+ var/incoming_hal_damage_percent // Only affects halloss.
+ var/incoming_healing_percent // Adjusts amount of healing received.
+ var/outgoing_melee_damage_percent // Adjusts melee damage inflicted by holder by a percentage. Affects attacks by melee weapons and hand-to-hand.
+ var/slowdown // Negative numbers speed up, positive numbers slow down movement.
+
+/datum/modifier/New(var/new_holder)
+ holder = new_holder
+ ..()
+
+// Checks to see if this datum should continue existing.
+/datum/modifier/proc/check_if_valid()
+ if(expire_at && expire_at < world.time) // Is our time up?
+ src.expire()
+
+/datum/modifier/proc/expire(var/silent = FALSE)
+ if(on_expired_text && !silent)
+ to_chat(holder, on_expired_text)
+ on_expire()
+ holder.modifiers.Remove(src)
+ qdel(src)
+
+// Override this for special effects when it gets removed.
+/datum/modifier/proc/on_expire()
+ return
+
+/mob/living
+ var/list/modifiers = list() // A list of modifier datums, which can adjust certain mob numbers.
+
+/mob/living/Destroy()
+ remove_all_modifiers(TRUE)
+ ..()
+
+// Called by Life().
+/mob/living/proc/handle_modifiers()
+ if(!modifiers.len) // No work to do.
+ return
+ // Get rid of anything we shouldn't have.
+ for(var/datum/modifier/M in modifiers)
+ M.check_if_valid()
+
+// Call this to add a modifier to a mob. First argument is the modifier type you want, second is how long it should last, in ticks.
+// The SECONDS/MINUTES macro is very helpful for this. E.g. M.add_modifier(/datum/modifier/example, 5 MINUTES)
+/mob/living/proc/add_modifier(var/modifier_type, var/expire_at = null)
+ // First, check if the mob already has this modifier.
+ for(var/datum/modifier/M in modifiers)
+ if(ispath(modifier_type, M.type))
+ switch(M.stacks)
+ if(MODIFIER_STACK_FORBID)
+ return // Stop here.
+ if(MODIFIER_STACK_ALLOWED)
+ break // No point checking anymore.
+ if(MODIFIER_STACK_EXTEND)
+ // Not allow to add a second instance, but we can try to prolong the first instance.
+ if(expire_at && world.time + expire_at > M.expire_at)
+ M.expire_at = world.time + expire_at
+ return
+
+ // If we're at this point, the mob doesn't already have it, or it does but stacking is allowed.
+ var/datum/modifier/mod = new modifier_type(src)
+ if(expire_at)
+ mod.expire_at = world.time + expire_at
+ if(mod.on_created_text)
+ to_chat(src, mod.on_created_text)
+ modifiers.Add(mod)
+
+// Removes a specific instance of modifier
+/mob/living/proc/remove_specific_modifier(var/datum/modifier/M, var/silent = FALSE)
+ M.expire(silent)
+
+// Removes all modifiers of a type
+/mob/living/proc/remove_modifiers_of_type(var/modifier_type, var/silent = FALSE)
+ for(var/datum/modifier/M in modifiers)
+ if(ispath(modifier_type, M.type))
+ M.expire(silent)
+
+// Removes all modifiers, useful if the mob's being deleted
+/mob/living/proc/remove_all_modifiers(var/silent = FALSE)
+ for(var/datum/modifier/M in modifiers)
+ M.expire(silent)
\ No newline at end of file
diff --git a/code/modules/multiz/basic.dm b/code/modules/multiz/basic.dm
index 24d24b1049..0ed4e5364a 100644
--- a/code/modules/multiz/basic.dm
+++ b/code/modules/multiz/basic.dm
@@ -43,3 +43,11 @@ var/z_levels = 0 // Each bit represents a connection between adjacent levels. S
proc/AreConnectedZLevels(var/zA, var/zB)
return zA == zB || (zB in GetConnectedZlevels(zA))
+
+/proc/get_zstep(ref, dir)
+ if(dir == UP)
+ . = GetAbove(ref)
+ else if (dir == DOWN)
+ . = GetBelow(ref)
+ else
+ . = get_step(ref, dir)
\ No newline at end of file
diff --git a/code/modules/multiz/pipes.dm b/code/modules/multiz/pipes.dm
index 6b6b24c470..7570d12b35 100644
--- a/code/modules/multiz/pipes.dm
+++ b/code/modules/multiz/pipes.dm
@@ -51,7 +51,7 @@ obj/machinery/atmospherics/pipe/zpipe/New()
invisibility = i ? 101 : 0
update_icon()
-obj/machinery/atmospherics/pipe/up/process()
+obj/machinery/atmospherics/pipe/zpipe/process()
if(!parent) //This should cut back on the overhead calling build_network thousands of times per cycle
..()
else
@@ -81,10 +81,10 @@ obj/machinery/atmospherics/pipe/zpipe/proc/burst()
qdel(src) // NOT qdel.
obj/machinery/atmospherics/pipe/zpipe/proc/normalize_dir()
- if(dir==3)
- set_dir(1)
- else if(dir==12)
- set_dir(4)
+ if(dir == (NORTH|SOUTH))
+ set_dir(NORTH)
+ else if(dir == (EAST|WEST))
+ set_dir(EAST)
obj/machinery/atmospherics/pipe/zpipe/Destroy()
if(node1)
diff --git a/code/modules/organs/internal/brain.dm b/code/modules/organs/internal/brain.dm
index 6514092dfc..1390c89b29 100644
--- a/code/modules/organs/internal/brain.dm
+++ b/code/modules/organs/internal/brain.dm
@@ -35,7 +35,7 @@
if (. >= 2)
if(prob(1))
owner.custom_pain("Your feel very dizzy for a moment!",0)
- owner.confused = max(owner.confused, 2)
+ owner.Confuse(2)
/obj/item/organ/internal/brain/proc/replace_self_with(replace_path)
var/mob/living/carbon/human/tmp_owner = owner
diff --git a/code/modules/organs/internal/eyes.dm b/code/modules/organs/internal/eyes.dm
index 2a2b8305d3..4febf8f479 100644
--- a/code/modules/organs/internal/eyes.dm
+++ b/code/modules/organs/internal/eyes.dm
@@ -72,7 +72,7 @@
if(is_bruised())
owner.eye_blurry = 20
if(is_broken())
- owner.eye_blind = 20
+ owner.Blind(20)
/obj/item/organ/internal/eyes/handle_germ_effects()
. = ..() //Up should return an infection level as an integer
diff --git a/code/modules/organs/internal/liver.dm b/code/modules/organs/internal/liver.dm
index daa0a88f76..6b7459500b 100644
--- a/code/modules/organs/internal/liver.dm
+++ b/code/modules/organs/internal/liver.dm
@@ -53,6 +53,6 @@
if(prob(1))
owner.custom_pain("There's a sharp pain in your upper-right abdomen!",1)
if (. >= 2)
- if(prob(1) && owner.getToxLoss() < owner.maxHealth*0.3)
+ if(prob(1) && owner.getToxLoss() < owner.getMaxHealth()*0.3)
//owner << "" //Toxins provide their own messages for pain
owner.adjustToxLoss(5) //Not realistic to PA but there are basically no 'real' liver infections
diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm
index aebe847fb6..7a5c42ea41 100644
--- a/code/modules/organs/organ_external.dm
+++ b/code/modules/organs/organ_external.dm
@@ -492,7 +492,7 @@ This function completely restores a damaged organ to perfect condition.
//Burn damage can cause fluid loss due to blistering and cook-off
if((damage > 5 || damage + burn_dam >= 15) && type == BURN && (robotic < ORGAN_ROBOT) && !istype(owner.loc,/mob/living) && !istype(owner.loc,/obj/item/device/dogborg/sleeper)) // VOREStation Edit
- var/fluid_loss = 0.75 * (damage/(owner.maxHealth - config.health_threshold_dead)) * owner.species.blood_volume*(1 - BLOOD_VOLUME_SURVIVE/100)
+ var/fluid_loss = 0.75 * (damage/(owner.getMaxHealth() - config.health_threshold_dead)) * owner.species.blood_volume*(1 - BLOOD_VOLUME_SURVIVE/100)
owner.remove_blood(fluid_loss)
// first check whether we can widen an existing wound
diff --git a/code/modules/organs/organ_internal.dm b/code/modules/organs/organ_internal.dm
index 244c0b7971..cfc0910901 100644
--- a/code/modules/organs/organ_internal.dm
+++ b/code/modules/organs/organ_internal.dm
@@ -165,7 +165,7 @@
if(is_bruised())
owner.eye_blurry = 20
if(is_broken())
- owner.eye_blind = 20
+ owner.Blind(20)
/obj/item/organ/internal/liver
name = "liver"
diff --git a/code/modules/organs/subtypes/unathi.dm b/code/modules/organs/subtypes/unathi.dm
new file mode 100644
index 0000000000..212330577c
--- /dev/null
+++ b/code/modules/organs/subtypes/unathi.dm
@@ -0,0 +1,50 @@
+/obj/item/organ/external/chest/unathi
+ max_damage = 100
+ min_broken_damage = 40
+ encased = "upper ribplates"
+
+/obj/item/organ/external/groin/unathi
+ max_damage = 100
+ min_broken_damage = 40
+ encased = "lower ribplates"
+
+/obj/item/organ/external/head/unathi
+ max_damage = 75
+ min_broken_damage = 35
+ eye_icon = "eyes_s"
+ force = 5
+ throwforce = 10
+
+
+/obj/item/organ/internal/heart/unathi
+ icon_state = "unathi_heart-on"
+ dead_icon = "unath_heart-off"
+
+/obj/item/organ/internal/lungs/unathi
+ color = "#b3cbc3"
+
+/obj/item/organ/internal/liver/unathi
+ name = "filtration organ"
+ icon_state = "unathi_liver"
+
+//Unathi liver acts as kidneys, too.
+/obj/item/organ/internal/liver/unathi/process()
+ ..()
+ if(!owner) return
+
+ var/datum/reagent/coffee = locate(/datum/reagent/drink/coffee) in owner.reagents.reagent_list
+ if(coffee)
+ if(is_bruised())
+ owner.adjustToxLoss(0.1 * PROCESS_ACCURACY)
+ else if(is_broken())
+ owner.adjustToxLoss(0.3 * PROCESS_ACCURACY)
+
+ var/datum/reagent/sugar = locate(/datum/reagent/sugar) in owner.reagents.reagent_list
+ if(sugar)
+ if(is_bruised())
+ owner.adjustToxLoss(0.1 * PROCESS_ACCURACY)
+ else if(is_broken())
+ owner.adjustToxLoss(0.3 * PROCESS_ACCURACY)
+
+/obj/item/organ/internal/brain/unathi
+ color = "#b3cbc3"
\ No newline at end of file
diff --git a/code/modules/planet/planet.dm b/code/modules/planet/planet.dm
index 53a07f228b..4c308ca930 100644
--- a/code/modules/planet/planet.dm
+++ b/code/modules/planet/planet.dm
@@ -12,8 +12,17 @@
var/datum/weather_holder/weather_holder
var/sun_position = 0 // 0 means midnight, 1 means noon.
+ var/list/sun = list("range","brightness","color")
var/expected_z_levels = list()
+ var/turf/unsimulated/wall/planetary/planetary_wall_type = /turf/unsimulated/wall/planetary
+
+ var/turf/simulated/floor/planet_floors = list()
+ var/turf/unsimulated/wall/planetary/planet_walls = list()
+
+
+ var/needs_work = 0 // Bitflags to signal to the planet controller these need (properly deferrable) work. Flags defined in controller.
+
/datum/planet/New()
..()
weather_holder = new(src)
@@ -31,17 +40,13 @@
/datum/planet/proc/update_sun()
sun_last_process = world.time
-
/datum/planet/proc/update_weather()
if(weather_holder)
weather_holder.process()
/datum/planet/proc/update_sun_deferred(var/new_range, var/new_brightness, var/new_color)
- set background = 1
- set waitfor = 0
- var/i = 0
- for(var/turf/simulated/floor/T in outdoor_turfs)
- T.set_light(new_range, new_brightness, new_color)
- i++
- if(i % 30 == 0)
- sleep(1)
+ sun["range"] = new_range
+ sun["brightness"] = new_brightness
+ sun["color"] = new_color
+ needs_work |= PLANET_PROCESS_SUN
+
diff --git a/code/modules/planet/sif.dm b/code/modules/planet/sif.dm
index 303d05f509..e35646ce7f 100644
--- a/code/modules/planet/sif.dm
+++ b/code/modules/planet/sif.dm
@@ -10,6 +10,7 @@ var/datum/planet/sif/planet_sif = null
Its center of government is the equatorial city and site of first settlement, New Reykjavik." // Ripped straight from the wiki.
current_time = new /datum/time/sif() // 32 hour clocks are nice.
expected_z_levels = list(1) // To be changed when real map is finished.
+ planetary_wall_type = /turf/unsimulated/wall/planetary/sif
/datum/planet/sif/New()
..()
@@ -104,3 +105,197 @@ var/datum/planet/sif/planet_sif = null
/proc/get_sif_time()
if(planet_sif)
return planet_sif.current_time
+
+//Weather definitions
+/datum/weather_holder/sif
+ temperature = T0C
+ allowed_weather_types = list(
+ WEATHER_CLEAR = new /datum/weather/sif/clear(),
+ WEATHER_OVERCAST = new /datum/weather/sif/overcast(),
+ WEATHER_LIGHT_SNOW = new /datum/weather/sif/light_snow(),
+ WEATHER_SNOW = new /datum/weather/sif/snow(),
+ WEATHER_BLIZZARD = new /datum/weather/sif/blizzard(),
+ WEATHER_RAIN = new /datum/weather/sif/rain(),
+ WEATHER_STORM = new /datum/weather/sif/storm(),
+ WEATHER_HAIL = new /datum/weather/sif/hail(),
+ WEATHER_BLOOD_MOON = new /datum/weather/sif/blood_moon()
+ )
+ roundstart_weather_chances = list(
+ WEATHER_CLEAR = 30,
+ WEATHER_OVERCAST = 30,
+ WEATHER_LIGHT_SNOW = 20,
+ WEATHER_SNOW = 5,
+ WEATHER_BLIZZARD = 5,
+ WEATHER_RAIN = 5,
+ WEATHER_STORM = 2.5,
+ WEATHER_HAIL = 2.5
+ )
+
+datum/weather/sif
+ name = "sif base"
+ temp_high = 243.15 // -20c
+ temp_low = 233.15 // -30c
+
+/datum/weather/sif/clear
+ name = "clear"
+ transition_chances = list(
+ WEATHER_CLEAR = 60,
+ WEATHER_OVERCAST = 40
+ )
+
+/datum/weather/sif/overcast
+ name = "overcast"
+ light_modifier = 0.8
+ transition_chances = list(
+ WEATHER_CLEAR = 25,
+ WEATHER_OVERCAST = 50,
+ WEATHER_LIGHT_SNOW = 10,
+ WEATHER_SNOW = 5,
+ WEATHER_RAIN = 5,
+ WEATHER_HAIL = 5
+ )
+
+/datum/weather/sif/light_snow
+ name = "light snow"
+ icon_state = "snowfall_light"
+ temp_high = 238.15 // -25c
+ temp_low = 228.15 // -35c
+ light_modifier = 0.7
+ transition_chances = list(
+ WEATHER_OVERCAST = 20,
+ WEATHER_LIGHT_SNOW = 50,
+ WEATHER_SNOW = 25,
+ WEATHER_HAIL = 5
+ )
+
+/datum/weather/sif/snow
+ name = "moderate snow"
+ icon_state = "snowfall_med"
+ temp_high = 233.15 // -30c
+ temp_low = 223.15 // -40c
+ light_modifier = 0.5
+ transition_chances = list(
+ WEATHER_LIGHT_SNOW = 20,
+ WEATHER_SNOW = 50,
+ WEATHER_BLIZZARD = 20,
+ WEATHER_HAIL = 5,
+ WEATHER_OVERCAST = 5
+ )
+
+/datum/weather/sif/snow/process_effects()
+ for(var/turf/simulated/floor/outdoors/snow/S in outdoor_turfs)
+ if(S.z in holder.our_planet.expected_z_levels)
+ for(var/dir_checked in cardinal)
+ var/turf/simulated/floor/T = get_step(S, dir_checked)
+ if(istype(T))
+ if(istype(T, /turf/simulated/floor/outdoors) && prob(33))
+ T.chill()
+
+/datum/weather/sif/blizzard
+ name = "blizzard"
+ icon_state = "snowfall_heavy"
+ temp_high = 223.15 // -40c
+ temp_low = 203.15 // -60c
+ light_modifier = 0.3
+ transition_chances = list(
+ WEATHER_SNOW = 45,
+ WEATHER_BLIZZARD = 40,
+ WEATHER_HAIL = 10,
+ WEATHER_OVERCAST = 5
+ )
+
+/datum/weather/sif/blizzard/process_effects()
+ for(var/turf/simulated/floor/outdoors/snow/S in outdoor_turfs)
+ if(S.z in holder.our_planet.expected_z_levels)
+ for(var/dir_checked in cardinal)
+ var/turf/simulated/floor/T = get_step(S, dir_checked)
+ if(istype(T))
+ if(istype(T, /turf/simulated/floor/outdoors) && prob(50))
+ T.chill()
+
+/datum/weather/sif/rain
+ name = "rain"
+ icon_state = "rain"
+ light_modifier = 0.5
+ transition_chances = list(
+ WEATHER_OVERCAST = 25,
+ WEATHER_LIGHT_SNOW = 10,
+ WEATHER_RAIN = 50,
+ WEATHER_STORM = 10,
+ WEATHER_HAIL = 5
+ )
+
+/datum/weather/sif/rain/process_effects()
+ for(var/mob/living/L in living_mob_list)
+ if(L.z in holder.our_planet.expected_z_levels)
+ var/turf/T = get_turf(L)
+ if(!T.outdoors)
+ return // They're indoors, so no need to rain on them.
+
+ L.adjust_fire_stacks(-5)
+ to_chat(L, "Rain falls on you.")
+
+/datum/weather/sif/storm
+ name = "storm"
+ icon_state = "storm"
+ temp_high = 233.15 // -30c
+ temp_low = 213.15 // -50c
+ light_modifier = 0.3
+ transition_chances = list(
+ WEATHER_RAIN = 45,
+ WEATHER_STORM = 40,
+ WEATHER_HAIL = 10,
+ WEATHER_OVERCAST = 5
+ )
+
+/datum/weather/sif/rain/process_effects()
+ for(var/mob/living/L in living_mob_list)
+ if(L.z in holder.our_planet.expected_z_levels)
+ var/turf/T = get_turf(L)
+ if(!T.outdoors)
+ return // They're indoors, so no need to rain on them.
+
+ L.adjust_fire_stacks(-10)
+ to_chat(L, "Rain falls on you, drenching you in water.")
+
+/datum/weather/sif/hail
+ name = "hail"
+ icon_state = "hail"
+ temp_high = 233.15 // -30c
+ temp_low = 213.15 // -50c
+ light_modifier = 0.3
+ transition_chances = list(
+ WEATHER_RAIN = 45,
+ WEATHER_STORM = 10,
+ WEATHER_HAIL = 40,
+ WEATHER_OVERCAST = 5
+ )
+
+/datum/weather/sif/hail/process_effects()
+ for(var/mob/living/L in living_mob_list)
+ if(L.z in holder.our_planet.expected_z_levels)
+ var/turf/T = get_turf(L)
+ if(!T.outdoors)
+ return // They're indoors, so no need to pelt them with ice.
+
+ var/target_zone = pick(BP_ALL)
+ var/amount_blocked = L.run_armor_check(target_zone, "melee")
+ var/amount_soaked = L.get_armor_soak(target_zone, "melee")
+
+ if(amount_blocked >= 100)
+ return // No need to apply damage.
+
+ if(amount_soaked >= 10)
+ return // No need to apply damage.
+
+ L.apply_damage(rand(5, 10), BRUTE, target_zone, amount_blocked, amount_soaked, used_weapon = "hail")
+ to_chat(L, "The hail raining down on you [L.can_feel_pain() ? "hurts" : "damages you"]!")
+
+/datum/weather/sif/blood_moon
+ name = "blood moon"
+ light_modifier = 0.5
+ light_color = "#FF0000"
+ transition_chances = list(
+ WEATHER_BLOODMOON = 100
+ )
+
diff --git a/code/modules/planet/weather.dm b/code/modules/planet/weather.dm
index 3c06b350df..5a58c1323e 100644
--- a/code/modules/planet/weather.dm
+++ b/code/modules/planet/weather.dm
@@ -1,15 +1,3 @@
-#define WEATHER_CLEAR "clear"
-#define WEATHER_OVERCAST "overcast"
-#define WEATHER_LIGHT_SNOW "light snow"
-#define WEATHER_SNOW "snow"
-#define WEATHER_BLIZZARD "blizzard"
-#define WEATHER_RAIN "rain"
-#define WEATHER_STORM "storm"
-#define WEATHER_HAIL "hail"
-#define WEATHER_WINDY "windy"
-#define WEATHER_HOT "hot"
-#define WEATHER_BLOOD_MOON "blood moon" // For admin fun or cult later on.
-
/datum/weather_holder
var/datum/planet/our_planet = null
var/datum/weather/current_weather = null
@@ -19,7 +7,6 @@
var/list/allowed_weather_types = list()
var/list/roundstart_weather_chances = list()
var/next_weather_shift = null
- var/planetary_wall_type = null // Which walls to look for when updating temperature.
/datum/weather_holder/New(var/source)
..()
@@ -54,55 +41,15 @@
current_weather.process_effects()
/datum/weather_holder/proc/update_icon_effects()
- set background = 1
- set waitfor = 0
- if(current_weather)
- for(var/turf/simulated/floor/T in outdoor_turfs)
- if(T.z in our_planet.expected_z_levels)
- T.overlays -= T.weather_overlay
- T.weather_overlay = image(icon = current_weather.icon, icon_state = current_weather.icon_state, layer = LIGHTING_LAYER - 1)
- T.overlays += T.weather_overlay
+ our_planet.needs_work |= PLANET_PROCESS_WEATHER
/datum/weather_holder/proc/update_temperature()
temperature = Interpolate(current_weather.temp_low, current_weather.temp_high, weight = our_planet.sun_position)
-
- for(var/turf/unsimulated/wall/planetary/wall in planetary_walls)
- if(ispath(wall.type, planetary_wall_type))
- wall.temperature = temperature
- for(var/dir in cardinal)
- var/turf/simulated/T = get_step(wall, dir)
- if(istype(T))
- if(T.zone)
- T.zone.rebuild()
-
+ our_planet.needs_work |= PLANET_PROCESS_TEMP
/datum/weather_holder/proc/get_weather_datum(desired_type)
return allowed_weather_types[desired_type]
-/datum/weather_holder/sif
- temperature = T0C
- allowed_weather_types = list(
- WEATHER_CLEAR = new /datum/weather/sif/clear(),
- WEATHER_OVERCAST = new /datum/weather/sif/overcast(),
- WEATHER_LIGHT_SNOW = new /datum/weather/sif/light_snow(),
- WEATHER_SNOW = new /datum/weather/sif/snow(),
- WEATHER_BLIZZARD = new /datum/weather/sif/blizzard(),
- WEATHER_RAIN = new /datum/weather/sif/rain(),
- WEATHER_STORM = new /datum/weather/sif/storm(),
- WEATHER_HAIL = new /datum/weather/sif/hail(),
- WEATHER_BLOOD_MOON = new /datum/weather/sif/blood_moon()
- )
- planetary_wall_type = /turf/unsimulated/wall/planetary/sif
- roundstart_weather_chances = list(
- WEATHER_CLEAR = 30,
- WEATHER_OVERCAST = 30,
- WEATHER_LIGHT_SNOW = 20,
- WEATHER_SNOW = 5,
- WEATHER_BLIZZARD = 5,
- WEATHER_RAIN = 5,
- WEATHER_STORM = 2.5,
- WEATHER_HAIL = 2.5
- )
/datum/weather
var/name = "weather base"
@@ -117,169 +64,3 @@
/datum/weather/proc/process_effects()
return
-
-/datum/weather/sif
- name = "sif base"
- temp_high = 243.15 // -20c
- temp_low = 233.15 // -30c
-
-/datum/weather/sif/clear
- name = "clear"
- transition_chances = list(
- WEATHER_CLEAR = 60,
- WEATHER_OVERCAST = 40
- )
-
-/datum/weather/sif/overcast
- name = "overcast"
- light_modifier = 0.8
- transition_chances = list(
- WEATHER_CLEAR = 25,
- WEATHER_OVERCAST = 50,
- WEATHER_LIGHT_SNOW = 10,
- WEATHER_SNOW = 5,
- WEATHER_RAIN = 5,
- WEATHER_HAIL = 5
- )
-
-/datum/weather/sif/light_snow
- name = "light snow"
- icon_state = "snowfall_light"
- temp_high = 238.15 // -25c
- temp_low = 228.15 // -35c
- light_modifier = 0.7
- transition_chances = list(
- WEATHER_OVERCAST = 20,
- WEATHER_LIGHT_SNOW = 50,
- WEATHER_SNOW = 25,
- WEATHER_HAIL = 5
- )
-
-/datum/weather/sif/snow
- name = "moderate snow"
- icon_state = "snowfall_med"
- temp_high = 233.15 // -30c
- temp_low = 223.15 // -40c
- light_modifier = 0.5
- transition_chances = list(
- WEATHER_LIGHT_SNOW = 20,
- WEATHER_SNOW = 50,
- WEATHER_BLIZZARD = 20,
- WEATHER_HAIL = 5,
- WEATHER_OVERCAST = 5
- )
-
-/datum/weather/sif/snow/process_effects()
- for(var/turf/simulated/floor/outdoors/snow/S in outdoor_turfs)
- for(var/dir_checked in cardinal)
- var/turf/simulated/floor/T = get_step(S, dir_checked)
- if(istype(T))
- if(istype(T, /turf/simulated/floor/outdoors) && prob(33))
- T.chill()
-
-/datum/weather/sif/blizzard
- name = "blizzard"
- icon_state = "snowfall_heavy"
- temp_high = 223.15 // -40c
- temp_low = 203.15 // -60c
- light_modifier = 0.3
- transition_chances = list(
- WEATHER_SNOW = 45,
- WEATHER_BLIZZARD = 40,
- WEATHER_HAIL = 10,
- WEATHER_OVERCAST = 5
- )
-
-/datum/weather/sif/blizzard/process_effects()
- for(var/turf/simulated/floor/outdoors/snow/S in outdoor_turfs)
- for(var/dir_checked in cardinal)
- var/turf/simulated/floor/T = get_step(S, dir_checked)
- if(istype(T))
- if(istype(T, /turf/simulated/floor/outdoors) && prob(50))
- T.chill()
-
-/datum/weather/sif/rain
- name = "rain"
- icon_state = "rain"
- light_modifier = 0.5
- transition_chances = list(
- WEATHER_OVERCAST = 25,
- WEATHER_LIGHT_SNOW = 10,
- WEATHER_RAIN = 50,
- WEATHER_STORM = 10,
- WEATHER_HAIL = 5
- )
-
-/datum/weather/sif/rain/process_effects()
- for(var/mob/living/L in living_mob_list)
- if(L.z in holder.our_planet.expected_z_levels)
- var/turf/T = get_turf(L)
- if(!T.outdoors)
- return // They're indoors, so no need to rain on them.
-
- L.adjust_fire_stacks(-5)
- to_chat(L, "Rain falls on you.")
-
-/datum/weather/sif/storm
- name = "storm"
- icon_state = "storm"
- temp_high = 233.15 // -30c
- temp_low = 213.15 // -50c
- light_modifier = 0.3
- transition_chances = list(
- WEATHER_RAIN = 45,
- WEATHER_STORM = 40,
- WEATHER_HAIL = 10,
- WEATHER_OVERCAST = 5
- )
-
-/datum/weather/sif/rain/process_effects()
- for(var/mob/living/L in living_mob_list)
- if(L.z in holder.our_planet.expected_z_levels)
- var/turf/T = get_turf(L)
- if(!T.outdoors)
- return // They're indoors, so no need to rain on them.
-
- L.adjust_fire_stacks(-10)
- to_chat(L, "Rain falls on you, drenching you in water.")
-
-/datum/weather/sif/hail
- name = "hail"
- icon_state = "hail"
- temp_high = 233.15 // -30c
- temp_low = 213.15 // -50c
- light_modifier = 0.3
- transition_chances = list(
- WEATHER_RAIN = 45,
- WEATHER_STORM = 10,
- WEATHER_HAIL = 40,
- WEATHER_OVERCAST = 5
- )
-
-/datum/weather/sif/hail/process_effects()
- for(var/mob/living/L in living_mob_list)
- if(L.z in holder.our_planet.expected_z_levels)
- var/turf/T = get_turf(L)
- if(!T.outdoors)
- return // They're indoors, so no need to pelt them with ice.
-
- var/target_zone = pick(BP_ALL)
- var/amount_blocked = L.run_armor_check(target_zone, "melee")
- var/amount_soaked = L.get_armor_soak(target_zone, "melee")
-
- if(amount_blocked >= 100)
- return // No need to apply damage.
-
- if(amount_soaked >= 10)
- return // No need to apply damage.
-
- L.apply_damage(rand(5, 10), BRUTE, target_zone, amount_blocked, amount_soaked, used_weapon = "hail")
- to_chat(L, "The hail raining down on you [L.can_feel_pain() ? "hurts" : "damages you"]!")
-
-/datum/weather/sif/blood_moon
- name = "blood moon"
- light_modifier = 0.5
- light_color = "#FF0000"
- transition_chances = list(
- WEATHER_BLOODMOON = 100
- )
diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm
index 671d57e04e..27bf4c0ab7 100644
--- a/code/modules/power/cable.dm
+++ b/code/modules/power/cable.dm
@@ -48,7 +48,7 @@ var/list/possible_cable_coil_colours = list(
anchored =1
var/datum/powernet/powernet
name = "power cable"
- desc = "A flexible superconducting cable for heavy-duty power transfer"
+ desc = "A flexible superconducting cable for heavy-duty power transfer."
icon = 'icons/obj/power_cond_white.dmi'
icon_state = "0-1"
var/d1 = 0
@@ -116,9 +116,9 @@ var/list/possible_cable_coil_colours = list(
user.examinate(src)
// following code taken from attackby (multitool)
if(powernet && (powernet.avail > 0))
- user << "[powernet.avail]W in power network."
+ to_chat(user, "[powernet.avail]W in power network.")
else
- user << "The cable is not powered."
+ to_chat(user, "The cable is not powered.")
return
///////////////////////////////////
@@ -159,12 +159,12 @@ var/list/possible_cable_coil_colours = list(
return
if(istype(W, /obj/item/weapon/wirecutters))
- if(d1 == 12 || d2 == 12)
- user << "You must cut this cable from above."
+ if(d1 == UP || d2 == UP)
+ to_chat(user, "You must cut this cable from above.")
return
if(breaker_box)
- user << "\red This cable is connected to nearby breaker box. Use breaker box to interact with it."
+ to_chat(user, "This cable is connected to nearby breaker box. Use breaker box to interact with it.")
return
if (shock(user, 50))
@@ -178,11 +178,11 @@ var/list/possible_cable_coil_colours = list(
for(var/mob/O in viewers(src, null))
O.show_message("[user] cuts the cable.", 1)
- if(d1 == 11 || d2 == 11)
+ if(d1 == DOWN || d2 == DOWN)
var/turf/turf = GetBelow(src)
if(turf)
for(var/obj/structure/cable/c in turf)
- if(c.d1 == 12 || c.d2 == 12)
+ if(c.d1 == UP || c.d2 == UP)
qdel(c)
investigate_log("was cut by [key_name(usr, usr.client)] in [user.loc.loc]","wires")
@@ -194,17 +194,17 @@ var/list/possible_cable_coil_colours = list(
else if(istype(W, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/coil = W
if (coil.get_amount() < 1)
- user << "Not enough cable"
+ to_chat(user, "Not enough cable")
return
coil.cable_join(src, user)
else if(istype(W, /obj/item/device/multitool))
if(powernet && (powernet.avail > 0)) // is it powered?
- user << "[powernet.avail]W in power network."
+ to_chat(user, "[powernet.avail]W in power network.")
else
- user << "The cable is not powered."
+ to_chat(user, "The cable is not powered.")
shock(user, 5, 0.2)
@@ -300,12 +300,12 @@ obj/structure/cable/proc/cableColor(var/colorC)
// merge with the powernets of power objects in the given direction
/obj/structure/cable/proc/mergeConnectedNetworks(var/direction)
- var/fdir = (!direction)? 0 : turn(direction, 180) //flip the direction, to match with the source position on its turf
+ var/fdir = direction ? reverse_dir[direction] : 0 //flip the direction, to match with the source position on its turf
if(!(d1 == direction || d2 == direction)) //if the cable is not pointed in this direction, do nothing
return
- var/turf/TB = get_step(src, direction)
+ var/turf/TB = get_zstep(src, direction)
for(var/obj/structure/cable/C in TB)
@@ -376,25 +376,15 @@ obj/structure/cable/proc/cableColor(var/colorC)
. = list() // this will be a list of all connected power objects
var/turf/T
- // Handle up/down cables
- if(d1 == 11 || d2 == 11)
- T = GetBelow(src)
- if(T)
- . += power_list(T, src, 12, 1)
- if(d1 == 12 || d1 == 12)
- T = GetAbove(src)
- if(T)
- . += power_list(T, src, 11, 1)
-
// Handle standard cables in adjacent turfs
for(var/cable_dir in list(d1, d2))
- if(cable_dir == 11 || cable_dir == 12 || cable_dir == 0)
+ if(cable_dir == 0)
continue
var/reverse = reverse_dir[cable_dir]
- T = get_step(src, cable_dir)
+ T = get_zstep(src, cable_dir)
if(T)
for(var/obj/structure/cable/C in T)
- if((C.d1 && C.d1 == reverse) || (C.d2 && C.d2 == reverse))
+ if(C.d1 == reverse || C.d2 == reverse)
. += C
if(cable_dir & (cable_dir - 1)) // Diagonal, check for /\/\/\ style cables along cardinal directions
for(var/pair in list(NORTH|SOUTH, EAST|WEST))
@@ -402,7 +392,7 @@ obj/structure/cable/proc/cableColor(var/colorC)
if(T)
var/req_dir = cable_dir ^ pair
for(var/obj/structure/cable/C in T)
- if((C.d1 && C.d1 == req_dir) || (C.d2 && C.d2 == req_dir))
+ if(C.d1 == req_dir || C.d2 == req_dir)
. += C
// Handle cables on the same turf as us
@@ -566,7 +556,7 @@ obj/structure/cable/proc/cableColor(var/colorC)
final_color = possible_cable_coil_colours["Red"]
selected_color = "red"
color = final_color
- user << "You change \the [src]'s color to [lowertext(selected_color)]."
+ to_chat(user, "You change \the [src]'s color to [lowertext(selected_color)].")
/obj/item/stack/cable_coil/proc/update_wclass()
if(amount == 1)
@@ -579,11 +569,11 @@ obj/structure/cable/proc/cableColor(var/colorC)
return
if(get_amount() == 1)
- user << "A short piece of power cable."
+ to_chat(user, "A short piece of power cable.")
else if(get_amount() == 2)
- user << "A piece of power cable."
+ to_chat(user, "A piece of power cable.")
else
- user << "A coil of power cable. There are [get_amount()] lengths of cable in the coil."
+ to_chat(user, "A coil of power cable. There are [get_amount()] lengths of cable in the coil.")
/obj/item/stack/cable_coil/verb/make_restraint()
@@ -594,14 +584,14 @@ obj/structure/cable/proc/cableColor(var/colorC)
if(ishuman(M) && !M.restrained() && !M.stat && !M.paralysis && ! M.stunned)
if(!istype(usr.loc,/turf)) return
if(src.amount <= 14)
- usr << "\red You need at least 15 lengths to make restraints!"
+ to_chat(usr, "You need at least 15 lengths to make restraints!")
return
var/obj/item/weapon/handcuffs/cable/B = new /obj/item/weapon/handcuffs/cable(usr.loc)
B.color = color
- usr << "You wind some cable together to make some restraints."
+ to_chat(usr, "You wind some cable together to make some restraints.")
src.use(15)
else
- usr << "\blue You cannot do that."
+ to_chat(usr, "You cannot do that.")
..()
/obj/item/stack/cable_coil/cyborg/verb/set_colour()
diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm
index fe51b4152e..d6ae824fd1 100644
--- a/code/modules/power/gravitygenerator.dm
+++ b/code/modules/power/gravitygenerator.dm
@@ -3,7 +3,6 @@
/obj/machinery/computer/gravity_control_computer
name = "Gravity Generator Control"
desc = "A computer to control a local gravity generator. Qualified personnel only."
- icon = 'icons/obj/computer.dmi'
icon_state = "airtunnel0e"
anchored = 1
density = 1
diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm
index 7697fdf6a4..13213c2e7e 100644
--- a/code/modules/power/power.dm
+++ b/code/modules/power/power.dm
@@ -209,16 +209,8 @@
// if unmarked==1, only return those with no powernet
/proc/power_list(var/turf/T, var/source, var/d, var/unmarked=0, var/cable_only = 0)
. = list()
- var/fdir = (!d)? 0 : turn(d, 180) // the opposite direction to d (or 0 if d==0)
-///// Z-Level Stuff
- var/Zdir
- if(d==11)
- Zdir = 11
- else if (d==12)
- Zdir = 12
- else
- Zdir = 999
-///// Z-Level Stuff
+
+ var/reverse = d ? reverse_dir[d] : 0
for(var/AM in T)
if(AM == source) continue //we don't want to return source
@@ -234,11 +226,7 @@
var/obj/structure/cable/C = AM
if(!unmarked || !C.powernet)
-///// Z-Level Stuff
- if(C.d1 == fdir || C.d2 == fdir || C.d1 == Zdir || C.d2 == Zdir)
-///// Z-Level Stuff
- . += C
- else if(C.d1 == d || C.d2 == d)
+ if(C.d1 == d || C.d2 == d || C.d1 == reverse || C.d2 == reverse )
. += C
return .
diff --git a/code/modules/power/sensors/sensor_monitoring.dm b/code/modules/power/sensors/sensor_monitoring.dm
index 597ced19db..21aecc59ea 100644
--- a/code/modules/power/sensors/sensor_monitoring.dm
+++ b/code/modules/power/sensors/sensor_monitoring.dm
@@ -6,7 +6,6 @@
/obj/machinery/computer/power_monitor
name = "Power Monitoring Console"
desc = "Computer designed to remotely monitor power levels around the station"
- icon = 'icons/obj/computer.dmi'
icon_keyboard = "power_key"
icon_screen = "power:0"
light_color = "#ffcc33"
diff --git a/code/modules/power/turbine.dm b/code/modules/power/turbine.dm
index 8786930e2f..88c4ca34ac 100644
--- a/code/modules/power/turbine.dm
+++ b/code/modules/power/turbine.dm
@@ -28,7 +28,6 @@
/obj/machinery/computer/turbine_computer
name = "Gas turbine control computer"
desc = "A computer to remotely control a gas turbine"
- icon = 'icons/obj/computer.dmi'
icon_keyboard = "tech_key"
icon_screen = "turbinecomp"
circuit = /obj/item/weapon/circuitboard/turbine_control
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 75d574ed63..f7d963523c 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -425,21 +425,21 @@
/obj/item/weapon/gun/proc/handle_post_fire(mob/user, atom/target, var/pointblank=0, var/reflex=0)
if(silenced)
playsound(user, fire_sound, 10, 1)
+ to_chat(user, "You fire \the [src][pointblank ? " point blank at \the [target]":""][reflex ? " by reflex!":""]")
+ for(var/mob/living/L in oview(2,user))
+ if(L.stat)
+ continue
+ if(L.blinded)
+ to_chat(L, "You hear a [fire_sound_text]!")
+ continue
+ to_chat(L, "[user] fires \the [src][pointblank ? " point blank at \the [target]":""][reflex ? " by reflex!":""]")
else
playsound(user, fire_sound, 50, 1)
-
- if(reflex)
- user.visible_message(
- "\The [user] fires \the [src][pointblank ? " point blank at \the [target]":""] by reflex!",
- "You fire \the [src] by reflex!",
- "You hear a [fire_sound_text]!"
- )
- else
- user.visible_message(
- "\The [user] fires \the [src][pointblank ? " point blank at \the [target]":""]!",
- "You fire \the [src]!",
- "You hear a [fire_sound_text]!"
- )
+ user.visible_message(
+ "[user] fires \the [src][pointblank ? " point blank at \the [target]":""][reflex ? " by reflex!":""]",
+ "You fire \the [src][pointblank ? " point blank at \the [target]":""][reflex ? " by reflex!":""]",
+ "You hear a [fire_sound_text]!"
+ )
if(muzzle_flash)
set_light(muzzle_flash)
diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm
index faafd2e8c9..8fbfc0e657 100644
--- a/code/modules/projectiles/guns/energy/special.dm
+++ b/code/modules/projectiles/guns/energy/special.dm
@@ -21,7 +21,7 @@
item_state = null
w_class = ITEMSIZE_NORMAL
force = 5
- slot_flags = SLOT_BELT
+ slot_flags = SLOT_BELT|SLOT_HOLSTER
charge_cost = 480
projectile_type = /obj/item/projectile/ion
diff --git a/code/modules/projectiles/guns/projectile/boltaction.dm b/code/modules/projectiles/guns/projectile/boltaction.dm
index f96dfd22ea..e07c45294c 100644
--- a/code/modules/projectiles/guns/projectile/boltaction.dm
+++ b/code/modules/projectiles/guns/projectile/boltaction.dm
@@ -49,4 +49,19 @@
desc = "The firepower of a Mosin, now the size of a pistol, with an effective combat range of about three feet. Uses 7.62mm rounds."
user << "You shorten the barrel and stock of \the [src]!"
else
- ..()
\ No newline at end of file
+ ..()
+
+
+//Lever actions are the same thing, but bigger.
+/obj/item/weapon/gun/projectile/shotgun/pump/rifle/lever
+ name = "lever-action rifle"
+ desc = "A reproduction of an almost ancient weapon design from the 19th century. This one uses a lever-action to move new rounds into the chamber. Uses 5.56mm rounds."
+ item_state = "leveraction"
+ icon_state = "leveraction"
+ fire_sound = 'sound/weapons/rifleshot.ogg'
+ max_shells = 5
+ caliber = "a556"
+ origin_tech = list(TECH_COMBAT = 1)// Old as shit rifle doesn't have very good tech.
+ ammo_type = /obj/item/ammo_casing/a556
+ load_method = SINGLE_CASING|SPEEDLOADER
+ action_sound = 'sound/weapons/riflebolt.ogg'
\ No newline at end of file
diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm
index 54a2d301c7..033b406510 100644
--- a/code/modules/projectiles/projectile/energy.dm
+++ b/code/modules/projectiles/projectile/energy.dm
@@ -29,8 +29,8 @@
flash_strength *= H.species.flash_mod
if(flash_strength > 0)
- H.confused = max(H.confused, flash_strength + 5)
- H.eye_blind = max(H.eye_blind, flash_strength)
+ H.Confuse(flash_strength + 5)
+ H.Blind(flash_strength)
H.eye_blurry = max(H.eye_blurry, flash_strength + 5)
H.adjustHalLoss(22 * (flash_strength / 5)) // Five flashes to stun. Bit weaker than melee flashes due to being ranged.
@@ -146,9 +146,9 @@
var/ear_safety = 0
ear_safety = M.get_ear_protection()
if(ear_safety == 1)
- M.confused += 150
+ M.Confuse(150)
else if (ear_safety > 1)
- M.confused += 30
+ M.Confuse(30)
else if (!ear_safety)
M.Stun(10)
M.Weaken(2)
diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm
index b507afc316..dd81d713fe 100644
--- a/code/modules/projectiles/projectile/special.dm
+++ b/code/modules/projectiles/projectile/special.dm
@@ -150,7 +150,7 @@
on_hit(var/atom/target, var/blocked = 0)
if(ishuman(target))
var/mob/living/carbon/human/M = target
- M.confused += rand(5,8)
+ M.Confuse(rand(5,8))
/obj/item/projectile/chameleon
name = "bullet"
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm
index 091842663d..5909ed906f 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm
@@ -96,6 +96,8 @@
strength_mod *= 5
if(alien == IS_TAJARA)
strength_mod *= 1.75
+ if(alien == IS_UNATHI)
+ strength_mod *= 0.75
if(alien == IS_DIONA)
strength_mod = 0
@@ -106,7 +108,7 @@
if(dose * strength_mod >= strength * 2) // Slurring
M.slurring = max(M.slurring, 30)
if(dose * strength_mod >= strength * 3) // Confusion - walking in random directions
- M.confused = max(M.confused, 20)
+ M.Confuse(20)
if(dose * strength_mod >= strength * 4) // Blurry vision
M.eye_blurry = max(M.eye_blurry, 10)
if(dose * strength_mod >= strength * 5) // Drowsyness - periodically falling asleep
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm
index f7da207e15..566f3e20f9 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm
@@ -376,7 +376,7 @@
else if(eyes_covered)
M << "Your [safe_thing] protect you from most of the pepperspray!"
M.eye_blurry = max(M.eye_blurry, effective_strength * 3)
- M.eye_blind = max(M.eye_blind, effective_strength)
+ M.Blind(effective_strength)
M.Stun(5)
M.Weaken(5)
return
@@ -387,7 +387,7 @@
else // Oh dear :D
M << "You're sprayed directly in the eyes with pepperspray!"
M.eye_blurry = max(M.eye_blurry, effective_strength * 5)
- M.eye_blind = max(M.eye_blind, effective_strength * 2)
+ M.Blind(effective_strength * 2)
M.Stun(5)
M.Weaken(5)
return
@@ -1166,7 +1166,7 @@
if(M.dizziness)
M.dizziness = max(0, M.dizziness - 15)
if(M.confused)
- M.confused = max(0, M.confused - 5)
+ M.Confuse(-5)
/datum/reagent/drink/dry_ramen
name = "Dry Ramen"
@@ -2232,3 +2232,26 @@
glass_name = "special blend whiskey"
glass_desc = "Just when you thought regular station whiskey was good... This silky, amber goodness has to come along and ruin everything."
+/datum/reagent/ethanol/unathiliquor //Needs a better name
+ name = "Unathi Liquor"
+ id = "unathiliquor"
+ description = "This barely qualifies as a drink, and could give jetfuel a run for its money. Also known to cause feelings of euphoria and numbness."
+ taste_description = "spiced numbness"
+ color = "#242424"
+ strength = 5
+
+ glass_name = "unathi liquor"
+ glass_desc = "This barely qualifies as a drink, and may cause euphoria and numbness. Imbimber beware!"
+
+/datum/reagent/ethanol/unathiliquor/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
+ ..()
+ if(alien == IS_DIONA)
+ return
+
+ var/drug_strength = 10
+ if(alien == IS_SKRELL)
+ drug_strength = drug_strength * 0.8
+
+ M.druggy = max(M.druggy, drug_strength)
+ if(prob(10) && isturf(M.loc) && !istype(M.loc, /turf/space) && M.canmove && !M.restrained())
+ step(M, pick(cardinal))
\ No newline at end of file
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm
index e0307e07cc..ef6d8bb428 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm
@@ -258,7 +258,7 @@
/datum/reagent/oxycodone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.add_chemical_effect(CE_PAINKILLER, 200)
M.eye_blurry += 10
- M.confused += 5
+ M.Confuse(5)
/datum/reagent/oxycodone/overdose(var/mob/living/carbon/M, var/alien)
..()
@@ -319,7 +319,7 @@
/datum/reagent/imidazoline/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.eye_blurry = max(M.eye_blurry - 5, 0)
- M.eye_blind = max(M.eye_blind - 5, 0)
+ M.AdjustBlinded(-5)
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/obj/item/organ/internal/eyes/E = H.internal_organs_by_name[O_EYES]
@@ -349,7 +349,7 @@
continue
if(I.damage > 0) //Peridaxon heals only non-robotic organs
I.damage = max(I.damage - removed, 0)
- H.confused += 5
+ H.Confuse(5)
if(I.damage <= 5 && I.organ_tag == O_EYES)
H.eye_blurry += 10 //Eyes need to reset, or something
H.sdisabilities &= ~BLIND
@@ -441,7 +441,7 @@
M.dizziness = 0
M.drowsyness = 0
M.stuttering = 0
- M.confused = 0
+ M.SetConfused(0)
if(M.ingested)
for(var/datum/reagent/R in M.ingested.reagent_list)
if(istype(R, /datum/reagent/ethanol))
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm
index 4f8e17cb1e..0a7c78f952 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm
@@ -133,7 +133,7 @@
M.disabilities = 0
M.sdisabilities = 0
M.eye_blurry = 0
- M.eye_blind = 0
+ M.SetBlinded(0)
M.SetWeakened(0)
M.SetStunned(0)
M.SetParalysis(0)
@@ -141,7 +141,7 @@
M.dizziness = 0
M.drowsyness = 0
M.stuttering = 0
- M.confused = 0
+ M.SetConfused(0)
M.sleeping = 0
M.jitteriness = 0
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm
index 6e34257e4a..12540c2d04 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm
@@ -403,7 +403,7 @@
effective_dose *= 2
if(effective_dose == metabolism)
- M.confused += 2
+ M.Confuse(2)
M.drowsyness += 2
else if(effective_dose < 2 * threshold)
M.Weaken(30)
@@ -429,6 +429,7 @@
glass_name = "beer"
glass_desc = "A freezing pint of beer"
+
/* Drugs */
/datum/reagent/space_drugs
@@ -490,7 +491,7 @@
if(alien == IS_SKRELL)
drug_strength = drug_strength * 0.8
M.make_dizzy(drug_strength)
- M.confused = max(M.confused, drug_strength * 5)
+ M.Confuse(drug_strength * 5)
/datum/reagent/impedrezene
name = "Impedrezene"
diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm
index 41ad4cb5c6..e20ee9459f 100644
--- a/code/modules/reagents/Chemistry-Recipes.dm
+++ b/code/modules/reagents/Chemistry-Recipes.dm
@@ -384,7 +384,7 @@
name = "Stimm"
id = "stimm"
result = "stimm"
- required_reagents = list("sugar" = 1, "fuel" = 1)
+ required_reagents = list("left4zed" = 1, "fuel" = 1)
catalysts = list("fuel" = 5)
result_amount = 2
diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm
index ce377c8709..16a1cb3b26 100644
--- a/code/modules/reagents/reagent_containers/borghydro.dm
+++ b/code/modules/reagents/reagent_containers/borghydro.dm
@@ -121,7 +121,7 @@
recharge_time = 3
volume = 60
possible_transfer_amounts = list(5, 10, 20, 30)
- reagent_ids = list("beer", "kahlua", "whiskey", "specialwhiskey", "wine", "vodka", "gin", "rum", "tequilla", "vermouth", "cognac", "ale", "mead", "water", "sugar", "ice", "tea", "icetea", "cola", "spacemountainwind", "dr_gibb", "space_up", "tonic", "sodawater", "lemon_lime", "orangejuice", "limejuice", "watermelonjuice")
+ reagent_ids = list("ale", "beer", "berryjuice", "coffee", "cognac", "cola", "dr_gibb", "egg", "gin", "hot_coco", "ice", "icetea", "kahlua", "lemonjuice", "lemon_lime", "limejuice", "mead", "milk", "mint", "orangejuice", "rum", "sodawater", "soymilk", "space_up", "spacemountainwind", "specialwhiskey", "sugar", "tea", "tequilla", "tomatojuice", "tonic", "vermouth", "vodka", "water", "watermelonjuice", "whiskey", "wine")
/obj/item/weapon/reagent_containers/borghypo/service/attack(var/mob/M, var/mob/user)
return
diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm
index ed27e1a259..bd670cc8bc 100644
--- a/code/modules/reagents/reagent_containers/glass.dm
+++ b/code/modules/reagents/reagent_containers/glass.dm
@@ -243,6 +243,12 @@
user.drop_from_inventory(src)
qdel(src)
return
+ else if(istype(D, /obj/item/weapon/wirecutters))
+ to_chat(user, "You cut a big hole in \the [src] with \the [D]. It's kinda useless as a bucket now.")
+ user.put_in_hands(new /obj/item/clothing/head/helmet/bucket)
+ user.drop_from_inventory(src)
+ qdel(src)
+ return
else if(istype(D, /obj/item/weapon/mop))
if(reagents.total_volume < 1)
user << "\The [src] is empty!"
diff --git a/code/modules/shieldgen/emergency_shield.dm b/code/modules/shieldgen/emergency_shield.dm
index f7bc1d1c80..4872131429 100644
--- a/code/modules/shieldgen/emergency_shield.dm
+++ b/code/modules/shieldgen/emergency_shield.dm
@@ -290,7 +290,7 @@
else if(istype(W, /obj/item/stack/cable_coil) && malfunction && is_open)
var/obj/item/stack/cable_coil/coil = W
user << "You begin to replace the wires."
- //if(do_after(user, min(60, round( ((maxhealth/health)*10)+(malfunction*10) ))) //Take longer to repair heavier damage
+ //if(do_after(user, min(60, round( ((getMaxHealth()/health)*10)+(malfunction*10) ))) //Take longer to repair heavier damage
if(do_after(user, 30))
if (coil.use(1))
health = max_health
diff --git a/code/modules/shuttles/shuttle_console.dm b/code/modules/shuttles/shuttle_console.dm
index b6857a3f82..980053bd5d 100644
--- a/code/modules/shuttles/shuttle_console.dm
+++ b/code/modules/shuttles/shuttle_console.dm
@@ -1,6 +1,5 @@
/obj/machinery/computer/shuttle_control
name = "shuttle control console"
- icon = 'icons/obj/computer.dmi'
icon_keyboard = "atmos_key"
icon_screen = "shuttle"
circuit = null
diff --git a/code/modules/spells/spellbook.dm b/code/modules/spells/spellbook.dm
index a28f03e8fe..515453f6a3 100644
--- a/code/modules/spells/spellbook.dm
+++ b/code/modules/spells/spellbook.dm
@@ -322,7 +322,7 @@
/obj/item/weapon/spellbook/oneuse/blind/recoil(mob/user as mob)
..()
user <<"You go blind!"
- user.eye_blind = 10
+ user.Blind(10)
/obj/item/weapon/spellbook/oneuse/mindswap
spell = /spell/targeted/mind_transfer
diff --git a/code/modules/spells/targeted/targeted.dm b/code/modules/spells/targeted/targeted.dm
index 498d363408..d9d581e050 100644
--- a/code/modules/spells/targeted/targeted.dm
+++ b/code/modules/spells/targeted/targeted.dm
@@ -138,8 +138,8 @@ Targeted spells have two useful flags: INCLUDEUSER and SELECTABLE. These are exp
if(amt_weakened || amt_paralysis || amt_stunned)
if(target.buckled)
target.buckled = null
- target.eye_blind += amt_eye_blind
+ target.Blind(amt_eye_blind)
target.eye_blurry += amt_eye_blurry
target.dizziness += amt_dizziness
- target.confused += amt_confused
+ target.Confuse(amt_confused)
target.stuttering += amt_stuttering
\ No newline at end of file
diff --git a/code/modules/ventcrawl/ventcrawl.dm b/code/modules/ventcrawl/ventcrawl.dm
index c9d08c3385..1ece024833 100644
--- a/code/modules/ventcrawl/ventcrawl.dm
+++ b/code/modules/ventcrawl/ventcrawl.dm
@@ -44,10 +44,15 @@ var/list/ventcrawl_machinery = list(
/mob/living/proc/is_allowed_vent_crawl_item(var/obj/item/carried_item)
if(carried_item == ability_master)
return 1
+
+ var/list/allowed = list()
for(var/type in can_enter_vent_with)
- if(istype(carried_item, type)) //VOREStation Edit - It was a typo before maybe?
- return 1 //VOREStation Edit also
- return 0
+ var/list/types = typesof(type)
+ allowed += types
+
+ if(carried_item.type in allowed)
+ if(get_inventory_slot(carried_item) == 0)
+ return 1
/mob/living/carbon/is_allowed_vent_crawl_item(var/obj/item/carried_item)
if(carried_item in internal_organs)
diff --git a/code/modules/virus2/curer.dm b/code/modules/virus2/curer.dm
index d6c5189f19..c297643e2a 100644
--- a/code/modules/virus2/curer.dm
+++ b/code/modules/virus2/curer.dm
@@ -1,6 +1,5 @@
/obj/machinery/computer/curer
name = "cure research machine"
- icon = 'icons/obj/computer.dmi'
icon_keyboard = "med_key"
icon_screen = "dna"
circuit = /obj/item/weapon/circuitboard/curefab
diff --git a/code/modules/virus2/diseasesplicer.dm b/code/modules/virus2/diseasesplicer.dm
index 8d88639db3..298dc49f27 100644
--- a/code/modules/virus2/diseasesplicer.dm
+++ b/code/modules/virus2/diseasesplicer.dm
@@ -1,6 +1,5 @@
/obj/machinery/computer/diseasesplicer
name = "disease splicer"
- icon = 'icons/obj/computer.dmi'
icon_keyboard = "med_key"
icon_screen = "crew"
diff --git a/code/modules/virus2/effect.dm b/code/modules/virus2/effect.dm
index 5243bae35f..310f223159 100644
--- a/code/modules/virus2/effect.dm
+++ b/code/modules/virus2/effect.dm
@@ -264,7 +264,7 @@
stage = 3
activate(var/mob/living/carbon/mob,var/multiplier)
mob << "You have trouble telling right and left apart all of a sudden."
- mob.confused += 10
+ mob.Confuse(10)
/datum/disease2/effect/mutation
name = "DNA Degradation"
diff --git a/code/modules/xenobio2/machinery/injector_computer.dm b/code/modules/xenobio2/machinery/injector_computer.dm
index 6c2dc375e8..9dff9d43fb 100644
--- a/code/modules/xenobio2/machinery/injector_computer.dm
+++ b/code/modules/xenobio2/machinery/injector_computer.dm
@@ -76,7 +76,7 @@
if(injector.occupant)
data["occupantHealth"] = injector.occupant.health
- data["occupantHealthMax"] = injector.occupant.maxHealth
+ data["occupantHealthMax"] = injector.occupant.getMaxHealth()
else
data["occupantHealth"] = null
data["occupantHealthMax"] = null
diff --git a/config/example/game_options.txt b/config/example/game_options.txt
index 035431b8ba..9e122db423 100644
--- a/config/example/game_options.txt
+++ b/config/example/game_options.txt
@@ -57,6 +57,8 @@ ALIEN_DELAY 0
METROID_DELAY 0
ANIMAL_DELAY 0
+## Volume of footstep sound effects. Range: 1-100, Set to 0 to disable footstep sounds.
+FOOTSTEP_VOLUME 60
### Miscellaneous ###
diff --git a/html/changelog.html b/html/changelog.html
index beb8c38c32..f4d1c782d5 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -57,6 +57,41 @@
]Anewbe updated:
- Wooden circlets can now be worn on the head.
+ 19 April 2017
+ Anewbe updated:
+
+ - Unathi ribcages now reach down to their lower torso.
+ - Unathi no longer have appendices or kidneys, the function of the kidneys is now a function of their liver.
+ - Unathi are more slightly more difficult to damage.
+ - Unathi now process medicine 15% slower. Additionally, it's harder for them to get drunk.
+ - Unathi age range is now 32 to 260.
+ - Unathi are not as slowed by heavy items.
+
+ Atermonera updated:
+
+ - Translators no longer try to translate null languages.
+
+ LorenLuke updated:
+
+ - Allows Blast doors to be attacked and broken like regular airlocks.
+ - Changelings can bank up to a maximum of 3 respecs at one time.
+ - Changelings begin with 2 respecs.
+ - Firing a silenced weapon gives a message in text to the user.
+
+ MagmaRam updated:
+
+ - Added instructions on how to use the changelog updating scripts.
+ - Updated in-game EVA manual.
+
+ Neerti updated:
+
+ - Adds makeshift armor for the head and chest regions. How protective they are depends on the material used to craft it. The helmet is made by using wirecutters on a bucket, then using a stack of material. The chestpiece is made by crafting two armor plate, using wires on one of them, then hiting one with the other.
+
+ Yoshax updated:
+
+ - Water such as the pool will no longer apply fire stacks when you enter, meaning you will no longer be flammable from swimming.
+
+
16 April 2017
Anewbe updated:
diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml
index d65fec13f5..9ade78534e 100644
--- a/html/changelogs/.all_changelog.yml
+++ b/html/changelogs/.all_changelog.yml
@@ -3423,3 +3423,31 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
- tweak: Scrubbers now scrub Phoron by default.
- tweak: Scrubbers now have the first dangerzone at anything more than 0 Phoron.
- bugfix: No longer will you attack Alarms with your ID when trying to unlock them.
+2017-04-19:
+ Anewbe:
+ - rscadd: Unathi ribcages now reach down to their lower torso.
+ - rscadd: Unathi no longer have appendices or kidneys, the function of the kidneys
+ is now a function of their liver.
+ - rscadd: Unathi are more slightly more difficult to damage.
+ - rscadd: Unathi now process medicine 15% slower. Additionally, it's harder for
+ them to get drunk.
+ - rscadd: Unathi age range is now 32 to 260.
+ - rscadd: Unathi are not as slowed by heavy items.
+ Atermonera:
+ - bugfix: Translators no longer try to translate null languages.
+ LorenLuke:
+ - rscadd: Allows Blast doors to be attacked and broken like regular airlocks.
+ - tweak: Changelings can bank up to a maximum of 3 respecs at one time.
+ - tweak: Changelings begin with 2 respecs.
+ - tweak: Firing a silenced weapon gives a message in text to the user.
+ MagmaRam:
+ - rscadd: Added instructions on how to use the changelog updating scripts.
+ - tweak: Updated in-game EVA manual.
+ Neerti:
+ - rscadd: Adds makeshift armor for the head and chest regions. How protective they
+ are depends on the material used to craft it. The helmet is made by using wirecutters
+ on a bucket, then using a stack of material. The chestpiece is made by crafting
+ two armor plate, using wires on one of them, then hiting one with the other.
+ Yoshax:
+ - bugfix: Water such as the pool will no longer apply fire stacks when you enter,
+ meaning you will no longer be flammable from swimming.
diff --git a/html/changelogs/MagmaRam - changelog_instructions.yml b/html/changelogs/Anewbe - CultRobesEnergy.yml
similarity index 93%
rename from html/changelogs/MagmaRam - changelog_instructions.yml
rename to html/changelogs/Anewbe - CultRobesEnergy.yml
index 82235bc8f6..1d865cb090 100644
--- a/html/changelogs/MagmaRam - changelog_instructions.yml
+++ b/html/changelogs/Anewbe - CultRobesEnergy.yml
@@ -22,7 +22,7 @@
#################################
# Your name.
-author: MagmaRam
+author: Anewbe
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
delete-after: True
@@ -33,4 +33,4 @@ delete-after: True
# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
changes:
- - rscadd: "Added instructions on how to use the changelog updating scripts."
+ - rscadd: "Cultist armor now has better protection from strange energies."
diff --git a/html/changelogs/Yoshax-HumanTorch.yml b/html/changelogs/Anewbe - Ion Pistol.yml
similarity index 89%
rename from html/changelogs/Yoshax-HumanTorch.yml
rename to html/changelogs/Anewbe - Ion Pistol.yml
index 5ecdc4dd9a..efc5c77c0e 100644
--- a/html/changelogs/Yoshax-HumanTorch.yml
+++ b/html/changelogs/Anewbe - Ion Pistol.yml
@@ -22,7 +22,7 @@
#################################
# Your name.
-author: Yoshax
+author: Anewbe
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
delete-after: True
@@ -33,4 +33,5 @@ delete-after: True
# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
changes:
- - bugfix: "Water such as the pool will no longer apply fire stacks when you enter, meaning you will no longer be flammable from swimming."
+ - rscadd: "Adds the ion pistol to the uplink."
+ - tweak: "The ion pistol can now be holstered.
\ No newline at end of file
diff --git a/html/changelogs/MagmaRam - evabook.yml b/html/changelogs/Anewbe - Smoking Pipes.yml
similarity index 94%
rename from html/changelogs/MagmaRam - evabook.yml
rename to html/changelogs/Anewbe - Smoking Pipes.yml
index f94057e6a4..33ebbe8158 100644
--- a/html/changelogs/MagmaRam - evabook.yml
+++ b/html/changelogs/Anewbe - Smoking Pipes.yml
@@ -22,7 +22,7 @@
#################################
# Your name.
-author: MagmaRam
+author: Anewbe
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
delete-after: True
@@ -33,4 +33,4 @@ delete-after: True
# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
changes:
- - tweak: "Updated in-game EVA manual."
+ - bugfix: "Sprites on the smoking pipes should be fixed."
diff --git a/html/changelogs/Atermonera - Translators2.yml b/html/changelogs/Atermonera - Records.yml
similarity index 92%
rename from html/changelogs/Atermonera - Translators2.yml
rename to html/changelogs/Atermonera - Records.yml
index f330795d80..9b66e57129 100644
--- a/html/changelogs/Atermonera - Translators2.yml
+++ b/html/changelogs/Atermonera - Records.yml
@@ -1,36 +1,36 @@
-################################
-# Example Changelog File
-#
-# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
-#
-# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
-# When it is, any changes listed below will disappear.
-#
-# Valid Prefixes:
-# bugfix
-# wip (For works in progress)
-# tweak
-# soundadd
-# sounddel
-# rscadd (general adding of nice things)
-# rscdel (general deleting of nice things)
-# imageadd
-# imagedel
-# maptweak
-# spellcheck (typo fixes)
-# experiment
-#################################
-
-# Your name.
-author: Atermonera
-
-# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
-delete-after: True
-
-# Any changes you've made. See valid prefix list above.
-# INDENT WITH TWO SPACES. NOT TABS. SPACES.
-# SCREW THIS UP AND IT WON'T WORK.
-# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
-# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
-changes:
- - bugfix: "Translators no longer try to translate null languages."
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+#################################
+
+# Your name.
+author: Atermonera
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - rscadd: "Brain type (Organic, cyborg, posi, or drone) is now displayed in all records."
diff --git a/html/changelogs/Leshana-footstep-sounds.yml b/html/changelogs/Leshana-footstep-sounds.yml
new file mode 100644
index 0000000000..2e0045dd90
--- /dev/null
+++ b/html/changelogs/Leshana-footstep-sounds.yml
@@ -0,0 +1,4 @@
+author: Leshana
+delete-after: True
+changes:
+ - rscadd: "Implements footstep sound system and adds sounds to various floor types including plating, tiles, wood, and carpet."
diff --git a/html/changelogs/LorenLuke - Bodybags.yml b/html/changelogs/LorenLuke - Bodybags.yml
new file mode 100644
index 0000000000..e9dbd37406
--- /dev/null
+++ b/html/changelogs/LorenLuke - Bodybags.yml
@@ -0,0 +1,37 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+#################################
+
+# Your name.
+author: Belsima
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - tweak: "Changes relaymove() code in bodybags."
+ - bugfix: "Above tweak used to allow exiting bodybag while in closed morgue tray."
diff --git a/html/changelogs/LorenLuke - Buckle-Give.yml b/html/changelogs/LorenLuke - Buckle-Give.yml
new file mode 100644
index 0000000000..1332c7c576
--- /dev/null
+++ b/html/changelogs/LorenLuke - Buckle-Give.yml
@@ -0,0 +1,36 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+#################################
+
+# Your name.
+author: LorenLuke
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - bugfix: "Allows people who are bucked to give/receive items."
diff --git a/html/changelogs/LorenLuke - Bucklechanges.yml b/html/changelogs/LorenLuke - Bucklechanges.yml
new file mode 100644
index 0000000000..771cce1148
--- /dev/null
+++ b/html/changelogs/LorenLuke - Bucklechanges.yml
@@ -0,0 +1,36 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+#################################
+
+# Your name.
+author: LorenLuke
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - tweak: "Can click-drag people onto chairs/beds from 1 tile away to buckle them."
diff --git a/html/changelogs/LorenLuke - Tape.yml b/html/changelogs/LorenLuke - Tape.yml
new file mode 100644
index 0000000000..42135bb9ca
--- /dev/null
+++ b/html/changelogs/LorenLuke - Tape.yml
@@ -0,0 +1,36 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+#################################
+
+# Your name.
+author: LorenLuke
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - tweak: "Allows you to place tape masks/restraints back on the roll (roll is still infinite)."
diff --git a/html/changelogs/LorenLuke - Ventcrawl.yml b/html/changelogs/LorenLuke - Ventcrawl.yml
new file mode 100644
index 0000000000..ad43257fdc
--- /dev/null
+++ b/html/changelogs/LorenLuke - Ventcrawl.yml
@@ -0,0 +1,36 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+#################################
+
+# Your name.
+author: LorenLuke
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - bugfix: "Fixes ventcrawling for spiderbots/implants/etc."
diff --git a/html/changelogs/Neerti-DroneID.yml b/html/changelogs/Neerti-DroneID.yml
new file mode 100644
index 0000000000..15837f65b8
--- /dev/null
+++ b/html/changelogs/Neerti-DroneID.yml
@@ -0,0 +1,36 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+#################################
+
+# Your name.
+author: Neerti
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - rscadd: "Drones will now spawn with an EIO-mandated ID card alongside their NT ID."
diff --git a/html/changelogs/Yoshax-Tape.yml b/html/changelogs/Yoshax-Tape.yml
new file mode 100644
index 0000000000..ffc7f56037
--- /dev/null
+++ b/html/changelogs/Yoshax-Tape.yml
@@ -0,0 +1,36 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+#################################
+
+# Your name.
+author: Yoshax
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - tweak: "Tape color is different now. Security tape is red rather than yellow, Engineering tape remains yellow and Atmos tape is a lighter cyan rather than blue."
\ No newline at end of file
diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi
index a69e893b6f..c13a604dba 100644
Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ
diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi
index 7407aeefb5..44f920fe30 100644
Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ
diff --git a/icons/mob/human_races/r_lizard.dmi b/icons/mob/human_races/r_lizard.dmi
index 5fb2c58be4..97e6f04bdc 100644
Binary files a/icons/mob/human_races/r_lizard.dmi and b/icons/mob/human_races/r_lizard.dmi differ
diff --git a/icons/mob/items/lefthand_guns.dmi b/icons/mob/items/lefthand_guns.dmi
index ff49dc5577..7b2b705c94 100644
Binary files a/icons/mob/items/lefthand_guns.dmi and b/icons/mob/items/lefthand_guns.dmi differ
diff --git a/icons/mob/items/righthand_guns.dmi b/icons/mob/items/righthand_guns.dmi
index 44521ed36e..7c05fbd61d 100644
Binary files a/icons/mob/items/righthand_guns.dmi and b/icons/mob/items/righthand_guns.dmi differ
diff --git a/icons/mob/mask.dmi b/icons/mob/mask.dmi
index 00f14c373e..8a4ce2c73e 100644
Binary files a/icons/mob/mask.dmi and b/icons/mob/mask.dmi differ
diff --git a/icons/mob/species/tajaran/helmet.dmi b/icons/mob/species/tajaran/helmet.dmi
index 87a3d3f58f..ff89b2dcdd 100644
Binary files a/icons/mob/species/tajaran/helmet.dmi and b/icons/mob/species/tajaran/helmet.dmi differ
diff --git a/icons/mob/species/tajaran/mask.dmi b/icons/mob/species/tajaran/mask.dmi
index cf3be6425f..d7028d66a6 100644
Binary files a/icons/mob/species/tajaran/mask.dmi and b/icons/mob/species/tajaran/mask.dmi differ
diff --git a/icons/mob/species/unathi/helmet.dmi b/icons/mob/species/unathi/helmet.dmi
index 1af66a7d08..618d3be573 100644
Binary files a/icons/mob/species/unathi/helmet.dmi and b/icons/mob/species/unathi/helmet.dmi differ
diff --git a/icons/mob/species/unathi/mask.dmi b/icons/mob/species/unathi/mask.dmi
index cf3be6425f..25cc585aed 100644
Binary files a/icons/mob/species/unathi/mask.dmi and b/icons/mob/species/unathi/mask.dmi differ
diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi
index 5d7180da7c..b2eb9c72fe 100644
Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ
diff --git a/icons/obj/card.dmi b/icons/obj/card.dmi
index e1a2c1c2ae..390fdb88ea 100644
Binary files a/icons/obj/card.dmi and b/icons/obj/card.dmi differ
diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi
index 9337d5127c..ef18c7bf49 100644
Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ
diff --git a/icons/obj/clothing/masks.dmi b/icons/obj/clothing/masks.dmi
index b6b28fdfbe..fd3ff5ceca 100644
Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ
diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi
index b1750efa36..c1183a4e93 100644
Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ
diff --git a/icons/obj/gun.dmi b/icons/obj/gun.dmi
index d9e2dfef95..ba02b5a324 100644
Binary files a/icons/obj/gun.dmi and b/icons/obj/gun.dmi differ
diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi
index dc3456ba67..778ec461bb 100644
Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ
diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi
index b2ff3108ea..39ed73fc3d 100644
Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ
diff --git a/icons/obj/vending.dmi b/icons/obj/vending.dmi
index 5671731aab..9bb3378c8e 100755
Binary files a/icons/obj/vending.dmi and b/icons/obj/vending.dmi differ
diff --git a/icons/policetape.dmi b/icons/policetape.dmi
index bc469f2eab..5dde02f1b5 100644
Binary files a/icons/policetape.dmi and b/icons/policetape.dmi differ
diff --git a/nano/templates/pai_medrecords.tmpl b/nano/templates/pai_medrecords.tmpl
index 89926d3915..24e00e949f 100644
--- a/nano/templates/pai_medrecords.tmpl
+++ b/nano/templates/pai_medrecords.tmpl
@@ -19,6 +19,10 @@ code/modules/mob/living/silicon/pai/software_modules.dm
Record ID
{{:data.general.id}}
+
+ Entity Classification
+ {{:data.general.brain_type}}
+
Sex
{{:data.general.sex}}
diff --git a/nano/templates/pai_secrecords.tmpl b/nano/templates/pai_secrecords.tmpl
index 51cb45dee2..5ba1e4d90d 100644
--- a/nano/templates/pai_secrecords.tmpl
+++ b/nano/templates/pai_secrecords.tmpl
@@ -19,6 +19,10 @@ code/modules/mob/living/silicon/pai/software_modules.dm
Record ID
{{:data.general.id}}
+
+ Entity Classification
+ {{:data.general.brain_type}}
+
Sex
{{:data.general.sex}}
diff --git a/nano/templates/pda.tmpl b/nano/templates/pda.tmpl
index 6cd3004654..77f026a349 100644
--- a/nano/templates/pda.tmpl
+++ b/nano/templates/pda.tmpl
@@ -568,6 +568,7 @@ Used In File(s): \code\game\objects\items\devices\PDA\PDA.dm
{{if data.records.general_exists == 1}}
Name: {{:data.records.general.name}}
+ Entity Class: {{:data.records.general.brain_type}}
Sex: {{:data.records.general.sex}}
Species: {{:data.records.general.species}}
Age: {{:data.records.general.age}}
diff --git a/sound/effects/footstep/carpet1.ogg b/sound/effects/footstep/carpet1.ogg
new file mode 100644
index 0000000000..2735a9bf3d
Binary files /dev/null and b/sound/effects/footstep/carpet1.ogg differ
diff --git a/sound/effects/footstep/carpet2.ogg b/sound/effects/footstep/carpet2.ogg
new file mode 100644
index 0000000000..07e5f2320a
Binary files /dev/null and b/sound/effects/footstep/carpet2.ogg differ
diff --git a/sound/effects/footstep/carpet3.ogg b/sound/effects/footstep/carpet3.ogg
new file mode 100644
index 0000000000..edb0193f6e
Binary files /dev/null and b/sound/effects/footstep/carpet3.ogg differ
diff --git a/sound/effects/footstep/carpet4.ogg b/sound/effects/footstep/carpet4.ogg
new file mode 100644
index 0000000000..c9598e2b73
Binary files /dev/null and b/sound/effects/footstep/carpet4.ogg differ
diff --git a/sound/effects/footstep/carpet5.ogg b/sound/effects/footstep/carpet5.ogg
new file mode 100644
index 0000000000..076818323a
Binary files /dev/null and b/sound/effects/footstep/carpet5.ogg differ
diff --git a/sound/effects/footstep/floor1.ogg b/sound/effects/footstep/floor1.ogg
new file mode 100644
index 0000000000..1e3e155839
Binary files /dev/null and b/sound/effects/footstep/floor1.ogg differ
diff --git a/sound/effects/footstep/floor2.ogg b/sound/effects/footstep/floor2.ogg
new file mode 100644
index 0000000000..cce5a25d82
Binary files /dev/null and b/sound/effects/footstep/floor2.ogg differ
diff --git a/sound/effects/footstep/floor3.ogg b/sound/effects/footstep/floor3.ogg
new file mode 100644
index 0000000000..16ab67f729
Binary files /dev/null and b/sound/effects/footstep/floor3.ogg differ
diff --git a/sound/effects/footstep/floor4.ogg b/sound/effects/footstep/floor4.ogg
new file mode 100644
index 0000000000..9ef15430ff
Binary files /dev/null and b/sound/effects/footstep/floor4.ogg differ
diff --git a/sound/effects/footstep/floor5.ogg b/sound/effects/footstep/floor5.ogg
new file mode 100644
index 0000000000..0f6a66057d
Binary files /dev/null and b/sound/effects/footstep/floor5.ogg differ
diff --git a/sound/effects/footstep/hull1.ogg b/sound/effects/footstep/hull1.ogg
new file mode 100644
index 0000000000..615df6c550
Binary files /dev/null and b/sound/effects/footstep/hull1.ogg differ
diff --git a/sound/effects/footstep/hull2.ogg b/sound/effects/footstep/hull2.ogg
new file mode 100644
index 0000000000..3aecb743f7
Binary files /dev/null and b/sound/effects/footstep/hull2.ogg differ
diff --git a/sound/effects/footstep/hull3.ogg b/sound/effects/footstep/hull3.ogg
new file mode 100644
index 0000000000..03339131f6
Binary files /dev/null and b/sound/effects/footstep/hull3.ogg differ
diff --git a/sound/effects/footstep/hull4.ogg b/sound/effects/footstep/hull4.ogg
new file mode 100644
index 0000000000..2fba89d318
Binary files /dev/null and b/sound/effects/footstep/hull4.ogg differ
diff --git a/sound/effects/footstep/hull5.ogg b/sound/effects/footstep/hull5.ogg
new file mode 100644
index 0000000000..10c5912b97
Binary files /dev/null and b/sound/effects/footstep/hull5.ogg differ
diff --git a/sound/effects/footstep/plating1.ogg b/sound/effects/footstep/plating1.ogg
new file mode 100644
index 0000000000..0df770e663
Binary files /dev/null and b/sound/effects/footstep/plating1.ogg differ
diff --git a/sound/effects/footstep/plating2.ogg b/sound/effects/footstep/plating2.ogg
new file mode 100644
index 0000000000..314b9133d2
Binary files /dev/null and b/sound/effects/footstep/plating2.ogg differ
diff --git a/sound/effects/footstep/plating3.ogg b/sound/effects/footstep/plating3.ogg
new file mode 100644
index 0000000000..5c571d77eb
Binary files /dev/null and b/sound/effects/footstep/plating3.ogg differ
diff --git a/sound/effects/footstep/plating4.ogg b/sound/effects/footstep/plating4.ogg
new file mode 100644
index 0000000000..5953262764
Binary files /dev/null and b/sound/effects/footstep/plating4.ogg differ
diff --git a/sound/effects/footstep/plating5.ogg b/sound/effects/footstep/plating5.ogg
new file mode 100644
index 0000000000..4676a637a6
Binary files /dev/null and b/sound/effects/footstep/plating5.ogg differ
diff --git a/sound/effects/footstep/wood1.ogg b/sound/effects/footstep/wood1.ogg
new file mode 100644
index 0000000000..c76fc423fc
Binary files /dev/null and b/sound/effects/footstep/wood1.ogg differ
diff --git a/sound/effects/footstep/wood2.ogg b/sound/effects/footstep/wood2.ogg
new file mode 100644
index 0000000000..71dc1aa967
Binary files /dev/null and b/sound/effects/footstep/wood2.ogg differ
diff --git a/sound/effects/footstep/wood3.ogg b/sound/effects/footstep/wood3.ogg
new file mode 100644
index 0000000000..bf86889006
Binary files /dev/null and b/sound/effects/footstep/wood3.ogg differ
diff --git a/sound/effects/footstep/wood4.ogg b/sound/effects/footstep/wood4.ogg
new file mode 100644
index 0000000000..44734425ce
Binary files /dev/null and b/sound/effects/footstep/wood4.ogg differ
diff --git a/sound/effects/footstep/wood5.ogg b/sound/effects/footstep/wood5.ogg
new file mode 100644
index 0000000000..5ad4fa81e7
Binary files /dev/null and b/sound/effects/footstep/wood5.ogg differ
diff --git a/vorestation.dme b/vorestation.dme
index d2cc5088d9..fcc0e50d77 100644
--- a/vorestation.dme
+++ b/vorestation.dme
@@ -36,6 +36,7 @@
#include "code\__defines\misc.dm"
#include "code\__defines\misc_vr.dm"
#include "code\__defines\mobs.dm"
+#include "code\__defines\planets.dm"
#include "code\__defines\process_scheduler.dm"
#include "code\__defines\research.dm"
#include "code\__defines\roguemining_vr.dm"
@@ -947,6 +948,7 @@
#include "code\game\objects\items\weapons\material\foam.dm"
#include "code\game\objects\items\weapons\material\kitchen.dm"
#include "code\game\objects\items\weapons\material\knives.dm"
+#include "code\game\objects\items\weapons\material\material_armor.dm"
#include "code\game\objects\items\weapons\material\material_weapons.dm"
#include "code\game\objects\items\weapons\material\misc.dm"
#include "code\game\objects\items\weapons\material\shards.dm"
@@ -1612,6 +1614,7 @@
#include "code\modules\mob\mob_helpers.dm"
#include "code\modules\mob\mob_movement.dm"
#include "code\modules\mob\mob_transformation_simple.dm"
+#include "code\modules\mob\modifiers.dm"
#include "code\modules\mob\say.dm"
#include "code\modules\mob\say_vr.dm"
#include "code\modules\mob\transform_procs.dm"
@@ -1944,6 +1947,7 @@
#include "code\modules\organs\subtypes\machine.dm"
#include "code\modules\organs\subtypes\seromi.dm"
#include "code\modules\organs\subtypes\standard.dm"
+#include "code\modules\organs\subtypes\unathi.dm"
#include "code\modules\organs\subtypes\unbreakable.dm"
#include "code\modules\organs\subtypes\vox.dm"
#include "code\modules\overmap\_defines.dm"
|
|
|
|
|