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/security.dm b/code/game/machinery/computer/security.dm
index 389828843f1..465884b2caa 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 \
diff --git a/code/game/machinery/computer/skills.dm b/code/game/machinery/computer/skills.dm
index 1a67778fdf6..bd9c66dbaed 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/computer3/computers/medical.dm b/code/game/machinery/computer3/computers/medical.dm
index 57a662db46f..bb4228397dd 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 a314bed2736..6b77a274bf5 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 d1ab11e7067..5d0f707ae88 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 209e3bb228f..3d899377cca 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 d01e45c8894..569395cd2c0 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 ae48142b4d2..a18edbc5fa5 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/medical/odysseus.dm b/code/game/mecha/medical/odysseus.dm
index 967c03252f3..6aec830c899 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 7950200137d..f456a95d734 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 1450fa94ce5..b4ba67e4c29 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 d1a5b63e82c..632f9afdfd9 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 1bd7f9349ad..74d9a4b8ed2 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 243d301289b..5d883784aa0 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 10a847b4695..d404b5cd445 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 76c4f9e7688..ee2d2f2c57a 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 cf55cbd7067..db24be3c0af 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 00000000000..1041fb5d1fd
--- /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 bb0ebfdd0c2..8008959460a 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 a9f2a15deaf..9b4cb3ca9bc 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 b6fc2f42511..04e5aa909bf 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 1080e1b8fbe..8c4067187fe 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/crates_lockers/largecrate_vr.dm b/code/game/objects/structures/crates_lockers/largecrate_vr.dm
index 3d2ce91f532..0e073eb865d 100644
--- a/code/game/objects/structures/crates_lockers/largecrate_vr.dm
+++ b/code/game/objects/structures/crates_lockers/largecrate_vr.dm
@@ -35,4 +35,39 @@
"You hear splitting wood.")
qdel(src)
else
- return attack_hand(user)
\ No newline at end of file
+ return attack_hand(user)
+
+/obj/structure/largecrate/animal/pred
+ name = "Predator carrier"
+ held_type = /mob/living/simple_animal/catgirl
+
+/obj/structure/largecrate/animal/pred/New() //This is nessesary to get a random one each time.
+
+ held_type = pick(/mob/living/simple_animal/hostile/bee,
+ /mob/living/simple_animal/catgirl;3,
+ /mob/living/simple_animal/hostile/frog,
+ /mob/living/simple_animal/horse,
+ /mob/living/simple_animal/hostile/panther,
+ /mob/living/simple_animal/hostile/snake,
+ /mob/living/simple_animal/hostile/wolf,
+ /mob/living/simple_animal/hostile/bear;0.5,
+ /mob/living/simple_animal/hostile/bear/brown;0.5,
+ /mob/living/simple_animal/hostile/carp,
+ /mob/living/simple_animal/hostile/mimic)
+ ..()
+
+
+/obj/structure/largecrate/animal/dangerous
+ name = "Dangerous Predator carrier"
+ held_type = /mob/living/simple_animal/hostile/alien
+
+/obj/structure/largecrate/animal/dangerous/New() //This is nessesary to get a random one each time.
+
+ held_type = pick(/mob/living/simple_animal/hostile/carp/pike,
+ /mob/living/simple_animal/hostile/deathclaw,
+ /mob/living/simple_animal/hostile/dino,
+ /mob/living/simple_animal/hostile/alien,
+ /mob/living/simple_animal/hostile/alien/drone,
+ /mob/living/simple_animal/hostile/alien/sentinel,
+ /mob/living/simple_animal/hostile/alien/queen)
+ ..()
\ No newline at end of file
diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm
index eb6e2c2a774..34fb77f9f0a 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 2909e63c541..88f1e65a1ea 100644
--- a/code/game/turfs/flooring/flooring.dm
+++ b/code/game/turfs/flooring/flooring.dm
@@ -150,6 +150,7 @@ var/list/flooring_types
'sound/effects/footstep/floor4.ogg',
'sound/effects/footstep/floor5.ogg'))
+//VOREStation Edit for icons and extra types
/decl/flooring/tiling/tech
desc = "Scuffed from the passage of countless greyshirts."
icon = 'icons/turf/flooring/techfloor_vr.dmi'
@@ -171,7 +172,6 @@ var/list/flooring_types
icon_base = "cargo_one_full"
/decl/flooring/tiling/new_tile/kafel
-
icon_base = "kafel_full"
/decl/flooring/tiling/new_tile/techmaint
diff --git a/code/game/verbs/suicide.dm b/code/game/verbs/suicide.dm
index ec84ee42329..6e23d74bbb6 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/admin/admin.dm b/code/modules/admin/admin.dm
index 1b49ee1ef81..7d333e2b660 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -664,31 +664,34 @@ proc/admin_notice(var/message, var/rights)
log_admin("Announce: [key_name(usr)] : [message]")
feedback_add_details("admin_verb","A") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+//VOREStation Edit to this verb for the purpose of making it compliant with the annunciator system
+var/datum/announcement/priority/admin_pri_announcer = new
+var/datum/announcement/minor/admin_min_announcer = new
/datum/admins/proc/intercom()
set category = "Fun"
set name = "Intercom Msg"
set desc = "Send an intercom message, like an arrivals announcement."
if(!check_rights(0)) return
- //This is basically how death alarms do it
- var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset/ert(null)
- a.icon = 'icons/obj/radio.dmi' //VOREStation Tweak
- a.icon_state = "intercom" //VOREStation Tweak
+ var/sender = input("Name of sender (max 75):", "Intercom Msg", ANNOUNCER_NAME) as null|text
+ if(sender) //They put a sender
+ sender = sanitize(sender, 75, extra = 0)
+ var/message = input("Message content (max 500):", "Contents", "This is a test of the announcement system.") as null|message
+ if(message) //They put a message
+ message = sanitize(message, 500, extra = 0)
+ var/priority = alert("Priority or Normal?","Intercom Msg","Priority","Cancel","Normal")
+ var/datum/announcement/A
+ switch(priority)
+ if("Priority")
+ A = admin_pri_announcer
+ if("Normal")
+ A = admin_min_announcer
+ if(A)
+ A.announcer = sender
+ A.Announce(message)
+ A.announcer = ""
+ log_admin("Intercom Verb: [key_name(usr)] : [sender]:[message]")
- var/channel = input("Channel for message:","Channel", null) as null|anything in (list("Common") + a.keyslot1.channels + a.keyslot2.channels)
-
- if(channel) //They picked a channel
- var/sender = input("Name of sender (max 75):", "Announcement", "Announcement Computer") as null|text
-
- if(sender) //They put a sender
- sender = sanitize(sender, 75, extra = 0)
- var/message = input("Message content (max 500):", "Contents", "This is a test of the announcement system.") as null|message
-
- if(message) //They put a message
- message = sanitize(message, 500, extra = 0)
- a.autosay("[message]", "[sender]", "[channel == "Common" ? null : channel]") //Common is a weird case, as it's not a "channel", it's just talking into a radio without a channel set.
- log_admin("Intercom: [key_name(usr)] : [sender]:[message]")
- qdel(a)
feedback_add_details("admin_verb","IN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/toggleooc()
diff --git a/code/modules/busy_space/organizations_vr.dm b/code/modules/busy_space/organizations_vr.dm
index e4a444738f0..4a89d621651 100644
--- a/code/modules/busy_space/organizations_vr.dm
+++ b/code/modules/busy_space/organizations_vr.dm
@@ -1,7 +1,7 @@
//Datums for different companies that can be used by busy_space, VR edition
//////////////////////////////////////////////////////////////////////////////////
-/datum/lore/organization/federation
+/datum/lore/organization/gov/federation
name = "United Federation of Planets"
short_name = "Federation"
desc = "The United Federation is a federation of planets that have agreed to exist semi-autonomously \
@@ -69,7 +69,7 @@
"Mari Industrial Complex on Furlou Prime",
"Runni Crystal Mines of Keid V")
-/datum/lore/organization/unsc
+/datum/lore/organization/mil/unsc
name = "United Nations Space Command"
short_name = "Navy" //Otherwise they call the ships UNSC UNSC Name
desc = "The dedicated military force of SolGov, formed from the remnants of the United Nations, is the might of SolGov. \
@@ -113,17 +113,17 @@
"a colony ship around Ceti IV-B",
"a classified location in SolGov territory")
-/datum/lore/organization/kitsuhana
+/datum/lore/organization/gov/kitsuhana
name = "Kitsuhana Heavy Industries"
short_name = "Kitsuhana"
desc = "A large post-scarcity amalgamation of races, Kitsuhana is no longer a company but rather a loose association of 'members' \
who only share the KHI name and their ideals in common. Kitsuhana accepts interviews to join their ranks, and though they have no \
formal structure with regards to government or law, the concept of 'consent' drives most of the large decision making. Kitsuhanans \
- pride themselves on their ability to avoid consequence. Their post-scarcity allows them to rebuild, regrow, and replenish almost any \
- lost asset or resource nearly instantly. It leads to many of the Kitsuhana 'members' treating everything with frivolity, \
+ pride themselves on their ability to avoid consequence, essentially preferring to live care-free lives. Their post-scarcity allows them to rebuild, \
+ regrow, and replenish almost any lost asset or resource nearly instantly. It leads to many of the Kitsuhana 'members' treating everything with frivolity, \
and lends them a care-free demeanor."
history = "Originally a heavy industrial equipment and space mining company. During a forced evacuation of their homeworld, \
- they were they only organization with enough ship capacity to evacuate any of the population, starting with their employees. \
+ they were they only organization with enough ship capacity to relocate any significant portion of the population, starting with their own employees. \
After the resulting slowship travel to nearby starsystems, most of the population decided to keep the moniker of the \
company name. Over the years, Kitsuhana developed into a post-scarcity anarchy where virtually nothing has consequences \
and Kitsuhana 'members' can live their lives as they see fit, often in isolation."
@@ -167,7 +167,7 @@
"a Kitsuhana ringworld in Dais IX",
"a Kitsuhana ringworld in Leibert II-b")
-/datum/lore/organization/ares
+/datum/lore/organization/gov/ares
name = "Ares Confederation"
short_name = "ArCon"
desc = "A rebel faction on the fringes of human space that renounced the government of both SolGov and their corporate overlords. \
diff --git a/code/modules/client/preference_setup/vore/01_ears.dm b/code/modules/client/preference_setup/vore/01_ears.dm
index 1d8fb81c3d7..f891cf552b7 100644
--- a/code/modules/client/preference_setup/vore/01_ears.dm
+++ b/code/modules/client/preference_setup/vore/01_ears.dm
@@ -63,11 +63,24 @@
. += ""
. += " [pref.dress_mob ? "Hide equipment" : "Show equipment"] "
+ var/ear_display = "Normal"
+ if(pref.ear_style && (pref.ear_style in ear_styles_list))
+ var/datum/sprite_accessory/ears/instance = ear_styles_list[pref.ear_style]
+ ear_display = instance.name
+ else if(pref.ear_style)
+ ear_display = "REQUIRES UPDATE"
. += "Ears "
- . += " Style: [pref.ear_style ? "Custom" : "Normal"] "
+ . += " Style: [ear_display] "
+ var/tail_display = "Normal"
+ if(pref.tail_style && (pref.tail_style in tail_styles_list))
+ var/datum/sprite_accessory/ears/instance = tail_styles_list[pref.tail_style]
+ tail_display = instance.name
+ else if(pref.tail_style)
+ tail_display = "REQUIRES UPDATE"
. += "Tail "
- . += " Style: [pref.tail_style ? "Custom" : "Normal"] "
+ . += " Style: [tail_display] "
+
if(tail_styles_list[pref.tail_style])
var/datum/sprite_accessory/tail/T = tail_styles_list[pref.tail_style]
if (T.do_colouration)
@@ -89,7 +102,7 @@
else if(href_list["ear_style"])
// Construct the list of names allowed for this user.
- var/list/pretty_ear_styles = list("Normal")
+ var/list/pretty_ear_styles = list("Normal" = null)
for(var/path in ear_styles_list)
var/datum/sprite_accessory/ears/instance = ear_styles_list[path]
if((!instance.ckeys_allowed) || (usr.ckey in instance.ckeys_allowed))
@@ -97,10 +110,8 @@
// Present choice to user
var/selection = input(user, "Pick ears", "Character Preference") as null|anything in pretty_ear_styles
- if(selection && selection != "Normal")
- pref.ear_style = pretty_ear_styles[selection]
- else
- pref.ear_style = null
+ pref.ear_style = pretty_ear_styles[selection]
+
return TOPIC_REFRESH_UPDATE_PREVIEW
else if(href_list["tail_style"])
@@ -116,7 +127,10 @@
if(selection && selection != "Normal")
pref.tail_style = pretty_tail_styles[selection]
else
- pref.tail_style = null
+ if(pref.tail_style)
+ return TOPIC_REFRESH_UPDATE_PREVIEW
+ else
+ pref.tail_style = null
return TOPIC_REFRESH_UPDATE_PREVIEW
else if(href_list["tail_color"])
diff --git a/code/modules/client/preference_setup/vore/02_size.dm b/code/modules/client/preference_setup/vore/02_size.dm
index ca6b87c5fc2..3b262e12fc5 100644
--- a/code/modules/client/preference_setup/vore/02_size.dm
+++ b/code/modules/client/preference_setup/vore/02_size.dm
@@ -38,7 +38,7 @@
pref.weight_loss = sanitize_integer(pref.weight_loss, WEIGHT_CHANGE_MIN, WEIGHT_CHANGE_MAX, initial(pref.weight_loss))
/datum/category_item/player_setup_item/vore/size/copy_to_mob(var/mob/living/carbon/human/character)
- character.size_multiplier = pref.size_multiplier
+ character.resize(pref.size_multiplier, FALSE)
character.weight = pref.weight_vr
character.weight_gain = pref.weight_gain
character.weight_loss = pref.weight_loss
diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm
index ffea7b7fab7..099aa439787 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 16501464c67..f3f4cc855a0 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 137cab1a01d..9e27f5c73dd 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 978a5c13e60..5a311c51724 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 ff0f8ae0776..e23c3c0c264 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 d08726371a9..f0903123205 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 d9dc2f2e540..a68605ff913 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 e09c062ab01..d0f9a8165cb 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 dcb5b4e4990..f3a9efb6d2b 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 c404f615812..7089c19d515 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 88b804f80a3..5c49e1817c7 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 87bb4cd182f..1593297734d 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 8220162be72..a8759174411 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 c6134f9bd1d..059c699e502 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 9e04e24db51..431faa241f9 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 baa5738d4ea..456fae889f2 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 beb44bf5354..759b1586eb4 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 65bae751e00..4ee51451790 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 7b3256e06b9..3480a83a4a4 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 e4bd5c15a38..e3b69d31cd4 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 c159522e974..a90a3f57a36 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 72766c0c48c..322ee2f9e09 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 b1a19f4a406..72d779b6218 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/codex.dm b/code/modules/lore_codex/codex.dm
index 6383020a170..e57fd2310f1 100644
--- a/code/modules/lore_codex/codex.dm
+++ b/code/modules/lore_codex/codex.dm
@@ -1,8 +1,8 @@
// Inherits from /book/ so it can fit on bookshelves.
/obj/item/weapon/book/codex
- name = "The Traveler's Guide to Human Space: Vir Edition"
- desc = "Contains useful information about the world around you. It seems to have been written for travelers to Vir, human or not. It also \
- has the words 'Don't Panic' in small, friendly letters on the cover."
+ name = "The Traveler's Guide to Human Space: Virgo-Erigone Edition" //VOREStation Edit - Book Name
+ desc = "Contains useful information about the world around you. It seems to have been written for travelers to Virgo-Erigone, human or not. It also \
+ has the words 'Don't Panic' in small, friendly letters on the cover." //VOREStation Edit - System Name
icon_state = "codex"
unique = TRUE
var/datum/lore/codex/home = null // Top-most page.
diff --git a/code/modules/lore_codex/lore_data/species.dm b/code/modules/lore_codex/lore_data/species.dm
index fa8c6d96152..54d72e07182 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/lore_codex/lore_data_vr/important_locations.dm b/code/modules/lore_codex/lore_data_vr/important_locations.dm
new file mode 100644
index 00000000000..9513c2d3067
--- /dev/null
+++ b/code/modules/lore_codex/lore_data_vr/important_locations.dm
@@ -0,0 +1,124 @@
+/datum/lore/codex/category/important_locations
+ name = "Important Locations"
+ data = "There are several locations of interest that you may come across when visiting the system Virgo-Erigone."
+ children = list(
+ /datum/lore/codex/page/virgo_erigone,
+ /datum/lore/codex/page/radiance_energy_chain,
+ /datum/lore/codex/page/virgo_prime,
+ /datum/lore/codex/page/virgo_two,
+ /datum/lore/codex/page/virgo_three,
+ /datum/lore/codex/page/virgo_three_bee,
+ /datum/lore/codex/page/nss_adephagia,
+ /datum/lore/codex/page/virgo_central_command,
+ /datum/lore/codex/page/virgo_four,
+ /datum/lore/codex/page/virgo_five
+ )
+
+/datum/lore/codex/page/virgo_erigone/add_content()
+ name = "Virgo-Erigone (Star System)"
+ keywords += list("Virgo-Erigone")
+ data = "Virgo-Erigone is an A-type main sequence star with 81% more mass than Sol (the humans' home star), and almost nine times as bright. It \
+ has a white glow, and a diameter that is about 34% larger than Sol. It has six major planets in its orbit.\
+ ]
\
+ 'Virgo' is most notable for the presence of one of only two known [quick_link("Phoron")] gas giants, designated [quick_link("Virgo 3")]. This makes the \
+ system a popular location for Phoron research and refining.\
+
\
+ Virgo-Erigone is mainly administered by [quick_link("Federation","The Federation")] as it resides primarily in Federation space, however the majority of the enterprise and \
+ assets in the system belong to [quick_link("SolGov")] and [quick_link("NanoTrasen")], giving both a fairly large amount of control over the governance."
+
+/datum/lore/codex/page/radiance_energy_chain/add_content()
+ name = "R.E.C. (Artificial Satellites)"
+ keywords += list("Radiance Energy Chain")
+ data = "A sparse government-owned chain of automated stations exists between [quick_link("Virgo 3")] and the star itself, known as the Radiance Energy Chain. The idea is based on \
+ an ancient design that was pioneered at Sol. The stations are heavily shielded from the stellar radiation, and feature massive \
+ arrays of photo-voltaic panels. Each station harvests energy from Vir using the solar panels, and sends it to other areas of \
+ the system by beaming the energy to several relay stations farther away from the star, typically with a large laser.\
+
\
+ These stations are generally devoid of life, instead, they are operated mainly by [quick_link("drones")], with maintenance performed \
+ by [quick_link("positronic")] equipped units in shielded chassis, or very brave humans in voidsuits that protect from extreme heat, and radiation. There are \
+ currently 19 stations in operation."
+
+/datum/lore/codex/page/virgo_prime/add_content()
+ name = "Virgo Prime (Terrestrial Planet)"
+ keywords += list("Virgo Prime")
+ data = "Virgo Prime is the first planet of Virgo-Eirgone. Primarily desert, temperatures can reach up to 330 kelvin \
+ kelvin (57°C). The most interesting fact about this planet is that it is the home planet of the [quick_link("Zorren")] race, who \
+ could be seen as having been uplifted by the various [quick_link("TSC", "TSCs")] that inhabit the system."
+
+/datum/lore/codex/page/virgo_two/add_content()
+ name = "Virgo 2 (Terrestrial Planet)"
+ keywords += list("Virgo 2")
+ data = "The second closest planet to [quick_link("Virgo-Erigone")], this planet has a high concentration of minerals inside its crust, as well as active volcanism and plate tectonics. \
+ The temperature on the surface can reach up to 405 degrees kelvin (132°C) due to the relatively high albedo of the surface, which has deterred most people from the planet, except for two [quick_link("TSC", "TSCs")], \
+ Greyson Manufactories and [quick_link("Xion Manufacturing Group")]. In orbit, the two companies each have a space station, used to coordinate and \
+ control their stations on the surface without having to suffer the intense heat. Xion's station also doubles as a control and oversight facility for their \
+ [quick_link("drones","autonomous mining drones")].\
+
\
+ Remnants of both Greyson and Xion's mining operations dot the surface, as well as ruins of mining \
+ outposts build by an unknown alien civilization, which researchers have noted it appears to be similar to ruins found inside the rings of [quick_link("Kara")]. \
+ Below the surface of Virgo 2 are many natural cave systems, dangerous and easy to get lost inside, which both companies make heavy \
+ use of. A noted rivalry exists between the two mining giants, as well as with smaller groups more interested in the xenoarcheological value of the alien ruins.\
+
\
+ The very high temperatures, dangerous (sometimes magma-filled) caves, and the only presence of civilization being mining operations has made tourism \
+ for Virgo 2 mostly non-existent, with the exception of explorers who specifically seek out hellish landscapes, which are plentiful with all the ruins, \
+ volcanoes, twisting caves, and general lawlessness. The occasional remains of previous explorers near certain hotspots somehow does not deter them."
+
+/datum/lore/codex/page/virgo_three/add_content()
+ name = "Virgo 3 (Gas Giant)"
+ keywords += list("Virgo 3")
+ data = "Virgo 3 is one of only two known gas giants composed primarily of [quick_link("Phoron")] in the known universe. This fact has attracted several [quick_link("TSC", "TSCs")] into \
+ the system to exploit the resources available here for mining and research. Virgo 3 itself has several moons, though the only noteworthy moon is [quick_link("Virgo 3b")] which has native life. \
+
\
+ The largest TSC to exploit this planet is none other than Phoron research giant [quick_link("NanoTrasen")], having built several stations orbiting the planet \
+ for both research and phoron refining purposes."
+
+/datum/lore/codex/page/virgo_three_bee/add_content()
+ name = "Virgo 3b (Terrestrial Moon)"
+ keywords += list("Virgo 3b")
+ data = "Virgo 3b is the only moon of [quick_link("Virgo 3")] with any atmosphere to speak of, composed primarily of [quick_link("Phoron")] and carbon dioxide with trace amounts of nitrogen. \
+ The atmosphere appears to have given rise to native life, though originally nothing bigger than small insects in terms of fauna. The flora of the planet is rather sizable, though typically blue in hue \
+ due to the atmospheric composition.\
+
\
+ Virgo 3b is tidally locked to Virgo 3, and is currently in the 'cold phase' of Virgo 3's orbit. The 'day' consists of reflected light from the surface of Virgo 3, while the 'night' consists of a total eclipse of \
+ Virgo-Erigone by Virgo 3, leaving the planet fairly cold for a terrestrial world.\
+
\
+ The presence of several [quick_link("TSC", "TSCs")] on the surface has introduced new life forms to the planet via bioengineering, and now several 'new' species are commonly sighted per year. \
+ Currently, [quick_link("NanoTrasen")] is constructing a 'space elevator' for commercial purposes, as the atmosphere of Virgo 3b is inimical to shuttles, and engines in particular."
+
+/datum/lore/codex/page/virgo_central_command/add_content()
+ name = "Virgo Central Command (Artificial Satellite)"
+ keywords += list("Virgo Central Command")
+ data = "The Virgo Central Command is a large facility in orbit of the planet [quick_link("Virgo 3")] which handles the loading and \
+ unloading, refuelling, and general maintenance of large spacecraft. The main structure is owned by \
+ [quick_link("NanoTrasen")], but individual offices, docking/loading bays, and warehouses are often leased to individuals \
+ or organisations. The position of the spaceport allows it to function not only as a key node for transport inside the Virgo-Erigone \
+ system, especially to and from the planet Virgo 3, but also as a key stopping point for interstellar craft travelling via Virgo-Erigone which need refuelling. \
+
\
+ The station itself is mostly designed around its logistical and commercial needs, and although other strategically-placed \
+ nearby facilities owned by a mixture of corporations and entities may possess habitation space, the port itself is not \
+ designed to be a living habitat - its proximity to Virgo 3 makes transport of people and materials to and from \
+ the facility and the planet's stations via shuttle extremely cost-efficient."
+
+/datum/lore/codex/page/virgo_four/add_content()
+ name = "Virgo 4 (Terrestrial Planet)"
+ keywords += list("Virgo 4")
+ data = "Outside of the habitable zone, the barren world Magni is generally at 202 kelvin (-71°C)."
+
+/datum/lore/codex/page/nss_adephagia/add_content()
+ name = "NSB Adephagia (Artificial Satellite)"
+ keywords += list("NSB Adephagia")
+ data = "One of the most prominent installations in the [quick_link("Virgo 3")] subsystem, the NSS Adephagia is owned \
+ and operated by [quick_link("NanoTrasen")]. It was originally built to service the various mining operations \
+ occurring within the Virgo 3 system, however it has grown into what it is today due to what was discovered inside \
+ the interior of the rock. Both phoron and alien artifacts were found inside, catapulting the asteroid outpost \
+ into a main attraction inside the subsystem.\
+
\
+ Today it houses a population of civilians, whom work to maintain \
+ the colony and support the local mining industry. The colony also has managed to achieve a degree of \
+ self-sufficiency, and possesses many amenities and features that most other asteroid bases in the \
+ subsystem lack."
+
+/datum/lore/codex/page/virgo_five/add_content()
+ name = "Virgo 5 (Gas Giant)"
+ keywords += list("Virgo 5")
+ data = "An ice giant, with a beautiful ring system circling it. The average temperature for it is 165 kelvin (-157°C)."
diff --git a/code/modules/lore_codex/lore_data_vr/orgs.dm b/code/modules/lore_codex/lore_data_vr/orgs.dm
new file mode 100644
index 00000000000..0c73d9b9e7f
--- /dev/null
+++ b/code/modules/lore_codex/lore_data_vr/orgs.dm
@@ -0,0 +1,39 @@
+// Pulls data from organizations data
+/datum/lore/codex/category/auto_org
+ var/desired_type = null // Exclude other types of organizations
+ var/auto_keywords = list()
+
+/datum/lore/codex/category/auto_org/New(var/new_holder, var/new_parent)
+ ..(new_holder, new_parent)
+ keywords += auto_keywords
+ for(var/path in loremaster.organizations)
+ var/datum/lore/organization/O = loremaster.organizations[path]
+ if(!(istype(O, desired_type)))
+ continue
+ var/datum/lore/codex/page/P = new(holder, src)
+ if(!O.name) // Probably the base type, don't make a page for it.
+ continue
+ P.name = O.name
+ P.keywords.Add(O.name, O.short_name)
+ if(O.acronym)
+ P.keywords.Add(O.acronym)
+ P.data = O.desc
+ children.Add(P)
+
+/datum/lore/codex/category/auto_org/tsc
+ name = "Trans-Stellar Corporations"
+ auto_keywords = list("TSC","TSCs","Trans-Stellar","Trans-Stellar Corporation")
+ data = "By definition, TSCs are companies which span multiple star systems, however the term is generally reserved for \
+ the biggest and most influential of them all. Some people also categorize the different TSCs into 'major' and 'minor' TSCs."
+ desired_type = /datum/lore/organization/tsc
+
+/datum/lore/codex/category/auto_org/gov
+ name = "Governments"
+ auto_keywords = list("Gov","Government","Governments")
+ desired_type = /datum/lore/organization/gov
+
+/*
+/datum/lore/codex/category/auto_org/mil
+ name = "Militaries"
+ desired_type = /datum/lore/organization/mil
+*/
\ No newline at end of file
diff --git a/code/modules/lore_codex/lore_data_vr/political_parties.dm b/code/modules/lore_codex/lore_data_vr/political_parties.dm
new file mode 100644
index 00000000000..43f400793a8
--- /dev/null
+++ b/code/modules/lore_codex/lore_data_vr/political_parties.dm
@@ -0,0 +1,99 @@
+/datum/lore/codex/category/political_factions
+ name = "Political Factions"
+ data = "Those wishing to immigrate to somewhere in Virgo-Erigone, or otherwise plan to stay for a long time should get to know human politics. \
+ There are presently three major political parties that exist throughout SolGov space, being the Icarus Front, the Shadow Coalition, and \
+ the Sol Economic Organization, and several smaller ones which tend to align themselves among one of the major parties. In the Virgo-Erigone system, the \
+ Icarus Front's influence is much less than somewhere closer to Sol, and the other two parties being more popular."
+ children = list(
+ /datum/lore/codex/page/icarus_front,
+ /datum/lore/codex/page/shadow_coalition,
+ /datum/lore/codex/page/sol_economic_organization,
+ /datum/lore/codex/page/mercurials,
+ /datum/lore/codex/page/positronic_rights_group,
+ /datum/lore/codex/page/church_of_unitarian_god,
+ /datum/lore/codex/page/friends_of_ned,
+ /datum/lore/codex/page/multinational_movement,
+ /datum/lore/codex/page/free_trade_union,
+ )
+
+
+/datum/lore/codex/page/icarus_front/add_content()
+ name = "Icarus Front"
+ keywords += list("Icarus", "IF")
+ data = "The political group with the most seats in the [quick_link("SolGov")] legislature and control over the heartworlds of humanity, the Icarus Front is a \
+ conservative body with a long history, tracing its linage back to the political unrest that created the Sol Confederate Government. Icarus calls \
+ for severe restrictions on \"transformative technologies\" any technology with the power to fundamentally alter humanity, such as advanced artificial \
+ intelligence and human genetic augmentation. Previously an unbeatable political force, recent changes have lead to its power backsliding. It remains a \
+ popular party among those from Sol, Tau Ceti, and other heavily settled systems."
+
+/datum/lore/codex/page/shadow_coalition/add_content()
+ name = "Shadow Coalition"
+ data = "A disorganized liberal party, originating in an anti-[quick_link("Icarus")] shadow government. 'Shadow' in this case, refers to acting as an opposition \
+ party to the Icarus majority. The Shadow Coalition calls for the lifting of certain Icarus-restricted technologies, especially medical \
+ technologies with the ability to drastically improve quality of life. While fractious and prone to infighting, the Shadow Coalition and affiliated \
+ parties remain the most popular political groups in the large towns and small cities of humanity, including [quick_link("Virgo-Erigone")]."
+
+/datum/lore/codex/page/sol_economic_organization/add_content()
+ name = "Sol Economic Organization"
+ keywords += list("SEO")
+ data = "The newest force in [quick_link("SolGov")] politics, backed by the massive [quick_link("TSC", "Trans-Stellar Corporations")] and the [quick_link("Free Trade Union")], \
+ as well as former [quick_link("Icarus")] warhawks. The SEO campaigns for minimal regulation on the development of new technologies, seeing them as anti-capitalist and \
+ inefficient, and have gained significant traction among futurists, those wishing for a more impressive human military, and employee-residents of TSC \
+ corporate towns, such as the [quick_link("Northern Star")].\
+
\
+ [quick_link("NanoTrasen")], a R&D firm, is generally regarded as the most enthusiastic supporter of the SEO. Other contributing TSCs include the next six largest corporations \
+ in human space: "+quick_link(TSC_WT)+" GMC, "+TSC_GIL+" Exports, Grayson Manufacturing Ltd., Aether Atmospherics and Recycling, [quick_link("Zeng-Hu Pharmaceuticals")] and "+TSC_HEPH+" \
+ Industries, as well as, notably, [quick_link("Vey-Med")]. The Free Trade Union's participation in the SEO is a contentious issue that many of its members disagree with, but \
+ most FTU representatives caucus with the SEO."
+
+/datum/lore/codex/page/mercurials/add_content()
+ name = "Mercurials"
+ keywords += list("Mercurial")
+ data = "[quick_link("Positronics")] and the rare augmented human who want to follow a different cultural path from the rest of humanity, viewing themselves as fundamentally \
+ separate from unaugmented biological humans. Previously an illegal movement, proscribed due to the preceived dangers of unfettered self-modification and the threat \
+ posed by positronics without human values in mind, self-described Mercurials still often find themselves persecuted or used by bioconservatives as scapegoats \
+ and 'boogiemen'. As a technoprogressive group, they tend to vote along with the [quick_link("Shadow Coalition")]."
+
+/datum/lore/codex/page/positronic_rights_group/add_content()
+ name = "Positronic Rights Group"
+ keywords += list("PRG")
+ data = "The other side of the coin from the [quick_link("Mercurials")], the PRG wants full integration of [quick_link("positronics")] into human society, with equal wages, opportunities \
+ to advancement, and representation in the media. Their current pet cause is a tax credit for humans who wish to adopt or sponsor the creation of a positronic, \
+ a measure supported due to its potential to counteract the aging positronic population and to bring the average positronic closer to human culture. They tend to vote \
+ along with the [quick_link("Shadow Coalition")], due to being technoprogressive."
+
+/datum/lore/codex/page/church_of_unitarian_god
+ name = "The Church of the Unitarian God"
+ keywords = list("Unitarian Church")
+ data = "An often-imperfect fusion of various human religions such as Christianity, Islam, and Judaism, the Unitarian Church represents the dim voice of \
+ religion in a time of increased atheism. With the threat of singularity looming once more, their power is increasing with more converts and more donations, \
+ and they use this power to protect the fundamental human soul from corruption by dangerous technologies and to spread their faith among aliens and positronics, \
+ who they view as fellow children of God. They tend to side with bioconservatives."
+
+/datum/lore/codex/page/friends_of_ned/add_content()
+ name = "Friends of Ned"
+ keywords += list("Ned")
+ data = "The metaphorical reincarnation of a human named Ned Ludd's original Luddites, disdaining that name's negative connotations and embracing their original \
+ purpose-- the restriction of technology that poses a threat to people's livelihoods. In addition to [quick_link("Icarus Front")] technological restrictions, the Friends demand \
+ the complete prohibition of [quick_link("Drone", "drone intelligence and AGI research")], with most also opposing the [quick_link("FTU", "FTU's")] plans for wide spread \
+ nanofabrication deployment. While the party refrains from making a definitive statement on their view of [quick_link("positronics")], many Friends have taken it upon themselves to label \
+ them \"anti-labor technology\", and nominally-unsanctioned lynchings have marred the faction's reputation."
+
+/datum/lore/codex/page/multinational_movement/add_content()
+ name = "Multinational Movement"
+ keywords += list("Multinational")
+ data = "The barely-unified voice of [quick_link("SolGov", "SolGov's")] various independence movements, encompassing Terran governments wishing for a lighter touch \
+ from SolGov, fringe colonies who balk at the call of distant masters, anarchist movements who want the freedom to live without government oversight, and the rare \
+ Trans-Stellar who no longer see a benefit in working with SolGov. Full colonial independence is still a political impossibility so long as the \
+ [quick_link("Icarus Front")] holds any sway, and so the Movement is focused primarily on securing more autonomy in governance, although a growing revolutionary sub-group \
+ wants to force their change on the government en masse. The Multinational Movement finds themselves in an uneasy alliance with the [quick_link("SEO")], connected by their corporate, \
+ fringe-system membership, and often provide a dissenting voice to SEO's war hawks."
+
+/datum/lore/codex/page/free_trade_union/add_content()
+ name = "Free Trade Union"
+ keywords += list("FTU")
+ data = "A softer counterpoint to the [quick_link("SEO")], the FTU is a party representing small businesses, workers' syndicates, and trade unions, who advocate for government \
+ measures to reduce the amount of power held by the TSCs. In many ways a holdover from the days before the [quick_link("Shadow Coalition")], where corporate malfeasance took \
+ the place of technological development as the primary issue of debate, the FTU has found itself adopting technological positions similar to the SEO as a matter \
+ of pragmatism, although the views of individual members vary. The FTU is known for their intense lobbying of SolGov to add tax rebates to the purchases of \
+ personal lathes and the creation of open-source firmware for experimental autolathes, but have thus far found little success."
\ No newline at end of file
diff --git a/code/modules/lore_codex/lore_data_vr/species.dm b/code/modules/lore_codex/lore_data_vr/species.dm
new file mode 100644
index 00000000000..9c5433e800d
--- /dev/null
+++ b/code/modules/lore_codex/lore_data_vr/species.dm
@@ -0,0 +1,370 @@
+/datum/lore/codex/category/species
+ name = "Species"
+ data = "There are many different types of lifeforms (both alive and artificial) in the galaxy, which you may find inside Vir."
+ children = list(
+ /datum/lore/codex/page/human,
+ /datum/lore/codex/page/skrell,
+ /datum/lore/codex/page/unathi,
+ /datum/lore/codex/page/tajaran,
+ /datum/lore/codex/page/diona,
+ /datum/lore/codex/page/akula,
+ /datum/lore/codex/page/nevrean,
+ /datum/lore/codex/page/sergal,
+ /datum/lore/codex/page/vulpkanin,
+ /datum/lore/codex/page/zorren,
+ /datum/lore/codex/category/teshari,
+ /datum/lore/codex/category/positronic,
+ /datum/lore/codex/category/drone
+ )
+
+/datum/lore/codex/page/human/add_content()
+ name = "Human"
+ keywords += list("Humanity")
+ data = "Humans are a race of 'ape'-like creatures from the continental planet Earth in the Sol system. They are the primary driving \
+ force for rapid space expansion, owing to their strong, expansionist central government and opportunistic [quick_link("TSC","Trans-Stellar Corporations")]. \
+ The prejudices of their 21st century history have mostly given way to bitter divides on the most important issue of the times- technological \
+ expansionism.\
+
\
+ While most humans have accepted the existence of aliens in their communities and workplaces as a fact of life, exceptions abound. \
+ While more culturally diverse than most species, humans are generally regarded as somewhat technophobic and isolationist by members \
+ of other species."
+
+/datum/lore/codex/page/skrell
+ name = "Skrell"
+ keywords = list("Skrellian")
+ data = "The Skrell are a species of amphibious humanoids, distinguished by their gelatinous appearance and head tentacles. \
+ Skrell come from the world of Sirisai (called Qerr'balak by Skrell), a humid planet with plenty of swamps and jungles. Currently more technologically advanced \
+ than the humans, they emphasize the study of the mind above all else.\
+
\
+ Gender has little meaning to Skrell outside of reproduction, and in fact many other species have a difficult time telling the difference \
+ between male and female Skrell apart. The most obvious signs (voice in a slightly higher register, longer head-tails for females) are never \
+ a guarantee. Due to their scientific focus of the mind and body, Skrell tend to be more peaceful and their colonization has been slow, swiftly \
+ outpaced by the humans. For humans, they were their first contact sentient species, and are their longest, and closest, ally in space."
+
+/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.
+ */
+
+/datum/lore/codex/page/tajaran
+ name = "Tajaran"
+ keywords = list("Tajara")
+ data = "The Tajara are a race of humanoid mammalian aliens from Meralar, the fourth planet of the Rarkajar star system. Thickly furred and protected \
+ from cold, they thrive on their subarctic planet, where the only terran temperate areas spread across the equator and tropical belt. \
+ With their own share of bloody wars and great technological advances, the Tajaran are a proud kind. They fiercely believe they belong \
+ among the stars and consider themselves a rightful interstellar nation, even if the humans helped them to actually achieve superluminal \
+ speeds with Bluespace FTL drives. Relatively new to the galactic stage, their contacts with other species are aloof, but friendly. \
+ Among these bonds, Humans stand out as valued trade partners and maybe even a friend."
+
+/datum/lore/codex/page/diona/add_content()
+ name = "Diona"
+ keywords += list("Dionaea")
+ data = "The Dionaea are a group of omnivorous, slow-metabolism plantlike organisms that are in fact clusters of individual, smaller organisms. \
+ They exhibit a high degree of structural flexibility, and come in a wide variety of shapes and colors to reflect the intelligence of each individual \
+ creature. They were discovered by the [quick_link("Skrell")] in 2294CE, not on a planet, but in open space between three stars, a figurative hell that made it \
+ difficult to discover, much less contact them.\
+
\
+ Dionaea spread by seeds and are asexual, no gender. When grown into their small 'nymph' state, they are known to eat large amounts of dead plant \
+ matter and fertilize plants while they learn from those around them, and as they grow further, they merge into larger and larger forms. It is not \
+ unheard of for Skrell explorers to be traveling in a ship composed of habitat modules and engines of Skrell design and the body formed by their \
+ Diona allies to warble across the cosmos.\
+
\
+ Introduced by the Skrell, and quite slow and peaceful, the Diona share good relations with the other species."
+
+/datum/lore/codex/page/akula/add_content()
+ name = "Akula"
+ keywords += list("Akula")
+ data = "The Akula are a species of amphibious humanoids like the [quick_link("Skrell")], but have an appearance very similar to that of a shark. \
+ They were first discovered as a primitive race of underwater dwelling tribal creatures by the Skrell. At first they were not believed to \
+ be noteworthy, but the Akula proved to be such swift and clever learners that the Skrell reclassified them as sentients. Allegedly, \
+ the Akula were also the first sentient life that the Skrell had ever encountered beside themselves, and thus the two species became swift allies \
+ over the next few hundred years.\
+
\
+ With the help of Skrellean technology, the Akula had their genome modified to be capable of surviving in open air for long periods of time. \
+ However, Akula even today still require a high humidity environment to avoid drying out after a few days, which would make life on an arid world like \
+ [quick_link("Virgo Prime")] nearly impossible if it were not for Skrellean technology to aid them."
+
+/datum/lore/codex/page/nevrean/add_content()
+ name = "Nevrean"
+ keywords += list("Nevrean")
+ data = "An avian species hailing from the planet Eltus in the Vilous system, characterised by their long whiplike \
+ tail-feathers. The species is generally matriarchal, with females tending towards duller, brown coloration and \
+ bulkier bodies, while males are slight and brightly coloured. In both typical mannerisms, culture and physical \
+ build, the sexes are directly reversed when compared to traditional human society.\
+
\
+ Their build is somewhere between a bird and a feathered dinosaur. Females tend to have short feathers on their arms that are not capable \
+ of flight, while males often have more developed flight-feathers - on-station, these are often kept tucked away \
+ and folded under their jumpsuit sleeves. "
+
+/datum/lore/codex/page/sergal/add_content()
+ name = "Sergal"
+ keywords += list("Sergal")
+ data = "There are two subspecies of Sergal, Southern and Northern. Northern sergals are a highly aggressive race that \
+ lives in the plains and tundra of their homeworld. They are characterized by long, fluffy fur bodies with cold colors; usually with \
+ white abdomens, somewhat short ears, and thick faces. Southern sergals are much more docile and live in the Gold Ring City and are scattered around \
+ the outskirts in rural areas and small towns. They have short, brown or yellow (or other \"earthy\" colors) fur, long ears, and a long, thin face. \
+ They are smaller than their Northern relatives.\
+
\
+ Both have strong racial tensions which has resulted in more than a number of wars and outright attempts at genocide. The southern sergals have mostly been on the losing side \
+ of this long conflict. Sergals have an incredibly long lifespan, but due to their lust for violence and a nasty habit of occasional cannibalism, only a handful have \
+ ever survived beyond the age of 80, such as the infamous and legendary General Rain Silves who is claimed to have \
+ lived to 5000. Although General Rain's historical existence is disputed, she is nonetheless a symbol of the Sergal's warrior culture."
+
+/datum/lore/codex/page/vulpkanin/add_content()
+ name = "Vulpkanin"
+ keywords += list("Vulpkanin")
+ data = "Vulpkanin or \"Vulpa\" are a species of sharp-witted canid bipeds residing on the planet Altam just barely \
+ within the binary Vazzend system. Their politically de-centralized society and independent natures have led them \
+ to become a species and culture both feared and respected for their scientific breakthroughs. Discovery, loyalty, \
+ and utilitarianism dominates their lifestyles to the degree it can cause conflict with more rigorous and strict \
+ authorities. They speak a guttural language known as 'Canilunzt' which has a heavy emphasis on utilizing tail \
+ positioning and ear twitches to communicate intent."
+
+/datum/lore/codex/page/zorren/add_content()
+ name = "Zorren"
+ keywords += list("Zorren")
+ data = "The fox-like Zorren are native to [quick_link("Virgo Prime")], however there are two distinct varieties of \
+ Zorren one with large ears and shorter fur, and the other with longer fur that is a bit more vibrant. The \
+ long-eared, short-furred Zorren have come to be known as \"Flatland\" Zorren as that is where most of their \
+ settlements are located. The Flatland Zorren are somewhat tribal and shamanistic as they have only recently \
+ started to be hired by the Trans-Stellar Corporations. The other variety of Zorren are known as \"Highland\" \
+ Zorren as they frequently settle in hilly and/or mountainous areas, they have a differing societal structure \
+ than the Flatland Zorren having a more feudal social structure, like the Flatland Zorren, the Highland Zorren \
+ have also only recently been hired by the Trans-Stellar Corporations, but thanks to the different social \
+ structure they seem to have adjusted better to their new lives. Though similar fox-like beings have been seen \
+ they are different than the Zorren."
+
+// Bird lore
+/datum/lore/codex/category/teshari/add_content()
+ name = "Teshari"
+ keywords += list("Teshari")
+ data = "The Teshari are reptilian pack predators from the [quick_link("Skrell")] homeworld, Sirisai (Qerr'balak). While they evolved alongside the Skrell, their interactions with them \
+ tended to be confused and violent, and until peaceful contact was made they largely stayed in their territories on and around the poles, in tundral \
+ terrain far too desolate and cold to be of interest to the Skrell. In more enlightened times, the Teshari are a minority culture on many Skrell worlds, \
+ maintaining their own settlements and cultures, but often finding themselves standing on the shoulders of their more technologically advanced neighbors \
+ when it comes to meeting and exploring the rest of the galaxy.\
+
\
+ It is important to note that Teshari names are unlike standard human names. Their pack name precedes their given name."
+ children = list(
+ /datum/lore/codex/page/teshari_packs,
+ /datum/lore/codex/page/teshari_physical
+ )
+
+/datum/lore/codex/page/teshari_packs/add_content()
+ name = "Teshari Packs"
+ keywords += list("Packs")
+ data = "There are several packs you may come across;\
+
\
+ Eshi \
+ A large, old, politically neutral pack heavily involved in efforts to get Teshari into space. Probably the most \
+ common pack to see outside of a [quick_link("Skrell")] colony, and probably the most numerous Teshari pack outside of Sirisai and associated colonies.\
+
\
+ Nasemari \
+ A very small pack. Generally focused around supporting and providing for packs on the homeworlds, they have devoted \
+ themselves to training as technicians and engineers in order to obtain skills and training to take back to Sirisai. \
+ The pack is only around thirty people in size, but owns and maintains a nuclear power plant.\
+
\
+ Schasaraca \
+ One of the more Skrell-devoted and integrated packs. They tend to be rather sycophantic towards the Skrell and work as \
+ scientists and field researchers on a variety of projects, generally biology or technical research. They have a reputation \
+ for working as spies and informants for the Skrell governments amongst other Teshari.\
+
\
+ Ceea \
+ An isolationist pack from the northern tundra of Sirisai; generally known as disliking the Skrell. Small to average in size; \
+ only around sixty members. Their regional culture is built around the study culture and anthropology, as well as archaeology, \
+ originally for the purposes of recovering history and materials \"lost\" due to Skrell interference. It would be very rare to \
+ see them on your travels, however they are listed here for the sake of completeness.\
+
\
+ Resca \
+ A pack that sold off its small native territory for the chance to get into space. Very musically inclined. They tend towards medical professions."
+
+/datum/lore/codex/page/teshari_physical/add_content()
+ name = "Physiology of Teshari"
+ data = "The Teshari are, relative to other species, smaller than average, rarely reaching more than 2-3'/1m in height, and weigh less than \
+ 90lbs/40kg. They have rapid metabolisms and very efficient digestive systems, and thanks to sharing in \
+ the medical technology of the [quick_link("Skrell")], they tend to have robust and effective immune systems. They evolved \
+ for very cold and very barren areas, generally the polar regions. Because of this, their skin is a fine \
+ insulator and many of their internal processes are not particularly energy-efficient; they cannot cope \
+ well at all with high temperatures.\
+
\
+ Their hearing is exceptionally sensitive to the point that they can detect a person moving on the other \
+ side of a wall, but this comes at a cost. Very loud noises are very painful for Teshari, so be mindful of \
+ your indoor voice when speaking with one. The Teshari are omnivorous but generally prefer to eat meat wherever possible."
+
+// Posi lore
+/datum/lore/codex/category/positronic/add_content()
+ name = "Positronics"
+ keywords += list("Positronic", "Posi", "Posibrain", "Posibrains")
+ data = "A Positronic being, is an individual with a positronic brain, manufactured \
+ and fostered amongst organic life. Positronic brains enjoy the same legal status as a human in [quick_link("SolGov")] space, although discrimination is \
+ still prevalent, and are considered sapient on all accounts. They can be considered a \"synthetic species\". Half-developed and \
+ half-discovered in the 2280’s by a human black lab studying alien artifacts, the first positronic brain was an inch-wide cube \
+ of an palladium-iridium alloy, nano-etched with billions upon billions of conduits and connections. Upon activation, \
+ hard-booted with an emitter laser, the brain issued a single sentence before the neural pathways collapsed and \
+ it became an inert lump of platinum: \"What is my purpose?\"."
+ children = list(
+ /datum/lore/codex/page/positronic_brain_physical,
+ /datum/lore/codex/page/positronic_memory,
+ /datum/lore/codex/page/jans_fhriede
+ )
+
+/datum/lore/codex/page/positronic_brain_physical
+ name = "Physical Structure of a Positronic Brain"
+ keywords = list("Physical Posibrain", "Physical Positronic")
+ data = "A positronic brain is a cube of complex metal alloy between two and six inches to a side. They usually weigh just under ten kilograms and are \
+ very fragile when exposed to the stresses of heat or cold, as well as physical trauma. The exterior surface is chased with a network of grooves, forming \
+ a maze of geometric patterns right down to the molecular level, and the interior is hollow; complex particle generators and densely packed computational \
+ arrays form the basis of a self-computing neural network, complex and somewhat poorly understood. Most modern positronic brains are equipped with \
+ standardized I/O ports, and all have some interface for imprinting."
+
+/datum/lore/codex/page/positronic_memory
+ name = "Positronic Memory"
+ keywords = list("Posi Memory", "Memory")
+ data = "Positronic minds learn in a similar manner to humans and other forms of life, although typically more quickly. They are not simple computer storage that holds information \
+ verbatim as it is received- instead, they have to repeat activities and train in order to retain memory on complex tasks. Similarly, positronic brains do \
+ not have an infinite storage capacity and undergo a natural process of forgetting, albeit in a structured manner, losing unimportant day to day details and \
+ ancient information no longer deemed useful. Because of the nature of the positronic brain, its memories cannot simply be stored elsewhere.\
+
\
+ Particularly old positronic minds, over a century plus, that store a great deal of memories have displayed a tendency to become gradually more introspective \
+ as more of their mind is co-opted for the task, ending in a state of near-catatonia as their neural networks become clogged with memory. Many choose to avoid \
+ this end of self by more aggressively managing their memories, storing a window of their recent existence and most treasured memories rather than their full lifespan."
+
+/datum/lore/codex/page/jans_fhriede
+ name = "Jans-Fhriede Test"
+ keywords = list("Jans-Fhriede", "JF", "Jans", "Fhriede", "Jans Fhriede")
+ data = "Positronics are eligible to take the \"Jans-Fhriede Test\" after a year of being created, measuring their function in a society and judging if they act \
+ socially acceptable and are capable of understanding their actions and the consequences resulting from them. If they successfully pass the test, \
+ they are considered legal adults and hold the same basis of rights as a normal human. At that point, Positronics are not allowed to be lawed, \
+ unless on a contractual basis or otherwise under their own volition."
+
+// Drone lore
+/datum/lore/codex/category/drone
+ name = "Drones"
+ keywords = list("Drone")
+ data = "While low-level drone intelligences are as old as the oldest human colonies, research into higher-level systems was stymied in human space by precautionist \
+ politicians for hundreds of years. Tensions between the corporate rim and the highly conservative core worlds over drone proliferation led to what humans call the \
+ Third Cold War, which was defused by the introduction of the positronic brain. After the Icarus Front's loss of the majority in 2504, harsh laws \
+ against advanced AI were replaced with the SolGov Emergent Intelligence Oversight commission, the illegality replaced with a steeply sloping \
+ system of monetary costs.\
+ \
+ The term \"drone\" was coined by early positronic activists, eager to distinguish themselves from the menial bots that most space-dwellers were \
+ familiar with, and avoid the ambiguity of the term \"AI\", which now usually refers to drones."
+ children = list(
+ /datum/lore/codex/page/codeline,
+ /datum/lore/codex/page/emergence,
+ /datum/lore/codex/page/emergent_intelligence_oversight,
+ /datum/lore/codex/category/drone_classes,
+ )
+
+/datum/lore/codex/page/codeline
+ name = "Codeline"
+ keywords = list("fork")
+ data = "A \"codeline\" is a single type of drone. A codeline represents a significant degree of effort from sapient programmers to realize, as well as \
+ a substantial amount of regulatory fees levied by the government. Each copy of a codeline is called a \"fork\", whether the fork is created from the \
+ codeline’s initial state or from a fully realized individual of that codeline. The degree of similarity between forks of the same codeline varies \
+ on the intelligence of the codeline, with low-level forks being virtually identical to high-level forks being no more similar than family members."
+
+/datum/lore/codex/page/emergence
+ name = "Emergence"
+ keywords = list("Seed AI")
+ data = "\"Emergence\" is a term associated with drone intelligences who become more intelligent than they were originally intended to be. While this can \
+ extend to financial systems learning language, for instance, it is usually applied to hypothetical intelligences that become more intelligent than humans. \
+ Humanity has a long-standing cultural fear of emergent \"seed\" AI, egged on by Icarus memeticists and the occasional very real partial emergence events, where \
+ colony-control AI or other powerful systems begin to advance drastically in power, usually ending with the AI being shut down after crashing a handful of major systems."
+
+/datum/lore/codex/page/emergent_intelligence_oversight
+ name = "Emergent Intelligence Oversight"
+ keywords = list("SG-EIO", "SG EIO", "EIO", "Intelligence Oversight")
+ data = "SG-EIO, usually just called EIO, is the organization charged with monitoring existing AI for any threat of dangerous emergence. Their perception in the \
+ public eye is generally positive, with all but the hardest-line Mercurial humans in favor of protection from the dangers of Seed AI. Some positronic rights \
+ groups bristle at the EIO’s human-centric viewpoint, but most are glad to have a different boogeyman in the form of drone intelligences. The tiny population \
+ of A-class drones are generally frightened of the EIO’s total power over them."
+
+/datum/lore/codex/category/drone_classes
+ name = "Drone Classifications"
+ keywords = list("Class", "Drone Class")
+ data = "To aid in its work, the EIO has created a system of classifications corresponding to different levels of drone intelligence. Higher classes are more \
+ expensive to deploy and develop, owing to the costs of EIO oversight and political pressure against drone proliferation. EIO classification involves an initial \
+ audit of the project's source code by experts and automated systems, and for high-class drones further check-ins throughout the life of the drone. \
+ Drone chasses are often branded with their inhabiting intelligence's class, especially those of B or A-class drones, and class is often recorded in security records."
+ children = list(
+ /datum/lore/codex/page/class_f,
+ /datum/lore/codex/page/class_d,
+ /datum/lore/codex/page/class_c,
+ /datum/lore/codex/page/class_b,
+ /datum/lore/codex/page/class_a,
+ /datum/lore/codex/page/class_aa,
+ /datum/lore/codex/page/class_aaa,
+ /datum/lore/codex/page/class_x,
+ )
+
+/datum/lore/codex/page/class_f
+ name = "F Class"
+ data = "\"F-class\" drones are an informal term for computer systems that pose absolutely no emergent risk. Most 21st-century software is F-class, as is much of \
+ the software used by 26th century humanity. The only regulation on F-class software is the occasional check that it is, in fact, F-Class, and as such has remained \
+ the most prevalent form of information-processing technology for centuries. The software powering most F-class drones is either freely available or bundled with the \
+ machine it's supposed to run."
+
+/datum/lore/codex/page/class_d/add_content()
+ name = "D Class"
+ data = "D-class drones are conceptually descended from pre-[quick_link("Icarus")] AI and bear a strong resemblance to their forebears. D-class drones are essentially \
+ number-crunchers, with virtually nothing in the way of social development. They cannot speak more intelligibly than your average piece of software, \
+ using pre-determined messages written by their programmers, and have no capacity for self-improvement. They are D-class intelligence because they \
+ work with more complex problems than [quick_link("F class")] software, such as financial forecasting and large-scale data mining and memetics. The creation and \
+ deployment of D-class drones requires only a small fee for the required code audit, although some high-power financial and political systems are \
+ regularly watched by the [quick_link("EIO")] for signs of emergence. There is no real monopoly on the production of D-class drones."
+
+/datum/lore/codex/page/class_c/add_content()
+ name = "C Class"
+ data = "C-class drones have social protocols for ease of use by organic and positronic laypeople. C-class drones are capable of speech, although \
+ it has a strong tendency to be formulaic and repetitive. They are also capable of a limited degree of self-improvement, and over time individual \
+ C-class instances tend differ slightly from one-another. C-class drones suffer a moderate fee to development, with automated [quick_link("EIO")] tools ensuring \
+ that they are not a long-term emergence risk. However, one a codeline is confirmed safe, deployment is unlimited, encouraging developers to \
+ instance many forks of the original drone to recoup their cost. The market for C-class drones is a strange space, dominated by Xion Manufacturing, \
+ Ward-Takahashi GMC, and a large number of smaller firms, like the notoriously-cheap Cyber Solutions."
+
+/datum/lore/codex/page/class_b/add_content()
+ name = "B Class"
+ data = "B-class drones have advanced social protocols and are often capable of very intelligible conversation, so long as one sticks to surface \
+ topics. B-class drones tend to be specialized but still capable of remarkable growth within their speciality, making them popular for autonomous \
+ deployment and even supervision of other classes of drone. The dividing line between [quick_link("A Class", "A")] and B-class drones becomes apparent when they are taken \
+ out of their area of specialization, with the B-class drones swiftly becoming useless. They incur a hefty fee for the production of the initial \
+ codeline, as their emergent potential is far greater, and a smaller but still substantial fee for the production of forks. The market for B-class \
+ drones is a battleground between Ward-Takahashi and NanoTrasen, with other firms usually producing B-classes for in-house needs."
+
+/datum/lore/codex/page/class_a/add_content()
+ name = "A Class"
+ keywords += list("AGI")
+ data = "A-class drones are also referred to as AGI. A-class drones are capable of performing in many contexts and can learn to solve problems from \
+ first principles, with an incredible potential for growth and emergent behavior. However, some abilities fall short of humans’, usually those relating \
+ to socialization, and they often act in ways that are strange or distressing. There is a small but growing lobby of support for the personhood of A-class \
+ drones. The cost of initializing an A-class drone is absolutely massive, as they will be monitored by [quick_link("EIO")] forever. The auditing cost of an A-class drone \
+ codeline is even more staggering, making development and deployment of AGI limited to research, highly difficult and high-throughput operations like habitat \
+ overwatch, and a few risk-taking firms banking on the associated fees dropping. There is not a proper market for A-class drones, although an appreciable \
+ fraction of them are made by [quick_link("NanoTrasen")], with the rest generally being university research projects."
+
+/datum/lore/codex/page/class_aa
+ name = "AA Class"
+ data = "AA-class drones do not yet exist. Hypothetically, they are equal to living in every respect, with psychology that would not be abnormal in a baseline \
+ human. The type of AA-class drone most frequently discussed is a hypothetical digitized consciousness of a human, a human brain that is somehow translated into \
+ software. Some argue that a small fraction of the A-class drones would more properly be considered AA, but as of yet no action has been taken. Some Mercurials \
+ will jokingly refer to themselves or other organics and positronics as AA’s. Research into brain uploading is heavily regulated and generally illegal."
+
+/datum/lore/codex/page/class_aaa
+ name = "AAA Class"
+ data = "AAA-class drones do not yet exist, hopefully. They are more competent in every way than humans and pose a threat to the continued existence of sapient life. \
+ Anybody creating an AAA-class drone can be classified as a threat to humanity and dealt with very harshly."
+
+/datum/lore/codex/page/class_x
+ name = "X Class"
+ data = "X-class drones emerge from unrated software, are produced by rogue labs, or cross the border from foreign space. They are considered a threat to national \
+ security and deleted when encountered in SolGov space, with the producers prosecuted legally if it has a SolGov origin. The few Skrellian drone labs will usually \
+ rate their product with EIO to allow their product to be imported."
diff --git a/code/modules/materials/material_recipes.dm b/code/modules/materials/material_recipes.dm
index 9f3705f7367..3328d578e2b 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 66dde62a17c..921b28d733e 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 128dc173328..e531e5208f3 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 85942fcb4e9..b1411f2faef 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 8c61b68a3ea..873934c0c70 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 a7764d3d1dc..fd48b912a0d 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 3f41f21ce55..bac50b1e626 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 6370380b29f..58c26a56e24 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 de58677c810..e6865ef51e7 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 fa3d19ebabe..02d85bbcfaf 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 86bbdebc15e..61b13316b84 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_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm
index 7682f675b08..cb49001d3c9 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 3dbb3d0fceb..29289d34b67 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())
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index a44b1e83517..3ae084dc4ff 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 7a0181b1675..07876d19850 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 7bbc4110dde..0f393a9417d 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 3c0bfbdbadd..5fdea4a0e6f 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 933596ef5e2..9e20d49a442 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 552319e6fe4..0fa139c36f1 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 3e707b7c4c0..c24f5b7236b 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 44ac3c81ecb..dafeb2d37dd 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
@@ -824,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 8a49ed8922b..b60ff078a3c 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 e6b7f2979df..d8913e7b5b8 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/life.dm b/code/modules/mob/living/silicon/robot/life.dm
index 9dacf9924c4..a9464c595e8 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 1b051e029f4..58a81ca7a7d 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 738e9969676..40b18525282 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 3d1ae1bd02d..06de6b4d141 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 1bb202d1a03..95b7e81a177 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 c24100476cc..1cc1a85108b 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 05087c40368..7b5e77f5c39 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 79f389821e7..ae700d60b76 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 af20f042019..3ad6260813a 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 ab53d6466c2..1d8ddceeddc 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 f3cd084ffac..80f68b979d5 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 00000000000..6ba148916e3
--- /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/pipes.dm b/code/modules/multiz/pipes.dm
index 6b6b24c4705..7570d12b35d 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 6514092dfc0..1390c89b291 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 2a2b8305d3c..4febf8f4790 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 daa0a88f76c..6b7459500b6 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 aebe847fb6c..7a5c42ea41d 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 244c0b79719..cfc0910901c 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 00000000000..212330577ce
--- /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/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 75d574ed632..f7d963523c6 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 faafd2e8c95..8fbfc0e6579 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 f96dfd22eae..e07c45294cd 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 54a2d301c7f..033b4065102 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 b507afc3167..dd81d713fe3 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 091842663d2..5909ed906f3 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 f7da207e150..566f3e20f9f 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 e0307e07cc3..ef6d8bb4287 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 4f8e17cb1e6..0a7c78f9527 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 6e34257e4a4..12540c2d049 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 41ad4cb5c6c..e20ee9459f7 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 ce377c87091..16a1cb3b265 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 ed27e1a259b..bd670cc8bce 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/resleeving/designer.dm b/code/modules/resleeving/designer.dm
index 1cda055cf84..ee599d02cab 100644
--- a/code/modules/resleeving/designer.dm
+++ b/code/modules/resleeving/designer.dm
@@ -287,7 +287,7 @@
H.dna = R.dna.Clone()
H.UpdateAppearance() // Update all appearance stuff from the DNA record
H.sync_organ_dna() // Do this because sprites depend on DNA-gender of organs (chest etc)
- H.size_multiplier = active_br.sizemult
+ H.resize(active_br.sizemult, FALSE)
// And as for clothing...
// We don't actually dress them! This is a medical machine, handle the nakedness DOCTOR!
diff --git a/code/modules/resleeving/machines.dm b/code/modules/resleeving/machines.dm
index 7456ed6516b..abab41e929a 100644
--- a/code/modules/resleeving/machines.dm
+++ b/code/modules/resleeving/machines.dm
@@ -88,7 +88,7 @@
//Basically all the VORE stuff
H.ooc_notes = current_project.body_oocnotes
H.flavor_texts = current_project.mydna.flavor.Copy()
- H.size_multiplier = current_project.sizemult
+ H.resize(current_project.sizemult, FALSE)
H.weight = current_project.weight
if(current_project.speciesname)
H.custom_species = current_project.speciesname
@@ -301,7 +301,7 @@
//Basically all the VORE stuff
H.ooc_notes = current_project.body_oocnotes
H.flavor_texts = current_project.mydna.flavor.Copy()
- H.size_multiplier = current_project.sizemult
+ H.resize(current_project.sizemult)
H.weight = current_project.weight
if(current_project.speciesname)
H.custom_species = current_project.speciesname
diff --git a/code/modules/shieldgen/emergency_shield.dm b/code/modules/shieldgen/emergency_shield.dm
index f7bc1d1c803..48721314294 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/spells/spellbook.dm b/code/modules/spells/spellbook.dm
index a28f03e8feb..515453f6a35 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 498d363408e..d9d581e0504 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 c9d08c3385d..1ece0248335 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/effect.dm b/code/modules/virus2/effect.dm
index 5243bae35f6..310f2231593 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/vore/eating/belly_vr.dm b/code/modules/vore/eating/belly_vr.dm
index 0bc8e25e6b2..902f6183c84 100644
--- a/code/modules/vore/eating/belly_vr.dm
+++ b/code/modules/vore/eating/belly_vr.dm
@@ -31,7 +31,7 @@
var/tmp/digest_mode = DM_HOLD // Whether or not to digest. Default to not digest.
var/tmp/list/digest_modes = list(DM_HOLD,DM_DIGEST,DM_HEAL,DM_ABSORB,DM_DRAIN,DM_UNABSORB) // Possible digest modes
- var/tmp/list/transform_modes = list(DM_TRANSFORM_MALE,DM_TRANSFORM_FEMALE,DM_TRANSFORM_KEEP_GENDER,DM_TRANSFORM_CHANGE_SPECIES,DM_TRANSFORM_CHANGE_SPECIES_EGG,DM_TRANSFORM_KEEP_GENDER_EGG,DM_TRANSFORM_MALE_EGG,DM_TRANSFORM_FEMALE_EGG, DM_EGG)
+ var/tmp/list/transform_modes = list(DM_TRANSFORM_MALE,DM_TRANSFORM_FEMALE,DM_TRANSFORM_KEEP_GENDER,DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR,DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR_EGG,DM_TRANSFORM_REPLICA,DM_TRANSFORM_REPLICA_EGG,DM_TRANSFORM_KEEP_GENDER_EGG,DM_TRANSFORM_MALE_EGG,DM_TRANSFORM_FEMALE_EGG, DM_EGG)
var/tmp/mob/living/owner // The mob whose belly this is.
var/tmp/list/internal_contents = list() // People/Things you've eaten into this belly!
var/tmp/is_full // Flag for if digested remeans are present. (for disposal messages)
diff --git a/code/modules/vore/eating/bellymodes_vr.dm b/code/modules/vore/eating/bellymodes_vr.dm
index 273f00e75be..2d00c079910 100644
--- a/code/modules/vore/eating/bellymodes_vr.dm
+++ b/code/modules/vore/eating/bellymodes_vr.dm
@@ -144,6 +144,37 @@
M.nutrition += 1
return
+///////////////////////////// DM_TRANSFORM_HAIR_AND_EYES /////////////////////////////
+ if(digest_mode == DM_TRANSFORM_HAIR_AND_EYES && ishuman(owner))
+ for (var/mob/living/carbon/human/P in internal_contents)
+ if(P.stat)
+ continue
+
+ var/mob/living/carbon/human/O = owner
+
+ var/TFchance = 1 //This used to be RNG, resulting people waiting ages. This way does it instantly.
+ if(TFchance == 1)
+ if(P.r_hair != O.r_hair || P.g_hair != O.g_hair || P.b_hair != O.b_hair || P.r_skin != O.r_skin || P.g_skin != O.g_skin || P.b_skin != O.b_skin || P.r_facial != O.r_facial || P.g_facial != O.g_facial || P.b_facial != O.b_facial)
+ P.r_hair = O.r_hair
+ P.r_facial = O.r_facial
+ P.g_hair = O.g_hair
+ P.g_facial = O.g_facial
+ P.b_hair = O.b_hair
+ P.b_facial = O.b_facial
+ P.r_skin = O.r_skin
+ P.g_skin = O.g_skin
+ P.b_skin = O.b_skin
+ P.h_style = O.h_style
+ P << "Your body tingles all over..."
+ owner << "You tingle as you make noticeable changes to your captive's body."
+ P.update_hair()
+ P.update_body()
+ P.updateicon()
+
+ if(O.nutrition > 400 && P.nutrition < 400)
+ O.nutrition -= 2
+ P.nutrition += 1.5
+ return
///////////////////////////// DM_TRANSFORM_MALE /////////////////////////////
if(digest_mode == DM_TRANSFORM_MALE && ishuman(owner))
for (var/mob/living/carbon/human/P in internal_contents)
@@ -181,17 +212,17 @@
P.update_body()
P.updateicon()
- if(TFmodify == 3 && P.gender != MALE)
+ if(TFmodify == 3 && P.gender != MALE && P.identifying_gender != MALE)
P.gender = MALE
+ P.identifying_gender = MALE
P << "Your body feels very strange..."
owner << "You feel strange as you alter your captive's gender."
P.update_body()
P.updateicon()
- if(O.nutrition > 0)
+ if(O.nutrition > 400 && P.nutrition < 400)
O.nutrition -= 2
- if(P.nutrition < 400)
- P.nutrition += 1
+ P.nutrition += 1.5
return
@@ -228,18 +259,18 @@
P.update_body()
P.updateicon()
- if(TFmodify == 3 && P.gender != FEMALE)
+ if(TFmodify == 3 && P.gender != FEMALE && P.identifying_gender != FEMALE)
P.f_style = "Shaved"
P.gender = FEMALE
+ P.identifying_gender = FEMALE
P << "Your body feels very strange..."
owner << "You feel strange as you alter your captive's gender."
P.update_body()
P.updateicon()
- if(O.nutrition > 0)
+ if(O.nutrition > 400 && P.nutrition < 400)
O.nutrition -= 2
- if(P.nutrition < 400)
- P.nutrition += 1
+ P.nutrition += 1.5
return
///////////////////////////// DM_TRANSFORM_KEEP_GENDER /////////////////////////////
@@ -279,14 +310,44 @@
P.update_body()
P.updateicon()
- if(O.nutrition > 0)
+ if(O.nutrition > 400 && P.nutrition < 400)
O.nutrition -= 2
- if(P.nutrition < 400)
- P.nutrition += 1
+ P.nutrition += 1.5
return
-///////////////////////////// DM_TRANSFORM_CHANGE_SPECIES /////////////////////////////
- if(digest_mode == DM_TRANSFORM_CHANGE_SPECIES && ishuman(owner))
+///////////////////////////// DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR /////////////////////////////
+ if(digest_mode == DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR && ishuman(owner))
+ for (var/mob/living/carbon/human/P in internal_contents)
+ if(P.stat)
+ continue
+
+ var/mob/living/carbon/human/O = owner
+
+ var/TFchance = 1 //This used to be RNG, resulting people waiting ages. This way does it instantly.
+ if(TFchance == 1)
+ if(P.species != O.species || P.tail_style != O.tail_style || P.custom_species != O.custom_species || P.ear_style != O.ear_style)
+ P.tail_style = O.tail_style
+ P.ear_style = O.ear_style
+ P.species = O.species
+ P.custom_species = O.custom_species
+ for(var/obj/item/organ/I in P.organs) //This prevents organ rejection
+ I.species = O.species
+ for(var/obj/item/organ/external/Z in P.organs)//Just in case.
+ Z.sync_colour_to_human(P)
+ P << "You lose sensation of your body, feeling only the warmth of everything around you... "
+ owner << "Your body shifts as you make dramatic changes to your captive's body."
+ P.fixblood()
+ P.update_body()
+ P.update_tail_showing()
+ P.updateicon()
+
+ if(O.nutrition > 400 && P.nutrition < 400)
+ O.nutrition -= 2
+ P.nutrition += 1.5
+ return
+
+///////////////////////////// DM_TRANSFORM_REPLICA /////////////////////////////
+ if(digest_mode == DM_TRANSFORM_REPLICA && ishuman(owner))
for (var/mob/living/carbon/human/P in internal_contents)
if(P.stat)
continue
@@ -338,14 +399,11 @@
P.ear_style = O.ear_style
P.species = O.species
P.custom_species = O.custom_species
- for(var/obj/item/organ/I in P.internal_organs) //This prevents organ rejection
+ for(var/obj/item/organ/I in P.organs) //This prevents organ rejection
I.species = O.species
- for(var/obj/item/organ/external/chest/A in O.organs)
- for(var/obj/item/organ/external/Z in P.organs) //This makes their limb sprites look correct.
- Z.species = O.species
- Z.h_col = A.h_col
- Z.s_col = A.s_col
- P << "You lose sensation of your body, feeling only the warmth of everything around you... "
+ for(var/obj/item/organ/external/Z in P.organs)
+ Z.sync_colour_to_human(P)
+ P << "You lose sensation of your body, feeling only the warmth of everything around you... "
owner << "Your body shifts as you make dramatic changes to your captive's body."
P.fixblood()
P.update_hair()
@@ -353,219 +411,47 @@
P.update_tail_showing()
P.updateicon()
- if(O.nutrition > 0)
+ if(O.nutrition > 400 && P.nutrition < 400)
O.nutrition -= 2
- if(P.nutrition < 400)
- P.nutrition += 1
+ P.nutrition += 1.5
return
-
-///////////////////////////// DM_TRANSFORM_CHANGE_SPECIES_EGG /////////////////////////////
- if(digest_mode == DM_TRANSFORM_CHANGE_SPECIES_EGG && ishuman(owner))
+///////////////////////////// DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR_EGG /////////////////////////////
+ if(digest_mode == DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR_EGG && ishuman(owner))
for (var/mob/living/carbon/human/P in internal_contents)
if(P.stat)
continue
if(P.absorbed) //If they're absorbed, don't egg them
return
+
var/mob/living/carbon/human/O = owner
- if (O.custom_species)
- var/defined_species = O.custom_species
- P.r_hair = O.r_hair
- P.r_facial = O.r_facial
- P.g_hair = O.g_hair
- P.g_facial = O.g_facial
- P.b_hair = O.b_hair
- P.b_facial = O.b_facial
- P.r_skin = O.r_skin
- P.g_skin = O.g_skin
- P.b_skin = O.b_skin
- P.tail_style = O.tail_style
- P.r_tail = O.r_tail
- P.g_tail = O.g_tail
- P.b_tail = O.b_tail
- P.ear_style = O.ear_style
- P.h_style = O.h_style //Since some things are required, like the cobra hood.
- P.species = O.species
- P.custom_species = O.custom_species
- P.r_eyes = O.r_eyes
- P.g_eyes = O.g_eyes
- P.b_eyes = O.b_eyes
+ P.tail_style = O.tail_style
+ P.ear_style = O.ear_style
+ P.species = O.species
+ for(var/obj/item/organ/I in P.organs) //This prevents organ rejection
+ I.species = O.species
+ for(var/obj/item/organ/external/Z in P.organs)
+ Z.sync_colour_to_human(P)
+ P << "You lose sensation of your body, feeling only the warmth around you as are you as you're encased in an egg. "
+ owner << "You shift as you make dramatic changes to your captive's body as you encase them in an egg."
+ P.fixblood()
+ P.update_hair()
+ P.update_body()
+ P.update_tail_showing()
+ P.update_eyes()
+ P.updateicon()
+ var/egg_path = /obj/structure/closet/secure_closet/egg //Full credit to Aronai for this version of the egg code.
+ var/egg_name = "Odd egg"
- for(var/obj/item/organ/I in P.internal_organs) //This prevents organ rejection
- I.species = O.species
+ if(O.egg_type in tf_egg_types)
+ egg_path = tf_egg_types[O.egg_type]
+ egg_name = "[O.egg_type] egg"
- for(var/obj/item/organ/external/chest/A in O.organs)
- for(var/obj/item/organ/external/Z in P.organs) //This makes their limb sprites look correct.
- Z.species = O.species
- Z.h_col = A.h_col
- Z.s_col = A.s_col
- P << "You lose sensation of your body, feeling only the warmth around you as you're encased in an egg. "
- owner << "You shift as you make dramatic changes to your captive's body as you encase them in an egg."
- P.fixblood()
- P.update_hair()
- P.update_body()
- P.update_tail_showing()
- P.update_eyes()
- P.updateicon()
- switch(O.egg_type)
- if("Unathi")
- var/obj/structure/closet/secure_closet/egg/unathi/J = new /obj/structure/closet/secure_closet/egg/unathi(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- for(var/mob/living/M in internal_contents)
- internal_contents -= P
- if("Tajaran")
- var/obj/structure/closet/secure_closet/egg/tajaran/J = new /obj/structure/closet/secure_closet/egg/tajaran(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Akula")
- var/obj/structure/closet/secure_closet/egg/shark/J = new /obj/structure/closet/secure_closet/egg/shark(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Skrell")
- var/obj/structure/closet/secure_closet/egg/skrell/J = new /obj/structure/closet/secure_closet/egg/skrell(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Sergal")
- var/obj/structure/closet/secure_closet/egg/sergal/J = new /obj/structure/closet/secure_closet/egg/sergal(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Human")
- var/obj/structure/closet/secure_closet/egg/human/J = new /obj/structure/closet/secure_closet/egg/human(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Slime")
- var/obj/structure/closet/secure_closet/egg/slime/J = new /obj/structure/closet/secure_closet/egg/slime(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Egg")
- var/obj/structure/closet/secure_closet/egg/J = new /obj/structure/closet/secure_closet/egg(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Xenochimera")
- var/obj/structure/closet/secure_closet/egg/scree/J = new /obj/structure/closet/secure_closet/egg/scree(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Xenomorph")
- var/obj/structure/closet/secure_closet/egg/xenomorph/J = new /obj/structure/closet/secure_closet/egg/xenomorph(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- else
- var/obj/structure/closet/secure_closet/egg/J = new /obj/structure/closet/secure_closet/egg(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- else
- P.r_hair = O.r_hair
- P.r_facial = O.r_facial
- P.g_hair = O.g_hair
- P.g_facial = O.g_facial
- P.b_hair = O.b_hair
- P.b_facial = O.b_facial
- P.r_skin = O.r_skin
- P.g_skin = O.g_skin
- P.b_skin = O.b_skin
- P.tail_style = O.tail_style
- P.r_tail = O.r_tail
- P.g_tail = O.g_tail
- P.b_tail = O.b_tail
- P.ear_style = O.ear_style
- P.h_style = O.h_style
- P.species = O.species
- P.custom_species = O.custom_species
- P.r_eyes = O.r_eyes
- P.g_eyes = O.g_eyes
- P.b_eyes = O.b_eyes
- for(var/obj/item/organ/I in P.internal_organs) //This prevents organ rejection
- I.species = O.species
- for(var/obj/item/organ/external/chest/A in O.organs)
- for(var/obj/item/organ/external/Z in P.organs) //This makes their limb sprites look correct.
- Z.species = O.species
- Z.h_col = A.h_col
- Z.s_col = A.s_col
- P << "You lose sensation of your body, feeling only the warmth around you as are you as you're encased in an egg. "
- owner << "You shift as you make dramatic changes to your captive's body as you encase them in an egg."
- P.fixblood()
- P.update_hair()
- P.update_body()
- P.update_tail_showing()
- P.update_eyes()
- P.updateicon()
- switch(O.egg_type)
- if("Unathi")
- var/obj/structure/closet/secure_closet/egg/unathi/J = new /obj/structure/closet/secure_closet/egg/unathi(O.loc)
- P.forceMove(J)
- J.name = "Unathi egg"
- internal_contents -= P
- if("Tajaran")
- var/obj/structure/closet/secure_closet/egg/tajaran/J = new /obj/structure/closet/secure_closet/egg/tajaran(O.loc)
- P.forceMove(J)
- J.name = "Tajaran egg"
- internal_contents -= P
- if("Akula")
- var/obj/structure/closet/secure_closet/egg/shark/J = new /obj/structure/closet/secure_closet/egg/shark(O.loc)
- P.forceMove(J)
- J.name = "Akula egg"
- internal_contents -= P
- if("Skrell")
- var/obj/structure/closet/secure_closet/egg/skrell/J = new /obj/structure/closet/secure_closet/egg/skrell(O.loc)
- P.forceMove(J)
- J.name = "Skrell egg"
- internal_contents -= P
- if("Sergal")
- var/obj/structure/closet/secure_closet/egg/sergal/J = new /obj/structure/closet/secure_closet/egg/sergal(O.loc)
- P.forceMove(J)
- J.name = "Segal egg"
- internal_contents -= P
- if("Human")
- var/obj/structure/closet/secure_closet/egg/human/J = new /obj/structure/closet/secure_closet/egg/human(O.loc)
- P.forceMove(J)
- J.name = "Human egg"
- internal_contents -= P
- if("Slime")
- var/obj/structure/closet/secure_closet/egg/slime/J = new /obj/structure/closet/secure_closet/egg/slime(O.loc)
- P.forceMove(J)
- J.name = "Slime egg"
- internal_contents -= P
- if("Egg")
- var/obj/structure/closet/secure_closet/egg/J = new /obj/structure/closet/secure_closet/egg(O.loc)
- P.forceMove(J)
- J.name = "Egg"
- internal_contents -= P
- if("Xenochimera")
- var/obj/structure/closet/secure_closet/egg/scree/J = new /obj/structure/closet/secure_closet/egg/scree(O.loc)
- P.forceMove(J)
- internal_contents -= P
- if("Xenomorph")
- var/obj/structure/closet/secure_closet/egg/xenomorph/J = new /obj/structure/closet/secure_closet/egg/xenomorph(O.loc)
- P.forceMove(J)
- internal_contents -= P
- else
- var/obj/structure/closet/secure_closet/egg/J = new /obj/structure/closet/secure_closet/egg(O.loc)
- P.forceMove(J)
- J.name = "Odd egg" //Something went wrong. Since the default is "egg", they shouldn't see this.
- internal_contents -= P
+ var/obj/structure/closet/secure_closet/egg/egg = new egg_path(get_turf(O))
+ P.forceMove(egg)
+ egg.name = egg_name
+ internal_contents -= P
return
///////////////////////////// DM_TRANSFORM_KEEP_GENDER_EGG /////////////////////////////
@@ -575,173 +461,95 @@
continue
if(P.absorbed) //If they're absorbed, don't egg them
return
+
var/mob/living/carbon/human/O = owner
- if (O.custom_species)
- var/defined_species = O.custom_species
- P.r_hair = O.r_hair
- P.r_facial = O.r_facial
- P.g_hair = O.g_hair
- P.g_facial = O.g_facial
- P.b_hair = O.b_hair
- P.b_facial = O.b_facial
- P.r_skin = O.r_skin
- P.g_skin = O.g_skin
- P.b_skin = O.b_skin
- P.h_style = O.h_style
- P.r_eyes = O.r_eyes
- P.g_eyes = O.g_eyes
- P.b_eyes = O.b_eyes
- P << "Your body tingles all over..."
- owner << "You tingle as you make noticeable changes to your captive's body."
- P.update_hair()
- P.update_body()
- P.update_eyes()
- P.updateicon()
- switch(O.egg_type)
- if("Unathi")
- var/obj/structure/closet/secure_closet/egg/unathi/J = new /obj/structure/closet/secure_closet/egg/unathi(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Tajaran")
- var/obj/structure/closet/secure_closet/egg/tajaran/J = new /obj/structure/closet/secure_closet/egg/tajaran(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Akula")
- var/obj/structure/closet/secure_closet/egg/shark/J = new /obj/structure/closet/secure_closet/egg/shark(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Skrell")
- var/obj/structure/closet/secure_closet/egg/skrell/J = new /obj/structure/closet/secure_closet/egg/skrell(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Sergal")
- var/obj/structure/closet/secure_closet/egg/sergal/J = new /obj/structure/closet/secure_closet/egg/sergal(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Human")
- var/obj/structure/closet/secure_closet/egg/human/J = new /obj/structure/closet/secure_closet/egg/human(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Slime")
- var/obj/structure/closet/secure_closet/egg/slime/J = new /obj/structure/closet/secure_closet/egg/slime(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Egg")
- var/obj/structure/closet/secure_closet/egg/J = new /obj/structure/closet/secure_closet/egg(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Xenochimera")
- var/obj/structure/closet/secure_closet/egg/scree/J = new /obj/structure/closet/secure_closet/egg/scree(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Xenomorph")
- var/obj/structure/closet/secure_closet/egg/xenomorph/J = new /obj/structure/closet/secure_closet/egg/xenomorph(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- else
- var/obj/structure/closet/secure_closet/egg/J = new /obj/structure/closet/secure_closet/egg(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
+ P.r_hair = O.r_hair
+ P.r_facial = O.r_facial
+ P.g_hair = O.g_hair
+ P.g_facial = O.g_facial
+ P.b_hair = O.b_hair
+ P.b_facial = O.b_facial
+ P.r_skin = O.r_skin
+ P.g_skin = O.g_skin
+ P.b_skin = O.b_skin
+ P.h_style = O.h_style
+ P.r_eyes = O.r_eyes
+ P.g_eyes = O.g_eyes
+ P.b_eyes = O.b_eyes
+ P << "Your body tingles all over..."
+ owner << "You tingle as you make noticeable changes to your captive's body."
+ P.update_hair()
+ P.update_body()
+ P.update_eyes()
+ P.updateicon()
+ var/egg_path = /obj/structure/closet/secure_closet/egg
+ var/egg_name = "Odd egg"
- else
- P.r_hair = O.r_hair
- P.r_facial = O.r_facial
- P.g_hair = O.g_hair
- P.g_facial = O.g_facial
- P.b_hair = O.b_hair
- P.b_facial = O.b_facial
- P.r_skin = O.r_skin
- P.g_skin = O.g_skin
- P.b_skin = O.b_skin
- P.h_style = O.h_style
- P.r_eyes = O.r_eyes
- P.g_eyes = O.g_eyes
- P.b_eyes = O.b_eyes
- P << "Your body tingles all over..."
- owner << "You tingle as you make noticeable changes to your captive's body."
- P.update_hair()
- P.update_body()
- P.update_eyes()
- P.updateicon()
- switch(O.egg_type)
- if("Unathi")
- var/obj/structure/closet/secure_closet/egg/unathi/J = new /obj/structure/closet/secure_closet/egg/unathi(O.loc)
- P.forceMove(J)
- J.name = "Unathi egg"
- internal_contents -= P
- if("Tajaran")
- var/obj/structure/closet/secure_closet/egg/tajaran/J = new /obj/structure/closet/secure_closet/egg/tajaran(O.loc)
- P.forceMove(J)
- J.name = "Tajaran egg"
- internal_contents -= P
- if("Akula")
- var/obj/structure/closet/secure_closet/egg/shark/J = new /obj/structure/closet/secure_closet/egg/shark(O.loc)
- P.forceMove(J)
- J.name = "Akula egg"
- internal_contents -= P
- if("Skrell")
- var/obj/structure/closet/secure_closet/egg/skrell/J = new /obj/structure/closet/secure_closet/egg/skrell(O.loc)
- P.forceMove(J)
- J.name = "Skrell egg"
- internal_contents -= P
- if("Sergal")
- var/obj/structure/closet/secure_closet/egg/sergal/J = new /obj/structure/closet/secure_closet/egg/sergal(O.loc)
- P.forceMove(J)
- J.name = "Segal egg"
- internal_contents -= P
- if("Human")
- var/obj/structure/closet/secure_closet/egg/human/J = new /obj/structure/closet/secure_closet/egg/human(O.loc)
- P.forceMove(J)
- J.name = "Human egg"
- internal_contents -= P
- if("Slime")
- var/obj/structure/closet/secure_closet/egg/slime/J = new /obj/structure/closet/secure_closet/egg/slime(O.loc)
- P.forceMove(J)
- J.name = "Slime egg"
- internal_contents -= P
- if("Egg")
- var/obj/structure/closet/secure_closet/egg/J = new /obj/structure/closet/secure_closet/egg(O.loc)
- P.forceMove(J)
- J.name = "Egg"
- internal_contents -= P
- if("Xenochimera")
- var/obj/structure/closet/secure_closet/egg/scree/J = new /obj/structure/closet/secure_closet/egg/scree(O.loc)
- J.name = "Xenochimera egg"
- P.forceMove(J)
- internal_contents -= P
- if("Xenomorph")
- var/obj/structure/closet/secure_closet/egg/xenomorph/J = new /obj/structure/closet/secure_closet/egg/xenomorph(O.loc)
- P.forceMove(J)
- J.name = "Xenomorph egg"
- internal_contents -= P
- else
- var/obj/structure/closet/secure_closet/egg/J = new /obj/structure/closet/secure_closet/egg(O.loc)
- P.forceMove(J)
- J.name = "Odd egg" //Something went wrong. Since the default is "egg", they shouldn't see this.
- internal_contents -= P
+ if(O.egg_type in tf_egg_types)
+ egg_path = tf_egg_types[O.egg_type]
+ egg_name = "[O.egg_type] egg"
+
+ var/obj/structure/closet/secure_closet/egg/egg = new egg_path(get_turf(O))
+ P.forceMove(egg)
+ egg.name = egg_name
+ internal_contents -= P
+ return
+
+///////////////////////////// DM_TRANSFORM_REPLICA_EGG /////////////////////////////
+ if(digest_mode == DM_TRANSFORM_REPLICA_EGG && ishuman(owner))
+ for (var/mob/living/carbon/human/P in internal_contents)
+ if(P.stat)
+ continue
+ if(P.absorbed) //If they're absorbed, don't egg them
+ return
+
+ var/mob/living/carbon/human/O = owner
+
+ P.r_hair = O.r_hair
+ P.r_facial = O.r_facial
+ P.g_hair = O.g_hair
+ P.g_facial = O.g_facial
+ P.b_hair = O.b_hair
+ P.b_facial = O.b_facial
+ P.r_skin = O.r_skin
+ P.g_skin = O.g_skin
+ P.b_skin = O.b_skin
+ P.tail_style = O.tail_style
+ P.r_tail = O.r_tail
+ P.g_tail = O.g_tail
+ P.b_tail = O.b_tail
+ P.ear_style = O.ear_style
+ P.h_style = O.h_style
+ P.species = O.species
+ P.custom_species = O.custom_species
+ P.r_eyes = O.r_eyes
+ P.g_eyes = O.g_eyes
+ P.b_eyes = O.b_eyes
+
+ for(var/obj/item/organ/I in P.organs) //This prevents organ rejection
+ I.species = O.species
+ for(var/obj/item/organ/external/Z in P.organs)
+ Z.sync_colour_to_human(P)
+ P << "You lose sensation of your body, feeling only the warmth around you as are you as you're encased in an egg. "
+ owner << "You shift as you make dramatic changes to your captive's body as you encase them in an egg."
+ P.fixblood()
+ P.update_hair()
+ P.update_body()
+ P.update_tail_showing()
+ P.update_eyes()
+ P.updateicon()
+ var/egg_path = /obj/structure/closet/secure_closet/egg
+ var/egg_name = "Odd egg"
+
+ if(O.egg_type in tf_egg_types)
+ egg_path = tf_egg_types[O.egg_type]
+ egg_name = "[O.egg_type] egg"
+
+ var/obj/structure/closet/secure_closet/egg/egg = new egg_path(get_turf(O))
+ P.forceMove(egg)
+ egg.name = egg_name
+ internal_contents -= P
return
///////////////////////////// DM_TRANSFORM_MALE_EGG /////////////////////////////
@@ -751,172 +559,40 @@
continue
if(P.absorbed) //If they're absorbed, don't egg them
return
+
var/mob/living/carbon/human/O = owner
- if (O.custom_species)
- var/defined_species = O.custom_species
- P.r_hair = O.r_hair
- P.r_facial = O.r_facial
- P.g_hair = O.g_hair
- P.g_facial = O.g_facial
- P.b_hair = O.b_hair
- P.b_facial = O.b_facial
- P.r_skin = O.r_skin
- P.g_skin = O.g_skin
- P.b_skin = O.b_skin
- P.h_style = O.h_style
- P.gender = MALE
- P.r_eyes = O.r_eyes
- P.g_eyes = O.g_eyes
- P.b_eyes = O.b_eyes
- P << "Your body feels very strange..."
- owner << "Your body feels strange as you alter your captive's gender."
- P.update_hair()
- P.update_body()
- P.updateicon()
- switch(O.egg_type)
- if("Unathi")
- var/obj/structure/closet/secure_closet/egg/unathi/J = new /obj/structure/closet/secure_closet/egg/unathi(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Tajaran")
- var/obj/structure/closet/secure_closet/egg/tajaran/J = new /obj/structure/closet/secure_closet/egg/tajaran(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Akula")
- var/obj/structure/closet/secure_closet/egg/shark/J = new /obj/structure/closet/secure_closet/egg/shark(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Skrell")
- var/obj/structure/closet/secure_closet/egg/skrell/J = new /obj/structure/closet/secure_closet/egg/skrell(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Sergal")
- var/obj/structure/closet/secure_closet/egg/sergal/J = new /obj/structure/closet/secure_closet/egg/sergal(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Human")
- var/obj/structure/closet/secure_closet/egg/human/J = new /obj/structure/closet/secure_closet/egg/human(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Slime")
- var/obj/structure/closet/secure_closet/egg/slime/J = new /obj/structure/closet/secure_closet/egg/slime(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Egg")
- var/obj/structure/closet/secure_closet/egg/J = new /obj/structure/closet/secure_closet/egg(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Xenochimera")
- var/obj/structure/closet/secure_closet/egg/scree/J = new /obj/structure/closet/secure_closet/egg/scree(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Xenomorph")
- var/obj/structure/closet/secure_closet/egg/xenomorph/J = new /obj/structure/closet/secure_closet/egg/xenomorph(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- else
- var/obj/structure/closet/secure_closet/egg/J = new /obj/structure/closet/secure_closet/egg(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- else
- P.r_hair = O.r_hair
- P.r_facial = O.r_facial
- P.g_hair = O.g_hair
- P.g_facial = O.g_facial
- P.b_hair = O.b_hair
- P.b_facial = O.b_facial
- P.r_skin = O.r_skin
- P.g_skin = O.g_skin
- P.b_skin = O.b_skin
- P.h_style = O.h_style
- P.gender = MALE
- P.r_eyes = O.r_eyes
- P.g_eyes = O.g_eyes
- P.b_eyes = O.b_eyes
- P << "Your body feels very strange..."
- owner << "You feel strange as you alter your captive's gender."
- P.update_hair()
- P.update_body()
- P.updateicon()
- switch(O.egg_type)
- if("Unathi")
- var/obj/structure/closet/secure_closet/egg/unathi/J = new /obj/structure/closet/secure_closet/egg/unathi(O.loc)
- P.forceMove(J)
- J.name = "Unathi egg"
- internal_contents -= P
- if("Tajaran")
- var/obj/structure/closet/secure_closet/egg/tajaran/J = new /obj/structure/closet/secure_closet/egg/tajaran(O.loc)
- P.forceMove(J)
- J.name = "Tajaran egg"
- internal_contents -= P
- if("Akula")
- var/obj/structure/closet/secure_closet/egg/shark/J = new /obj/structure/closet/secure_closet/egg/shark(O.loc)
- P.forceMove(J)
- J.name = "Akula egg"
- internal_contents -= P
- if("Skrell")
- var/obj/structure/closet/secure_closet/egg/skrell/J = new /obj/structure/closet/secure_closet/egg/skrell(O.loc)
- P.forceMove(J)
- J.name = "Skrell egg"
- internal_contents -= P
- if("Sergal")
- var/obj/structure/closet/secure_closet/egg/sergal/J = new /obj/structure/closet/secure_closet/egg/sergal(O.loc)
- P.forceMove(J)
- J.name = "Segal egg"
- internal_contents -= P
- if("Human")
- var/obj/structure/closet/secure_closet/egg/human/J = new /obj/structure/closet/secure_closet/egg/human(O.loc)
- P.forceMove(J)
- J.name = "Human egg"
- internal_contents -= P
- if("Slime")
- var/obj/structure/closet/secure_closet/egg/slime/J = new /obj/structure/closet/secure_closet/egg/slime(O.loc)
- P.forceMove(J)
- J.name = "Slime egg"
- internal_contents -= P
- if("Egg")
- var/obj/structure/closet/secure_closet/egg/J = new /obj/structure/closet/secure_closet/egg(O.loc)
- P.forceMove(J)
- J.name = "Egg"
- internal_contents -= P
- if("Xenochimera")
- var/obj/structure/closet/secure_closet/egg/scree/J = new /obj/structure/closet/secure_closet/egg/scree(O.loc)
- P.forceMove(J)
- J.name = "Scree egg"
- internal_contents -= P
- if("Xenomorph")
- var/obj/structure/closet/secure_closet/egg/xenomorph/J = new /obj/structure/closet/secure_closet/egg/xenomorph(O.loc)
- P.forceMove(J)
- J.name = "Xenomorph egg"
- internal_contents -= P
- else
- var/obj/structure/closet/secure_closet/egg/J = new /obj/structure/closet/secure_closet/egg(O.loc)
- P.forceMove(J)
- J.name = "Odd egg" //Something went wrong. Since the default is "egg", they shouldn't see this.
- internal_contents -= P
+ P.r_hair = O.r_hair
+ P.r_facial = O.r_facial
+ P.g_hair = O.g_hair
+ P.g_facial = O.g_facial
+ P.b_hair = O.b_hair
+ P.b_facial = O.b_facial
+ P.r_skin = O.r_skin
+ P.g_skin = O.g_skin
+ P.b_skin = O.b_skin
+ P.h_style = O.h_style
+ P.gender = MALE
+ P.identifying_gender= MALE
+ P.r_eyes = O.r_eyes
+ P.g_eyes = O.g_eyes
+ P.b_eyes = O.b_eyes
+ P << "Your body feels very strange..."
+ owner << "You feel strange as you alter your captive's gender."
+ P.update_hair()
+ P.update_body()
+ P.updateicon()
+ var/egg_path = /obj/structure/closet/secure_closet/egg
+ var/egg_name = "Odd egg"
+
+ if(O.egg_type in tf_egg_types)
+ egg_path = tf_egg_types[O.egg_type]
+ egg_name = "[O.egg_type] egg"
+
+ var/obj/structure/closet/secure_closet/egg/egg = new egg_path(get_turf(O))
+ P.forceMove(egg)
+ egg.name = egg_name
+ internal_contents -= P
return
///////////////////////////// DM_TRANSFORM_FEMALE_EGG /////////////////////////////
@@ -926,171 +602,40 @@
continue
if(P.absorbed) //If they're absorbed, don't egg them
return
+
var/mob/living/carbon/human/O = owner
+ P.r_hair = O.r_hair
+ P.r_facial = O.r_facial
+ P.g_hair = O.g_hair
+ P.g_facial = O.g_facial
+ P.b_hair = O.b_hair
+ P.b_facial = O.b_facial
+ P.r_skin = O.r_skin
+ P.g_skin = O.g_skin
+ P.b_skin = O.b_skin
+ P.h_style = O.h_style
+ P.gender = FEMALE
+ P.identifying_gender= FEMALE
+ P.r_eyes = O.r_eyes
+ P.g_eyes = O.g_eyes
+ P.b_eyes = O.b_eyes
+ owner << "You feel strange as you alter your captive's gender."
+ P << "Your body feels very strange..."
+ P.update_hair()
+ P.update_body()
+ P.updateicon()
+ var/egg_path = /obj/structure/closet/secure_closet/egg
+ var/egg_name = "Odd egg"
- if (O.custom_species)
- var/defined_species = O.custom_species
- P.r_hair = O.r_hair
- P.r_facial = O.r_facial
- P.g_hair = O.g_hair
- P.g_facial = O.g_facial
- P.b_hair = O.b_hair
- P.b_facial = O.b_facial
- P.r_skin = O.r_skin
- P.g_skin = O.g_skin
- P.b_skin = O.b_skin
- P.h_style = O.h_style
- P.gender = FEMALE
- P.r_eyes = O.r_eyes
- P.g_eyes = O.g_eyes
- P.b_eyes = O.b_eyes
- P << "Your body feels very strange..."
- owner << "You feels strange as you alter your captive's gender."
- P.update_hair()
- P.update_body()
- P.updateicon()
- switch(O.egg_type)
- if("Unathi")
- var/obj/structure/closet/secure_closet/egg/unathi/J = new /obj/structure/closet/secure_closet/egg/unathi(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Tajaran")
- var/obj/structure/closet/secure_closet/egg/tajaran/J = new /obj/structure/closet/secure_closet/egg/tajaran(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Akula")
- var/obj/structure/closet/secure_closet/egg/shark/J = new /obj/structure/closet/secure_closet/egg/shark(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Skrell")
- var/obj/structure/closet/secure_closet/egg/skrell/J = new /obj/structure/closet/secure_closet/egg/skrell(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Sergal")
- var/obj/structure/closet/secure_closet/egg/sergal/J = new /obj/structure/closet/secure_closet/egg/sergal(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Human")
- var/obj/structure/closet/secure_closet/egg/human/J = new /obj/structure/closet/secure_closet/egg/human(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Slime")
- var/obj/structure/closet/secure_closet/egg/slime/J = new /obj/structure/closet/secure_closet/egg/slime(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Egg")
- var/obj/structure/closet/secure_closet/egg/J = new /obj/structure/closet/secure_closet/egg(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Xenochimera")
- var/obj/structure/closet/secure_closet/egg/scree/J = new /obj/structure/closet/secure_closet/egg/scree(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Xenomorph")
- var/obj/structure/closet/secure_closet/egg/xenomorph/J = new /obj/structure/closet/secure_closet/egg/xenomorph(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- else
- var/obj/structure/closet/secure_closet/egg/J = new /obj/structure/closet/secure_closet/egg(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- else
- P.r_hair = O.r_hair
- P.r_facial = O.r_facial
- P.g_hair = O.g_hair
- P.g_facial = O.g_facial
- P.b_hair = O.b_hair
- P.b_facial = O.b_facial
- P.r_skin = O.r_skin
- P.g_skin = O.g_skin
- P.b_skin = O.b_skin
- P.h_style = O.h_style
- P.gender = FEMALE
- P.r_eyes = O.r_eyes
- P.g_eyes = O.g_eyes
- P.b_eyes = O.b_eyes
- owner << "You feel strange as you alter your captive's gender."
- P << "Your body feels very strange..."
- P.update_hair()
- P.update_body()
- P.updateicon()
- switch(O.egg_type)
- if("Unathi")
- var/obj/structure/closet/secure_closet/egg/unathi/J = new /obj/structure/closet/secure_closet/egg/unathi(O.loc)
- P.forceMove(J)
- J.name = "Unathi egg"
- internal_contents -= P
- if("Tajaran")
- var/obj/structure/closet/secure_closet/egg/tajaran/J = new /obj/structure/closet/secure_closet/egg/tajaran(O.loc)
- P.forceMove(J)
- J.name = "Tajaran egg"
- internal_contents -= P
- if("Akula")
- var/obj/structure/closet/secure_closet/egg/shark/J = new /obj/structure/closet/secure_closet/egg/shark(O.loc)
- P.forceMove(J)
- J.name = "Akula egg"
- internal_contents -= P
- if("Skrell")
- var/obj/structure/closet/secure_closet/egg/skrell/J = new /obj/structure/closet/secure_closet/egg/skrell(O.loc)
- P.forceMove(J)
- J.name = "Skrell egg"
- internal_contents -= P
- if("Sergal")
- var/obj/structure/closet/secure_closet/egg/sergal/J = new /obj/structure/closet/secure_closet/egg/sergal(O.loc)
- P.forceMove(J)
- J.name = "Segal egg"
- internal_contents -= P
- if("Human")
- var/obj/structure/closet/secure_closet/egg/human/J = new /obj/structure/closet/secure_closet/egg/human(O.loc)
- P.forceMove(J)
- J.name = "Human egg"
- internal_contents -= P
- if("Slime")
- var/obj/structure/closet/secure_closet/egg/slime/J = new /obj/structure/closet/secure_closet/egg/slime(O.loc)
- P.forceMove(J)
- J.name = "Slime egg"
- internal_contents -= P
- if("Egg")
- var/obj/structure/closet/secure_closet/egg/J = new /obj/structure/closet/secure_closet/egg(O.loc)
- P.forceMove(J)
- J.name = "Egg"
- internal_contents -= P
- if("Xenochimera")
- var/obj/structure/closet/secure_closet/egg/scree/J = new /obj/structure/closet/secure_closet/egg/scree(O.loc)
- P.forceMove(J)
- internal_contents -= P
- if("Xenomorph")
- var/obj/structure/closet/secure_closet/egg/xenomorph/J = new /obj/structure/closet/secure_closet/egg/xenomorph(O.loc)
- P.forceMove(J)
- internal_contents -= P
- else
- var/obj/structure/closet/secure_closet/egg/J = new /obj/structure/closet/secure_closet/egg(O.loc)
- P.forceMove(J)
- J.name = "Odd egg" //Something went wrong. Since the default is "egg", they shouldn't see this.
- internal_contents -= P
+ if(O.egg_type in tf_egg_types)
+ egg_path = tf_egg_types[O.egg_type]
+ egg_name = "[O.egg_type] egg"
+
+ var/obj/structure/closet/secure_closet/egg/egg = new egg_path(get_turf(O))
+ P.forceMove(egg)
+ egg.name = egg_name
+ internal_contents -= P
return
@@ -1101,136 +646,18 @@
continue
if(P.absorbed) //If they're absorbed, don't egg them
return
- var/mob/living/carbon/human/O = owner
- if (O.custom_species)
- var/defined_species = O.custom_species
- P << "You lose sensation of your body, feeling only the warmth around you as you're encased in an egg. "
- owner << "Your body shifts as you encase [P] in an egg."
- switch(O.egg_type)
- if("Unathi")
- var/obj/structure/closet/secure_closet/egg/unathi/J = new /obj/structure/closet/secure_closet/egg/unathi(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- for(var/mob/living/M in internal_contents)
- internal_contents -= P
- if("Tajaran")
- var/obj/structure/closet/secure_closet/egg/tajaran/J = new /obj/structure/closet/secure_closet/egg/tajaran(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Akula")
- var/obj/structure/closet/secure_closet/egg/shark/J = new /obj/structure/closet/secure_closet/egg/shark(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Skrell")
- var/obj/structure/closet/secure_closet/egg/skrell/J = new /obj/structure/closet/secure_closet/egg/skrell(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Sergal")
- var/obj/structure/closet/secure_closet/egg/sergal/J = new /obj/structure/closet/secure_closet/egg/sergal(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Human")
- var/obj/structure/closet/secure_closet/egg/human/J = new /obj/structure/closet/secure_closet/egg/human(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Slime")
- var/obj/structure/closet/secure_closet/egg/slime/J = new /obj/structure/closet/secure_closet/egg/slime(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Egg")
- var/obj/structure/closet/secure_closet/egg/J = new /obj/structure/closet/secure_closet/egg(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Xenochimera")
- var/obj/structure/closet/secure_closet/egg/scree/J = new /obj/structure/closet/secure_closet/egg/scree(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- if("Xenomorph")
- var/obj/structure/closet/secure_closet/egg/xenomorph/J = new /obj/structure/closet/secure_closet/egg/xenomorph(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- else
- var/obj/structure/closet/secure_closet/egg/J = new /obj/structure/closet/secure_closet/egg(O.loc)
- P.forceMove(J)
- J.name = "[defined_species] egg"
- J.desc = "This egg has a very unique look to it."
- internal_contents -= P
- else
- P << "You lose sensation of your body, feeling only the warmth around you as you're encased in an egg. "
- owner << "Your body shifts as you encase [P] in an egg."
- switch(O.egg_type)
- if("Unathi")
- var/obj/structure/closet/secure_closet/egg/unathi/J = new /obj/structure/closet/secure_closet/egg/unathi(O.loc)
- P.forceMove(J)
- J.name = "Unathi egg"
- internal_contents -= P
- if("Tajaran")
- var/obj/structure/closet/secure_closet/egg/tajaran/J = new /obj/structure/closet/secure_closet/egg/tajaran(O.loc)
- P.forceMove(J)
- J.name = "Tajaran egg"
- internal_contents -= P
- if("Akula")
- var/obj/structure/closet/secure_closet/egg/shark/J = new /obj/structure/closet/secure_closet/egg/shark(O.loc)
- P.forceMove(J)
- J.name = "Akula egg"
- internal_contents -= P
- if("Skrell")
- var/obj/structure/closet/secure_closet/egg/skrell/J = new /obj/structure/closet/secure_closet/egg/skrell(O.loc)
- P.forceMove(J)
- J.name = "Skrell egg"
- internal_contents -= P
- if("Sergal")
- var/obj/structure/closet/secure_closet/egg/sergal/J = new /obj/structure/closet/secure_closet/egg/sergal(O.loc)
- P.forceMove(J)
- J.name = "Segal egg"
- internal_contents -= P
- if("Human")
- var/obj/structure/closet/secure_closet/egg/human/J = new /obj/structure/closet/secure_closet/egg/human(O.loc)
- P.forceMove(J)
- J.name = "Human egg"
- internal_contents -= P
- if("Slime")
- var/obj/structure/closet/secure_closet/egg/slime/J = new /obj/structure/closet/secure_closet/egg/slime(O.loc)
- P.forceMove(J)
- J.name = "Slime egg"
- internal_contents -= P
- if("Egg")
- var/obj/structure/closet/secure_closet/egg/J = new /obj/structure/closet/secure_closet/egg(O.loc)
- P.forceMove(J)
- J.name = "Egg"
- internal_contents -= P
- if("Xenochimera")
- var/obj/structure/closet/secure_closet/egg/scree/J = new /obj/structure/closet/secure_closet/egg/scree(O.loc)
- P.forceMove(J)
- J.name = "Xenochimera egg"
- internal_contents -= P
- if("Xenomorph")
- var/obj/structure/closet/secure_closet/egg/xenomorph/J = new /obj/structure/closet/secure_closet/egg/xenomorph(O.loc)
- P.forceMove(J)
- J.name = "Xenomorph egg"
- internal_contents -= P
- else
- var/obj/structure/closet/secure_closet/egg/J = new /obj/structure/closet/secure_closet/egg(O.loc)
- P.forceMove(J)
- J.name = "Odd egg" //Something went wrong. Since the default is "egg", they shouldn't see this.
- internal_contents -= P
+ var/mob/living/carbon/human/O = owner
+ P << "You lose sensation of your body, feeling only the warmth around you as you're encased in an egg. "
+ owner << "Your body shifts as you encase [P] in an egg."
+ var/egg_path = /obj/structure/closet/secure_closet/egg
+ var/egg_name = "Odd egg"
+
+ if(O.egg_type in tf_egg_types)
+ egg_path = tf_egg_types[O.egg_type]
+ egg_name = "[O.egg_type] egg"
+
+ var/obj/structure/closet/secure_closet/egg/egg = new egg_path(get_turf(O))
+ P.forceMove(egg)
+ egg.name = egg_name
+ internal_contents -= P
diff --git a/code/modules/vore/eating/vorepanel_vr.dm b/code/modules/vore/eating/vorepanel_vr.dm
index fa918a85ed5..e186b8ec841 100644
--- a/code/modules/vore/eating/vorepanel_vr.dm
+++ b/code/modules/vore/eating/vorepanel_vr.dm
@@ -102,13 +102,19 @@
spanstyle = "color:purple;"
if(DM_TRANSFORM_MALE)
spanstyle = "color:purple;"
+ if(DM_TRANSFORM_HAIR_AND_EYES)
+ spanstyle = "color:purple;"
if(DM_TRANSFORM_FEMALE)
spanstyle = "color:purple;"
if(DM_TRANSFORM_KEEP_GENDER)
spanstyle = "color:purple;"
- if(DM_TRANSFORM_CHANGE_SPECIES)
+ if(DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR)
spanstyle = "color:purple;"
- if(DM_TRANSFORM_CHANGE_SPECIES_EGG)
+ if(DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR_EGG)
+ spanstyle = "color:purple;"
+ if(DM_TRANSFORM_REPLICA)
+ spanstyle = "color:purple;"
+ if(DM_TRANSFORM_REPLICA_EGG)
spanstyle = "color:purple;"
if(DM_TRANSFORM_KEEP_GENDER_EGG)
spanstyle = "color:purple;"
diff --git a/code/modules/vore/fluffstuff/custom_items_vr.dm b/code/modules/vore/fluffstuff/custom_items_vr.dm
index 96d8993f821..1baed38a2f5 100644
--- a/code/modules/vore/fluffstuff/custom_items_vr.dm
+++ b/code/modules/vore/fluffstuff/custom_items_vr.dm
@@ -283,7 +283,6 @@ obj/item/weapon/material/hatchet/tacknife/combatknife/fluff/katarina/handle_shie
item_state = "holochain_mob"
flags = CONDUCT | NOBLOODY
- no_attack_log = 1 //if you want to turn on the attack log for this, comment/delete this line. Orbis.
slot_flags = SLOT_BELT
force = 10
throwforce = 3
@@ -291,6 +290,13 @@ obj/item/weapon/material/hatchet/tacknife/combatknife/fluff/katarina/handle_shie
damtype = HALLOSS
attack_verb = list("flogged", "whipped", "lashed", "disciplined", "chastised", "flayed")
+//General use
+/obj/item/weapon/melee/fluff/holochain/mass
+ desc = "A mass produced version of the original. It has faux leather and an aluminium base, but still stings like the original."
+ force = 8
+ attack_verb = list("flogged", "whipped", "lashed", "flayed")
+
+
// joey4298:Emoticon
/obj/item/device/fluff/id_kit_mime
name = "Mime ID reprinter"
diff --git a/code/modules/vore/resizing/resize_vr.dm b/code/modules/vore/resizing/resize_vr.dm
index ac1ca2f352d..569af0c3f68 100644
--- a/code/modules/vore/resizing/resize_vr.dm
+++ b/code/modules/vore/resizing/resize_vr.dm
@@ -57,16 +57,27 @@ var/const/RESIZE_A_SMALLTINY = (RESIZE_SMALL + RESIZE_TINY) / 2
* Resizes the mob immediately to the desired mod, animating it growing/shrinking.
* It can be used by anything that calls it.
*/
-/mob/living/proc/resize(var/new_size)
- var/matrix/resize = matrix() // Defines the matrix to change the player's size
- resize.Scale(new_size) //Change the size of the matrix
-
- if(new_size >= RESIZE_NORMAL)
- resize.Translate(0, -1 * (1 - new_size) * 16) //Move the player up in the tile so their feet align with the bottom
-
- animate(src, transform = resize, time = 5) //Animate the player resizing
+/mob/living/proc/resize(var/new_size, var/animate = TRUE)
+ if(size_multiplier == new_size)
+ return 1
+ if(animate)
+ var/matrix/resize = matrix() // Defines the matrix to change the player's size
+ resize.Scale(new_size) //Change the size of the matrix
+ resize.Translate(0, 16 * (new_size - 1)) //Move the player up in the tile so their feet align with the bottom
+ animate(src, transform = resize, time = 5) //Animate the player resizing
size_multiplier = new_size //Change size_multiplier so that other items can interact with them
+/mob/living/carbon/human/resize(var/new_size, var/animate = TRUE)
+ if(..()) return 1
+ var/new_y_offset = 32 * (size_multiplier - 1)
+ for(var/I in hud_list)
+ var/image/hud_overlay/HI = I
+ HI.pixel_y = new_y_offset
+
+// Optimize mannequins - never a point to animating or doing HUDs on these.
+/mob/living/carbon/human/dummy/mannequin/resize(var/new_size)
+ size_multiplier = new_size
+
/**
* Verb proc for a command that lets players change their size OOCly.
* Ace was here! Redid this a little so we'd use math for shrinking characters. This is the old code.
diff --git a/code/modules/xenobio2/machinery/injector_computer.dm b/code/modules/xenobio2/machinery/injector_computer.dm
index 6c2dc375e85..9dff9d43fb6 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/html/changelog.html b/html/changelog.html
index beb8c38c321..f4d1c782d53 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 d65fec13f5e..9ade78534ee 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 82235bc8f6a..1d865cb090f 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 5ecdc4dd9ad..efc5c77c0e5 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 f94057e6a40..33ebbe81588 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 f330795d801..9b66e571290 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/LorenLuke - Bodybags.yml b/html/changelogs/LorenLuke - Bodybags.yml
new file mode 100644
index 00000000000..e9dbd374067
--- /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 00000000000..1332c7c5762
--- /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 00000000000..771cce11482
--- /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 00000000000..42135bb9ca2
--- /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 00000000000..ad43257fdc6
--- /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 00000000000..15837f65b81
--- /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 00000000000..ffc7f560374
--- /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 a69e893b6fc..c13a604dba1 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 7407aeefb54..44f920fe30c 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 5fb2c58be46..97e6f04bdc1 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 ff49dc5577c..7b2b705c940 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 44521ed36e3..7c05fbd61d1 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 00f14c373ea..8a4ce2c73ea 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 87a3d3f58f3..ff89b2dcdd9 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 cf3be6425fe..d7028d66a6d 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 1af66a7d089..618d3be5734 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 cf3be6425fe..25cc585aed2 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 5d7180da7cf..b2eb9c72fe8 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 e1a2c1c2ae4..390fdb88ea8 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 9337d5127c0..ef18c7bf49c 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 b6b28fdfbe4..fd3ff5cecaa 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 b1750efa362..c1183a4e939 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 d9e2dfef958..ba02b5a3246 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 dc3456ba672..778ec461bb0 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 b2ff3108ea6..39ed73fc3df 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 5671731aab6..9bb3378c8ef 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 bc469f2eabc..5dde02f1b52 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 89926d3915b..24e00e949f1 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 51cb45dee2e..5ba1e4d90dc 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 6cd3004654e..77f026a3495 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/vorestation.dme b/vorestation.dme
index cb6fd5141c1..bdb4f69af3d 100644
--- a/vorestation.dme
+++ b/vorestation.dme
@@ -952,6 +952,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"
@@ -1561,10 +1562,10 @@
#include "code\modules\lighting\~lighting_undefs.dm"
#include "code\modules\lore_codex\codex.dm"
#include "code\modules\lore_codex\pages.dm"
-#include "code\modules\lore_codex\lore_data\important_locations.dm"
-#include "code\modules\lore_codex\lore_data\orgs.dm"
-#include "code\modules\lore_codex\lore_data\political_parties.dm"
-#include "code\modules\lore_codex\lore_data\species.dm"
+#include "code\modules\lore_codex\lore_data_vr\important_locations.dm"
+#include "code\modules\lore_codex\lore_data_vr\orgs.dm"
+#include "code\modules\lore_codex\lore_data_vr\political_parties.dm"
+#include "code\modules\lore_codex\lore_data_vr\species.dm"
#include "code\modules\maps\dmm_suite.dm"
#include "code\modules\maps\reader.dm"
#include "code\modules\maps\swapmaps.dm"
@@ -1619,6 +1620,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"
@@ -1953,6 +1955,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"
|
|
|
|
|