diff --git a/code/ZAS/Diagnostic.dm b/code/ZAS/Diagnostic.dm
index 10ec2e731b..cbf35d93bd 100644
--- a/code/ZAS/Diagnostic.dm
+++ b/code/ZAS/Diagnostic.dm
@@ -4,7 +4,7 @@ client/proc/ZoneTick()
var/result = air_master.Tick()
if(result)
- src << "Sucessfully Processed."
+ src << "Successfully Processed."
else
src << "Failed to process! ([air_master.tick_progress])"
diff --git a/code/__defines/admin.dm b/code/__defines/admin.dm
index 1e64ed8a1b..5f9ada5e98 100644
--- a/code/__defines/admin.dm
+++ b/code/__defines/admin.dm
@@ -36,7 +36,7 @@
#define R_SOUNDS 0x800
#define R_SPAWN 0x1000
#define R_MOD 0x2000
-#define R_MENTOR 0x4000
+#define R_EVENT 0x4000
#define R_HOST 0x8000 //higher than this will overflow
#define R_MAXPERMISSION 0x8000 // This holds the maximum value for a permission. It is used in iteration, so keep it updated.
\ No newline at end of file
diff --git a/code/__defines/gamemode.dm b/code/__defines/gamemode.dm
index 896553e809..5327931608 100644
--- a/code/__defines/gamemode.dm
+++ b/code/__defines/gamemode.dm
@@ -86,6 +86,7 @@ var/list/be_special_flags = list(
#define MODE_TRAITOR "traitor"
#define MODE_AUTOTRAITOR "autotraitor"
#define MODE_INFILTRATOR "infiltrator"
+#define MODE_THUG "thug"
#define DEFAULT_TELECRYSTAL_AMOUNT 120
diff --git a/code/__defines/items_clothing.dm b/code/__defines/items_clothing.dm
index 0a8598d21f..7c80895a81 100644
--- a/code/__defines/items_clothing.dm
+++ b/code/__defines/items_clothing.dm
@@ -22,6 +22,19 @@
#define SLOT_TIE 0x4000
#define SLOT_HOLSTER 0x8000 //16th bit - higher than this will overflow
+#define ACCESSORY_SLOT_UTILITY "Utility"
+#define ACCESSORY_SLOT_ARMBAND "Armband"
+#define ACCESSORY_SLOT_RANK "Rank"
+#define ACCESSORY_SLOT_DEPT "Department"
+#define ACCESSORY_SLOT_DECOR "Decor"
+#define ACCESSORY_SLOT_MEDAL "Medal"
+#define ACCESSORY_SLOT_INSIGNIA "Insignia"
+#define ACCESSORY_SLOT_ARMOR_C "Chest armor"
+#define ACCESSORY_SLOT_ARMOR_A "Arm armor"
+#define ACCESSORY_SLOT_ARMOR_L "Leg armor"
+#define ACCESSORY_SLOT_ARMOR_S "Armor storage"
+#define ACCESSORY_SLOT_ARMOR_M "Misc armor"
+
// Flags bitmasks.
#define NOBLUDGEON 0x1 // When an item has this it produces no "X has been hit by Y with Z" message with the default handler.
#define CONDUCT 0x2 // Conducts electricity. (metal etc.)
diff --git a/code/_helpers/type2type.dm b/code/_helpers/type2type.dm
index 975e65e3ec..0316e1d186 100644
--- a/code/_helpers/type2type.dm
+++ b/code/_helpers/type2type.dm
@@ -148,7 +148,7 @@
if (rights & R_SOUNDS) . += "[seperator]+SOUND"
if (rights & R_SPAWN) . += "[seperator]+SPAWN"
if (rights & R_MOD) . += "[seperator]+MODERATOR"
- if (rights & R_MENTOR) . += "[seperator]+MENTOR"
+ if (rights & R_EVENT) . += "[seperator]+EVENT"
return .
// Converts a hexadecimal color (e.g. #FF0050) to a list of numbers for red, green, and blue (e.g. list(255,0,80) ).
diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm
index d7091bfb94..505a2745ad 100644
--- a/code/controllers/configuration.dm
+++ b/code/controllers/configuration.dm
@@ -67,7 +67,7 @@ var/list/gamemode_cache = list()
var/kick_inactive = 0 //force disconnect for inactive players after this many minutes, if non-0
var/show_mods = 0
var/show_devs = 0
- var/show_mentors = 0
+ var/show_event_managers = 0
var/mods_can_tempban = 0
var/mods_can_job_tempban = 0
var/mod_tempban_max = 1440
@@ -515,8 +515,8 @@ var/list/gamemode_cache = list()
if("show_devs")
config.show_devs = 1
- if("show_mentors")
- config.show_mentors = 1
+ if("show_event_managers")
+ config.show_event_managers = 1
if("mods_can_tempban")
config.mods_can_tempban = 1
diff --git a/code/datums/ghost_query.dm b/code/datums/ghost_query.dm
index 25fcbd6c7b..c06013105a 100644
--- a/code/datums/ghost_query.dm
+++ b/code/datums/ghost_query.dm
@@ -92,6 +92,13 @@
question = "An Alien has just been created on the facility. Would you like to play as them?"
be_special_flag = BE_ALIEN
+/datum/ghost_query/syndicate_drone
+ role_name = "Mercenary Drone"
+ question = "A team of dubious mercenaries have purchased a powerful drone, and they are attempting to activate it. Would you like to play as the drone?"
+ be_special_flag = BE_AI
+ check_bans = list("AI", "Cyborg", "Syndicate")
+ cutoff_number = 1
+
// Surface stuff.
/datum/ghost_query/lost_drone
role_name = "Lost Drone"
diff --git a/code/datums/outfits/_defines.dm b/code/datums/outfits/_defines.dm
index d105fc0ebc..ae07595c50 100644
--- a/code/datums/outfits/_defines.dm
+++ b/code/datums/outfits/_defines.dm
@@ -1,3 +1,7 @@
#define OUTFIT_HAS_JETPACK 1
#define OUTFIT_HAS_BACKPACK 2
#define OUTFIT_EXTENDED_SURVIVAL 4
+
+#define OUTFIT_JOB_NAME(job_name) ("Job - " + job_name)
+#define OUTFIT_MILITARY(job_name) ("Military Uniform - " + job_name)
+#define OUTFIT_COSTUME(job_name) ("Costume - " + job_name)
\ No newline at end of file
diff --git a/code/datums/outfits/costumes/costume.dm b/code/datums/outfits/costumes/costume.dm
new file mode 100644
index 0000000000..2e6167ee73
--- /dev/null
+++ b/code/datums/outfits/costumes/costume.dm
@@ -0,0 +1,2 @@
+/decl/hierarchy/outfit/costume
+ undress = 0
\ No newline at end of file
diff --git a/code/datums/outfits/costumes/halloween.dm b/code/datums/outfits/costumes/halloween.dm
index d4ad8fa8f9..36659e2141 100644
--- a/code/datums/outfits/costumes/halloween.dm
+++ b/code/datums/outfits/costumes/halloween.dm
@@ -1,5 +1,5 @@
-/decl/hierarchy/outfit/h_masked_killer
- name = "Costume - Masked Killer"
+/decl/hierarchy/outfit/costume/masked_killer
+ name = OUTFIT_COSTUME("Masked Killer")
uniform = /obj/item/clothing/under/overalls
shoes = /obj/item/clothing/shoes/white
gloves = /obj/item/clothing/gloves/sterile/latex
@@ -8,20 +8,20 @@
suit = /obj/item/clothing/suit/storage/apron
r_hand = /obj/item/weapon/material/twohanded/fireaxe/foam
-/decl/hierarchy/outfit/masked_killer/post_equip(var/mob/living/carbon/human/H)
+/decl/hierarchy/outfit/costume/masked_killer/post_equip(var/mob/living/carbon/human/H)
var/victim = get_mannequin(H.ckey)
for(var/obj/item/carried_item in H.get_equipped_items(TRUE))
carried_item.add_blood(victim) //Oh yes, there will be blood.. just not blood from the killer because that's odd. //If I knew how to make fake blood, I would
-/decl/hierarchy/outfit/h_professional
- name = "Costume - Professional"
+/decl/hierarchy/outfit/costume/professional
+ name = OUTFIT_COSTUME("Professional")
uniform = /obj/item/clothing/under/suit_jacket{ starting_accessories=list(/obj/item/clothing/accessory/wcoat) }
shoes = /obj/item/clothing/shoes/black
gloves = /obj/item/clothing/gloves/black
glasses = /obj/item/clothing/glasses/fakesunglasses
l_pocket = /obj/item/toy/sword
-/decl/hierarchy/outfit/h_professional/post_equip(var/mob/living/carbon/human/H)
+/decl/hierarchy/outfit/costume/professional/post_equip(var/mob/living/carbon/human/H)
var/obj/item/weapon/storage/briefcase/new_briefcase = new(H)
for(var/obj/item/briefcase_item in new_briefcase)
qdel(briefcase_item)
@@ -30,9 +30,9 @@
new_briefcase.contents += new /obj/item/clothing/mask/gas/clown_hat
H.equip_to_slot_or_del(new_briefcase, slot_l_hand)
-/decl/hierarchy/outfit/h_horrorcop
- name = "Costume - Slasher Movie Cop"
- uniform = /obj/item/clothing/under/pcrc{ starting_accessories=list(/obj/item/clothing/accessory/holster) }
+/decl/hierarchy/outfit/costume/horrorcop
+ name = OUTFIT_COSTUME("Slasher Movie Cop")
+ uniform = /obj/item/clothing/under/pcrc{ starting_accessories=list(/obj/item/clothing/accessory/holster/hip) }
shoes = /obj/item/clothing/shoes/black
gloves = /obj/item/clothing/gloves/black
glasses = /obj/item/clothing/glasses/fakesunglasses
@@ -40,7 +40,7 @@
head = /obj/item/clothing/head/beret
r_hand = /obj/item/weapon/gun/projectile/revolver/capgun
-/decl/hierarchy/outfit/h_horrorcop/post_equip(var/mob/living/carbon/human/H)
+/decl/hierarchy/outfit/costume/horrorcop/post_equip(var/mob/living/carbon/human/H)
var/obj/item/clothing/under/U = H.w_uniform
if(U.accessories.len)
for(var/obj/item/clothing/accessory/A in U.accessories)
@@ -48,16 +48,16 @@
var/obj/item/clothing/accessory/holster/O = A
O.holster_verb()
-/decl/hierarchy/outfit/h_cowboy
- name = "Costume - Cowboy"
- uniform = /obj/item/clothing/under/pants{ starting_accessories=list(/obj/item/clothing/accessory/holster) }
+/decl/hierarchy/outfit/costume/cowboy
+ name = OUTFIT_COSTUME("Cowboy")
+ uniform = /obj/item/clothing/under/pants{ starting_accessories=list(/obj/item/clothing/accessory/holster/hip) }
shoes = /obj/item/clothing/shoes/boots/cowboy
head = /obj/item/clothing/head/cowboy_hat
gloves = /obj/item/clothing/gloves/fingerless
suit = /obj/item/clothing/accessory/poncho
r_hand = /obj/item/weapon/gun/projectile/revolver/capgun
-/decl/hierarchy/outfit/h_cowboy/post_equip(var/mob/living/carbon/human/H)
+/decl/hierarchy/outfit/costume/cowboy/post_equip(var/mob/living/carbon/human/H)
var/obj/item/clothing/under/U = H.w_uniform
if(U.accessories.len)
for(var/obj/item/clothing/accessory/A in U.accessories)
@@ -65,8 +65,8 @@
var/obj/item/clothing/accessory/holster/O = A
O.holster_verb()
-/decl/hierarchy/outfit/h_lumberjack
- name = "Costume - Lumberjack"
+/decl/hierarchy/outfit/costume/lumberjack
+ name = OUTFIT_COSTUME("Lumberjack")
uniform = /obj/item/clothing/under/pants{ starting_accessories=list(/obj/item/clothing/accessory/sweater/blackneck) }
shoes = /obj/item/clothing/shoes/boots/workboots
head = /obj/item/clothing/head/beanie
@@ -74,8 +74,8 @@
suit = /obj/item/clothing/suit/storage/flannel/red
r_hand = /obj/item/weapon/material/twohanded/fireaxe/foam
-/decl/hierarchy/outfit/h_firefighter
- name = "Costume - Firefighter"
+/decl/hierarchy/outfit/costume/firefighter
+ name = OUTFIT_COSTUME("Firefighter")
uniform = /obj/item/clothing/under/pants
shoes = /obj/item/clothing/shoes/boots/workboots
head = /obj/item/clothing/head/hardhat/red
@@ -83,22 +83,22 @@
suit = /obj/item/clothing/suit/fire/firefighter
mask = /obj/item/clothing/mask/gas
-/decl/hierarchy/outfit/h_highlander
- name = "Costume - Highlander"
+/decl/hierarchy/outfit/costume/highlander
+ name = OUTFIT_COSTUME("Highlander")
uniform = /obj/item/clothing/under/kilt
shoes = /obj/item/clothing/shoes/boots/jackboots
head = /obj/item/clothing/head/beret
r_hand = /obj/item/weapon/material/sword/foam
-/decl/hierarchy/outfit/h_vampire
- name = "Costume - Vampire"
+/decl/hierarchy/outfit/costume/vampire
+ name = OUTFIT_COSTUME("Vampire")
uniform = /obj/item/clothing/under/suit_jacket/really_black
shoes = /obj/item/clothing/shoes/dress
gloves = /obj/item/clothing/gloves/white
r_hand = /obj/item/weapon/bedsheet/red
-/decl/hierarchy/outfit/h_vampire_hunter
- name = "Costume - Vampire Hunter"
+/decl/hierarchy/outfit/costume/vampire_hunter
+ name = OUTFIT_COSTUME("Vampire Hunter")
uniform = /obj/item/clothing/under/pants/tan
suit = /obj/item/clothing/suit/storage/toggle/brown_jacket/sleeveless
shoes = /obj/item/clothing/shoes/boots/jackboots
@@ -106,10 +106,18 @@
l_pocket = /obj/item/toy/crossbow
r_pocket = /obj/item/device/flashlight/color/red
-/decl/hierarchy/outfit/h_pirate
- name = "Costume - Pirate"
+/decl/hierarchy/outfit/costume/pirate
+ name = OUTFIT_COSTUME("Pirate")
uniform = /obj/item/clothing/under/pirate
shoes = /obj/item/clothing/shoes/brown
- head = /obj/item/clothing/head/helmet/space
+ head = /obj/item/clothing/head/pirate
suit = /obj/item/clothing/suit/pirate
- glasses = /obj/item/clothing/glasses/eyepatch
\ No newline at end of file
+ glasses = /obj/item/clothing/glasses/eyepatch
+
+/decl/hierarchy/outfit/costume/whiteout
+ name = OUTFIT_COSTUME("Snow Ghost")
+ uniform = /obj/item/clothing/under/color/white{ starting_accessories=list(/obj/item/clothing/accessory/scarf/white) }
+ shoes = /obj/item/clothing/shoes/white
+ suit = /obj/item/clothing/suit/storage/hooded/chaplain_hoodie/whiteout
+ gloves = /obj/item/clothing/gloves/white
+ mask = /obj/item/clothing/mask/surgical
\ No newline at end of file
diff --git a/code/datums/outfits/jobs/_defines.dm b/code/datums/outfits/jobs/_defines.dm
deleted file mode 100644
index e4bdd05fbb..0000000000
--- a/code/datums/outfits/jobs/_defines.dm
+++ /dev/null
@@ -1,2 +0,0 @@
-#define OUTFIT_JOB_NAME(job_name) ("Job - " + job_name)
-#define OUTFIT_MILITARY(job_name) ("Military Uniform - " + job_name)
\ No newline at end of file
diff --git a/code/datums/outfits/jobs/civilian.dm b/code/datums/outfits/jobs/civilian.dm
index bbd96990fb..ab102d2a8b 100644
--- a/code/datums/outfits/jobs/civilian.dm
+++ b/code/datums/outfits/jobs/civilian.dm
@@ -53,9 +53,9 @@
r_pocket = /obj/item/device/analyzer/plant_analyzer
backpack = /obj/item/weapon/storage/backpack/hydroponics
satchel_one = /obj/item/weapon/storage/backpack/satchel/hyd
+ messenger_bag = /obj/item/weapon/storage/backpack/messenger/hyd
id_type = /obj/item/weapon/card/id/civilian/botanist
pda_type = /obj/item/device/pda/botanist
- messenger_bag = /obj/item/weapon/storage/backpack/messenger/hyd
/decl/hierarchy/outfit/job/service/janitor
name = OUTFIT_JOB_NAME("Janitor")
@@ -77,7 +77,7 @@
suit = /obj/item/clothing/suit/storage/toggle/internalaffairs
shoes = /obj/item/clothing/shoes/brown
glasses = /obj/item/clothing/glasses/sunglasses/big
- l_hand = /obj/item/weapon/storage/briefcase
+ l_hand = /obj/item/weapon/clipboard
id_type = /obj/item/weapon/card/id/civilian/internal_affairs_agent
pda_type = /obj/item/device/pda/lawyer
diff --git a/code/datums/outfits/jobs/command.dm b/code/datums/outfits/jobs/command.dm
index 5fb5530ee4..8709bb9a79 100644
--- a/code/datums/outfits/jobs/command.dm
+++ b/code/datums/outfits/jobs/command.dm
@@ -1,16 +1,14 @@
/decl/hierarchy/outfit/job/captain
name = OUTFIT_JOB_NAME("Captain")
- head = /obj/item/clothing/head/caphat
glasses = /obj/item/clothing/glasses/sunglasses
uniform = /obj/item/clothing/under/rank/captain
l_ear = /obj/item/device/radio/headset/heads/captain
shoes = /obj/item/clothing/shoes/brown
backpack = /obj/item/weapon/storage/backpack/captain
satchel_one = /obj/item/weapon/storage/backpack/satchel/cap
+ messenger_bag = /obj/item/weapon/storage/backpack/messenger/com
id_type = /obj/item/weapon/card/id/gold/captain
pda_type = /obj/item/device/pda/captain
- backpack_contents = list(/obj/item/weapon/storage/box/ids = 1)
- messenger_bag = /obj/item/weapon/storage/backpack/messenger/com
/decl/hierarchy/outfit/job/captain/post_equip(var/mob/living/carbon/human/H)
..()
@@ -32,7 +30,6 @@
shoes = /obj/item/clothing/shoes/brown
id_type = /obj/item/weapon/card/id/silver/hop
pda_type = /obj/item/device/pda/heads/hop
- backpack_contents = list(/obj/item/weapon/storage/box/ids = 1)
/decl/hierarchy/outfit/job/secretary
name = OUTFIT_JOB_NAME("Command Secretary")
@@ -40,7 +37,7 @@
shoes = /obj/item/clothing/shoes/brown
id_type = /obj/item/weapon/card/id/silver/secretary
pda_type = /obj/item/device/pda/heads/hop
- r_hand = /obj/item/weapon/storage/briefcase
+ r_hand = /obj/item/weapon/clipboard
/decl/hierarchy/outfit/job/secretary/pre_equip(mob/living/carbon/human/H)
..()
diff --git a/code/datums/outfits/jobs/engineering.dm b/code/datums/outfits/jobs/engineering.dm
index 1eda9d5de0..3804bcb4c0 100644
--- a/code/datums/outfits/jobs/engineering.dm
+++ b/code/datums/outfits/jobs/engineering.dm
@@ -3,6 +3,7 @@
belt = /obj/item/weapon/storage/belt/utility/full
l_ear = /obj/item/device/radio/headset/headset_eng
shoes = /obj/item/clothing/shoes/boots/workboots
+ r_pocket = /obj/item/device/t_scanner
backpack = /obj/item/weapon/storage/backpack/industrial
satchel_one = /obj/item/weapon/storage/backpack/satchel/eng
messenger_bag = /obj/item/weapon/storage/backpack/messenger/engi
@@ -22,7 +23,6 @@
name = OUTFIT_JOB_NAME("Engineer")
head = /obj/item/clothing/head/hardhat
uniform = /obj/item/clothing/under/rank/engineer
- r_pocket = /obj/item/device/t_scanner
id_type = /obj/item/weapon/card/id/engineering/engineer
pda_type = /obj/item/device/pda/engineering
diff --git a/code/datums/outfits/jobs/medical.dm b/code/datums/outfits/jobs/medical.dm
index 2b3c2c2407..3b227a2612 100644
--- a/code/datums/outfits/jobs/medical.dm
+++ b/code/datums/outfits/jobs/medical.dm
@@ -103,3 +103,4 @@
/decl/hierarchy/outfit/job/medical/paramedic/emt
name = OUTFIT_JOB_NAME("Emergency Medical Technician")
uniform = /obj/item/clothing/under/rank/medical/paramedic
+ suit = /obj/item/clothing/suit/storage/toggle/labcoat/emt
diff --git a/code/datums/outfits/jobs/science.dm b/code/datums/outfits/jobs/science.dm
index 80ecbfb54a..abca107024 100644
--- a/code/datums/outfits/jobs/science.dm
+++ b/code/datums/outfits/jobs/science.dm
@@ -31,7 +31,7 @@
/decl/hierarchy/outfit/job/science/roboticist
name = OUTFIT_JOB_NAME("Roboticist")
- uniform = /obj/item/clothing/under/rank/scientist
+ uniform = /obj/item/clothing/under/rank/roboticist
shoes = /obj/item/clothing/shoes/black
belt = /obj/item/weapon/storage/belt/utility/full
id_type = /obj/item/weapon/card/id/science/roboticist
diff --git a/code/datums/outfits/jobs/security.dm b/code/datums/outfits/jobs/security.dm
index d96954a8f0..f0a44cd416 100644
--- a/code/datums/outfits/jobs/security.dm
+++ b/code/datums/outfits/jobs/security.dm
@@ -15,7 +15,6 @@
uniform = /obj/item/clothing/under/rank/head_of_security
id_type = /obj/item/weapon/card/id/security/head
pda_type = /obj/item/device/pda/heads/hos
- backpack_contents = list(/obj/item/weapon/handcuffs = 1)
/decl/hierarchy/outfit/job/security/warden
name = OUTFIT_JOB_NAME("Warden")
@@ -47,6 +46,5 @@
name = OUTFIT_JOB_NAME("Security Officer")
uniform = /obj/item/clothing/under/rank/security
l_pocket = /obj/item/device/flash
- r_pocket = /obj/item/weapon/handcuffs
id_type = /obj/item/weapon/card/id/security/officer
pda_type = /obj/item/device/pda/security
diff --git a/code/datums/outfits/outfit.dm b/code/datums/outfits/outfit.dm
index 93ea518df1..e69e9eb705 100644
--- a/code/datums/outfits/outfit.dm
+++ b/code/datums/outfits/outfit.dm
@@ -57,6 +57,8 @@ var/list/outfits_decls_by_type_
var/flags // Specific flags
+ var/undress = 1 //Does the outfit undress the mob upon equp?
+
/decl/hierarchy/outfit/New()
..()
diff --git a/code/datums/supplypacks/contraband.dm b/code/datums/supplypacks/contraband.dm
index c200e2edda..cbe52301df 100644
--- a/code/datums/supplypacks/contraband.dm
+++ b/code/datums/supplypacks/contraband.dm
@@ -52,4 +52,53 @@
cost = 50
contraband = 1
containertype = /obj/structure/closet/crate/secure/weapon
- containername = "Weapons crate"
\ No newline at end of file
+ containername = "Weapons crate"
+
+/datum/supply_packs/randomised/misc/telecrate //you get something awesome, a couple of decent things, and a few weak/filler things
+ name = "ERR_NULL_ENTRY" //null crate! also dream maker is hell,
+ num_contained = 1
+ contains = list(
+ list( //the operator,
+ /obj/item/weapon/gun/projectile/shotgun/pump/combat,
+ /obj/item/clothing/suit/storage/vest/heavy/merc,
+ /obj/item/clothing/glasses/night,
+ /obj/item/weapon/storage/box/anti_photons,
+ /obj/item/ammo_magazine/clip/c12g/pellet, /obj/item/ammo_magazine/clip/c12g
+ ),
+ list( //the doc,
+ /obj/item/weapon/storage/firstaid/combat,
+ /obj/item/weapon/gun/projectile/dartgun, /obj/item/weapon/reagent_containers/hypospray,
+ /obj/item/weapon/reagent_containers/glass/bottle/chloralhydrate,
+ /obj/item/weapon/reagent_containers/glass/bottle/cyanide,
+ /obj/item/ammo_magazine/chemdart
+ ),
+ list( //the sapper,
+ /obj/item/weapon/melee/energy/sword/ionic_rapier,
+ /obj/item/weapon/storage/box/syndie_kit/space, //doesn't matter what species you are,
+ /obj/item/weapon/storage/box/syndie_kit/demolitions,
+ /obj/item/device/multitool/ai_detector,
+ /obj/item/weapon/plastique,
+ /obj/item/weapon/storage/toolbox/syndicate
+ ),
+ list( //the infiltrator,
+ /obj/item/weapon/gun/projectile/silenced,
+ /obj/item/device/chameleon,
+ /obj/item/weapon/storage/box/syndie_kit/chameleon,
+ /obj/item/device/encryptionkey/syndicate,
+ /obj/item/weapon/card/id/syndicate,
+ /obj/item/clothing/mask/gas/voice
+ ),
+ list( //the professional,
+ /obj/item/weapon/gun/projectile/silenced,
+ /obj/item/weapon/gun/energy/ionrifle/pistol,
+ /obj/item/clothing/glasses/thermal/syndi,
+ /obj/item/weapon/card/emag,
+ /obj/item/ammo_magazine/m45/ap,
+ /obj/item/weapon/material/hatchet/tacknife/combatknife,
+ /obj/item/clothing/mask/balaclava
+ )
+ )
+ cost = 250 //more than a hat crate!,
+ contraband = 1
+ containertype = /obj/structure/largecrate
+ containername = "Suspicious crate"
\ No newline at end of file
diff --git a/code/datums/supplypacks/munitions.dm b/code/datums/supplypacks/munitions.dm
index 6c3b7cab73..a3184bf848 100644
--- a/code/datums/supplypacks/munitions.dm
+++ b/code/datums/supplypacks/munitions.dm
@@ -86,7 +86,7 @@
name = "Electromagnetic weapons crate"
contains = list(
/obj/item/weapon/gun/energy/ionrifle = 2,
- /obj/item/weapon/storage/box/emps
+ /obj/item/weapon/storage/box/empslite
)
cost = 50
containertype = /obj/structure/closet/crate/secure
@@ -97,7 +97,7 @@
name = "Electromagnetic pistols crate"
contains = list(
/obj/item/weapon/gun/energy/ionrifle/pistol = 2,
- /obj/item/weapon/storage/box/emps
+ /obj/item/weapon/storage/box/empslite
)
cost = 30
containertype = /obj/structure/closet/crate/secure
diff --git a/code/datums/uplink/backup.dm b/code/datums/uplink/backup.dm
new file mode 100644
index 0000000000..40f2a468f6
--- /dev/null
+++ b/code/datums/uplink/backup.dm
@@ -0,0 +1,35 @@
+/*********
+* Back up *
+**********/
+/datum/uplink_item/item/backup
+ category = /datum/uplink_category/backup
+ blacklisted = 1
+
+/datum/uplink_item/item/backup/syndicate_drone_protector
+ name = "Drone (Protector)"
+ desc = "A miniature teleport which will bring a powerful and loyal drone to you. \
+ This type comes with a directional shield projector, a supressive fire energy weapon, \
+ a stunbaton, handcuffs, an agent ID, energy sword, pinpointer, and a jetpack."
+ item_cost = DEFAULT_TELECRYSTAL_AMOUNT * 1.5
+ antag_roles = list("mercenary")
+ path = /obj/item/weapon/antag_spawner/syndicate_drone/protector
+
+/datum/uplink_item/item/backup/syndicate_drone_combat_medic
+ name = "Drone (Combat Medic)"
+ desc = "A miniature teleport which will bring a powerful and loyal drone to you. \
+ This type comes with standard medical equipment, full set of surgery tools, \
+ a powerful hypospray that can create many potent chemicals, an agent ID, energy \
+ sword, pinpointer, and a jetpack."
+ item_cost = DEFAULT_TELECRYSTAL_AMOUNT * 1.5
+ antag_roles = list("mercenary")
+ path = /obj/item/weapon/antag_spawner/syndicate_drone/combat_medic
+
+/datum/uplink_item/item/backup/syndicate_drone_mechanist
+ name = "Drone (Mechanist)"
+ desc = "A miniature teleport which will bring a powerful and loyal drone to you. \
+ This type comes with a full set of tools, an RCD, the ability to unlock other bound synthetics, \
+ a cryptographic sequencer, an AI detector, the ability to analyze and repair full-body prosthetics, \
+ a set of construction materials, an ionic rapier, an agent ID, energy sword, pinpointer, and a jetpack."
+ item_cost = DEFAULT_TELECRYSTAL_AMOUNT * 1.5
+ antag_roles = list("mercenary")
+ path = /obj/item/weapon/antag_spawner/syndicate_drone/mechanist
\ No newline at end of file
diff --git a/code/datums/uplink/uplink_categories.dm b/code/datums/uplink/uplink_categories.dm
index 7c65747f0b..2776085594 100644
--- a/code/datums/uplink/uplink_categories.dm
+++ b/code/datums/uplink/uplink_categories.dm
@@ -49,4 +49,7 @@ datum/uplink_category/ammunition
name = "Highly Visible and Dangerous Weapons"
/datum/uplink_category/telecrystals
- name = "Telecrystals"
\ No newline at end of file
+ name = "Telecrystals"
+
+/datum/uplink_category/backup
+ name = "Backup"
\ No newline at end of file
diff --git a/code/datums/uplink/visible_weapons.dm b/code/datums/uplink/visible_weapons.dm
index f7d79c5b6a..ce4e205f64 100644
--- a/code/datums/uplink/visible_weapons.dm
+++ b/code/datums/uplink/visible_weapons.dm
@@ -112,6 +112,12 @@
path = /obj/item/weapon/storage/secure/briefcase/rifle
antag_roles = list("traitor", "autotraitor", "infiltrator")
+/datum/uplink_item/item/visible_weapons/fuelrodcannon
+ name = "Fuel-Rod Cannon"
+ desc = "An incredibly bulky weapon whose devastating firepower is only matched by its severe need for expensive, and rare, ammunition. This device will likely require extra preparation to use, you are warned."
+ item_cost = DEFAULT_TELECRYSTAL_AMOUNT
+ path = /obj/item/weapon/storage/secure/briefcase/fuelrod
+
/datum/uplink_item/item/visible_weapons/tommygun
name = "Tommygun (.45)" // We're keeping this because it's CLASSY. -Spades
item_cost = 60
diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm
index 69965ef7f0..4cd21a5527 100644
--- a/code/defines/obj/weapon.dm
+++ b/code/defines/obj/weapon.dm
@@ -78,7 +78,7 @@
/obj/item/weapon/cane
name = "cane"
- desc = "A cane used by a true gentlemen. Or a clown."
+ desc = "A cane used by a true gentleman."
icon = 'icons/obj/weapons.dmi'
icon_state = "cane"
item_icons = list(
@@ -88,7 +88,7 @@
flags = CONDUCT
force = 5.0
throwforce = 7.0
- w_class = ITEMSIZE_SMALL
+ w_class = ITEMSIZE_NORMAL
matter = list(DEFAULT_WALL_MATERIAL = 50)
attack_verb = list("bludgeoned", "whacked", "disciplined", "thrashed")
@@ -218,7 +218,7 @@
/obj/item/weapon/SWF_uplink
name = "station-bounced radio"
- desc = "used to comunicate it appears."
+ desc = "Used to communicate, it appears."
icon = 'icons/obj/radio.dmi'
icon_state = "radio"
var/temp = null
@@ -607,7 +607,7 @@
/obj/item/weapon/ectoplasm
name = "ectoplasm"
- desc = "spooky"
+ desc = "Spooky!"
gender = PLURAL
icon = 'icons/obj/wizard.dmi'
icon_state = "ectoplasm"
@@ -643,4 +643,4 @@
icon = 'icons/obj/stock_parts.dmi'
icon_state = "spring"
origin_tech = list(TECH_ENGINEERING = 1)
- matter = list(DEFAULT_WALL_MATERIAL = 40)
\ No newline at end of file
+ matter = list(DEFAULT_WALL_MATERIAL = 40)
diff --git a/code/game/antagonist/station/thug.dm b/code/game/antagonist/station/thug.dm
new file mode 100644
index 0000000000..54f5f83663
--- /dev/null
+++ b/code/game/antagonist/station/thug.dm
@@ -0,0 +1,17 @@
+var/datum/antagonist/thug/thugs
+
+/datum/antagonist/THUG
+ id = MODE_THUG
+ role_type = BE_RENEGADE
+ role_text = "Thug"
+ role_text_plural = "Thugs"
+ bantype = "renegade"
+ restricted_jobs = list("AI", "Cyborg")
+ welcome_text = "Sometimes, people just need to get messed up. Luckily, that's what you're here to do."
+ antag_text = "You are a minor antagonist! Within the server rules, do whatever it is \
+ that you came to the station to do, be it violence, theft, or just extreme self-defense. \
+ Try to make sure other players have fun! If you are confused or at a loss, always adminhelp, \
+ and before taking extreme actions, please try to also contact the administration! \
+ Think through your actions and make the roleplay immersive! Please remember all \
+ rules aside from those without explicit exceptions apply to antagonists."
+ flags = ANTAG_SUSPICIOUS | ANTAG_IMPLANT_IMMUNE | ANTAG_RANDSPAWN | ANTAG_VOTABLE
\ No newline at end of file
diff --git a/code/game/gamemodes/nuclear/pinpointer.dm b/code/game/gamemodes/nuclear/pinpointer.dm
index 5d67b6eece..bd140c3061 100644
--- a/code/game/gamemodes/nuclear/pinpointer.dm
+++ b/code/game/gamemodes/nuclear/pinpointer.dm
@@ -9,6 +9,7 @@
throw_speed = 4
throw_range = 20
matter = list(DEFAULT_WALL_MATERIAL = 500)
+ preserve_item = 1
var/obj/item/weapon/disk/nuclear/the_disk = null
var/active = 0
@@ -263,3 +264,57 @@
icon_state = "pinonfar"
spawn(5) .()
+
+
+// This one only points to the ship. Useful if there is no nuking to occur today.
+/obj/item/weapon/pinpointer/shuttle
+ var/shuttle_comp_id = null
+ var/obj/machinery/computer/shuttle_control/our_shuttle = null
+
+/obj/item/weapon/pinpointer/shuttle/attack_self(mob/user as mob)
+ if(!active)
+ active = TRUE
+ find_shuttle()
+ to_chat(user, "Shuttle Locator active.")
+ else
+ active = FALSE
+ icon_state = "pinoff"
+ to_chat(user, "You deactivate the pinpointer.")
+
+/obj/item/weapon/pinpointer/shuttle/proc/find_shuttle()
+ if(!active)
+ return
+
+ if(!our_shuttle)
+ for(var/obj/machinery/computer/shuttle_control/S in machines)
+ if(S.shuttle_tag == shuttle_comp_id) // Shuttle tags are used so that it will work if the computer path changes, as it does on the southern cross map.
+ our_shuttle = S
+ break
+
+ if(!our_shuttle)
+ icon_state = "pinonnull"
+ return
+
+ if(loc.z != our_shuttle.z) //If you are on a different z-level from the shuttle
+ icon_state = "pinonnull"
+ else
+ set_dir(get_dir(src, our_shuttle))
+ switch(get_dist(src, our_shuttle))
+ if(0)
+ icon_state = "pinondirect"
+ if(1 to 8)
+ icon_state = "pinonclose"
+ if(9 to 16)
+ icon_state = "pinonmedium"
+ if(16 to INFINITY)
+ icon_state = "pinonfar"
+
+ spawn(5)
+ .()
+
+
+/obj/item/weapon/pinpointer/shuttle/merc
+ shuttle_comp_id = "Mercenary"
+
+/obj/item/weapon/pinpointer/shuttle/heist
+ shuttle_comp_id = "Skipjack"
\ No newline at end of file
diff --git a/code/game/gamemodes/technomancer/assistance/assistance.dm b/code/game/gamemodes/technomancer/assistance/assistance.dm
index db9e98a266..0e550a08b2 100644
--- a/code/game/gamemodes/technomancer/assistance/assistance.dm
+++ b/code/game/gamemodes/technomancer/assistance/assistance.dm
@@ -10,90 +10,6 @@
cost = 300
obj_path = /obj/item/weapon/antag_spawner/technomancer_apprentice
-/obj/item/weapon/antag_spawner
- w_class = ITEMSIZE_TINY
- var/used = 0
- var/ghost_query_type = null
-
-/obj/item/weapon/antag_spawner/proc/spawn_antag(client/C, turf/T)
- return
-
-/obj/item/weapon/antag_spawner/proc/equip_antag(mob/target)
- return
-
-/obj/item/weapon/antag_spawner/proc/request_player()
- if(!ghost_query_type)
- return
-
- var/datum/ghost_query/Q = new ghost_query_type()
- var/list/winner = Q.query()
- if(winner.len)
- var/mob/observer/dead/D = winner[1]
- spawn_antag(D.client, get_turf(src))
- else
- reset_search()
- return
-
-/obj/item/weapon/antag_spawner/proc/reset_search()
- return
-
-/obj/item/weapon/antag_spawner/technomancer_apprentice
- name = "apprentice teleporter"
- desc = "A teleportation device, which will bring a less potent manipulator of space to you."
- icon = 'icons/obj/objects.dmi'
- icon_state = "oldshieldoff"
- ghost_query_type = /datum/ghost_query/apprentice
- var/searching = 0
- var/datum/effect/effect/system/spark_spread/sparks
-
-/obj/item/weapon/antag_spawner/technomancer_apprentice/New()
- ..()
- sparks = new /datum/effect/effect/system/spark_spread()
- sparks.set_up(5, 0, src)
- sparks.attach(loc)
-
-/obj/item/weapon/antag_spawner/technomancer_apprentice/Destroy()
- qdel(sparks)
- return ..()
-
-/obj/item/weapon/antag_spawner/technomancer_apprentice/attack_self(mob/user)
- user << "Teleporter attempting to lock on to your apprentice."
- request_player()
-
-/obj/item/weapon/antag_spawner/technomancer_apprentice/request_player()
- searching = 1
- icon_state = "oldshieldon"
- ..()
-
-/obj/item/weapon/antag_spawner/technomancer_apprentice/reset_search()
- searching = 0
- if(!used)
- icon_state = "oldshieldoff"
- visible_message("The teleporter failed to find the apprentice. Perhaps another attempt could be made later?")
-
-/obj/item/weapon/antag_spawner/technomancer_apprentice/spawn_antag(client/C, turf/T)
- sparks.start()
- var/mob/living/carbon/human/H = new/mob/living/carbon/human(T)
- C.prefs.copy_to(H)
- H.key = C.key
-
- H << "You are the Technomancer's apprentice! Your goal is to assist them in their mission at the [station_name()]."
- H << "Your service has not gone unrewarded, however. Studying under them, you have learned how to use a Manipulation Core \
- of your own. You also have a catalog, to purchase your own functions and equipment as you see fit."
- H << "It would be wise to speak to your master, and learn what their plans are for today."
-
- spawn(1)
- technomancers.add_antagonist(H.mind, 0, 1, 0, 0, 0)
- equip_antag(H)
- used = 1
- qdel(src)
-
-
-/obj/item/weapon/antag_spawner/technomancer_apprentice/equip_antag(mob/technomancer_mob)
- var/datum/antagonist/technomancer/antag_datum = all_antag_types[MODE_TECHNOMANCER]
- antag_datum.equip_apprentice(technomancer_mob)
-
-
/*
// For when no one wants to play support.
/datum/technomancer/assistance/golem
diff --git a/code/game/jobs/job/civilian_chaplain.dm b/code/game/jobs/job/civilian_chaplain.dm
index 95809c63f4..88a448c571 100644
--- a/code/game/jobs/job/civilian_chaplain.dm
+++ b/code/game/jobs/job/civilian_chaplain.dm
@@ -28,17 +28,21 @@
return
spawn(0)
- var/religion_name = "Christianity"
- var/new_religion = sanitize(input(H, "You are the crew services officer. Would you like to change your religion? Default is Christianity, in SPACE.", "Name change", religion_name), MAX_NAME_LEN)
+ var/religion_name = "Unitarianism"
+ var/new_religion = sanitize(input(H, "You are the crew services officer. Would you like to change your religion? Default is Unitarianism", "Name change", religion_name), MAX_NAME_LEN)
if (!new_religion)
new_religion = religion_name
switch(lowertext(new_religion))
+ if("unitarianism")
+ B.name = "The Talmudic Quran"
if("christianity")
B.name = pick("The Holy Bible","The Dead Sea Scrolls")
+ if("Judaism")
+ B.name = "The Torah"
if("satanism")
- B.name = "The Unholy Bible"
- if("cthulu")
+ B.name = "The Satanic Bible"
+ if("cthulhu")
B.name = "The Necronomicon"
if("islam")
B.name = "Quran"
@@ -52,20 +56,21 @@
B.name = "Toolbox Manifesto"
if("homosexuality")
B.name = "Guys Gone Wild"
- //if("lol", "wtf", "gay", "penis", "ass", "poo", "badmin", "shitmin", "deadmin", "cock", "cocks")
- // B.name = pick("Woodys Got Wood: The Aftermath", "War of the Cocks", "Sweet Bro and Hella Jef: Expanded Edition")
- // H.setBrainLoss(100) // starts off retarded as fuck
if("science")
B.name = pick("Principle of Relativity", "Quantum Enigma: Physics Encounters Consciousness", "Programming the Universe", "Quantum Physics and Theology", "String Theory for Dummies", "How To: Build Your Own Warp Drive", "The Mysteries of Bluespace", "Playing God: Collector's Edition")
+ if("capitalism")
+ B.name = "Wealth of Nations"
+ if("communism")
+ B.name = "The Communist Manifesto"
else
B.name = "The Holy Book of [new_religion]"
feedback_set_details("religion_name","[new_religion]")
spawn(1)
- var/deity_name = "Space Jesus"
- var/new_deity = sanitize(input(H, "Would you like to change your deity? Default is Space Jesus.", "Name change", deity_name), MAX_NAME_LEN)
+ var/deity_name = "Hashem"
+ var/new_deity = sanitize(input(H, "Would you like to change your deity? Default is Hashem", "Name change", deity_name), MAX_NAME_LEN)
- if ((length(new_deity) == 0) || (new_deity == "Space Jesus") )
+ if ((length(new_deity) == 0) || (new_deity == "Hashem") )
new_deity = deity_name
B.deity_name = new_deity
diff --git a/code/game/jobs/job/medical.dm b/code/game/jobs/job/medical.dm
index a5e6498dec..a8e5d6a3fc 100644
--- a/code/game/jobs/job/medical.dm
+++ b/code/game/jobs/job/medical.dm
@@ -103,7 +103,7 @@
outfit_type = /decl/hierarchy/outfit/job/medical/psychiatrist
alt_titles = list("Psychologist" = /decl/hierarchy/outfit/job/medical/psychiatrist/psychologist)
-/datum/job/Paramedic
+/datum/job/paramedic
title = "Paramedic"
flag = PARAMEDIC
department = "Medical"
diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm
index 27a84b8c31..94dabbcd2e 100644
--- a/code/game/jobs/job_controller.dm
+++ b/code/game/jobs/job_controller.dm
@@ -636,7 +636,7 @@ var/global/datum/controller/occupations/job_master
else
spawnpos = spawntypes[H.client.prefs.spawnpoint]
- if(spawnpos && istype(spawnpos) && spawnpos.turfs.len) // VOREStation Edit - Fix runtime if no landmarks exist for a spawntype
+ if(spawnpos && istype(spawnpos) && spawnpos.turfs.len)
if(spawnpos.check_job_spawning(rank))
H.forceMove(spawnpos.get_spawn_position())
. = spawnpos.msg
diff --git a/code/game/jobs/jobs.dm b/code/game/jobs/jobs.dm
index 72295fe01d..2a225228bc 100644
--- a/code/game/jobs/jobs.dm
+++ b/code/game/jobs/jobs.dm
@@ -97,7 +97,7 @@ var/list/cargo_positions = list(
var/list/civilian_positions = list(
"Head of Personnel",
"Bartender",
- "Gardener",
+ "Botanist",
"Chef",
"Janitor",
"Librarian",
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index 5bddc29499..ff32e65c07 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -172,6 +172,15 @@
//Grow clones to maturity then kick them out. FREELOADERS
/obj/machinery/clonepod/process()
+ var/visible_message = 0
+ for(var/obj/item/weapon/reagent_containers/food/snacks/meat in range(1, src))
+ qdel(meat)
+ biomass += 50
+ visible_message = 1 // Prevent chatspam when multiple meat are near
+
+ if(visible_message)
+ visible_message("[src] sucks in and processes the nearby biomass.")
+
if(stat & NOPOWER) //Autoeject if power is lost
if(occupant)
locked = 0
@@ -520,4 +529,4 @@
/* EMP grenade/spell effect
if(istype(A, /obj/machinery/clonepod))
A:malfunction()
-*/
\ No newline at end of file
+*/
diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm
index 838350508f..473430c74c 100644
--- a/code/game/machinery/cryopod.dm
+++ b/code/game/machinery/cryopod.dm
@@ -228,24 +228,6 @@
var/last_no_computer_message = 0
var/applies_stasis = 1
- // These items are preserved when the process() despawn proc occurs.
- var/list/preserve_items = list(
- /obj/item/weapon/hand_tele,
- /obj/item/weapon/card/id/captains_spare,
- /obj/item/device/aicard,
- /obj/item/device/paicard,
- /obj/item/weapon/gun,
- /obj/item/weapon/cell/device,
- /obj/item/ammo_magazine,
- /obj/item/ammo_casing,
- /obj/item/weapon/pinpointer,
- /obj/item/clothing/suit,
- /obj/item/clothing/shoes/magboots,
- /obj/item/blueprints,
- /obj/item/clothing/head/helmet/space,
- /obj/item/weapon/storage/internal
- )
-
/obj/machinery/cryopod/robot
name = "robotic storage unit"
desc = "A storage unit for robots."
@@ -413,12 +395,10 @@
for(var/obj/item/W in items)
- var/preserve = null
+ var/preserve = 0
- for(var/T in preserve_items)
- if(istype(W,T))
- preserve = 1
- break
+ if(W.preserve_item)
+ preserve = 1
if(istype(W,/obj/item/weapon/implant/health))
for(var/obj/machinery/computer/cloning/com in world)
diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm
index 5c57b81ecb..c47d3738a0 100644
--- a/code/game/machinery/recharger.dm
+++ b/code/game/machinery/recharger.dm
@@ -120,6 +120,17 @@ obj/machinery/recharger
update_use_power(1)
return
+ if(istype(charging, /obj/item/weapon/gun/magnetic))
+ var/obj/item/weapon/gun/magnetic/M = charging
+ if(!M.cell.fully_charged())
+ icon_state = icon_state_charging
+ M.cell.give(active_power_usage*CELLRATE)
+ update_use_power(2)
+ else
+ icon_state = icon_state_charged
+ update_use_power(1)
+ return
+
if(istype(charging, /obj/item/weapon/melee/baton))
var/obj/item/weapon/melee/baton/B = charging
if(B.bcell)
@@ -239,7 +250,7 @@ obj/machinery/recharger
icon = 'icons/obj/stationobjs.dmi'
icon_state = "wrecharger0"
active_power_usage = 25000 //25 kW , It's more specialized than the standalone recharger (guns, batons, and flashlights only) so make it more powerful
- allowed_devices = list(/obj/item/weapon/gun/energy, /obj/item/weapon/melee/baton, /obj/item/device/flashlight, /obj/item/weapon/cell/device)
+ allowed_devices = list(/obj/item/weapon/gun/energy, /obj/item/weapon/gun/magnetic, /obj/item/weapon/melee/baton, /obj/item/device/flashlight, /obj/item/weapon/cell/device)
icon_state_charged = "wrecharger2"
icon_state_charging = "wrecharger1"
icon_state_idle = "wrecharger0"
diff --git a/code/game/mecha/mech_prosthetics.dm b/code/game/mecha/mech_prosthetics.dm
index d8ee027658..87da5760ce 100644
--- a/code/game/mecha/mech_prosthetics.dm
+++ b/code/game/mecha/mech_prosthetics.dm
@@ -239,7 +239,7 @@
/obj/machinery/pros_fabricator/proc/can_build(var/datum/design/D)
for(var/M in D.materials)
- if(materials[M] < D.materials[M])
+ if(materials[M] < (D.materials[M] * mat_efficiency))
return 0
return 1
diff --git a/code/game/objects/effects/decals/Cleanable/fuel.dm b/code/game/objects/effects/decals/Cleanable/fuel.dm
index 85e68c31af..d9e9baabf6 100644
--- a/code/game/objects/effects/decals/Cleanable/fuel.dm
+++ b/code/game/objects/effects/decals/Cleanable/fuel.dm
@@ -52,11 +52,17 @@
/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel/New(newLoc, amt = 1, d = 0)
set_dir(d) //Setting this direction means you won't get torched by your own flamethrower.
+ if(istype(newLoc, /turf/simulated))
+ var/turf/simulated/T = newLoc
+ T.hotspot_expose((T20C*2) + 380,500) //Ignite the fuel.
. = ..()
/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel/Spread()
//The spread for flamethrower fuel is much more precise, to create a wide fire pattern.
- if(amount < 0.1) return
+ if(amount <= 0.1)
+ if(amount < 0.025) //Hopefully stops fuel spreading into unburnable puddles.
+ qdel(src)
+ return
var/turf/simulated/S = loc
if(!istype(S)) return
@@ -65,7 +71,12 @@
if(locate(/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel) in O)
continue
if(O.CanPass(null, S, 0, 0) && S.CanPass(null, O, 0, 0))
- new/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel(O,amount*0.25,d)
+ var/new_pool_amount = amount * 0.25
+ if(new_pool_amount > 0.1)
+ var/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel/F = new(O, new_pool_amount, d)
+ if(F.amount < 0.025) //Safety.
+ qdel(F)
+ return
O.hotspot_expose((T20C*2) + 380,500) //Light flamethrower fuel on fire immediately.
amount *= 0.25
diff --git a/code/game/objects/items/antag_spawners.dm b/code/game/objects/items/antag_spawners.dm
new file mode 100644
index 0000000000..ce358bc1ee
--- /dev/null
+++ b/code/game/objects/items/antag_spawners.dm
@@ -0,0 +1,135 @@
+/obj/item/weapon/antag_spawner
+ w_class = ITEMSIZE_TINY
+ var/used = 0
+ var/ghost_query_type = null
+ var/searching = FALSE
+ var/datum/effect/effect/system/spark_spread/sparks
+
+/obj/item/weapon/antag_spawner/New()
+ ..()
+ sparks = new /datum/effect/effect/system/spark_spread()
+ sparks.set_up(5, 0, src)
+ sparks.attach(loc)
+
+/obj/item/weapon/antag_spawner/Destroy()
+ qdel(sparks)
+ return ..()
+
+/obj/item/weapon/antag_spawner/proc/spawn_antag(client/C, turf/T)
+ return
+
+/obj/item/weapon/antag_spawner/proc/equip_antag(mob/target)
+ return
+
+/obj/item/weapon/antag_spawner/proc/request_player()
+ if(!ghost_query_type)
+ return
+ if(searching)
+ return // Already searching.
+ searching = TRUE
+
+ var/datum/ghost_query/Q = new ghost_query_type()
+ var/list/winner = Q.query()
+ if(winner.len)
+ var/mob/observer/dead/D = winner[1]
+ spawn_antag(D.client, get_turf(src))
+ else
+ reset_search()
+ return
+
+/obj/item/weapon/antag_spawner/proc/reset_search()
+ searching = FALSE
+ return
+
+/obj/item/weapon/antag_spawner/technomancer_apprentice
+ name = "apprentice teleporter"
+ desc = "A teleportation device, which will bring a less potent manipulator of space to you."
+ icon = 'icons/obj/objects.dmi'
+ icon_state = "oldshieldoff"
+ ghost_query_type = /datum/ghost_query/apprentice
+
+/obj/item/weapon/antag_spawner/technomancer_apprentice/attack_self(mob/user)
+ user << "Teleporter attempting to lock on to your apprentice."
+ request_player()
+
+/obj/item/weapon/antag_spawner/technomancer_apprentice/request_player()
+ icon_state = "oldshieldon"
+ ..()
+
+/obj/item/weapon/antag_spawner/technomancer_apprentice/reset_search()
+ ..()
+ if(!used)
+ icon_state = "oldshieldoff"
+ visible_message("The teleporter failed to find the apprentice. Perhaps another attempt could be made later?")
+
+/obj/item/weapon/antag_spawner/technomancer_apprentice/spawn_antag(client/C, turf/T)
+ sparks.start()
+ var/mob/living/carbon/human/H = new/mob/living/carbon/human(T)
+ C.prefs.copy_to(H)
+ H.key = C.key
+
+ H << "You are the Technomancer's apprentice! Your goal is to assist them in their mission at the [station_name()]."
+ H << "Your service has not gone unrewarded, however. Studying under them, you have learned how to use a Manipulation Core \
+ of your own. You also have a catalog, to purchase your own functions and equipment as you see fit."
+ H << "It would be wise to speak to your master, and learn what their plans are for today."
+
+ spawn(1)
+ technomancers.add_antagonist(H.mind, 0, 1, 0, 0, 0)
+ equip_antag(H)
+ used = 1
+ qdel(src)
+
+/obj/item/weapon/antag_spawner/technomancer_apprentice/equip_antag(mob/technomancer_mob)
+ var/datum/antagonist/technomancer/antag_datum = all_antag_types[MODE_TECHNOMANCER]
+ antag_datum.equip_apprentice(technomancer_mob)
+
+
+
+
+/obj/item/weapon/antag_spawner/syndicate_drone
+ name = "drone teleporter"
+ desc = "A teleportation device, which will bring a powerful and loyal drone to you."
+ icon = 'icons/obj/objects.dmi'
+ icon_state = "oldshieldoff"
+ ghost_query_type = /datum/ghost_query/syndicate_drone
+ var/drone_type = null
+
+/obj/item/weapon/antag_spawner/syndicate_drone/attack_self(mob/user)
+ to_chat(user, "Teleporter attempting to lock on to an available unit.")
+ request_player()
+
+/obj/item/weapon/antag_spawner/syndicate_drone/request_player()
+ icon_state = "oldshieldon"
+ ..()
+
+/obj/item/weapon/antag_spawner/syndicate_drone/reset_search()
+ ..()
+ if(!used)
+ icon_state = "oldshieldoff"
+ visible_message("The teleporter failed to find any available. Perhaps another attempt could be made later?")
+
+/obj/item/weapon/antag_spawner/syndicate_drone/spawn_antag(client/C, turf/T)
+ sparks.start()
+ var/mob/living/silicon/robot/R = new drone_type(T)
+
+ // Put this text here before ckey change so that their laws are shown below it, since borg login() shows it.
+ to_chat(C, "You are a Mercenary Drone, activated to serve your team.")
+ to_chat(C, "Be sure to examine your currently loaded lawset closely. It would be wise \
+ to speak with your team, and learn what their plan is for today.")
+
+ R.key = C.key
+// R.Namepick() // Apparnetly making someone a merc lets them pick a name, so this isn't needed.
+
+ spawn(1)
+ mercs.add_antagonist(R.mind, FALSE, TRUE, FALSE, FALSE, FALSE)
+ //add_antagonist(var/datum/mind/player, var/ignore_role, var/do_not_equip, var/move_to_spawn, var/do_not_announce, var/preserve_appearance)
+ qdel(src)
+
+/obj/item/weapon/antag_spawner/syndicate_drone/protector
+ drone_type = /mob/living/silicon/robot/syndicate/protector
+
+/obj/item/weapon/antag_spawner/syndicate_drone/combat_medic
+ drone_type = /mob/living/silicon/robot/syndicate/combat_medic
+
+/obj/item/weapon/antag_spawner/syndicate_drone/mechanist
+ drone_type = /mob/living/silicon/robot/syndicate/mechanist
\ No newline at end of file
diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm
index 5a7a028054..ab893415ac 100644
--- a/code/game/objects/items/devices/aicard.dm
+++ b/code/game/objects/items/devices/aicard.dm
@@ -7,6 +7,7 @@
w_class = ITEMSIZE_NORMAL
slot_flags = SLOT_BELT
show_messages = 0
+ preserve_item = 1
var/flush = null
origin_tech = list(TECH_DATA = 4, TECH_MATERIAL = 4)
diff --git a/code/game/objects/items/devices/communicator/communicator.dm b/code/game/objects/items/devices/communicator/communicator.dm
index e2dc8af7c6..6c300bd833 100644
--- a/code/game/objects/items/devices/communicator/communicator.dm
+++ b/code/game/objects/items/devices/communicator/communicator.dm
@@ -985,7 +985,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
if(text_message && O.exonet)
O.exonet.send_message(chosen_communicator.exonet.address, "text", text_message)
- src << "You have sent '[text_message]' to [chosen_communicator].."
+ src << "You have sent '[text_message]' to [chosen_communicator]."
exonet_messages.Add("To [chosen_communicator]:
[text_message]")
log_pda("[usr] (COMM: [src]) sent \"[text_message]\" to [chosen_communicator]")
@@ -1132,4 +1132,4 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
/obj/machinery/camera/communicator/New()
..()
client_huds |= global_hud.whitense
- client_huds |= global_hud.darkMask
\ No newline at end of file
+ client_huds |= global_hud.darkMask
diff --git a/code/game/objects/items/devices/defib.dm b/code/game/objects/items/devices/defib.dm
index b9b8af0c0d..decb40d807 100644
--- a/code/game/objects/items/devices/defib.dm
+++ b/code/game/objects/items/devices/defib.dm
@@ -11,6 +11,7 @@
slot_flags = SLOT_BACK
force = 5
throwforce = 6
+ preserve_item = 1
w_class = ITEMSIZE_LARGE
origin_tech = list(TECH_BIO = 4, TECH_POWER = 2)
action_button_name = "Remove/Replace Paddles"
@@ -542,6 +543,13 @@
var/mob/living/silicon/robot/R = src.loc
return (R.cell && R.cell.checked_use(charge_amt))
+/obj/item/weapon/shockpaddles/robot/combat
+ name = "combat defibrillator paddles"
+ desc = "A pair of advanced shockpaddles powered by a robot's internal power cell, able to penetrate thick clothing. This version \
+ appears to be optimized for combat situations, foregoing the safety inhabitors in favor of a faster charging time."
+ safety = 0
+ chargetime = (1 SECONDS)
+
/*
Shockpaddles that are linked to a base unit
*/
diff --git a/code/game/objects/items/devices/paicard.dm b/code/game/objects/items/devices/paicard.dm
index 8e1803ad40..2cf67da30c 100644
--- a/code/game/objects/items/devices/paicard.dm
+++ b/code/game/objects/items/devices/paicard.dm
@@ -7,6 +7,7 @@
slot_flags = SLOT_BELT
origin_tech = list(TECH_DATA = 2)
show_messages = 0
+ preserve_item = 1
var/obj/item/device/radio/radio
var/looking_for_personality = 0
diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm
index f113e5f153..9a56cf94a7 100644
--- a/code/game/objects/items/robot/robot_parts.dm
+++ b/code/game/objects/items/robot/robot_parts.dm
@@ -177,8 +177,9 @@
if(M.brainmob.mind)
for(var/mob/observer/dead/G in player_list)
if(G.can_reenter_corpse && G.mind == M.brainmob.mind)
- ghost_can_reenter = 1
- break
+ ghost_can_reenter = 1 //May come in use again at another point.
+ to_chat(user, "\The [W] is completely unresponsive; though it may be able to auto-resuscitate.") //Jamming a ghosted brain into a borg is likely detrimental, and may result in some problems.
+ return
if(!ghost_can_reenter)
user << "\The [W] is completely unresponsive; there's no point."
return
diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm
index de6f90591f..cedd54ac6f 100644
--- a/code/game/objects/items/robot/robot_upgrades.dm
+++ b/code/game/objects/items/robot/robot_upgrades.dm
@@ -175,3 +175,23 @@
R.emag_items = 1
return 1
+
+/obj/item/borg/upgrade/language
+ name = "language module"
+ desc = "Used to let cyborgs other than clerical or service speak a variety of languages."
+ icon_state = "cyborg_upgrade3"
+ item_state = "cyborg_upgrade"
+
+/obj/item/borg/upgrade/language/action(var/mob/living/silicon/robot/R)
+ if(..()) return 0
+
+ R.add_language(LANGUAGE_SOL_COMMON, 1)
+ R.add_language(LANGUAGE_TRADEBAND, 1)
+ R.add_language(LANGUAGE_UNATHI, 1)
+ R.add_language(LANGUAGE_SIIK, 1)
+ R.add_language(LANGUAGE_SKRELLIAN, 1)
+ R.add_language(LANGUAGE_GUTTER, 1)
+ R.add_language(LANGUAGE_SCHECHI, 1)
+ R.add_language(LANGUAGE_ROOTLOCAL, 1)
+
+ return 1
\ No newline at end of file
diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm
index a4dcd6d96f..ddd6f98f16 100644
--- a/code/game/objects/items/stacks/tiles/tile_types.dm
+++ b/code/game/objects/items/stacks/tiles/tile_types.dm
@@ -123,7 +123,6 @@
icon_state = "tile_white"
no_variants = FALSE
-// VOREStation Edit
/obj/item/stack/tile/floor/techgrey
name = "grey techfloor tile"
singular_name = "grey techfloor tile"
@@ -142,7 +141,6 @@
icon_state = "tile_steel"
matter = list("plasteel" = SHEET_MATERIAL_AMOUNT / 4)
no_variants = FALSE
-// VOREStation Edit End
/obj/item/stack/tile/floor/steel
name = "steel floor tile"
diff --git a/code/game/objects/items/weapons/AI_modules.dm b/code/game/objects/items/weapons/AI_modules.dm
index 60a847a4d6..5c0f43e139 100755
--- a/code/game/objects/items/weapons/AI_modules.dm
+++ b/code/game/objects/items/weapons/AI_modules.dm
@@ -18,6 +18,7 @@ AI MODULES
throw_speed = 3
throw_range = 15
origin_tech = list(TECH_DATA = 3)
+ preserve_item = 1
var/datum/ai_laws/laws = null
/obj/item/weapon/aiModule/proc/install(var/atom/movable/AM, var/mob/living/user)
diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm
index d79f584e2f..df744d1df3 100644
--- a/code/game/objects/items/weapons/RCD.dm
+++ b/code/game/objects/items/weapons/RCD.dm
@@ -15,6 +15,7 @@
w_class = ITEMSIZE_NORMAL
origin_tech = list(TECH_ENGINEERING = 4, TECH_MATERIAL = 2)
matter = list(DEFAULT_WALL_MATERIAL = 50000)
+ preserve_item = 1
var/datum/effect/effect/system/spark_spread/spark_system
var/stored_matter = 0
var/max_stored_matter = 30
@@ -178,6 +179,9 @@
/obj/item/weapon/rcd/borg
canRwall = 1
+/obj/item/weapon/rcd/borg/lesser
+ canRwall = FALSE
+
/obj/item/weapon/rcd/borg/useResource(var/amount, var/mob/user)
if(isrobot(user))
var/mob/living/silicon/robot/R = user
diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm
index 6f8e1782eb..46543b901b 100644
--- a/code/game/objects/items/weapons/gift_wrappaper.dm
+++ b/code/game/objects/items/weapons/gift_wrappaper.dm
@@ -103,7 +103,7 @@
/obj/item/device/paicard,
/obj/item/device/violin,
/obj/item/weapon/storage/belt/utility/full,
- /obj/item/clothing/accessory/horrible)
+ /obj/item/clothing/accessory/tie/horrible)
if(!ispath(gift_type,/obj/item)) return
diff --git a/code/game/objects/items/weapons/id cards/station_ids.dm b/code/game/objects/items/weapons/id cards/station_ids.dm
index 68d969a6b5..f075ea49f9 100644
--- a/code/game/objects/items/weapons/id cards/station_ids.dm
+++ b/code/game/objects/items/weapons/id cards/station_ids.dm
@@ -23,6 +23,8 @@
var/primary_color = rgb(0,0,0) // Obtained by eyedroppering the stripe in the middle of the card
var/secondary_color = rgb(0,0,0) // Likewise for the oval in the top-left corner
+ var/datum/job/job_access_type = /datum/job/assistant // Job type to acquire access rights from, if any
+
//alt titles are handled a bit weirdly in order to unobtrusively integrate into existing ID system
var/assignment = null //can be alt title or the actual job
var/rank = null //actual job
@@ -110,52 +112,49 @@
usr << "The fingerprint hash on the card is [fingerprint_hash]."
return
+/obj/item/weapon/card/id/New()
+ ..()
+ var/datum/job/jobdatum
+ for(var/jobtype in typesof(/datum/job))
+ var/datum/job/J = new jobtype
+ if(J.title == rank)
+ jobdatum = J
+ access = jobdatum.get_access()
+ return
+
/obj/item/weapon/card/id/silver
name = "identification card"
desc = "A silver card which shows honour and dedication."
icon_state = "silver"
item_state = "silver_id"
-/obj/item/weapon/card/id/silver/secretary/New()
- ..()
+/obj/item/weapon/card/id/silver/secretary
assignment = "Command Secretary"
rank = "Command Secretary"
- access |= list(access_heads)
+ job_access_type = /datum/job/secretary
-/obj/item/weapon/card/id/silver/hop/New()
- ..()
+/obj/item/weapon/card/id/silver/hop
assignment = "Head of Personnel"
rank = "Head of Personnel"
- access |= list(access_security, access_sec_doors, access_brig, access_forensics_lockers,
- access_medical, access_engine, access_change_ids, access_ai_upload, access_eva, access_heads,
- access_all_personal_lockers, access_maint_tunnels, access_bar, access_janitor, access_construction, access_morgue,
- access_crematorium, access_kitchen, access_cargo, access_cargo_bot, access_mailsorting, access_qm, access_hydroponics, access_lawyer,
- access_chapel_office, access_library, access_research, access_mining, access_heads_vault, access_mining_station,
- access_hop, access_RC_announce, access_keycard_auth, access_gateway)
+ job_access_type = /datum/job/hop
/obj/item/weapon/card/id/gold
name = "identification card"
desc = "A golden card which shows power and might."
icon_state = "gold"
item_state = "gold_id"
+ preserve_item = 1
-/obj/item/weapon/card/id/gold/captain/New()
+/obj/item/weapon/card/id/gold/captain
assignment = "Colony Director"
rank = "Colony Director"
- access = get_all_station_access()
- ..()
+ job_access_type = /datum/job/captain
-/obj/item/weapon/card/id/captains_spare
+/obj/item/weapon/card/id/gold/captain/spare
name = "colony director's spare ID"
desc = "The spare ID of the High Lord himself."
- icon_state = "gold"
- item_state = "gold_id"
registered_name = "Colony Director"
- assignment = "Colony Director"
-
-/obj/item/weapon/card/id/captains_spare/New()
- access = get_all_station_access()
- ..()
+ job_access_type = /datum/job/captain
/obj/item/weapon/card/id/synthetic
name = "\improper Synthetic ID"
@@ -165,13 +164,13 @@
assignment = "Synthetic"
/obj/item/weapon/card/id/synthetic/New()
- access = get_all_station_access() + access_synth
..()
+ access = get_all_station_access() + access_synth
/obj/item/weapon/card/id/centcom
name = "\improper CentCom. ID"
desc = "An ID straight from Central Command."
- icon_state = "centcom"
+ icon_state = "nanotrasen"
registered_name = "Central Command"
assignment = "General"
@@ -186,6 +185,7 @@
/obj/item/weapon/card/id/centcom/ERT
name = "\improper Emergency Response Team ID"
assignment = "Emergency Response Team"
+ icon_state = "centcom"
/obj/item/weapon/card/id/centcom/ERT/New()
..()
@@ -198,50 +198,41 @@
icon_state = "med"
primary_color = rgb(189,237,237)
secondary_color = rgb(223,255,255)
- access = list(access_medical, access_medical_equip)
-/obj/item/weapon/card/id/medical/doctor/New()
- ..()
+/obj/item/weapon/card/id/medical/doctor
assignment = "Medical Doctor"
rank = "Medical Doctor"
- access |= list(access_morgue, access_surgery, access_virology, access_eva)
+ job_access_type = /datum/job/doctor
-/obj/item/weapon/card/id/medical/chemist/New()
- ..()
+/obj/item/weapon/card/id/medical/chemist
assignment = "Chemist"
rank = "Chemist"
- access |= list(access_chemistry)
+ job_access_type = /datum/job/chemist
-/obj/item/weapon/card/id/medical/geneticist/New()
- ..()
+/obj/item/weapon/card/id/medical/geneticist
assignment = "Geneticist"
rank = "Geneticist"
- access |= list(access_morgue, access_genetics)
+ job_access_type = /datum/job/doctor //geneticist
-/obj/item/weapon/card/id/medical/psychiatrist/New()
- ..()
+/obj/item/weapon/card/id/medical/psychiatrist
assignment = "Psychiatrist"
rank = "Psychiatrist"
- access |= list(access_psychiatrist)
+ job_access_type = /datum/job/psychiatrist
-/obj/item/weapon/card/id/medical/paramedic/New()
- ..()
+/obj/item/weapon/card/id/medical/paramedic
assignment = "Paramedic"
rank = "Paramedic"
- access |= list(access_morgue, access_eva, access_maint_tunnels, access_external_airlocks)
+ job_access_type = /datum/job/paramedic
/obj/item/weapon/card/id/medical/head
name = "identification card"
desc = "A card which represents care and compassion."
- assignment = "Chief Medical Officer"
- rank = "Chief Medical Officer"
icon_state = "medGold"
primary_color = rgb(189,237,237)
secondary_color = rgb(255,223,127)
-
-/obj/item/weapon/card/id/medical/head/New()
- access |= list(access_morgue, access_genetics, access_heads, access_chemistry, access_virology, access_cmo, access_surgery, access_RC_announce,
- access_keycard_auth, access_sec_doors, access_psychiatrist, access_eva, access_external_airlocks, access_maint_tunnels)
+ assignment = "Chief Medical Officer"
+ rank = "Chief Medical Officer"
+ job_access_type = /datum/job/cmo
/obj/item/weapon/card/id/security
name = "identification card"
@@ -249,40 +240,31 @@
icon_state = "sec"
primary_color = rgb(189,47,0)
secondary_color = rgb(223,127,95)
- access = list(access_security, access_sec_doors, access_maint_tunnels, access_external_airlocks, access_eva)
-/obj/item/weapon/card/id/security/officer/New()
- ..()
- assignment = "Assignment"
+/obj/item/weapon/card/id/security/officer
+ assignment = "Security Officer"
rank = "Security Officer"
- access |= list(access_brig)
+ job_access_type = /datum/job/officer
-/obj/item/weapon/card/id/security/detective/New()
- ..()
+/obj/item/weapon/card/id/security/detective
assignment = "Detective"
rank = "Detective"
- access |= list(access_forensics_lockers, access_morgue)
+ job_access_type = /datum/job/detective
-/obj/item/weapon/card/id/security/warden/New()
- ..()
+/obj/item/weapon/card/id/security/warden
assignment = "Warden"
rank = "Warden"
- access |= list(access_brig, access_armory)
+ job_access_type = /datum/job/warden
/obj/item/weapon/card/id/security/head
name = "identification card"
desc = "A card which represents honor and protection."
icon_state = "secGold"
- assignment = "Head of Security"
- rank = "Head of Security"
primary_color = rgb(189,47,0)
secondary_color = rgb(255,223,127)
-
-/obj/item/weapon/card/id/security/head/New()
- ..()
- access |= list(access_brig, access_armory, access_forensics_lockers, access_morgue, access_all_personal_lockers,
- access_research, access_engine, access_mining, access_medical, access_construction, access_mailsorting,
- access_heads, access_hos, access_RC_announce, access_keycard_auth, access_gateway)
+ assignment = "Head of Security"
+ rank = "Head of Security"
+ job_access_type = /datum/job/hos
/obj/item/weapon/card/id/engineering
name = "identification card"
@@ -290,33 +272,26 @@
icon_state = "eng"
primary_color = rgb(189,94,0)
secondary_color = rgb(223,159,95)
- access = list(access_eva, access_engine, access_maint_tunnels, access_construction, access_external_airlocks)
-/obj/item/weapon/card/id/engineering/engineer/New()
- ..()
+/obj/item/weapon/card/id/engineering/engineer
assignment = "Station Engineer"
rank = "Station Engineer"
- access |= list(access_engine_equip, access_tech_storage)
+ job_access_type = /datum/job/engineer
-/obj/item/weapon/card/id/engineering/atmos/New()
- ..()
+/obj/item/weapon/card/id/engineering/atmos
assignment = "Atmospheric Technician"
rank = "Atmospheric Technician"
- access |= list(access_atmospherics, access_emergency_storage)
+ job_access_type = /datum/job/atmos
/obj/item/weapon/card/id/engineering/head
name = "identification card"
desc = "A card which represents creativity and ingenuity."
icon_state = "engGold"
- assignment = "Chief Engineer"
- rank = "Chief Engineer"
primary_color = rgb(189,94,0)
secondary_color = rgb(255,223,127)
-
-/obj/item/weapon/card/id/engineering/head/New()
- ..()
- access |= list(access_engine_equip, access_tech_storage, access_teleporter, access_atmospherics, access_emergency_storage,
- access_heads, access_sec_doors, access_ce, access_RC_announce, access_keycard_auth, access_tcomsat, access_ai_upload)
+ assignment = "Chief Engineer"
+ rank = "Chief Engineer"
+ job_access_type = /datum/job/chief_engineer
/obj/item/weapon/card/id/science
name = "identification card"
@@ -324,40 +299,31 @@
icon_state = "sci"
primary_color = rgb(142,47,142)
secondary_color = rgb(191,127,191)
- access = list(access_research)
-/obj/item/weapon/card/id/science/scientist/New()
- ..()
+/obj/item/weapon/card/id/science/scientist
assignment = "Scientist"
rank = "Scientist"
- access |= list(access_tox, access_tox_storage, access_xenoarch)
+ job_access_type = /datum/job/scientist
-/obj/item/weapon/card/id/science/xenobiologist/New()
- ..()
+/obj/item/weapon/card/id/science/xenobiologist
assignment = "Xenobiologist"
rank = "Xenobiologist"
- access |= list(access_xenobiology, access_hydroponics, access_tox_storage)
+ job_access_type = /datum/job/xenobiologist
-/obj/item/weapon/card/id/science/roboticist/New()
- ..()
+/obj/item/weapon/card/id/science/roboticist
assignment = "Roboticist"
rank = "Roboticist"
- access |= list(access_robotics, access_tech_storage, access_morgue)
+ job_access_type = /datum/job/roboticist
/obj/item/weapon/card/id/science/head
name = "identification card"
desc = "A card which represents knowledge and reasoning."
icon_state = "sciGold"
- assignment = "Research Director"
- rank = "Research Director"
primary_color = rgb(142,47,142)
secondary_color = rgb(255,223,127)
-
-/obj/item/weapon/card/id/science/head/New()
- ..()
- access |= list(access_rd, access_heads, access_tox, access_genetics, access_morgue, access_tox_storage, access_teleporter, access_sec_doors,
- access_robotics, access_xenobiology, access_ai_upload, access_tech_storage, access_RC_announce, access_keycard_auth,
- access_tcomsat, access_gateway, access_xenoarch)
+ assignment = "Research Director"
+ rank = "Research Director"
+ job_access_type = /datum/job/rd
/obj/item/weapon/card/id/cargo
name = "identification card"
@@ -365,90 +331,76 @@
icon_state = "cargo"
primary_color = rgb(142,94,0)
secondary_color = rgb(191,159,95)
- access = list(access_mailsorting)
-/obj/item/weapon/card/id/cargo/cargo_tech/New()
- ..()
+/obj/item/weapon/card/id/cargo/cargo_tech
assignment = "Cargo Technician"
rank = "Cargo Technician"
- access |= list(access_maint_tunnels, access_cargo, access_cargo_bot)
+ job_access_type = /datum/job/cargo_tech
-/obj/item/weapon/card/id/cargo/mining/New()
- ..()
+/obj/item/weapon/card/id/cargo/mining
assignment = "Shaft Miner"
rank = "Shaft Miner"
- access |= list(access_mining, access_mining_station)
+ job_access_type = /datum/job/mining
/obj/item/weapon/card/id/cargo/head
name = "identification card"
desc = "A card which represents service and planning."
icon_state = "cargoGold"
- assignment = "Quartermaster"
- rank = "Quartermaster"
primary_color = rgb(142,94,0)
secondary_color = rgb(255,223,127)
-
-/obj/item/weapon/card/id/cargo/head/New()
- ..()
- access |= list(access_maint_tunnels, access_cargo, access_cargo_bot, access_qm, access_mining, access_mining_station)
+ assignment = "Quartermaster"
+ rank = "Quartermaster"
+ job_access_type = /datum/job/qm
/obj/item/weapon/card/id/assistant
- name = "identification card"
-// assignment = "Assistant"
-// rank = "Assistant"
- access = list()
+ assignment = "Assistant"
+ rank = "Assistant"
+ job_access_type = /datum/job/assistant
/obj/item/weapon/card/id/civilian
name = "identification card"
desc = "A card issued to station civilian staff."
icon_state = "civ"
- assignment = "Civilian"
- rank = "Assistant"
primary_color = rgb(0,94,142)
secondary_color = rgb(95,159,191)
- access = list()
+ assignment = "Civilian"
+ rank = "Assistant"
+ job_access_type = /datum/job/assistant
-/obj/item/weapon/card/id/civilian/bartender/New()
- ..()
+/obj/item/weapon/card/id/civilian/bartender
assignment = "Bartender"
rank = "Bartender"
- access |= list(access_bar)
+ job_access_type = /datum/job/bartender
-/obj/item/weapon/card/id/civilian/botanist/New()
- ..()
+/obj/item/weapon/card/id/civilian/botanist
assignment = "Gardener"
rank = "Gardener"
- access |= list(access_hydroponics)
+ job_access_type = /datum/job/hydro
-/obj/item/weapon/card/id/civilian/chaplain/New()
- ..()
+/obj/item/weapon/card/id/civilian/chaplain
assignment = "Chaplain"
rank = "Chaplain"
- access |= list(access_chapel_office, access_crematorium)
+ job_access_type = /datum/job/chaplain
-/obj/item/weapon/card/id/civilian/chef/New()
- ..()
+/obj/item/weapon/card/id/civilian/chef
assignment = "Chef"
rank = "Chef"
- access |= list(access_kitchen)
+ job_access_type = /datum/job/chef
-/obj/item/weapon/card/id/civilian/internal_affairs_agent/New()
- ..()
+/obj/item/weapon/card/id/civilian/internal_affairs_agent
assignment = "Internal Affairs Agent"
rank = "Internal Affairs Agent"
- access |= list(access_lawyer, access_sec_doors, access_heads)
+ job_access_type = /datum/job/lawyer
-/obj/item/weapon/card/id/civilian/janitor/New()
- ..()
+/obj/item/weapon/card/id/civilian/janitor
assignment = "Janitor"
rank = "Janitor"
- access |= list(access_janitor, access_maint_tunnels)
+ job_access_type = /datum/job/janitor
-/obj/item/weapon/card/id/civilian/librarian/New()
- ..()
+/obj/item/weapon/card/id/civilian/librarian
assignment = "Librarian"
rank = "Librarian"
- access |= list(access_library)
+ job_access_type = /datum/job/librarian
/obj/item/weapon/card/id/civilian/head //This is not the HoP. There's no position that uses this right now.
name = "identification card"
diff --git a/code/game/objects/items/weapons/power_cells.dm b/code/game/objects/items/weapons/power_cells.dm
index 3a2373c696..2b63fb79bd 100644
--- a/code/game/objects/items/weapons/power_cells.dm
+++ b/code/game/objects/items/weapons/power_cells.dm
@@ -34,6 +34,7 @@
throw_range = 7
maxcharge = 480
matter = list("metal" = 350, "glass" = 50)
+ preserve_item = 1
/obj/item/weapon/cell/device/weapon
name = "weapon power cell"
diff --git a/code/game/objects/items/weapons/shields.dm b/code/game/objects/items/weapons/shields.dm
index 5e3c96c8a0..814592a890 100644
--- a/code/game/objects/items/weapons/shields.dm
+++ b/code/game/objects/items/weapons/shields.dm
@@ -32,6 +32,7 @@
/obj/item/weapon/shield
name = "shield"
var/base_block_chance = 50
+ preserve_item = 1
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_melee.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_melee.dmi',
diff --git a/code/game/objects/items/weapons/storage/internal.dm b/code/game/objects/items/weapons/storage/internal.dm
index c915053c9f..498f6aa5d3 100644
--- a/code/game/objects/items/weapons/storage/internal.dm
+++ b/code/game/objects/items/weapons/storage/internal.dm
@@ -1,6 +1,7 @@
//A storage item intended to be used by other items to provide storage functionality.
//Types that use this should consider overriding emp_act() and hear_talk(), unless they shield their contents somehow.
/obj/item/weapon/storage/internal
+ preserve_item = 1
var/obj/item/master_item
/obj/item/weapon/storage/internal/New(obj/item/MI)
diff --git a/code/game/objects/items/weapons/storage/lockbox.dm b/code/game/objects/items/weapons/storage/lockbox.dm
index 770ecd169b..e52ad4d812 100644
--- a/code/game/objects/items/weapons/storage/lockbox.dm
+++ b/code/game/objects/items/weapons/storage/lockbox.dm
@@ -9,6 +9,7 @@
max_w_class = ITEMSIZE_NORMAL
max_storage_space = ITEMSIZE_COST_NORMAL * 4 //The sum of the w_classes of all the items in this storage item.
req_access = list(access_armory)
+ preserve_item = 1
var/locked = 1
var/broken = 0
var/icon_locked = "lockbox+l"
diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm
index 0c7ec20167..cd3aca0f37 100644
--- a/code/game/objects/items/weapons/storage/uplink_kits.dm
+++ b/code/game/objects/items/weapons/storage/uplink_kits.dm
@@ -295,3 +295,22 @@
for(var/i = 1 to 4)
new /obj/item/ammo_casing/a145(src)
+
+/obj/item/weapon/storage/secure/briefcase/fuelrod
+ name = "heavy briefcase"
+ desc = "A heavy, locked briefcase."
+ description_fluff = "The container, upon opening, looks to have a few oddly shaped indentations in its packing."
+ description_antag = "This case will likely contain a charged fuel rod gun, and a few fuel rods to go with it. It can only hold the fuel rod gun, fuel rods, batteries, a screwdriver, and stock machine parts."
+ force = 12 //Anti-rad lined i.e. Lead, probably gonna hurt a bit if you get bashed with it.
+ can_hold = list(/obj/item/weapon/gun/magnetic/fuelrod, /obj/item/weapon/fuel_assembly, /obj/item/weapon/cell, /obj/item/weapon/stock_parts, /obj/item/weapon/screwdriver)
+
+
+/obj/item/weapon/storage/secure/briefcase/fuelrod/New()
+ ..()
+ new /obj/item/weapon/gun/magnetic/fuelrod(src)
+ new /obj/item/weapon/fuel_assembly/deuterium(src)
+ new /obj/item/weapon/fuel_assembly/deuterium(src)
+ new /obj/item/weapon/fuel_assembly/tritium(src)
+ new /obj/item/weapon/fuel_assembly/tritium(src)
+ new /obj/item/weapon/fuel_assembly/phoron(src)
+ new /obj/item/weapon/screwdriver(src)
diff --git a/code/game/objects/items/weapons/teleportation.dm b/code/game/objects/items/weapons/teleportation.dm
index e0e11a6285..b991db0510 100644
--- a/code/game/objects/items/weapons/teleportation.dm
+++ b/code/game/objects/items/weapons/teleportation.dm
@@ -129,6 +129,7 @@ Frequency:
throw_range = 5
origin_tech = list(TECH_MAGNET = 1, TECH_BLUESPACE = 3)
matter = list(DEFAULT_WALL_MATERIAL = 10000)
+ preserve_item = 1
/obj/item/weapon/hand_tele/attack_self(mob/user as mob)
var/turf/current_location = get_turf(user)//What turf is the user on?
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index a3f77757f2..84f9f88602 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -12,6 +12,7 @@
var/damtype = "brute"
var/armor_penetration = 0
var/show_messages
+ var/preserve_item = 0 //whether this object is preserved when its owner goes into cryo-storage, gateway, etc
/obj/Destroy()
processing_objects -= src
diff --git a/code/game/objects/random/random.dm b/code/game/objects/random/random.dm
index b18e1500aa..82545b5293 100644
--- a/code/game/objects/random/random.dm
+++ b/code/game/objects/random/random.dm
@@ -992,7 +992,7 @@ var/list/multi_point_spawns
/obj/random_multi/single_item/captains_spare_id
name = "Multi Point - Captain's Spare"
id = "Captain's spare id"
- item_path = /obj/item/weapon/card/id/captains_spare
+ item_path = /obj/item/weapon/card/id/gold/captain/spare
//Multiple Object Spawn
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
index ce688a9375..f4af008dd4 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
@@ -20,6 +20,7 @@
new /obj/item/weapon/gun/energy/gun(src)
new /obj/item/weapon/melee/telebaton(src)
new /obj/item/device/flash(src)
+ new /obj/item/weapon/storage/box/ids(src)
return
diff --git a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm
index 7e543b75cd..079948cebe 100644
--- a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm
+++ b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm
@@ -685,4 +685,5 @@
new /obj/item/clothing/under/gimmick/rank/captain/suit(src)
new /obj/item/clothing/under/gimmick/rank/captain/suit/skirt(src)
new /obj/item/clothing/glasses/sunglasses(src)
+ new /obj/item/clothing/head/caphat(src)
return
diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm
index 367c6587d1..9b3958e5a1 100644
--- a/code/game/objects/structures/flora.dm
+++ b/code/game/objects/structures/flora.dm
@@ -1,78 +1,6 @@
-//trees
-/obj/structure/flora/tree
- name = "tree"
- anchored = 1
- density = 1
- pixel_x = -16
- layer = MOB_LAYER // You know what, let's play it safe.
-
-/obj/structure/flora/tree/pine
- name = "pine tree"
- icon = 'icons/obj/flora/pinetrees.dmi'
- icon_state = "pine_1"
-
-/obj/structure/flora/tree/pine/New()
- ..()
- icon_state = "pine_[rand(1, 3)]"
-
-/obj/structure/flora/tree/pine/xmas
- name = "xmas tree"
- icon = 'icons/obj/flora/pinetrees.dmi'
- icon_state = "pine_c"
-
-/obj/structure/flora/tree/pine/xmas/New()
- ..()
- icon_state = "pine_c"
-
-/obj/structure/flora/tree/dead
- icon = 'icons/obj/flora/deadtrees.dmi'
- icon_state = "tree_1"
-
-/obj/structure/flora/tree/dead/New()
- ..()
- icon_state = "tree_[rand(1, 6)]"
-
-/obj/structure/flora/tree/sif
- name = "glowing tree"
- desc = "It's a tree, except this one seems quite alien. It glows a deep blue."
- icon = 'icons/obj/flora/deadtrees.dmi'
- icon_state = "tree_sif"
-
-/obj/structure/flora/tree/sif/New()
- update_icon()
-
-/obj/structure/flora/tree/sif/update_icon()
- set_light(5, 1, "#33ccff")
- overlays.Cut()
- overlays.Add(image(icon = 'icons/obj/flora/deadtrees.dmi', icon_state = "[icon_state]_glow", layer = LIGHTING_LAYER + 0.1))
-
-//grass
-/obj/structure/flora/grass
- name = "grass"
- icon = 'icons/obj/flora/snowflora.dmi'
- anchored = 1
-
-/obj/structure/flora/grass/brown
- icon_state = "snowgrass1bb"
-
-/obj/structure/flora/grass/brown/New()
- ..()
- icon_state = "snowgrass[rand(1, 3)]bb"
-/obj/structure/flora/grass/green
- icon_state = "snowgrass1gb"
-/obj/structure/flora/grass/green/New()
- ..()
- icon_state = "snowgrass[rand(1, 3)]gb"
-
-/obj/structure/flora/grass/both
- icon_state = "snowgrassall1"
-
-/obj/structure/flora/grass/both/New()
- ..()
- icon_state = "snowgrassall[rand(1, 3)]"
//bushes
diff --git a/code/game/objects/structures/flora/grass.dm b/code/game/objects/structures/flora/grass.dm
new file mode 100644
index 0000000000..d5e7e965a8
--- /dev/null
+++ b/code/game/objects/structures/flora/grass.dm
@@ -0,0 +1,27 @@
+//grass
+/obj/structure/flora/grass
+ name = "grass"
+ icon = 'icons/obj/flora/snowflora.dmi'
+ anchored = 1
+
+/obj/structure/flora/grass/brown
+ icon_state = "snowgrass1bb"
+
+/obj/structure/flora/grass/brown/New()
+ ..()
+ icon_state = "snowgrass[rand(1, 3)]bb"
+
+
+/obj/structure/flora/grass/green
+ icon_state = "snowgrass1gb"
+
+/obj/structure/flora/grass/green/New()
+ ..()
+ icon_state = "snowgrass[rand(1, 3)]gb"
+
+/obj/structure/flora/grass/both
+ icon_state = "snowgrassall1"
+
+/obj/structure/flora/grass/both/New()
+ ..()
+ icon_state = "snowgrassall[rand(1, 3)]"
\ No newline at end of file
diff --git a/code/game/objects/structures/flora/trees.dm b/code/game/objects/structures/flora/trees.dm
new file mode 100644
index 0000000000..d7960b5982
--- /dev/null
+++ b/code/game/objects/structures/flora/trees.dm
@@ -0,0 +1,202 @@
+//trees
+/obj/structure/flora/tree
+ name = "tree"
+ anchored = 1
+ density = 1
+ pixel_x = -16
+ layer = MOB_LAYER // You know what, let's play it safe.
+ var/base_state = null // Used for stumps.
+ var/health = 200 // Used for chopping down trees.
+ var/max_health = 200
+ var/shake_animation_degrees = 4 // How much to shake the tree when struck. Larger trees should have smaller numbers or it looks weird.
+ var/obj/item/stack/material/product = null // What you get when chopping this tree down. Generally it will be a type of wood.
+ var/product_amount = 10 // How much of a stack you get, if the above is defined.
+ var/is_stump = FALSE // If true, suspends damage tracking and most other effects.
+
+/obj/structure/flora/tree/attackby(var/obj/item/weapon/W, var/mob/living/user)
+ if(!istype(W))
+ return ..()
+
+ if(is_stump)
+ return
+
+ visible_message("\The [user] hits \the [src] with \the [W]!")
+
+ var/damage_to_do = W.force
+ if(!W.sharp && !W.edge)
+ damage_to_do = round(damage_to_do / 4)
+ if(damage_to_do > 0)
+ if(W.sharp && W.edge)
+ playsound(get_turf(src), 'sound/effects/woodcutting.ogg', 50, 1)
+ else
+ playsound(get_turf(src), W.hitsound, 50, 1)
+ if(damage_to_do > 5)
+ adjust_health(-damage_to_do)
+ else
+ to_chat(user, "\The [W] is ineffective at harming \the [src].")
+
+ hit_animation()
+ user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
+ user.do_attack_animation(src)
+
+// Shakes the tree slightly, more or less stolen from lockers.
+/obj/structure/flora/tree/proc/hit_animation()
+ var/init_px = pixel_x
+ var/shake_dir = pick(-1, 1)
+ animate(src, transform=turn(matrix(), shake_animation_degrees * shake_dir), pixel_x=init_px + 2*shake_dir, time=1)
+ animate(transform=null, pixel_x=init_px, time=6, easing=ELASTIC_EASING)
+
+// Used when the tree gets hurt.
+/obj/structure/flora/tree/proc/adjust_health(var/amount)
+ if(is_stump)
+ return
+
+ health = between(0, health + amount, max_health)
+ if(health <= 0)
+ die()
+
+// Called when the tree loses all health, for whatever reason.
+/obj/structure/flora/tree/proc/die()
+ if(is_stump)
+ return
+
+ if(product && product_amount) // Make wooden logs.
+ var/obj/item/stack/material/M = new product(get_turf(src))
+ M.amount = product_amount
+ M.update_icon()
+ visible_message("\The [src] is felled!")
+ stump()
+
+// Makes the tree into a mostly non-interactive stump.
+/obj/structure/flora/tree/proc/stump()
+ if(is_stump)
+ return
+
+ is_stump = TRUE
+ icon_state = "[base_state]_stump"
+ overlays.Cut() // For the Sif tree and other future glowy trees.
+ set_light(0)
+
+/obj/structure/flora/tree/ex_act(var/severity)
+ adjust_health(-(max_health / severity))
+
+
+/obj/structure/flora/tree/get_description_interaction()
+ var/list/results = list()
+
+ if(!is_stump)
+ results += "[desc_panel_image("hatchet")]to cut down this tree into logs. Any sharp and strong weapon will do."
+
+ results += ..()
+
+ return results
+
+// Subtypes.
+
+// Pine trees
+
+/obj/structure/flora/tree/pine
+ name = "pine tree"
+ icon = 'icons/obj/flora/pinetrees.dmi'
+ icon_state = "pine_1"
+ base_state = "pine"
+ product = /obj/item/stack/material/log
+ shake_animation_degrees = 3
+
+/obj/structure/flora/tree/pine/New()
+ ..()
+ icon_state = "[base_state]_[rand(1, 3)]"
+
+
+/obj/structure/flora/tree/pine/xmas
+ name = "xmas tree"
+ icon = 'icons/obj/flora/pinetrees.dmi'
+ icon_state = "pine_c"
+
+/obj/structure/flora/tree/pine/xmas/New()
+ ..()
+ icon_state = "pine_c"
+
+// Palm trees
+
+/obj/structure/flora/tree/palm
+ icon = 'icons/obj/flora/palmtrees.dmi'
+ icon_state = "palm1"
+ base_state = "palm"
+ product = /obj/item/stack/material/log
+ product_amount = 5
+ health = 200
+ max_health = 200
+ pixel_x = 0
+
+/obj/structure/flora/tree/palm/New()
+ ..()
+ icon_state = "[base_state][rand(1, 2)]"
+
+
+// Dead trees
+
+/obj/structure/flora/tree/dead
+ icon = 'icons/obj/flora/deadtrees.dmi'
+ icon_state = "tree_1"
+ base_state = "tree"
+ product = /obj/item/stack/material/log
+ product_amount = 5
+ health = 200
+ max_health = 200
+
+/obj/structure/flora/tree/dead/New()
+ ..()
+ icon_state = "[base_state]_[rand(1, 6)]"
+
+// Small jungle trees
+
+/obj/structure/flora/tree/jungle_small
+ icon = 'icons/obj/flora/jungletreesmall.dmi'
+ icon_state = "tree"
+ base_state = "tree"
+ product = /obj/item/stack/material/log
+ product_amount = 10
+ health = 400
+ max_health = 400
+ pixel_x = -32
+
+/obj/structure/flora/tree/jungle_small/New()
+ ..()
+ icon_state = "[base_state][rand(1, 6)]"
+
+// Big jungle trees
+
+/obj/structure/flora/tree/jungle
+ icon = 'icons/obj/flora/jungletree.dmi'
+ icon_state = "tree"
+ base_state = "tree"
+ product = /obj/item/stack/material/log
+ product_amount = 20
+ health = 800
+ max_health = 800
+ pixel_x = -48
+ pixel_y = -16
+ shake_animation_degrees = 2
+
+/obj/structure/flora/tree/jungle/New()
+ ..()
+ icon_state = "[base_state][rand(1, 6)]"
+
+// Sif trees
+
+/obj/structure/flora/tree/sif
+ name = "glowing tree"
+ desc = "It's a tree, except this one seems quite alien. It glows a deep blue."
+ icon = 'icons/obj/flora/deadtrees.dmi'
+ icon_state = "tree_sif"
+ base_state = "tree_sif"
+ product = /obj/item/stack/material/log/sif
+
+/obj/structure/flora/tree/sif/New()
+ update_icon()
+
+/obj/structure/flora/tree/sif/update_icon()
+ set_light(5, 1, "#33ccff")
+ overlays.Cut()
+ overlays.Add(image(icon = 'icons/obj/flora/deadtrees.dmi', icon_state = "[icon_state]_glow", layer = LIGHTING_LAYER + 0.1))
\ No newline at end of file
diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm
index 6597f62107..ac231eb947 100644
--- a/code/game/objects/structures/lattice.dm
+++ b/code/game/objects/structures/lattice.dm
@@ -68,7 +68,6 @@
new /obj/item/stack/rods(src.loc)
qdel(src)
return
- // VOREStation Edit - Added Catwalks
if (istype(C, /obj/item/stack/rods))
var/obj/item/stack/rods/R = C
if(R.use(2))
@@ -78,7 +77,6 @@
new /obj/structure/catwalk(src.loc)
qdel(src)
return
- // VOREStation Edit End
return
/obj/structure/lattice/proc/updateOverlays()
diff --git a/code/game/objects/structures/railing.dm b/code/game/objects/structures/railing.dm
index 98bae005f8..ea52ed3845 100644
--- a/code/game/objects/structures/railing.dm
+++ b/code/game/objects/structures/railing.dm
@@ -1,7 +1,7 @@
// Based on railing.dmi from https://github.com/Endless-Horizon/CEV-Eris
/obj/structure/railing
name = "railing"
- desc = "A standard steel railing. Play stupid games win stupid prizes."
+ desc = "A standard steel railing. Play stupid games, win stupid prizes."
icon = 'icons/obj/railing.dmi'
density = 1
throwpass = 1
@@ -103,7 +103,7 @@
/obj/structure/railing/update_icon(var/UpdateNeighgors = 1)
NeighborsCheck(UpdateNeighgors)
- //layer = (dir == SOUTH) ? FLY_LAYER : initial(layer) // Vorestation edit because wtf does this even do
+ //layer = (dir == SOUTH) ? FLY_LAYER : initial(layer) // wtf does this even do
overlays.Cut()
if (!check || !anchored)//|| !anchored
icon_state = "railing0"
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index 1a40675ca7..843c2f0dab 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -13,6 +13,7 @@
var/maximal_heat = T0C + 100 // Maximal heat before this window begins taking damage from fire
var/damage_per_fire_tick = 2.0 // Amount of damage per fire tick. Regular windows are not fireproof so they might as well break quickly.
var/health
+ var/force_threshold = 0
var/ini_dir = null
var/state = 2
var/reinf = 0
@@ -313,9 +314,9 @@
return
/obj/structure/window/proc/hit(var/damage, var/sound_effect = 1)
- if(reinf) damage *= 0.5
- if(damage < 5)
+ if(damage < force_threshold || force_threshold < 0)
return
+ if(reinf) damage *= 0.5
take_damage(damage)
return
@@ -452,13 +453,14 @@
/obj/structure/window/basic
- desc = "It looks thin and flimsy. A few knocks with... anything, really should shatter it."
+ desc = "It looks thin and flimsy. A few knocks with... almost anything, really should shatter it."
icon_state = "window"
basestate = "window"
glasstype = /obj/item/stack/material/glass
maximal_heat = T0C + 100
damage_per_fire_tick = 2.0
maxhealth = 12.0
+ force_threshold = 3
/obj/structure/window/phoronbasic
name = "phoron window"
@@ -470,6 +472,7 @@
maximal_heat = T0C + 2000
damage_per_fire_tick = 1.0
maxhealth = 40.0
+ force_threshold = 5
/obj/structure/window/phoronbasic/full
dir = SOUTHWEST
@@ -486,6 +489,7 @@
maximal_heat = T0C + 4000
damage_per_fire_tick = 1.0 // This should last for 80 fire ticks if the window is not damaged at all. The idea is that borosilicate windows have something like ablative layer that protects them for a while.
maxhealth = 80.0
+ force_threshold = 10
/obj/structure/window/phoronreinforced/full
dir = SOUTHWEST
@@ -501,6 +505,7 @@
maximal_heat = T0C + 750
damage_per_fire_tick = 2.0
glasstype = /obj/item/stack/material/glass/reinforced
+ force_threshold = 6
/obj/structure/window/New(Loc, constructed=0)
@@ -528,6 +533,7 @@
icon_state = "fwindow"
basestate = "fwindow"
maxhealth = 30
+ force_threshold = 5
/obj/structure/window/shuttle
name = "shuttle window"
@@ -539,6 +545,7 @@
reinf = 1
basestate = "w"
dir = 5
+ force_threshold = 7
/obj/structure/window/reinforced/polarized
name = "electrochromic window"
diff --git a/code/game/supplyshuttle.dm b/code/game/supplyshuttle.dm
index be376e0f65..2d07f0ffbd 100644
--- a/code/game/supplyshuttle.dm
+++ b/code/game/supplyshuttle.dm
@@ -2,7 +2,7 @@
#define SUPPLY_DOCKZ 2 //Z-level of the Dock.
#define SUPPLY_STATIONZ 1 //Z-level of the Station.
#define SUPPLY_STATION_AREATYPE "/area/supply/station" //Type of the supply shuttle area for station
-#define SUPPLY_DOCK_AREATYPE "/area/supply/dock" //Type of the supply shuttle area for dock
+#define SUPPLY_DOCK_AREATYPE "/area/supply/dock" //Type of the supply shuttle area for dock
//Supply packs are in /code/defines/obj/supplypacks.dm
//Computers are in /code/game/machinery/computer/supply.dm
@@ -10,294 +10,304 @@
var/datum/controller/supply/supply_controller = new()
var/list/mechtoys = list(
- /obj/item/toy/prize/ripley,
- /obj/item/toy/prize/fireripley,
- /obj/item/toy/prize/deathripley,
- /obj/item/toy/prize/gygax,
- /obj/item/toy/prize/durand,
- /obj/item/toy/prize/honk,
- /obj/item/toy/prize/marauder,
- /obj/item/toy/prize/seraph,
- /obj/item/toy/prize/mauler,
- /obj/item/toy/prize/odysseus,
- /obj/item/toy/prize/phazon
+ /obj/item/toy/prize/ripley,
+ /obj/item/toy/prize/fireripley,
+ /obj/item/toy/prize/deathripley,
+ /obj/item/toy/prize/gygax,
+ /obj/item/toy/prize/durand,
+ /obj/item/toy/prize/honk,
+ /obj/item/toy/prize/marauder,
+ /obj/item/toy/prize/seraph,
+ /obj/item/toy/prize/mauler,
+ /obj/item/toy/prize/odysseus,
+ /obj/item/toy/prize/phazon
)
/obj/item/weapon/paper/manifest
- name = "supply manifest"
- var/is_copy = 1
+ name = "supply manifest"
+ var/is_copy = 1
/area/supply/station
- name = "Supply Shuttle"
- icon_state = "shuttle3"
- requires_power = 0
- base_turf = /turf/space
+ name = "Supply Shuttle"
+ icon_state = "shuttle3"
+ requires_power = 0
+ base_turf = /turf/space
/area/supply/dock
- name = "Supply Shuttle"
- icon_state = "shuttle3"
- requires_power = 0
- base_turf = /turf/space
+ name = "Supply Shuttle"
+ icon_state = "shuttle3"
+ requires_power = 0
+ base_turf = /turf/space
/obj/structure/plasticflaps //HOW DO YOU CALL THOSE THINGS ANYWAY
- name = "\improper plastic flaps"
- desc = "Completely impassable - or are they?"
- icon = 'icons/obj/stationobjs.dmi' //Change this.
- icon_state = "plasticflaps"
- density = 0
- anchored = 1
- layer = 4
- explosion_resistance = 5
- var/list/mobs_can_pass = list(
- /mob/living/bot,
- /mob/living/simple_animal/slime,
- /mob/living/simple_animal/mouse,
- /mob/living/silicon/robot/drone
- )
+ name = "\improper plastic flaps"
+ desc = "Completely impassable - or are they?"
+ icon = 'icons/obj/stationobjs.dmi' //Change this.
+ icon_state = "plasticflaps"
+ density = 0
+ anchored = 1
+ layer = 4
+ explosion_resistance = 5
+ var/list/mobs_can_pass = list(
+ /mob/living/bot,
+ /mob/living/simple_animal/slime,
+ /mob/living/simple_animal/mouse,
+ /mob/living/silicon/robot/drone
+ )
/obj/structure/plasticflaps/attackby(obj/item/P, mob/user)
- if(istype(P, /obj/item/weapon/wirecutters))
- playsound(src, P.usesound, 50, 1)
- user << "You start to cut the plastic flaps."
- if(do_after(user, 10 * P.toolspeed))
- user << "You cut the plastic flaps."
- var/obj/item/stack/material/plastic/A = new /obj/item/stack/material/plastic( src.loc )
- A.amount = 4
- qdel(src)
- return
- else
- return
+ if(istype(P, /obj/item/weapon/wirecutters))
+ playsound(src, P.usesound, 50, 1)
+ user << "You start to cut the plastic flaps."
+ if(do_after(user, 10 * P.toolspeed))
+ user << "You cut the plastic flaps."
+ var/obj/item/stack/material/plastic/A = new /obj/item/stack/material/plastic( src.loc )
+ A.amount = 4
+ qdel(src)
+ return
+ else
+ return
/obj/structure/plasticflaps/CanPass(atom/A, turf/T)
- if(istype(A) && A.checkpass(PASSGLASS))
- return prob(60)
+ if(istype(A) && A.checkpass(PASSGLASS))
+ return prob(60)
- var/obj/structure/bed/B = A
- if (istype(A, /obj/structure/bed) && B.buckled_mob)//if it's a bed/chair and someone is buckled, it will not pass
- return 0
+ var/obj/structure/bed/B = A
+ if (istype(A, /obj/structure/bed) && B.buckled_mob)//if it's a bed/chair and someone is buckled, it will not pass
+ return 0
- if(istype(A, /obj/vehicle)) //no vehicles
- return 0
+ if(istype(A, /obj/vehicle)) //no vehicles
+ return 0
- var/mob/living/M = A
- if(istype(M))
- if(M.lying)
- return ..()
- for(var/mob_type in mobs_can_pass)
- if(istype(A, mob_type))
- return ..()
- return issmall(M)
+ var/mob/living/M = A
+ if(istype(M))
+ if(M.lying)
+ return ..()
+ for(var/mob_type in mobs_can_pass)
+ if(istype(A, mob_type))
+ return ..()
+ return issmall(M)
- return ..()
+ return ..()
/obj/structure/plasticflaps/ex_act(severity)
- switch(severity)
- if (1)
- qdel(src)
- if (2)
- if (prob(50))
- qdel(src)
- if (3)
- if (prob(5))
- qdel(src)
+ switch(severity)
+ if (1)
+ qdel(src)
+ if (2)
+ if (prob(50))
+ qdel(src)
+ if (3)
+ if (prob(5))
+ qdel(src)
/obj/structure/plasticflaps/mining //A specific type for mining that doesn't allow airflow because of them damn crates
- name = "airtight plastic flaps"
- desc = "Heavy duty, airtight, plastic flaps."
+ name = "airtight plastic flaps"
+ desc = "Heavy duty, airtight, plastic flaps."
- New() //set the turf below the flaps to block air
- var/turf/T = get_turf(loc)
- if(T)
- T.blocks_air = 1
- ..()
+ New() //set the turf below the flaps to block air
+ var/turf/T = get_turf(loc)
+ if(T)
+ T.blocks_air = 1
+ ..()
- Destroy() //lazy hack to set the turf to allow air to pass if it's a simulated floor
- var/turf/T = get_turf(loc)
- if(T)
- if(istype(T, /turf/simulated/floor))
- T.blocks_air = 0
- ..()
+ Destroy() //lazy hack to set the turf to allow air to pass if it's a simulated floor
+ var/turf/T = get_turf(loc)
+ if(T)
+ if(istype(T, /turf/simulated/floor))
+ T.blocks_air = 0
+ ..()
/*
/obj/effect/marker/supplymarker
- icon_state = "X"
- icon = 'icons/misc/mark.dmi'
- name = "X"
- invisibility = 101
- anchored = 1
- opacity = 0
+ icon_state = "X"
+ icon = 'icons/misc/mark.dmi'
+ name = "X"
+ invisibility = 101
+ anchored = 1
+ opacity = 0
*/
/datum/supply_order
- var/ordernum
- var/datum/supply_packs/object = null
- var/orderedby = null
- var/comment = null
+ var/ordernum
+ var/datum/supply_packs/object = null
+ var/orderedby = null
+ var/comment = null
/datum/controller/supply
- //supply points
- var/points = 50
- var/points_per_process = 1.5
- var/points_per_slip = 2
- var/points_per_platinum = 5 // 5 points per sheet
- var/points_per_phoron = 5
- //control
- var/ordernum
- var/list/shoppinglist = list()
- var/list/requestlist = list()
- var/list/supply_packs = list()
- //shuttle movement
- var/movetime = 1200
- var/datum/shuttle/ferry/supply/shuttle
+ //supply points
+ var/points = 50
+ var/points_per_process = 1.5
+ var/points_per_slip = 2
+ var/points_per_platinum = 5 // 5 points per sheet
+ var/points_per_phoron = 5
+ var/points_per_money = 0.02
+ //control
+ var/ordernum
+ var/list/shoppinglist = list()
+ var/list/requestlist = list()
+ var/list/supply_packs = list()
+ //shuttle movement
+ var/movetime = 1200
+ var/datum/shuttle/ferry/supply/shuttle
- New()
- ordernum = rand(1,9000)
+ New()
+ ordernum = rand(1,9000)
- for(var/typepath in (typesof(/datum/supply_packs) - /datum/supply_packs))
- var/datum/supply_packs/P = new typepath()
- supply_packs[P.name] = P
+ for(var/typepath in (typesof(/datum/supply_packs) - /datum/supply_packs))
+ var/datum/supply_packs/P = new typepath()
+ supply_packs[P.name] = P
- // Supply shuttle ticker - handles supply point regeneration
- // This is called by the process scheduler every thirty seconds
- proc/process()
- points += points_per_process
+ // Supply shuttle ticker - handles supply point regeneration
+ // This is called by the process scheduler every thirty seconds
+ proc/process()
+ points += points_per_process
- //To stop things being sent to CentCom which should not be sent to centcomm. Recursively checks for these types.
- proc/forbidden_atoms_check(atom/A)
- if(istype(A,/mob/living))
- return 1
- if(istype(A,/obj/item/weapon/disk/nuclear))
- return 1
- if(istype(A,/obj/machinery/nuclearbomb))
- return 1
- if(istype(A,/obj/item/device/radio/beacon))
- return 1
+ //To stop things being sent to CentCom which should not be sent to centcomm. Recursively checks for these types.
+ proc/forbidden_atoms_check(atom/A)
+ if(istype(A,/mob/living))
+ return 1
+ if(istype(A,/obj/item/weapon/disk/nuclear))
+ return 1
+ if(istype(A,/obj/machinery/nuclearbomb))
+ return 1
+ if(istype(A,/obj/item/device/radio/beacon))
+ return 1
- for(var/i=1, i<=A.contents.len, i++)
- var/atom/B = A.contents[i]
- if(.(B))
- return 1
+ for(var/i=1, i<=A.contents.len, i++)
+ var/atom/B = A.contents[i]
+ if(.(B))
+ return 1
- //Sellin
- proc/sell()
- var/area/area_shuttle = shuttle.get_location_area()
- if(!area_shuttle) return
+ //Sellin
+ proc/sell()
+ var/area/area_shuttle = shuttle.get_location_area()
+ if(!area_shuttle) return
- callHook("sell_shuttle", list(area_shuttle));
+ callHook("sell_shuttle", list(area_shuttle));
- var/phoron_count = 0
- var/plat_count = 0
+ var/phoron_count = 0
+ var/plat_count = 0
+ var/money_count = 0
- for(var/atom/movable/MA in area_shuttle)
- if(MA.anchored) continue
+ for(var/atom/movable/MA in area_shuttle)
+ if(MA.anchored) continue
- // Must be in a crate!
- if(istype(MA,/obj/structure/closet/crate))
- var/obj/structure/closet/crate/CR = MA
- callHook("sell_crate", list(CR, area_shuttle))
+ // Must be in a crate!
+ if(istype(MA,/obj/structure/closet/crate))
+ var/obj/structure/closet/crate/CR = MA
+ callHook("sell_crate", list(CR, area_shuttle))
- points += CR.points_per_crate
- var/find_slip = 1
+ points += CR.points_per_crate
+ var/find_slip = 1
- for(var/atom in CR)
- // Sell manifests
- var/atom/A = atom
- if(find_slip && istype(A,/obj/item/weapon/paper/manifest))
- var/obj/item/weapon/paper/manifest/slip = A
- if(!slip.is_copy && slip.stamped && slip.stamped.len) //yes, the clown stamp will work. clown is the highest authority on the station, it makes sense
- points += points_per_slip
- find_slip = 0
- continue
+ for(var/atom in CR)
+ // Sell manifests
+ var/atom/A = atom
+ if(find_slip && istype(A,/obj/item/weapon/paper/manifest))
+ var/obj/item/weapon/paper/manifest/slip = A
+ if(!slip.is_copy && slip.stamped && slip.stamped.len) //yes, the clown stamp will work. clown is the highest authority on the station, it makes sense
+ points += points_per_slip
+ find_slip = 0
+ continue
- // Sell phoron and platinum
- if(istype(A, /obj/item/stack))
- var/obj/item/stack/P = A
- switch(P.get_material_name())
- if("phoron") phoron_count += P.get_amount()
- if("platinum") plat_count += P.get_amount()
- qdel(MA)
+ // Sell phoron and platinum
+ if(istype(A, /obj/item/stack))
+ var/obj/item/stack/P = A
+ switch(P.get_material_name())
+ if("phoron") phoron_count += P.get_amount()
+ if("platinum") plat_count += P.get_amount()
- if(phoron_count)
- points += phoron_count * points_per_phoron
+ //Sell spacebucks
+ if(istype(A, /obj/item/weapon/spacecash))
+ var/obj/item/weapon/spacecash/cashmoney = A
+ money_count += cashmoney.worth
+ qdel(MA)
- if(plat_count)
- points += plat_count * points_per_platinum
+ if(phoron_count)
+ points += phoron_count * points_per_phoron
- //Buyin
- proc/buy()
- if(!shoppinglist.len) return
+ if(plat_count)
+ points += plat_count * points_per_platinum
- var/area/area_shuttle = shuttle.get_location_area()
- if(!area_shuttle) return
+ if(money_count)
+ points += money_count * points_per_money
- var/list/clear_turfs = list()
+ //Buyin
+ proc/buy()
+ if(!shoppinglist.len) return
- for(var/turf/T in area_shuttle)
- if(T.density) continue
- var/contcount
- for(var/atom/A in T.contents)
- if(!A.simulated)
- continue
- contcount++
- if(contcount)
- continue
- clear_turfs += T
+ var/area/area_shuttle = shuttle.get_location_area()
+ if(!area_shuttle) return
- for(var/S in shoppinglist)
- if(!clear_turfs.len) break
- var/i = rand(1,clear_turfs.len)
- var/turf/pickedloc = clear_turfs[i]
- clear_turfs.Cut(i,i+1)
- shoppinglist -= S
+ var/list/clear_turfs = list()
- var/datum/supply_order/SO = S
- var/datum/supply_packs/SP = SO.object
+ for(var/turf/T in area_shuttle)
+ if(T.density) continue
+ var/contcount
+ for(var/atom/A in T.contents)
+ if(!A.simulated)
+ continue
+ contcount++
+ if(contcount)
+ continue
+ clear_turfs += T
- var/obj/A = new SP.containertype(pickedloc)
- A.name = "[SP.containername] [SO.comment ? "([SO.comment])":"" ]"
+ for(var/S in shoppinglist)
+ if(!clear_turfs.len) break
+ var/i = rand(1,clear_turfs.len)
+ var/turf/pickedloc = clear_turfs[i]
+ clear_turfs.Cut(i,i+1)
+ shoppinglist -= S
- //supply manifest generation begin
+ var/datum/supply_order/SO = S
+ var/datum/supply_packs/SP = SO.object
- var/obj/item/weapon/paper/manifest/slip
- if(!SP.contraband)
- slip = new /obj/item/weapon/paper/manifest(A)
- slip.is_copy = 0
- slip.info = "
[command_name()] Shipping Manifest
"
- slip.info +="Order #[SO.ordernum]
"
- slip.info +="Destination: [station_name()]
"
- slip.info +="[shoppinglist.len] PACKAGES IN THIS SHIPMENT
"
- slip.info +="CONTENTS:
"
+ var/obj/A = new SP.containertype(pickedloc)
+ A.name = "[SP.containername] [SO.comment ? "([SO.comment])":"" ]"
- //spawn the stuff, finish generating the manifest while you're at it
- if(SP.access)
- if(isnum(SP.access))
- A.req_access = list(SP.access)
- else if(islist(SP.access))
- var/list/L = SP.access // access var is a plain var, we need a list
- A.req_access = L.Copy()
- else
- world << "Supply pack with invalid access restriction [SP.access] encountered!"
+ //supply manifest generation begin
- var/list/contains
- if(istype(SP,/datum/supply_packs/randomised))
- var/datum/supply_packs/randomised/SPR = SP
- contains = list()
- if(SPR.contains.len)
- for(var/j=1,j<=SPR.num_contained,j++)
- contains += pick(SPR.contains)
- else
- contains = SP.contains
+ var/obj/item/weapon/paper/manifest/slip
+ if(!SP.contraband)
+ slip = new /obj/item/weapon/paper/manifest(A)
+ slip.is_copy = 0
+ slip.info = "[command_name()] Shipping Manifest
"
+ slip.info +="Order #[SO.ordernum]
"
+ slip.info +="Destination: [station_name()]
"
+ slip.info +="[shoppinglist.len] PACKAGES IN THIS SHIPMENT
"
+ slip.info +="CONTENTS:
"
- for(var/typepath in contains)
- if(!typepath) continue
- var/number_of_items = max(1, contains[typepath])
- for(var/j = 1 to number_of_items)
- var/atom/B2 = new typepath(A)
- if(slip) slip.info += "- [B2.name]
" //add the item to the manifest
+ //spawn the stuff, finish generating the manifest while you're at it
+ if(SP.access)
+ if(isnum(SP.access))
+ A.req_access = list(SP.access)
+ else if(islist(SP.access))
+ var/list/L = SP.access // access var is a plain var, we need a list
+ A.req_access = L.Copy()
+ else
+ world << "Supply pack with invalid access restriction [SP.access] encountered!"
- //manifest finalisation
- if(slip)
- slip.info += "
"
- slip.info += "CHECK CONTENTS AND STAMP BELOW THE LINE TO CONFIRM RECEIPT OF GOODS
"
+ var/list/contains
+ if(istype(SP,/datum/supply_packs/randomised))
+ var/datum/supply_packs/randomised/SPR = SP
+ contains = list()
+ if(SPR.contains.len)
+ for(var/j=1,j<=SPR.num_contained,j++)
+ contains += pick(SPR.contains)
+ else
+ contains = SP.contains
- return
+ for(var/typepath in contains)
+ if(!typepath) continue
+ var/number_of_items = max(1, contains[typepath])
+ for(var/j = 1 to number_of_items)
+ var/atom/B2 = new typepath(A)
+ if(slip) slip.info += "- [B2.name]
" //add the item to the manifest
+
+ //manifest finalisation
+ if(slip)
+ slip.info += "
"
+ slip.info += "CHECK CONTENTS AND STAMP BELOW THE LINE TO CONFIRM RECEIPT OF GOODS
"
+
+ return
\ No newline at end of file
diff --git a/code/game/turfs/flooring/flooring_decals.dm b/code/game/turfs/flooring/flooring_decals.dm
index 3aaa2409b9..6e2d4e48ac 100644
--- a/code/game/turfs/flooring/flooring_decals.dm
+++ b/code/game/turfs/flooring/flooring_decals.dm
@@ -14,7 +14,7 @@ var/list/floor_decals = list()
if(newcolour) color = newcolour
..(newloc)
-// VOREStation Edit - Hack to workaround byond crash bug
+// Hack to workaround byond crash bug
/obj/effect/floor_decal/initialize()
if(!floor_decals_initialized || !loc || QDELETED(src))
return
@@ -23,7 +23,6 @@ var/list/floor_decals = list()
T.apply_decals()
qdel(src)
return
-// VOREStation Edit End
/obj/effect/floor_decal/reset
name = "reset marker"
diff --git a/code/game/turfs/simulated/floor_icon.dm b/code/game/turfs/simulated/floor_icon.dm
index dadb173d99..24008b485e 100644
--- a/code/game/turfs/simulated/floor_icon.dm
+++ b/code/game/turfs/simulated/floor_icon.dm
@@ -60,11 +60,10 @@ var/list/flooring_cache = list()
if(!(istype(T) && T.flooring && T.flooring.name == flooring.name))
overlays |= get_flooring_overlay("[flooring.icon_base]-corner-[SOUTHWEST]", "[flooring.icon_base]_corners", SOUTHWEST)
- // VOREStation Edit - Hack workaround to byond crash bug
+ // Hack workaround to byond crash bug
//if(decals && decals.len)
//overlays |= decals
apply_decals()
- // VOREStation Edit End
if(is_plating() && !(isnull(broken) && isnull(burnt))) //temp, todo
icon = 'icons/turf/flooring/plating.dmi'
diff --git a/code/game/turfs/simulated/outdoors/snow.dm b/code/game/turfs/simulated/outdoors/snow.dm
index 16678d7c98..22f9085a8c 100644
--- a/code/game/turfs/simulated/outdoors/snow.dm
+++ b/code/game/turfs/simulated/outdoors/snow.dm
@@ -25,7 +25,7 @@
/turf/simulated/floor/outdoors/snow/attackby(var/obj/item/W, var/mob/user)
if(istype(W, /obj/item/weapon/shovel))
to_chat(user, "You begin to remove \the [src] with your [W].")
- if(do_after(user, 4 SECONDS))
+ if(do_after(user, 4 SECONDS * W.toolspeed))
to_chat(user, "\The [src] has been dug up, and now lies in a pile nearby.")
new /obj/item/stack/material/snow(src)
demote()
diff --git a/code/game/turfs/simulated/wall_types.dm b/code/game/turfs/simulated/wall_types.dm
index 9d939caab6..66ad584150 100644
--- a/code/game/turfs/simulated/wall_types.dm
+++ b/code/game/turfs/simulated/wall_types.dm
@@ -53,6 +53,12 @@
/turf/simulated/wall/sifwood/New(var/newloc)
..(newloc,"alien wood")
+/turf/simulated/wall/log/New(var/newloc)
+ ..(newloc,"log")
+
+/turf/simulated/wall/log_sif/New(var/newloc)
+ ..(newloc,"alien log")
+
// Shuttle Walls
/turf/simulated/shuttle/wall
name = "autojoin wall"
diff --git a/code/game/verbs/who.dm b/code/game/verbs/who.dm
index 8b50dfb095..06402a90a4 100644
--- a/code/game/verbs/who.dm
+++ b/code/game/verbs/who.dm
@@ -70,16 +70,16 @@
var/msg = ""
var/modmsg = ""
var/devmsg = ""
- var/mentmsg = ""
+ var/eventMmsg = ""
var/num_mods_online = 0
var/num_admins_online = 0
var/num_devs_online = 0
- var/num_mentors_online = 0
+ var/num_event_managers_online = 0
if(holder)
for(var/client/C in admins)
- if(R_ADMIN & C.holder.rights || (!R_MOD & C.holder.rights && !R_MENTOR & C.holder.rights)) //Used to determine who shows up in admin rows
+ if(R_ADMIN & C.holder.rights || (!R_MOD & C.holder.rights && !R_EVENT & C.holder.rights)) //Used to determine who shows up in admin rows
- if(C.holder.fakekey && (!R_ADMIN & holder.rights && !R_MOD & holder.rights)) //Mentors can't see stealthmins
+ if(C.holder.fakekey && (!R_ADMIN & holder.rights && !R_MOD & holder.rights)) //Event Managerss can't see stealthmins
continue
msg += "\t[C] is a [C.holder.rank]"
@@ -102,7 +102,7 @@
msg += "\n"
num_admins_online++
- else if(R_MOD & C.holder.rights) //Who shows up in mod/mentor rows.
+ else if(R_MOD & C.holder.rights) //Who shows up in mod rows.
modmsg += "\t[C] is a [C.holder.rank]"
if(isobserver(C.mob))
@@ -137,26 +137,26 @@
devmsg += "\n"
num_devs_online++
- else if(R_MENTOR & C.holder.rights)
- mentmsg += "\t[C] is a [C.holder.rank]"
+ else if(R_EVENT & C.holder.rights)
+ eventMmsg += "\t[C] is a [C.holder.rank]"
if(isobserver(C.mob))
- mentmsg += " - Observing"
+ eventMmsg += " - Observing"
else if(istype(C.mob,/mob/new_player))
- mentmsg += " - Lobby"
+ eventMmsg += " - Lobby"
else
- mentmsg += " - Playing"
+ eventMmsg += " - Playing"
if(C.is_afk())
var/seconds = C.last_activity_seconds()
- mentmsg += " (AFK - "
- mentmsg += "[round(seconds / 60)] minutes, "
- mentmsg += "[seconds % 60] seconds)"
- mentmsg += "\n"
- num_mentors_online++
+ eventMmsg += " (AFK - "
+ eventMmsg += "[round(seconds / 60)] minutes, "
+ eventMmsg += "[seconds % 60] seconds)"
+ eventMmsg += "\n"
+ num_event_managers_online++
else
for(var/client/C in admins)
- if(R_ADMIN & C.holder.rights || (!R_MOD & C.holder.rights && !R_MENTOR & C.holder.rights))
+ if(R_ADMIN & C.holder.rights || (!R_MOD & C.holder.rights && !R_EVENT & C.holder.rights))
if(!C.holder.fakekey)
msg += "\t[C] is a [C.holder.rank]\n"
num_admins_online++
@@ -166,9 +166,9 @@
else if (R_SERVER & C.holder.rights)
devmsg += "\t[C] is a [C.holder.rank]\n"
num_devs_online++
- else if (R_MENTOR & C.holder.rights)
- mentmsg += "\t[C] is a [C.holder.rank]\n"
- num_mentors_online++
+ else if (R_EVENT & C.holder.rights)
+ eventMmsg += "\t[C] is a [C.holder.rank]\n"
+ num_event_managers_online++
if(config.admin_irc)
src << "Adminhelps are also sent to IRC. If no admins are available in game try anyway and an admin on IRC may see it and respond."
@@ -180,7 +180,7 @@
if(config.show_devs)
msg += "\n Current Developers ([num_devs_online]):\n" + devmsg
- if(config.show_mentors)
- msg += "\n Current Mentors ([num_mentors_online]):\n" + mentmsg
+ if(config.show_event_managers)
+ msg += "\n Current Event Managers ([num_event_managers_online]):\n" + eventMmsg
src << msg
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 95d55b32dd..c5ebcf7587 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -863,7 +863,7 @@ var/datum/announcement/minor/admin_min_announcer = new
set desc="Delay the game start/end"
set name="Delay"
- if(!check_rights(R_SERVER)) return
+ if(!check_rights(R_SERVER|R_EVENT)) return
if (!ticker || ticker.current_state != GAME_STATE_PREGAME)
ticker.delay_end = !ticker.delay_end
log_admin("[key_name(usr)] [ticker.delay_end ? "delayed the round end" : "has made the round end normally"].")
@@ -1228,16 +1228,16 @@ var/datum/announcement/minor/admin_min_announcer = new
/*
- helper proc to test if someone is a mentor or not. Got tired of writing this same check all over the place.
+ helper proc to test if someone is an event manager or not. Got tired of writing this same check all over the place.
*/
-/proc/is_mentor(client/C)
+/proc/is_eventM(client/C)
if(!istype(C))
return 0
if(!C.holder)
return 0
- if(C.holder.rights == R_MENTOR)
+ if(C.holder.rights == R_EVENT)
return 1
return 0
@@ -1269,7 +1269,7 @@ var/datum/announcement/minor/admin_min_announcer = new
var/ref_mob = "\ref[M]"
return "[key_name(C, link, name, highlight_special)](VV)([admin_jump_link(M, src)]) (TAKE)"
- if(4) //Mentors
+ if(4) //Event Managers
var/ref_mob = "\ref[M]"
return "[key_name(C, link, name, highlight_special)] (?) (PP) (VV) (SM) ([admin_jump_link(M, src)]) (TAKE)"
diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm
index 3652237454..12c00aa708 100644
--- a/code/modules/admin/admin_ranks.dm
+++ b/code/modules/admin/admin_ranks.dm
@@ -37,11 +37,11 @@ var/list/admin_ranks = list() //list of all ranks with associated rights
if("stealth") rights |= R_STEALTH
if("rejuv","rejuvinate") rights |= R_REJUVINATE
if("varedit") rights |= R_VAREDIT
- if("everything","host","all") rights |= (R_HOST | R_BUILDMODE | R_ADMIN | R_BAN | R_FUN | R_SERVER | R_DEBUG | R_PERMISSIONS | R_POSSESS | R_STEALTH | R_REJUVINATE | R_VAREDIT | R_SOUNDS | R_SPAWN | R_MOD| R_MENTOR)
+ if("everything","host","all") rights |= (R_HOST | R_BUILDMODE | R_ADMIN | R_BAN | R_FUN | R_SERVER | R_DEBUG | R_PERMISSIONS | R_POSSESS | R_STEALTH | R_REJUVINATE | R_VAREDIT | R_SOUNDS | R_SPAWN | R_MOD| R_EVENT)
if("sound","sounds") rights |= R_SOUNDS
if("spawn","create") rights |= R_SPAWN
if("mod") rights |= R_MOD
- if("mentor") rights |= R_MENTOR
+ if("event") rights |= R_EVENT
admin_ranks[rank] = rights
previous_rights = rights
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index ec673b321c..2151bc1ab0 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -8,7 +8,7 @@ var/list/admin_verbs_default = list(
/client/proc/debug_variables, //allows us to -see- the variables of any instance in the game. +VAREDIT needed to modify,
// /client/proc/check_antagonists, //shows all antags,
// /client/proc/cmd_mod_say,
- /client/proc/cmd_mentor_check_new_players,
+ /client/proc/cmd_eventM_check_new_players,
// /client/proc/deadchat //toggles deadchat on/off,
// /client/proc/toggle_ahelp_sound,
)
@@ -188,7 +188,7 @@ var/list/admin_verbs_debug = list(
/client/proc/cmd_debug_tog_aliens,
/client/proc/air_report,
/client/proc/reload_admins,
- /client/proc/reload_mentors,
+ /client/proc/reload_eventMs,
/client/proc/restart_controller,
/datum/admins/proc/restart,
/client/proc/print_random_map,
@@ -333,19 +333,53 @@ var/list/admin_verbs_mod = list(
/client/proc/getserverlog, //allows us to fetch server logs (diary) for other days,
/datum/admins/proc/view_txt_log, //shows the server log (diary) for today,
/datum/admins/proc/view_atk_log //shows the server combat-log, doesn't do anything presently,
-
-
)
-var/list/admin_verbs_mentor = list(
+var/list/admin_verbs_event_manager = list(
/client/proc/cmd_admin_pm_context,
/client/proc/cmd_admin_pm_panel,
/datum/admins/proc/PlayerNotes,
/client/proc/admin_ghost,
/client/proc/cmd_mod_say,
/datum/admins/proc/show_player_info,
-// /client/proc/dsay,
- /client/proc/cmd_admin_subtle_message
+ /client/proc/dsay,
+ /client/proc/cmd_admin_subtle_message,
+ /client/proc/debug_variables,
+ /client/proc/check_antagonists,
+ /client/proc/aooc,
+ /datum/admins/proc/paralyze_mob,
+ /client/proc/cmd_admin_direct_narrate,
+ /client/proc/allow_character_respawn,
+ /datum/admins/proc/sendFax,
+ /client/proc/respawn_character,
+ /proc/possess,
+ /proc/release,
+ /client/proc/callproc,
+ /client/proc/callproc_target,
+ /client/proc/debug_controller,
+ /client/proc/show_gm_status,
+ /datum/admins/proc/change_weather,
+ /datum/admins/proc/change_time,
+ /client/proc/admin_give_modifier,
+ /client/proc/Jump,
+ /client/proc/jumptomob,
+ /client/proc/jumptocoord,
+ /client/proc/cmd_admin_delete,
+ /datum/admins/proc/delay,
+ /client/proc/Set_Holiday,
+ /client/proc/make_sound,
+ /client/proc/toggle_random_events,
+ /datum/admins/proc/cmd_admin_dress,
+ /client/proc/cmd_admin_gib_self,
+ /client/proc/drop_bomb,
+ /client/proc/cmd_admin_add_freeform_ai_law,
+ /client/proc/cmd_admin_add_random_ai_law,
+ /client/proc/make_sound,
+ /client/proc/toggle_random_events,
+ /client/proc/editappear,
+ /client/proc/roll_dices,
+ /datum/admins/proc/call_supply_drop,
+ /datum/admins/proc/call_drop_pod
)
/client/proc/add_admin_verbs()
@@ -367,7 +401,7 @@ var/list/admin_verbs_mentor = list(
if(holder.rights & R_SOUNDS) verbs += admin_verbs_sounds
if(holder.rights & R_SPAWN) verbs += admin_verbs_spawn
if(holder.rights & R_MOD) verbs += admin_verbs_mod
- if(holder.rights & R_MENTOR) verbs += admin_verbs_mentor
+ if(holder.rights & R_EVENT) verbs += admin_verbs_event_manager
/client/proc/remove_admin_verbs()
verbs.Remove(
@@ -430,12 +464,10 @@ var/list/admin_verbs_mentor = list(
if(istype(mob,/mob/observer/dead))
//re-enter
var/mob/observer/dead/ghost = mob
- if(!is_mentor(usr.client))
- ghost.can_reenter_corpse = 1
if(ghost.can_reenter_corpse)
ghost.reenter_corpse()
else
- ghost << "Error: Aghost: Can't reenter corpse, mentors that use adminHUD while aghosting are not permitted to enter their corpse again"
+ ghost << "Error: Aghost: Can't reenter corpse, event managers that use adminHUD while aghosting are not permitted to enter their corpse again"
return
feedback_add_details("admin_verb","P") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm
index ece5f068d7..1531790268 100644
--- a/code/modules/admin/player_panel.dm
+++ b/code/modules/admin/player_panel.dm
@@ -367,7 +367,7 @@
if(usr.client)
var/client/C = usr.client
- if(is_mentor(C))
+ if(is_eventM(C))
dat += {" N/A | "}
else
switch(is_special_character(M))
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 350bfe9a24..71069be22e 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -237,7 +237,7 @@
href_list["secretsadmin"] = "check_antagonist"
else if(href_list["delay_round_end"])
- if(!check_rights(R_SERVER)) return
+ if(!check_rights(R_SERVER|R_EVENT)) return
ticker.delay_end = !ticker.delay_end
log_admin("[key_name(usr)] [ticker.delay_end ? "delayed the round end" : "has made the round end normally"].")
@@ -1194,7 +1194,7 @@
show_player_panel(M)
else if(href_list["adminplayerobservejump"])
- if(!check_rights(R_MENTOR|R_MOD|R_ADMIN|R_SERVER)) return
+ if(!check_rights(R_EVENT|R_MOD|R_ADMIN|R_SERVER|R_EVENT)) return
var/mob/M = locate(href_list["adminplayerobservejump"])
@@ -1204,7 +1204,7 @@
C.jumptomob(M)
else if(href_list["adminplayerobservefollow"])
- if(!check_rights(R_MENTOR|R_MOD|R_ADMIN|R_SERVER))
+ if(!check_rights(R_EVENT|R_MOD|R_ADMIN|R_SERVER|R_EVENT))
return
var/mob/M = locate(href_list["adminplayerobservefollow"])
@@ -1224,14 +1224,14 @@
if(ismob(M))
var/take_msg = "ADMINHELP: [key_name(usr.client)] is attending to [key_name(M)]'s adminhelp, please don't dogpile them."
for(var/client/X in admins)
- if((R_ADMIN|R_MOD|R_MENTOR) & X.holder.rights)
+ if((R_ADMIN|R_MOD|R_EVENT) & X.holder.rights)
to_chat(X, take_msg)
to_chat(M, "Your adminhelp is being attended to by [usr.client]. Thanks for your patience!")
else
to_chat(usr, "Unable to locate mob.")
else if(href_list["adminplayerobservecoodjump"])
- if(!check_rights(R_ADMIN|R_SERVER|R_MOD)) return
+ if(!check_rights(R_ADMIN|R_SERVER|R_MOD|R_EVENT)) return
var/x = text2num(href_list["X"])
var/y = text2num(href_list["Y"])
@@ -1843,7 +1843,7 @@
vsc.SetDefault(usr)
else if(href_list["toglang"])
- if(check_rights(R_SPAWN))
+ if(check_rights(R_SPAWN|R_EVENT))
var/mob/M = locate(href_list["toglang"])
if(!istype(M))
usr << "[M] is illegal type, must be /mob!"
diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm
index cb16b16a42..c843255f85 100644
--- a/code/modules/admin/verbs/adminhelp.dm
+++ b/code/modules/admin/verbs/adminhelp.dm
@@ -88,24 +88,20 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","
if(ai_found)
ai_cl = " (CL)"
- //Options bar: mob, details ( admin = 2, dev = 3, mentor = 4, character name (0 = just ckey, 1 = ckey and character name), link? (0 no don't make it a link, 1 do so),
+ //Options bar: mob, details ( admin = 2, dev = 3, event manager = 4, character name (0 = just ckey, 1 = ckey and character name), link? (0 no don't make it a link, 1 do so),
// highlight special roles (0 = everyone has same looking name, 1 = antags / special roles get a golden name)
- var/mentor_msg = "Request for Help: [get_options_bar(mob, 4, 1, 1, 0)][ai_cl]: [msg]"
msg = "Request for Help: [get_options_bar(mob, 2, 1, 1)][ai_cl] [msg]"
var/admin_number_afk = 0
for(var/client/X in admins)
- if((R_ADMIN|R_MOD|R_MENTOR|R_SERVER) & X.holder.rights)
+ if((R_ADMIN|R_MOD|R_EVENT|R_SERVER) & X.holder.rights)
if(X.is_afk())
admin_number_afk++
+ X << msg
if(X.is_preference_enabled(/datum/client_preference/holder/play_adminhelp_ping))
X << 'sound/effects/adminhelp.ogg'
- if(X.holder.rights == R_MENTOR)
- X << mentor_msg // Mentors won't see coloring of names on people with special_roles (Antags, etc.)
- else
- X << msg
//show it to the person adminhelping too
src << "PM to-Staff : [original_msg]"
diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm
index bcb87f06d8..dcaa745485 100644
--- a/code/modules/admin/verbs/adminpm.dm
+++ b/code/modules/admin/verbs/adminpm.dm
@@ -112,7 +112,7 @@
//check client/X is an admin and isn't the sender or recipient
if(X == C || X == src)
continue
- if(X.key != key && X.key != C.key && (X.holder.rights & R_ADMIN|R_MOD|R_MENTOR))
+ if(X.key != key && X.key != C.key && (X.holder.rights & R_ADMIN|R_MOD|R_EVENT))
X << "" + create_text_tag("pm_other", "PM:", X) + " [key_name(src, X, 0)] to [key_name(C, X, 0)]: [msg]"
/client/proc/cmd_admin_irc_pm(sender)
diff --git a/code/modules/admin/verbs/adminsay.dm b/code/modules/admin/verbs/adminsay.dm
index b4e60fbd62..63209f84b4 100644
--- a/code/modules/admin/verbs/adminsay.dm
+++ b/code/modules/admin/verbs/adminsay.dm
@@ -23,7 +23,7 @@
set name = "Msay"
set hidden = 1
- if(!check_rights(R_ADMIN|R_MOD|R_MENTOR|R_SERVER))
+ if(!check_rights(R_ADMIN|R_MOD|R_SERVER))
return
msg = sanitize(msg)
@@ -45,7 +45,7 @@
set name = "Esay"
set hidden = 1
- if(!check_rights(R_ADMIN|R_MOD|R_MENTOR|R_SERVER))
+ if(!check_rights(R_ADMIN|R_MOD|R_EVENT|R_SERVER))
return
msg = sanitize(msg)
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index 1845dd6569..58bc18f4b3 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -408,10 +408,10 @@
feedback_add_details("admin_verb","SEQ")
dressup_human(H, outfit, 1)
-/proc/dressup_human(var/mob/living/carbon/human/H, var/decl/hierarchy/outfit/outfit, var/undress = 1)
+/proc/dressup_human(var/mob/living/carbon/human/H, var/decl/hierarchy/outfit/outfit)
if(!H || !outfit)
return
- if(undress)
+ if(outfit.undress)
H.delete_inventory()
outfit.equip(H)
log_and_message_admins("changed the equipment of [key_name(H)] to [outfit.name].")
diff --git a/code/modules/admin/verbs/diagnostics.dm b/code/modules/admin/verbs/diagnostics.dm
index b78b473e65..595675ea80 100644
--- a/code/modules/admin/verbs/diagnostics.dm
+++ b/code/modules/admin/verbs/diagnostics.dm
@@ -108,13 +108,13 @@
load_admins()
feedback_add_details("admin_verb","RLDA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-/client/proc/reload_mentors()
- set name = "Reload Mentors"
+/client/proc/reload_eventMs()
+ set name = "Reload Event Managers"
set category = "Debug"
if(!check_rights(R_SERVER)) return
- message_admins("[usr] manually reloaded Mentors")
+ message_admins("[usr] manually reloaded Event Managers")
world.load_mods()
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index fcf4a5db0c..c14c74edd1 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -65,7 +65,7 @@
message_admins("SubtleMessage: [key_name_admin(usr)] -> [key_name_admin(M)] : [msg]", 1)
feedback_add_details("admin_verb","SMS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-/client/proc/cmd_mentor_check_new_players() //Allows mentors / admins to determine who the newer players are.
+/client/proc/cmd_eventM_check_new_players() //Allows event managers / admins to determine who the newer players are.
set category = "Admin"
set name = "Check new Players"
if(!holder)
@@ -82,7 +82,7 @@
var/msg = ""
var/highlight_special_characters = 1
- if(is_mentor(usr.client))
+ if(is_eventM(usr.client))
highlight_special_characters = 0
for(var/client/C in clients)
@@ -610,7 +610,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
set category = "Special Verbs"
set name = "Explosion"
- if(!check_rights(R_DEBUG|R_FUN)) return
+ if(!check_rights(R_DEBUG|R_FUN|R_EVENT)) return
var/devastation = input("Range of total devastation. -1 to none", text("Input")) as num|null
if(devastation == null) return
@@ -638,7 +638,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
set category = "Special Verbs"
set name = "EM Pulse"
- if(!check_rights(R_DEBUG|R_FUN)) return
+ if(!check_rights(R_DEBUG|R_FUN|R_EVENT)) return
var/heavy = input("Range of heavy pulse.", text("Input")) as num|null
if(heavy == null) return
@@ -664,7 +664,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
set category = "Special Verbs"
set name = "Gib"
- if(!check_rights(R_ADMIN|R_FUN)) return
+ if(!check_rights(R_ADMIN|R_FUN|R_EVENT)) return
var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No")
if(confirm != "Yes") return
@@ -820,7 +820,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
if ((!( ticker ) || !emergency_shuttle.location()))
return
- if(!check_rights(R_ADMIN)) return
+ if(!check_rights(R_ADMIN|R_EVENT)) return
var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No")
if(confirm != "Yes") return
@@ -849,7 +849,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
set category = "Admin"
set name = "Cancel Shuttle"
- if(!check_rights(R_ADMIN)) return
+ if(!check_rights(R_ADMIN|R_EVENT)) return
if(alert(src, "You sure?", "Confirm", "Yes", "No") != "Yes") return
@@ -870,7 +870,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
if (!ticker)
return
- if(!check_rights(R_ADMIN)) return
+ if(!check_rights(R_ADMIN|R_EVENT)) return
emergency_shuttle.deny_shuttle = !emergency_shuttle.deny_shuttle
@@ -926,7 +926,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
set name = "Toggle random events on/off"
set desc = "Toggles random events such as meteors, black holes, blob (but not space dust) on/off"
- if(!check_rights(R_SERVER)) return
+ if(!check_rights(R_SERVER|R_EVENT)) return
if(!config.allow_random_events)
config.allow_random_events = 1
diff --git a/code/modules/busy_space/organizations.dm b/code/modules/busy_space/organizations.dm
index e9ff11e963..26e3a9c733 100644
--- a/code/modules/busy_space/organizations.dm
+++ b/code/modules/busy_space/organizations.dm
@@ -363,7 +363,7 @@
"Please Don't Explode II"
)
destination_names = list(
- "A trade outpost in Shelf"
+ "a trade outpost in Shelf"
)
/datum/lore/organization/tsc/xion
diff --git a/code/modules/client/preference_setup/general/01_basic.dm b/code/modules/client/preference_setup/general/01_basic.dm
index 0d5721a81e..be33813825 100644
--- a/code/modules/client/preference_setup/general/01_basic.dm
+++ b/code/modules/client/preference_setup/general/01_basic.dm
@@ -12,6 +12,7 @@ datum/preferences/proc/set_biological_gender(var/gender)
/datum/category_item/player_setup_item/general/basic/load_character(var/savefile/S)
S["real_name"] >> pref.real_name
+ S["nickname"] >> pref.nickname
S["name_is_always_random"] >> pref.be_random_name
S["gender"] >> pref.biological_gender
S["id_gender"] >> pref.identifying_gender
@@ -21,6 +22,7 @@ datum/preferences/proc/set_biological_gender(var/gender)
/datum/category_item/player_setup_item/general/basic/save_character(var/savefile/S)
S["real_name"] << pref.real_name
+ S["nickname"] << pref.nickname
S["name_is_always_random"] << pref.be_random_name
S["gender"] << pref.biological_gender
S["id_gender"] << pref.identifying_gender
@@ -35,6 +37,7 @@ datum/preferences/proc/set_biological_gender(var/gender)
pref.real_name = sanitize_name(pref.real_name, pref.species, is_FBP())
if(!pref.real_name)
pref.real_name = random_name(pref.identifying_gender, pref.species)
+ pref.nickname = sanitize_name(pref.nickname)
pref.spawnpoint = sanitize_inlist(pref.spawnpoint, spawntypes, initial(pref.spawnpoint))
pref.be_random_name = sanitize_integer(pref.be_random_name, 0, 1, initial(pref.be_random_name))
@@ -53,6 +56,8 @@ datum/preferences/proc/set_biological_gender(var/gender)
if(character.dna)
character.dna.real_name = character.real_name
+ character.nickname = pref.nickname
+
character.gender = pref.biological_gender
character.identifying_gender = pref.identifying_gender
character.age = pref.age
@@ -62,7 +67,9 @@ datum/preferences/proc/set_biological_gender(var/gender)
. += "Name: "
. += "[pref.real_name]
"
. += "Randomize Name
"
- . += "Always Random Name: [pref.be_random_name ? "Yes" : "No"]"
+ . += "Always Random Name: [pref.be_random_name ? "Yes" : "No"]
"
+ . += "Nickname: "
+ . += "[pref.nickname]"
. += "
"
. += "Biological Gender: [gender2text(pref.biological_gender)]
"
. += "Gender Identity: [gender2text(pref.identifying_gender)]
"
@@ -92,6 +99,17 @@ datum/preferences/proc/set_biological_gender(var/gender)
pref.be_random_name = !pref.be_random_name
return TOPIC_REFRESH
+ else if(href_list["nickname"])
+ var/raw_nickname = input(user, "Choose your character's nickname:", "Character Nickname") as text|null
+ if (!isnull(raw_nickname) && CanUseTopic(user))
+ var/new_nickname = sanitize_name(raw_nickname, pref.species, is_FBP())
+ if(new_nickname)
+ pref.nickname = new_nickname
+ return TOPIC_REFRESH
+ else
+ user << "Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and ."
+ return TOPIC_NOACTION
+
else if(href_list["bio_gender"])
var/new_gender = input(user, "Choose your character's biological gender:", "Character Preference", pref.biological_gender) as null|anything in get_genders()
if(new_gender && CanUseTopic(user))
diff --git a/code/modules/client/preference_setup/general/03_body.dm b/code/modules/client/preference_setup/general/03_body.dm
index c59ecebf6a..ab70fb464a 100644
--- a/code/modules/client/preference_setup/general/03_body.dm
+++ b/code/modules/client/preference_setup/general/03_body.dm
@@ -733,7 +733,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
if("preview" in icon_states(current_species.icobase))
usr << browse_rsc(icon(current_species.icobase,"preview"), "species_preview_[current_species.name].png")
dat += "
"
- dat += "Language: [current_species.language]
"
+ dat += "Language: [current_species.species_language]
"
dat += ""
if(current_species.spawn_flags & SPECIES_CAN_JOIN)
dat += "Often present on human stations."
diff --git a/code/modules/client/preference_setup/loadout/loadout.dm b/code/modules/client/preference_setup/loadout/loadout.dm
index 44a814ac67..ecd61cae71 100644
--- a/code/modules/client/preference_setup/loadout/loadout.dm
+++ b/code/modules/client/preference_setup/loadout/loadout.dm
@@ -14,7 +14,8 @@ var/list/gear_datums = list()
//create a list of gear datums to sort
for(var/geartype in typesof(/datum/gear)-/datum/gear)
var/datum/gear/G = geartype
-
+ if(initial(G.type_category) == geartype)
+ continue
var/use_name = initial(G.display_name)
var/use_category = initial(G.sort_category)
@@ -205,6 +206,7 @@ var/list/gear_datums = list()
var/sort_category = "General"
var/list/gear_tweaks = list() //List of datums which will alter the item after it has been spawned.
var/exploitable = 0 //Does it go on the exploitable information list?
+ var/type_category = null
/datum/gear/New()
..()
diff --git a/code/modules/client/preference_setup/loadout/loadout_accessories.dm b/code/modules/client/preference_setup/loadout/loadout_accessories.dm
index bbae19a02a..6bc944552c 100644
--- a/code/modules/client/preference_setup/loadout/loadout_accessories.dm
+++ b/code/modules/client/preference_setup/loadout/loadout_accessories.dm
@@ -1,42 +1,28 @@
/datum/gear/accessory
- display_name = "armband, red"
- path = /obj/item/clothing/accessory/armband
+ display_name = "accessory"
slot = slot_tie
sort_category = "Accessories"
+ type_category = /datum/gear/accessory
+ path = /obj/item/clothing/accessory
+ cost = 1
-/datum/gear/accessory/cargo
- display_name = "armband, cargo"
- path = /obj/item/clothing/accessory/armband/cargo
+/datum/gear/accessory/armband
+ display_name = "armband selection"
+ path = /obj/item/clothing/accessory/armband
-/datum/gear/accessory/emt
- display_name = "armband, EMT"
- path = /obj/item/clothing/accessory/armband/medblue
+/datum/gear/accessory/armband/New()
+ ..()
+ var/list/armbands = list()
+ for(var/armband in (typesof(/obj/item/clothing/accessory/armband) - typesof(/obj/item/clothing/accessory/armband/med/color)))
+ var/obj/item/clothing/accessory/armband_type = armband
+ armbands[initial(armband_type.name)] = armband_type
+ gear_tweaks += new/datum/gear_tweak/path(sortAssoc(armbands))
-/datum/gear/accessory/engineering
- display_name = "armband, engineering"
- path = /obj/item/clothing/accessory/armband/engine
-
-/datum/gear/accessory/hydroponics
- display_name = "armband, hydroponics"
- path = /obj/item/clothing/accessory/armband/hydro
-
-/datum/gear/accessory/medical
- display_name = "armband, medical"
- path = /obj/item/clothing/accessory/armband/med
-
-/datum/gear/accessory/medical/cross
- display_name = "armband, medic"
- path = /obj/item/clothing/accessory/armband/med/cross
-
-/datum/gear/accessory/science
- display_name = "armband, science"
- path = /obj/item/clothing/accessory/armband/science
-
-/datum/gear/accessory/colored
+/datum/gear/accessory/armband/colored
display_name = "armband"
path = /obj/item/clothing/accessory/armband/med/color
-/datum/gear/accessory/colored/New()
+/datum/gear/accessory/armband/colored/New()
..()
gear_tweaks = list(gear_tweak_free_color_choice)
@@ -74,215 +60,109 @@
..()
gear_tweaks = list(gear_tweak_free_color_choice)
-
/datum/gear/accessory/wcoat
- display_name = "waistcoat"
+ display_name = "waistcoat selection"
path = /obj/item/clothing/accessory/wcoat
cost = 1
-/datum/gear/accessory/wcoat/red
- display_name = "waistcoat, red"
- path = /obj/item/clothing/accessory/wcoat/red
-
-/datum/gear/accessory/wcoat/grey
- display_name = "waistcoat, grey"
- path = /obj/item/clothing/accessory/wcoat/grey
-
-/datum/gear/accessory/wcoat/brown
- display_name = "waistcoat, brown"
- path = /obj/item/clothing/accessory/wcoat/brown
-
-/datum/gear/accessory/swvest
- display_name = "sweatervest, black"
- path = /obj/item/clothing/accessory/wcoat/swvest
- cost = 1
-
-/datum/gear/accessory/swvest/blue
- display_name = "sweatervest, blue"
- path = /obj/item/clothing/accessory/wcoat/swvest/blue
-
-/datum/gear/accessory/swvest/red
- display_name = "sweatervest, red"
- path = /obj/item/clothing/accessory/wcoat/swvest/red
+/datum/gear/accessory/wcoat/New()
+ ..()
+ var/list/wcoats = list()
+ for(var/wcoat in typesof(/obj/item/clothing/accessory/wcoat))
+ var/obj/item/clothing/accessory/wcoat_type = wcoat
+ wcoats[initial(wcoat_type.name)] = wcoat_type
+ gear_tweaks += new/datum/gear_tweak/path(sortAssoc(wcoats))
/datum/gear/accessory/holster
- display_name = "holster, armpit"
- path = /obj/item/clothing/accessory/holster/armpit
+ display_name = "holster selection (Security, CD, HoP)"
+ path = /obj/item/clothing/accessory/holster
allowed_roles = list("Colony Director", "Head of Personnel", "Security Officer", "Warden", "Head of Security","Detective")
-/datum/gear/accessory/holster/hip
- display_name = "holster, hip"
- path = /obj/item/clothing/accessory/holster/hip
-
-/datum/gear/accessory/holster/leg
- display_name = "holster, leg"
- path = /obj/item/clothing/accessory/holster/leg
-
-/datum/gear/accessory/holster/waist
- display_name = "holster, waist"
- path = /obj/item/clothing/accessory/holster/waist
+/datum/gear/accessory/holster/New()
+ ..()
+ var/list/holsters = list()
+ for(var/holster in typesof(/obj/item/clothing/accessory/holster))
+ var/obj/item/clothing/accessory/holster_type = holster
+ holsters[initial(holster_type.name)] = holster_type
+ gear_tweaks += new/datum/gear_tweak/path(sortAssoc(holsters))
/datum/gear/accessory/tie
- display_name = "tie, black"
- path = /obj/item/clothing/accessory/black
+ display_name = "tie selection"
+ path = /obj/item/clothing/accessory/tie
+ cost = 1
-/datum/gear/accessory/tie/blue
- display_name = "tie, blue"
- path = /obj/item/clothing/accessory/blue
-
-/datum/gear/accessory/tie/blue_clip
- display_name = "tie, blue with clip"
- path = /obj/item/clothing/accessory/blue_clip
-
-/datum/gear/accessory/tie/blue_long
- display_name = "tie, blue long"
- path = /obj/item/clothing/accessory/blue_long
-
-/datum/gear/accessory/tie/red
- display_name = "tie, red"
- path = /obj/item/clothing/accessory/red
-
-/datum/gear/accessory/tie/red_clip
- display_name = "tie, red with clip"
- path = /obj/item/clothing/accessory/red_clip
-
-/datum/gear/accessory/tie/red_long
- display_name = "tie, red long"
- path = /obj/item/clothing/accessory/red_long
-
-/datum/gear/accessory/tie/yellow
- display_name = "tie, yellow"
- path = /obj/item/clothing/accessory/yellow
-
-/datum/gear/accessory/tie/navy
- display_name = "tie, navy blue"
- path = /obj/item/clothing/accessory/navy
-
-/datum/gear/accessory/tie/white
- display_name = "tie, white"
- path = /obj/item/clothing/accessory/white
-
-/datum/gear/accessory/tie/horrible
- display_name = "tie, socially disgraceful"
- path = /obj/item/clothing/accessory/horrible
+/datum/gear/accessory/tie/New()
+ ..()
+ var/list/ties = list()
+ for(var/tie in typesof(/obj/item/clothing/accessory/tie))
+ var/obj/item/clothing/accessory/tie_type = tie
+ ties[initial(tie_type.name)] = tie_type
+ gear_tweaks += new/datum/gear_tweak/path(sortAssoc(ties))
/datum/gear/accessory/scarf
- display_name = "scarf"
+ display_name = "scarf selection"
path = /obj/item/clothing/accessory/scarf
+ cost = 1
-/datum/gear/accessory/scarf/red
- display_name = "scarf, red"
- path = /obj/item/clothing/accessory/scarf/red
+/datum/gear/accessory/scarf/New()
+ ..()
+ var/list/scarfs = list()
+ for(var/scarf in typesof(/obj/item/clothing/accessory/scarf))
+ var/obj/item/clothing/accessory/scarf_type = scarf
+ scarfs[initial(scarf_type.name)] = scarf_type
+ gear_tweaks += new/datum/gear_tweak/path(sortAssoc(scarfs))
-/datum/gear/accessory/scarf/green
- display_name = "scarf, green"
- path = /obj/item/clothing/accessory/scarf/green
+/datum/gear/accessory/jacket
+ display_name = "suit jacket selection"
+ path = /obj/item/clothing/accessory/jacket
+ cost = 1
-/datum/gear/accessory/scarf/darkblue
- display_name = "scarf, dark blue"
- path = /obj/item/clothing/accessory/scarf/darkblue
-
-/datum/gear/accessory/scarf/purple
- display_name = "scarf, purple"
- path = /obj/item/clothing/accessory/scarf/purple
-
-/datum/gear/accessory/scarf/yellow
- display_name = "scarf, yellow"
- path = /obj/item/clothing/accessory/scarf/yellow
-
-/datum/gear/accessory/scarf/orange
- display_name = "scarf, orange"
- path = /obj/item/clothing/accessory/scarf/orange
-
-/datum/gear/accessory/scarf/lightblue
- display_name = "scarf, light blue"
- path = /obj/item/clothing/accessory/scarf/lightblue
-
-/datum/gear/accessory/scarf/white
- display_name = "scarf, white"
- path = /obj/item/clothing/accessory/scarf/white
-
-/datum/gear/accessory/scarf/black
- display_name = "scarf, black"
- path = /obj/item/clothing/accessory/scarf/black
-
-/datum/gear/accessory/scarf/zebra
- display_name = "scarf, zebra"
- path = /obj/item/clothing/accessory/scarf/zebra
-
-/datum/gear/accessory/scarf/christmas
- display_name = "scarf, christmas"
- path = /obj/item/clothing/accessory/scarf/christmas
-
-/datum/gear/accessory/scarf/stripedred
- display_name = "scarf, striped red"
- path = /obj/item/clothing/accessory/stripedredscarf
-
-/datum/gear/accessory/scarf/stripedgreen
- display_name = "scarf, striped green"
- path = /obj/item/clothing/accessory/stripedgreenscarf
-
-/datum/gear/accessory/scarf/stripedblue
- display_name = "scarf, striped blue"
- path = /obj/item/clothing/accessory/stripedbluescarf
-
-/datum/gear/accessory/suitjacket
- display_name = "suit jacket, tan"
- path = /obj/item/clothing/accessory/tan_jacket
-
-/datum/gear/accessory/suitjacket/charcoal
- display_name = "suit jacket, charcoal"
- path = /obj/item/clothing/accessory/charcoal_jacket
-
-/datum/gear/accessory/suitjacket/navy
- display_name = "suit jacket, navy blue"
- path = /obj/item/clothing/accessory/navy_jacket
-
-/datum/gear/accessory/suitjacket/burgundy
- display_name = "suit jacket, burgundy"
- path = /obj/item/clothing/accessory/burgundy_jacket
-
-/datum/gear/accessory/suitjacket/checkered
- display_name = "suit jacket, checkered"
- path = /obj/item/clothing/accessory/checkered_jacket
+/datum/gear/accessory/jacket/New()
+ ..()
+ var/list/jackets = list()
+ for(var/jacket in typesof(/obj/item/clothing/accessory/jacket))
+ var/obj/item/clothing/accessory/jacket_type = jacket
+ jackets[initial(jacket_type.name)] = jacket_type
+ gear_tweaks += new/datum/gear_tweak/path(sortAssoc(jackets))
/datum/gear/accessory/suitvest
display_name = "suit vest"
path = /obj/item/clothing/accessory/vest
/datum/gear/accessory/brown_vest
- display_name = "webbing, engineering"
+ display_name = "webbing, brown"
path = /obj/item/clothing/accessory/storage/brown_vest
allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor")
/datum/gear/accessory/black_vest
- display_name = "webbing, security"
+ display_name = "webbing, black"
path = /obj/item/clothing/accessory/storage/black_vest
allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor")
/datum/gear/accessory/white_vest
- display_name = "webbing, medical"
+ display_name = "webbing, white"
path = /obj/item/clothing/accessory/storage/white_vest
allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor")
/datum/gear/accessory/brown_drop_pouches
- display_name = "drop pouches, engineering"
+ display_name = "drop pouches, brown"
path = /obj/item/clothing/accessory/storage/brown_drop_pouches
allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor")
/datum/gear/accessory/black_drop_pouches
- display_name = "drop pouches, security"
+ display_name = "drop pouches, black"
path = /obj/item/clothing/accessory/storage/black_drop_pouches
allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor")
/datum/gear/accessory/white_drop_pouches
- display_name = "drop pouches, medical"
+ display_name = "drop pouches, white"
path = /obj/item/clothing/accessory/storage/white_drop_pouches
allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor")
/datum/gear/accessory/fannypack
display_name = "fannypack selection"
cost = 2
+ path = /obj/item/weapon/storage/belt/fannypack
/datum/gear/accessory/fannypack/New()
..()
diff --git a/code/modules/client/preference_setup/loadout/loadout_eyes.dm b/code/modules/client/preference_setup/loadout/loadout_eyes.dm
index 5734563187..5f4791eca6 100644
--- a/code/modules/client/preference_setup/loadout/loadout_eyes.dm
+++ b/code/modules/client/preference_setup/loadout/loadout_eyes.dm
@@ -61,16 +61,16 @@
/datum/gear/eyes/medical/aviator
display_name = "Medical HUD Aviators (Medical)"
- path = /obj/item/clothing/glasses/sunglasses/medhud/aviator
+ path = /obj/item/clothing/glasses/hud/health/aviator
/datum/gear/eyes/medical/aviator/prescription
display_name = "Medical HUD Aviators, prescription (Medical)"
- path = /obj/item/clothing/glasses/sunglasses/medhud/aviator/prescription
+ path = /obj/item/clothing/glasses/hud/health/aviator/prescription
/datum/gear/eyes/meson
- display_name = "Optical Meson Scanners (Engineering)"
+ display_name = "Optical Meson Scanners (Engineering, Science)"
path = /obj/item/clothing/glasses/meson
- allowed_roles = list("Station Engineer","Chief Engineer","Atmospheric Technician")
+ allowed_roles = list("Station Engineer","Chief Engineer","Atmospheric Technician", "Scientist", "Research Director")
/datum/gear/eyes/meson/prescription
display_name = "Optical Meson Scanners, prescription (Engineering)"
@@ -93,8 +93,6 @@
display_name = "Optical Meson Aviators, prescription (Engineering)"
path = /obj/item/clothing/glasses/meson/aviator/prescription
-/datum/gear/eyes/meson/aviator/prescription
-
/datum/gear/eyes/glasses/fakesun
display_name = "Sunglasses, stylish"
path = /obj/item/clothing/glasses/fakesunglasses
@@ -112,7 +110,10 @@
display_name = "Sunglasses, fat (Security/Command)"
path = /obj/item/clothing/glasses/sunglasses/big
+/datum/gear/eyes/sun/aviators
+ display_name = "Sunglasses, aviators (Security/Command)"
+ path = /obj/item/clothing/glasses/sunglasses/aviator
+
/datum/gear/eyes/sun/prescriptionsun
display_name = "sunglasses, presciption (Security/Command)"
path = /obj/item/clothing/glasses/sunglasses/prescription
- cost = 2
diff --git a/code/modules/client/preference_setup/loadout/loadout_gloves.dm b/code/modules/client/preference_setup/loadout/loadout_gloves.dm
index 658b2c8e12..18eb05f882 100644
--- a/code/modules/client/preference_setup/loadout/loadout_gloves.dm
+++ b/code/modules/client/preference_setup/loadout/loadout_gloves.dm
@@ -68,7 +68,7 @@
cost = 3
/datum/gear/gloves/forensic
- display_name = "gloves, forensic"
+ display_name = "gloves, forensic (Detective)"
path = /obj/item/clothing/gloves/forensic
allowed_roles = list("Detective")
diff --git a/code/modules/client/preference_setup/loadout/loadout_head.dm b/code/modules/client/preference_setup/loadout/loadout_head.dm
index b42add9abe..da6c3949f3 100644
--- a/code/modules/client/preference_setup/loadout/loadout_head.dm
+++ b/code/modules/client/preference_setup/loadout/loadout_head.dm
@@ -136,7 +136,6 @@
/datum/gear/head/cowboy
display_name = "cowboy, rodeo"
path = /obj/item/clothing/head/cowboy_hat
- cost = 3
/datum/gear/head/cowboy/black
display_name = "cowboy, black"
@@ -268,6 +267,11 @@
..()
gear_tweaks = list(gear_tweak_free_color_choice)
+
+/datum/gear/head/kitty
+ display_name = "kitty ears"
+ path = /obj/item/clothing/head/kitty
+
/datum/gear/head/beanie
display_name = "beanie"
path = /obj/item/clothing/head/beanie
diff --git a/code/modules/client/preference_setup/loadout/loadout_shoes.dm b/code/modules/client/preference_setup/loadout/loadout_shoes.dm
index 82540018fb..ba2d995b27 100644
--- a/code/modules/client/preference_setup/loadout/loadout_shoes.dm
+++ b/code/modules/client/preference_setup/loadout/loadout_shoes.dm
@@ -195,6 +195,10 @@
..()
gear_tweaks = list(gear_tweak_free_color_choice)
+/datum/gear/shoes/slippers
+ display_name = "bunny slippers"
+ path = /obj/item/clothing/shoes/slippers
+
/datum/gear/shoes/boots/winter
display_name = "winter boots"
path = /obj/item/clothing/shoes/boots/winter
@@ -227,7 +231,7 @@
/datum/gear/shoes/boots/winter/medical
display_name = "medical winter boots"
path = /obj/item/clothing/shoes/boots/winter/medical
- allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist")
+ allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist", "Psychiatrist")
/datum/gear/shoes/boots/winter/mining
display_name = "mining winter boots"
diff --git a/code/modules/client/preference_setup/loadout/loadout_suit.dm b/code/modules/client/preference_setup/loadout/loadout_suit.dm
index 4216ab50c6..82631635af 100644
--- a/code/modules/client/preference_setup/loadout/loadout_suit.dm
+++ b/code/modules/client/preference_setup/loadout/loadout_suit.dm
@@ -149,7 +149,7 @@
/datum/gear/suit/labcoat/emt
display_name = "labcoat, EMT (Medical)"
path = /obj/item/clothing/suit/storage/toggle/labcoat/emt
- allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist")
+ allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist", "Psychiatrist")
/datum/gear/suit/roles/surgical_apron
display_name = "surgical apron"
@@ -182,7 +182,7 @@
/datum/gear/suit/roles/poncho/medical
display_name = "poncho, medical"
path = /obj/item/clothing/accessory/poncho/roles/medical
- allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist")
+ allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist", "Psychiatrist")
/datum/gear/suit/roles/poncho/engineering
display_name = "poncho, engineering"
@@ -292,7 +292,7 @@
/datum/gear/suit/wintercoat/medical
display_name = "winter coat, medical"
path = /obj/item/clothing/suit/storage/hooded/wintercoat/medical
- allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist")
+ allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist", "Psychiatrist")
/datum/gear/suit/wintercoat/science
display_name = "winter coat, science"
@@ -445,7 +445,7 @@
/datum/gear/suit/snowsuit/medical
display_name = "snowsuit, medical"
path = /obj/item/clothing/suit/storage/snowsuit/medical
- allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist")
+ allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist", "Psychiatrist")
/datum/gear/suit/snowsuit/science
display_name = "snowsuit, science"
diff --git a/code/modules/client/preference_setup/loadout/loadout_uniform.dm b/code/modules/client/preference_setup/loadout/loadout_uniform.dm
index 9edc5e81a1..836146d11f 100644
--- a/code/modules/client/preference_setup/loadout/loadout_uniform.dm
+++ b/code/modules/client/preference_setup/loadout/loadout_uniform.dm
@@ -243,7 +243,6 @@
/datum/gear/uniform/scrub
display_name = "scrubs selection"
path = /obj/item/clothing/under/rank/medical/scrubs
- allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist", "Roboticist")
/datum/gear/uniform/scrub/New()
..()
@@ -455,3 +454,7 @@
/datum/gear/uniform/red_swept_dress
display_name = "red swept dress"
path = /obj/item/clothing/under/dress/red_swept_dress
+
+/datum/gear/uniform/bathrobe
+ display_name = "bathrobe"
+ path = /obj/item/clothing/under/bathrobe
\ No newline at end of file
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index a507b3323a..ba7a70b968 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -25,6 +25,7 @@ datum/preferences
//character preferences
var/real_name //our character's name
var/be_random_name = 0 //whether we are a random name every round
+ var/nickname //our character's nickname
var/age = 30 //age of character
var/spawnpoint = "Arrivals Shuttle" //where this character will spawn (0-2).
var/b_type = "A+" //blood type (not-chooseable)
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index afcc676f59..d9e038cb4b 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -447,6 +447,8 @@
var/water_speed = 0 //Speed boost/decrease in water, lower/negative values mean more speed
var/snow_speed = 0 //Speed boost/decrease on snow, lower/negative values mean more speed
+ var/step_volume_mod = 1 //How quiet or loud footsteps in this shoe are
+
permeability_coefficient = 0.50
slowdown = SHOES_SLOWDOWN
force = 2
@@ -555,6 +557,7 @@
var/blood_overlay_type = "suit"
siemens_coefficient = 0.9
w_class = ITEMSIZE_NORMAL
+ preserve_item = 1
sprite_sheets = list(
"Teshari" = 'icons/mob/species/seromi/suit.dmi',
diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm
index 106500add0..48ab03ed3f 100644
--- a/code/modules/clothing/glasses/glasses.dm
+++ b/code/modules/clothing/glasses/glasses.dm
@@ -82,6 +82,20 @@ BLIND // can't see anything
desc = "Engineering Aviators with prescription lenses."
prescription = 1
+/obj/item/clothing/glasses/hud/health/aviator
+ name = "medical HUD aviators"
+ desc = "Modified aviator glasses with a toggled health HUD."
+ icon_state = "aviator_med"
+ off_state = "aviator"
+ action_button_name = "Toggle Mode"
+ toggleable = 1
+ activation_sound = 'sound/effects/pop.ogg'
+
+/obj/item/clothing/glasses/hud/health/aviator/prescription
+ name = "prescription medical HUD aviators"
+ desc = "Modified aviator glasses with a toggled health HUD. Comes with bonus prescription lenses."
+ prescription = 6
+
/obj/item/clothing/glasses/science
name = "Science Goggles"
desc = "The goggles do nothing!"
@@ -206,6 +220,11 @@ BLIND // can't see anything
item_state_slots = list(slot_r_hand_str = "sunglasses", slot_l_hand_str = "sunglasses")
darkness_view = -1
+/obj/item/clothing/glasses/sunglasses/aviator
+ name = "aviators"
+ desc = "A pair of designer sunglasses."
+ icon_state = "aviator"
+
/obj/item/clothing/glasses/welding
name = "welding goggles"
desc = "Protects the eyes from welders, approved by the mad scientist association."
@@ -353,53 +372,6 @@ BLIND // can't see anything
src.hud = new/obj/item/clothing/glasses/hud/health(src)
return
-/obj/item/clothing/glasses/sunglasses/medhud/aviator
- name = "medical HUD aviators"
- desc = "Modified aviator glasses with a toggled health HUD."
- icon_state = "aviator_med"
- off_state = "aviator"
- action_button_name = "Toggle Mode"
- var/on = 1
- toggleable = 1
- activation_sound = 'sound/effects/pop.ogg'
-
- var/hud_holder
-
-/obj/item/clothing/glasses/sunglasses/medhud/aviator/New()
- ..()
- hud_holder = hud
-
-/obj/item/clothing/glasses/sunglasses/medhud/aviator/Destroy()
- qdel(hud_holder)
- hud_holder = null
- hud = null
- . = ..()
-
-/obj/item/clothing/glasses/sunglasses/medhud/aviator/attack_self(mob/user)
- if(toggleable && !user.incapacitated())
- on = !on
- if(on)
- src.hud = hud_holder
- to_chat(user, "You switch the [src] to HUD mode.")
- else
- src.hud = null
- to_chat(user, "You switch \the [src] off.")
- update_icon()
- user << activation_sound
- user.update_inv_glasses()
- user.update_action_buttons()
-
-/obj/item/clothing/glasses/sunglasses/medhud/aviator/update_icon()
- if(on)
- icon_state = initial(icon_state)
- else
- icon_state = off_state
-
-/obj/item/clothing/glasses/sunglasses/medhud/aviator/prescription
- name = "prescription medical HUD aviators"
- desc = "Modified aviator glasses with a toggled health HUD. Comes with bonus prescription lenses."
- prescription = 6
-
/obj/item/clothing/glasses/thermal
name = "optical thermal scanner"
desc = "Thermals in the shape of glasses."
diff --git a/code/modules/clothing/shoes/boots.dm b/code/modules/clothing/shoes/boots.dm
index 0b5e1c7428..88206f4132 100644
--- a/code/modules/clothing/shoes/boots.dm
+++ b/code/modules/clothing/shoes/boots.dm
@@ -4,6 +4,7 @@
icon_state = "workboots"
force = 3
can_hold_knife = 1
+ step_volume_mod = 1.2
/obj/item/clothing/shoes/boots/cowboy
name = "cowboy boots"
@@ -47,6 +48,7 @@
heat_protection = FEET|LEGS
max_heat_protection_temperature = SHOE_MAX_HEAT_PROTECTION_TEMPERATURE
snow_speed = -1
+ step_volume_mod = 0.8
/obj/item/clothing/shoes/boots/winter/security
name = "security winter boots"
diff --git a/code/modules/clothing/shoes/leg_guards.dm b/code/modules/clothing/shoes/leg_guards.dm
index 786ded8a62..da38116537 100644
--- a/code/modules/clothing/shoes/leg_guards.dm
+++ b/code/modules/clothing/shoes/leg_guards.dm
@@ -5,6 +5,7 @@
slowdown = SHOES_SLOWDOWN+0.5
species_restricted = null //Unathi and Taj can wear leg armor now
w_class = ITEMSIZE_NORMAL
+ step_volume_mod = 1.3
/obj/item/clothing/shoes/leg_guard/mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0)
if(..()) //This will only run if no other problems occured when equiping.
diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm
index 4a53a24405..b2395b7edf 100644
--- a/code/modules/clothing/shoes/magboots.dm
+++ b/code/modules/clothing/shoes/magboots.dm
@@ -7,11 +7,13 @@
force = 3
overshoes = 1
shoes_under_pants = -1 //These things are huge
+ preserve_item = 1
var/magpulse = 0
var/icon_base = "magboots"
action_button_name = "Toggle Magboots"
var/obj/item/clothing/shoes/shoes = null //Undershoes
var/mob/living/carbon/human/wearer = null //For shoe procs
+ step_volume_mod = 1.3
/obj/item/clothing/shoes/magboots/proc/set_slowdown()
slowdown = shoes? max(SHOES_SLOWDOWN, shoes.slowdown): SHOES_SLOWDOWN //So you can't put on magboots to make you walk faster.
diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm
index c565ee6dca..c1c833a308 100644
--- a/code/modules/clothing/shoes/miscellaneous.dm
+++ b/code/modules/clothing/shoes/miscellaneous.dm
@@ -8,10 +8,12 @@
var/list/clothing_choices = list()
siemens_coefficient = 0.8
species_restricted = null
+ step_volume_mod = 0.5
/obj/item/clothing/shoes/mime
name = "mime shoes"
icon_state = "white"
+ step_volume_mod = 0 //It's a mime
/obj/item/clothing/shoes/galoshes
desc = "Rubber boots"
@@ -22,7 +24,6 @@
slowdown = SHOES_SLOWDOWN+1
species_restricted = null
-
/obj/item/clothing/shoes/dress
name = "dress shoes"
desc = "Sharp looking low quarters, perfect for a formal uniform."
diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm
index b586f04d27..6ff451dde1 100644
--- a/code/modules/clothing/spacesuits/rig/rig.dm
+++ b/code/modules/clothing/spacesuits/rig/rig.dm
@@ -24,6 +24,7 @@
siemens_coefficient = 0.2
permeability_coefficient = 0.1
unacidable = 1
+ preserve_item = 1
var/interface_path = "hardsuit.tmpl"
var/ai_interface_path = "hardsuit.tmpl"
diff --git a/code/modules/clothing/spacesuits/rig/suits/light.dm b/code/modules/clothing/spacesuits/rig/suits/light.dm
index 2fb3e040e2..0dd98de966 100644
--- a/code/modules/clothing/spacesuits/rig/suits/light.dm
+++ b/code/modules/clothing/spacesuits/rig/suits/light.dm
@@ -26,6 +26,7 @@
/obj/item/clothing/shoes/magboots/rig/light
name = "shoes"
+ step_volume_mod = 0.8
/obj/item/clothing/head/helmet/space/rig/light
name = "hood"
@@ -82,6 +83,7 @@
chest_type = /obj/item/clothing/suit/space/rig/light/ninja
glove_type = /obj/item/clothing/gloves/gauntlets/rig/light/ninja
+ boot_type = /obj/item/clothing/shoes/magboots/rig/light/ninja
cell_type = /obj/item/weapon/cell/hyper
req_access = list(access_syndicate)
@@ -107,6 +109,9 @@
name = "insulated gloves"
siemens_coefficient = 0
+/obj/item/clothing/shoes/magboots/rig/light/ninja
+ step_volume_mod = 0.25 //Not quite silent, but still damn quiet
+
/obj/item/clothing/suit/space/rig/light/ninja
breach_threshold = 38 //comparable to regular hardsuits
diff --git a/code/modules/clothing/spacesuits/spacesuits.dm b/code/modules/clothing/spacesuits/spacesuits.dm
index 159957bddb..52f6a9103f 100644
--- a/code/modules/clothing/spacesuits/spacesuits.dm
+++ b/code/modules/clothing/spacesuits/spacesuits.dm
@@ -15,6 +15,7 @@
min_cold_protection_temperature = SPACE_HELMET_MIN_COLD_PROTECTION_TEMPERATURE
siemens_coefficient = 0.9
species_restricted = list("exclude","Diona")
+ preserve_item = 1
var/obj/machinery/camera/camera
var/list/camera_networks
@@ -59,6 +60,7 @@
min_cold_protection_temperature = SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE
siemens_coefficient = 0.9
species_restricted = list("exclude","Diona")
+ preserve_item = 1
var/list/supporting_limbs //If not-null, automatically splints breaks. Checked when removing the suit.
diff --git a/code/modules/clothing/spacesuits/void/merc.dm b/code/modules/clothing/spacesuits/void/merc.dm
index 101f7bb657..b9aca8d29c 100644
--- a/code/modules/clothing/spacesuits/void/merc.dm
+++ b/code/modules/clothing/spacesuits/void/merc.dm
@@ -18,4 +18,22 @@
w_class = ITEMSIZE_NORMAL
armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 60)
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/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)
- siemens_coefficient = 0.6
\ No newline at end of file
+ siemens_coefficient = 0.6
+
+/obj/item/clothing/head/helmet/space/void/merc/fire
+ icon_state = "rig0-firebug"
+ name = "soot-covered voidsuit helmet"
+ desc = "A blackened helmet that has had many of its protective plates coated in or replaced with high-grade thermal insulation, to protect against incineration. Property of Gorlex Marauders."
+ armor = list(melee = 40, bullet = 40, laser = 60, energy = 20, bomb = 50, bio = 100, rad = 50)
+ max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE
+ siemens_coefficient = 0.7
+ light_overlay = "helmet_light_fire"
+
+/obj/item/clothing/suit/space/void/merc/fire
+ icon_state = "rig-firebug"
+ name = "soot-covered voidsuit"
+ desc = "A blackened suit that has had many of its protective plates coated in or replaced with high-grade thermal insulation, to protect against incineration. Property of Gorlex Marauders."
+ armor = list(melee = 40, bullet = 40, laser = 60, energy = 20, bomb = 50, bio = 100, rad = 50)
+ max_heat_protection_temperature = FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE
+ allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/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/material/twohanded/fireaxe,/obj/item/weapon/flamethrower)
+ siemens_coefficient = 0.7
diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm
index 68b656f0d7..864ee369ba 100644
--- a/code/modules/clothing/suits/armor.dm
+++ b/code/modules/clothing/suits/armor.dm
@@ -455,3 +455,71 @@
desc = "Pukish armor."
icon_state = "tdgreen"
siemens_coefficient = 1
+
+//Modular plate carriers
+/obj/item/clothing/suit/armor/pcarrier
+ name = "plate carrier"
+ desc = "A lightweight black plate carrier vest. It can be equipped with armor plates, but provides no protection of its own."
+ icon = 'icons/obj/clothing/modular_armor.dmi'
+ item_icons = list(slot_wear_suit_str = 'icons/mob/modular_armor.dmi')
+ icon_state = "pcarrier"
+ valid_accessory_slots = list(ACCESSORY_SLOT_INSIGNIA, ACCESSORY_SLOT_ARMOR_C, ACCESSORY_SLOT_ARMOR_A, ACCESSORY_SLOT_ARMOR_L, ACCESSORY_SLOT_ARMOR_S, ACCESSORY_SLOT_ARMOR_M)
+ restricted_accessory_slots = list(ACCESSORY_SLOT_INSIGNIA, ACCESSORY_SLOT_ARMOR_C, ACCESSORY_SLOT_ARMOR_A, ACCESSORY_SLOT_ARMOR_L, ACCESSORY_SLOT_ARMOR_S)
+ blood_overlay_type = "armor"
+
+/obj/item/clothing/suit/armor/pcarrier/light
+ starting_accessories = list(/obj/item/clothing/accessory/armorplate)
+
+/obj/item/clothing/suit/armor/pcarrier/light/sol
+ starting_accessories = list(/obj/item/clothing/accessory/armorplate, /obj/item/clothing/accessory/armor/tag)
+
+/obj/item/clothing/suit/armor/pcarrier/light/nt
+ starting_accessories = list(/obj/item/clothing/accessory/armorplate, /obj/item/clothing/accessory/armor/tag/nt)
+
+/obj/item/clothing/suit/armor/pcarrier/medium
+ starting_accessories = list(/obj/item/clothing/accessory/armorplate/medium, /obj/item/clothing/accessory/storage/pouches)
+
+/obj/item/clothing/suit/armor/pcarrier/medium/sol
+ starting_accessories = list(/obj/item/clothing/accessory/armorplate/medium, /obj/item/clothing/accessory/storage/pouches, /obj/item/clothing/accessory/armor/tag)
+
+/obj/item/clothing/suit/armor/pcarrier/medium/security
+ starting_accessories = list(/obj/item/clothing/accessory/armorplate/medium, /obj/item/clothing/accessory/storage/pouches, /obj/item/clothing/accessory/armor/tag/sec)
+
+/obj/item/clothing/suit/armor/pcarrier/medium/command
+ starting_accessories = list(/obj/item/clothing/accessory/armorplate/medium, /obj/item/clothing/accessory/storage/pouches, /obj/item/clothing/accessory/armor/tag/com)
+
+/obj/item/clothing/suit/armor/pcarrier/medium/nt
+ starting_accessories = list(/obj/item/clothing/accessory/armorplate/medium, /obj/item/clothing/accessory/storage/pouches, /obj/item/clothing/accessory/armor/tag/nt)
+
+/obj/item/clothing/suit/armor/pcarrier/blue
+ name = "blue plate carrier"
+ desc = "A lightweight blue plate carrier vest. It can be equipped with armor plates, but provides no protection of its own."
+ icon_state = "pcarrier_blue"
+
+/obj/item/clothing/suit/armor/pcarrier/blue/sol
+ name = "peacekeeper plate carrier"
+ desc = "A lightweight plate carrier vest in SCG Peacekeeper colors. It can be equipped with armor plates, but provides no protection of its own."
+ starting_accessories = list(/obj/item/clothing/accessory/armorplate/medium, /obj/item/clothing/accessory/storage/pouches/blue, /obj/item/clothing/accessory/armguards/blue, /obj/item/clothing/accessory/armor/tag)
+
+/obj/item/clothing/suit/armor/pcarrier/green
+ name = "green plate carrier"
+ desc = "A lightweight green plate carrier vest. It can be equipped with armor plates, but provides no protection of its own."
+ icon_state = "pcarrier_green"
+
+/obj/item/clothing/suit/armor/pcarrier/navy
+ name = "navy plate carrier"
+ desc = "A lightweight navy blue plate carrier vest. It can be equipped with armor plates, but provides no protection of its own."
+ icon_state = "pcarrier_navy"
+
+/obj/item/clothing/suit/armor/pcarrier/tan
+ name = "tan plate carrier"
+ desc = "A lightweight tan plate carrier vest. It can be equipped with armor plates, but provides no protection of its own."
+ icon_state = "pcarrier_tan"
+
+/obj/item/clothing/suit/armor/pcarrier/tan/tactical
+ name = "tactical plate carrier"
+ starting_accessories = list(/obj/item/clothing/accessory/armorplate/tactical, /obj/item/clothing/accessory/storage/pouches/large/tan)
+
+/obj/item/clothing/suit/armor/pcarrier/merc
+ starting_accessories = list(/obj/item/clothing/accessory/armorplate/merc, /obj/item/clothing/accessory/armguards/merc, /obj/item/clothing/accessory/legguards/merc, /obj/item/clothing/accessory/storage/pouches/large)
+
diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm
index 3298541540..602b854287 100644
--- a/code/modules/clothing/suits/miscellaneous.dm
+++ b/code/modules/clothing/suits/miscellaneous.dm
@@ -594,6 +594,12 @@ obj/item/clothing/suit/storage/toggle/peacoat
icon_state = "smw_hoodie"
item_state_slots = list(slot_r_hand_str = "suit_black", slot_l_hand_str = "suit_black")
+/obj/item/clothing/suit/storage/toggle/hoodie/nrti
+ name = "New Reykjavik Technical Institute hoodie"
+ desc = "A warm, gray sweatshirt. It bears the letters ‘NRT’ on the back, in reference to Sif's premiere technical institute."
+ icon_state = "nrti_hoodie"
+ item_state_slots = list(slot_r_hand_str = "suit_grey", slot_l_hand_str = "suit_grey")
+
/obj/item/clothing/suit/whitedress
name = "white dress"
desc = "A fancy dress."
diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm
index ee6eba13d6..4392a26492 100644
--- a/code/modules/clothing/under/accessories/accessory.dm
+++ b/code/modules/clothing/under/accessories/accessory.dm
@@ -80,51 +80,51 @@
return //we aren't an object on the ground so don't call parent
..()
-/obj/item/clothing/accessory/blue
+/obj/item/clothing/accessory/tie
name = "blue tie"
icon_state = "bluetie"
-/obj/item/clothing/accessory/red
+/obj/item/clothing/accessory/tie/red
name = "red tie"
icon_state = "redtie"
-/obj/item/clothing/accessory/blue_clip
+/obj/item/clothing/accessory/tie/blue_clip
name = "blue tie with a clip"
icon_state = "bluecliptie"
-/obj/item/clothing/accessory/blue_long
+/obj/item/clothing/accessory/tie/blue_long
name = "blue long tie"
icon_state = "bluelongtie"
-/obj/item/clothing/accessory/red_clip
+/obj/item/clothing/accessory/tie/red_clip
name = "red tie with a clip"
icon_state = "redcliptie"
-/obj/item/clothing/accessory/red_long
+/obj/item/clothing/accessory/tie/red_long
name = "red long tie"
icon_state = "redlongtie"
-/obj/item/clothing/accessory/black
+/obj/item/clothing/accessory/tie/black
name = "black tie"
icon_state = "blacktie"
-/obj/item/clothing/accessory/darkgreen
+/obj/item/clothing/accessory/tie/darkgreen
name = "dark green tie"
icon_state = "dgreentie"
-/obj/item/clothing/accessory/yellow
+/obj/item/clothing/accessory/tie/yellow
name = "yellow tie"
icon_state = "yellowtie"
-/obj/item/clothing/accessory/navy
+/obj/item/clothing/accessory/tie/navy
name = "navy tie"
icon_state = "navytie"
-/obj/item/clothing/accessory/white
+/obj/item/clothing/accessory/tie/white
name = "white tie"
icon_state = "whitetie"
-/obj/item/clothing/accessory/horrible
+/obj/item/clothing/accessory/tie/horrible
name = "horrible tie"
desc = "A neosilk clip-on tie. This one is disgusting."
icon_state = "horribletie"
@@ -237,17 +237,14 @@
//Scarves
/obj/item/clothing/accessory/scarf
- name = "scarf"
+ name = "green scarf"
desc = "A stylish scarf. The perfect winter accessory for those with a keen fashion sense, and those who just can't handle a cold breeze on their necks."
+ icon_state = "greenscarf"
/obj/item/clothing/accessory/scarf/red
name = "red scarf"
icon_state = "redscarf"
-/obj/item/clothing/accessory/scarf/green
- name = "green scarf"
- icon_state = "greenscarf"
-
/obj/item/clothing/accessory/scarf/darkblue
name = "dark blue scarf"
icon_state = "darkbluescarf"
@@ -284,14 +281,14 @@
name = "christmas scarf"
icon_state = "christmasscarf"
-/obj/item/clothing/accessory/stripedredscarf
+/obj/item/clothing/accessory/scarf/stripedred
name = "striped red scarf"
icon_state = "stripedredscarf"
-/obj/item/clothing/accessory/stripedgreenscarf
+/obj/item/clothing/accessory/scarf/stripedgreen
name = "striped green scarf"
icon_state = "stripedgreenscarf"
-/obj/item/clothing/accessory/stripedbluescarf
+/obj/item/clothing/accessory/scarf/stripedblue
name = "striped blue scarf"
icon_state = "stripedbluescarf"
diff --git a/code/modules/clothing/under/accessories/armor.dm b/code/modules/clothing/under/accessories/armor.dm
new file mode 100644
index 0000000000..0caa62b2a2
--- /dev/null
+++ b/code/modules/clothing/under/accessories/armor.dm
@@ -0,0 +1,228 @@
+//Pouches
+/obj/item/clothing/accessory/storage/pouches
+ name = "storage pouches"
+ desc = "A collection of black pouches that can be attached to a plate carrier. Carries up to two items."
+ icon_override = 'icons/mob/modular_armor.dmi'
+ icon = 'icons/obj/clothing/modular_armor.dmi'
+// accessory_icons = list(slot_tie_str = 'icons/mob/modular_armor.dmi', slot_wear_suit_str = 'icons/mob/modular_armor.dmi')
+ icon_state = "pouches"
+ gender = PLURAL
+ slot = ACCESSORY_SLOT_ARMOR_S
+ slots = 2
+
+/obj/item/clothing/accessory/storage/pouches/blue
+ desc = "A collection of blue pouches that can be attached to a plate carrier. Carries up to two items."
+ icon_state = "pouches_blue"
+
+/obj/item/clothing/accessory/storage/pouches/navy
+ desc = "A collection of navy blue pouches that can be attached to a plate carrier. Carries up to two items."
+ icon_state = "pouches_navy"
+
+/obj/item/clothing/accessory/storage/pouches/green
+ desc = "A collection of green pouches that can be attached to a plate carrier. Carries up to two items."
+ icon_state = "pouches_green"
+
+/obj/item/clothing/accessory/storage/pouches/tan
+ desc = "A collection of tan pouches that can be attached to a plate carrier. Carries up to two items."
+ icon_state = "pouches_tan"
+
+/obj/item/clothing/accessory/storage/pouches/large
+ name = "large storage pouches"
+ desc = "A collection of black pouches that can be attached to a plate carrier. Carries up to four items."
+ icon_state = "lpouches"
+ slots = 4
+
+/obj/item/clothing/accessory/storage/pouches/large/blue
+ desc = "A collection of blue pouches that can be attached to a plate carrier. Carries up to four items."
+ icon_state = "lpouches_blue"
+
+/obj/item/clothing/accessory/storage/pouches/large/navy
+ desc = "A collection of navy blue pouches that can be attached to a plate carrier. Carries up to four items."
+ icon_state = "lpouches_navy"
+
+/obj/item/clothing/accessory/storage/pouches/large/green
+ desc = "A collection of green pouches that can be attached to a plate carrier. Carries up to four items."
+ icon_state = "lpouches_green"
+
+/obj/item/clothing/accessory/storage/pouches/large/tan
+ desc = "A collection of tan pouches that can be attached to a plate carrier. Carries up to four items."
+ icon_state = "lpouches_tan"
+
+//Armor plates
+/obj/item/clothing/accessory/armorplate
+ name = "light armor plate"
+ desc = "A basic armor plate made of steel-reinforced synthetic fibers. Attaches to a plate carrier."
+ icon = 'icons/obj/clothing/modular_armor.dmi'
+ icon_state = "armor_light"
+ body_parts_covered = UPPER_TORSO|LOWER_TORSO
+ armor = list(melee = 30, bullet = 15, laser = 40, energy = 10, bomb = 25, bio = 0, rad = 0)
+ slot = ACCESSORY_SLOT_ARMOR_C
+
+/obj/item/clothing/accessory/armorplate/medium
+ name = "medium armor plate"
+ desc = "A plasteel-reinforced synthetic armor plate, providing good protection. Attaches to a plate carrier."
+ icon_state = "armor_medium"
+ armor = list(melee = 40, bullet = 40, laser = 40, energy = 25, bomb = 30, bio = 0, rad = 0)
+
+/obj/item/clothing/accessory/armorplate/tactical
+ name = "tactical armor plate"
+ desc = "A medium armor plate with additional ablative coating. Attaches to a plate carrier."
+ icon_state = "armor_tactical"
+ armor = list(melee = 40, bullet = 40, laser = 60, energy = 35, bomb = 30, bio = 0, rad = 0)
+
+/obj/item/clothing/accessory/armorplate/merc
+ name = "heavy armor plate"
+ desc = "A ceramics-reinforced synthetic armor plate, providing state of of the art protection. Attaches to a plate carrier."
+ icon_state = "armor_heavy"
+ armor = list(melee = 60, bullet = 60, laser = 60, energy = 40, bomb = 40, bio = 0, rad = 0)
+
+//Arm guards
+/obj/item/clothing/accessory/armguards
+ name = "arm guards"
+ desc = "A pair of black arm pads reinforced with armor plating. Attaches to a plate carrier."
+ icon_override = 'icons/mob/modular_armor.dmi'
+ icon = 'icons/obj/clothing/modular_armor.dmi'
+// accessory_icons = list(slot_tie_str = 'icons/mob/modular_armor.dmi', slot_wear_suit_str = 'icons/mob/modular_armor.dmi')
+ icon_state = "armguards"
+ gender = PLURAL
+ body_parts_covered = ARMS
+ armor = list(melee = 40, bullet = 40, laser = 40, energy = 25, bomb = 30, bio = 0, rad = 0)
+ slot = ACCESSORY_SLOT_ARMOR_A
+
+/obj/item/clothing/accessory/armguards/blue
+ desc = "A pair of blue arm pads reinforced with armor plating. Attaches to a plate carrier."
+ icon_state = "armguards_blue"
+
+/obj/item/clothing/accessory/armguards/navy
+ desc = "A pair of navy blue arm pads reinforced with armor plating. Attaches to a plate carrier."
+ icon_state = "armguards_navy"
+
+/obj/item/clothing/accessory/armguards/green
+ desc = "A pair of green arm pads reinforced with armor plating. Attaches to a plate carrier."
+ icon_state = "armguards_green"
+
+/obj/item/clothing/accessory/armguards/tan
+ desc = "A pair of tan arm pads reinforced with armor plating. Attaches to a plate carrier."
+ icon_state = "armguards_tan"
+
+/obj/item/clothing/accessory/armguards/merc
+ name = "heavy arm guards"
+ desc = "A pair of red-trimmed black arm pads reinforced with heavy armor plating. Attaches to a plate carrier."
+ icon_state = "armguards_merc"
+ armor = list(melee = 60, bullet = 60, laser = 60, energy = 40, bomb = 40, bio = 0, rad = 0)
+
+//Leg guards
+/obj/item/clothing/accessory/legguards
+ name = "leg guards"
+ desc = "A pair of armored leg pads in black. Attaches to a plate carrier."
+ icon_override = 'icons/mob/modular_armor.dmi'
+ icon = 'icons/obj/clothing/modular_armor.dmi'
+// accessory_icons = list(slot_tie_str = 'icons/mob/modular_armor.dmi', slot_wear_suit_str = 'icons/mob/modular_armor.dmi')
+ icon_state = "legguards"
+ gender = PLURAL
+ body_parts_covered = LEGS
+ armor = list(melee = 40, bullet = 40, laser = 40, energy = 25, bomb = 30, bio = 0, rad = 0)
+ slot = ACCESSORY_SLOT_ARMOR_L
+
+/obj/item/clothing/accessory/legguards/blue
+ desc = "A pair of armored leg pads in blue. Attaches to a plate carrier."
+ icon_state = "legguards_blue"
+
+/obj/item/clothing/accessory/legguards/navy
+ desc = "A pair of armored leg pads in navy blue. Attaches to a plate carrier."
+ icon_state = "legguards_navy"
+
+/obj/item/clothing/accessory/legguards/green
+ desc = "A pair of armored leg pads in green. Attaches to a plate carrier."
+ icon_state = "legguards_green"
+
+/obj/item/clothing/accessory/legguards/tan
+ desc = "A pair of armored leg pads in tan. Attaches to a plate carrier."
+ icon_state = "legguards_tan"
+
+/obj/item/clothing/accessory/legguards/merc
+ name = "heavy leg guards"
+ desc = "A pair of heavily armored leg pads in red-trimmed black. Attaches to a plate carrier."
+ icon_state = "legguards_merc"
+ armor = list(melee = 60, bullet = 60, laser = 60, energy = 40, bomb = 40, bio = 0, rad = 0)
+
+
+//Decorative attachments
+/obj/item/clothing/accessory/armor/tag
+ name = "\improper SCG Flag"
+ desc = "An emblem depicting the Sol Central Government's flag."
+ icon_override = 'icons/mob/modular_armor.dmi'
+ icon = 'icons/obj/clothing/modular_armor.dmi'
+// accessory_icons = list(slot_tie_str = 'icons/mob/modular_armor.dmi', slot_wear_suit_str = 'icons/mob/modular_armor.dmi')
+ icon_state = "solflag"
+ slot = ACCESSORY_SLOT_ARMOR_M
+
+/obj/item/clothing/accessory/armor/tag/ec
+ name = "\improper Expeditionary Corps crest"
+ desc = "An emblem depicting the crest of the SCG Expeditionary Corps."
+ icon_state = "ecflag"
+
+/obj/item/clothing/accessory/armor/tag/sec
+ name = "\improper POLICE tag"
+ desc = "An armor tag with the word POLICE printed in silver lettering on it."
+ icon_state = "sectag"
+
+/obj/item/clothing/accessory/armor/tag/com
+ name = "\improper SCG tag"
+ desc = "An armor tag with the words SOL CENTRAL GOVERNMENT printed in gold lettering on it."
+ icon_state = "comtag"
+
+/obj/item/clothing/accessory/armor/tag/nt
+ name = "\improper CORPORATE SECURITY tag"
+ desc = "An armor tag with the words CORPORATE SECURITY printed in red lettering on it."
+ icon_state = "nanotag"
+
+/obj/item/clothing/accessory/armor/tag/pcrc
+ name = "\improper PCRC tag"
+ desc = "An armor tag with the words PROXIMA CENTAURI RISK CONTROL printed in cyan lettering on it."
+ icon_state = "pcrctag"
+
+/obj/item/clothing/accessory/armor/tag/saare
+ name = "\improper SAARE tag"
+ desc = "An armor tag with the acronym SAARE printed in olive-green lettering on it."
+ icon_state = "saaretag"
+
+/obj/item/clothing/accessory/armor/tag/opos
+ name = "\improper O+ blood patch"
+ desc = "An embroidered patch indicating the wearer's blood type as O POSITIVE."
+ icon_state = "opostag"
+
+/obj/item/clothing/accessory/armor/tag/oneg
+ name = "\improper O- blood patch"
+ desc = "An embroidered patch indicating the wearer's blood type as O NEGATIVE."
+ icon_state = "onegtag"
+
+/obj/item/clothing/accessory/armor/tag/apos
+ name = "\improper A+ blood patch"
+ desc = "An embroidered patch indicating the wearer's blood type as A POSITIVE."
+ icon_state = "apostag"
+
+/obj/item/clothing/accessory/armor/tag/aneg
+ name = "\improper A- blood patch"
+ desc = "An embroidered patch indicating the wearer's blood type as A NEGATIVE."
+ icon_state = "anegtag"
+
+/obj/item/clothing/accessory/armor/tag/bpos
+ name = "\improper B+ blood patch"
+ desc = "An embroidered patch indicating the wearer's blood type as B POSITIVE."
+ icon_state = "bpostag"
+
+/obj/item/clothing/accessory/armor/tag/bneg
+ name = "\improper B- blood patch"
+ desc = "An embroidered patch indicating the wearer's blood type as B NEGATIVE."
+ icon_state = "bnegtag"
+
+/obj/item/clothing/accessory/armor/tag/abpos
+ name = "\improper AB+ blood patch"
+ desc = "An embroidered patch indicating the wearer's blood type as AB POSITIVE."
+ icon_state = "abpostag"
+
+/obj/item/clothing/accessory/armor/tag/abneg
+ name = "\improper AB- blood patch"
+ desc = "An embroidered patch indicating the wearer's blood type as AB NEGATIVE."
+ icon_state = "abnegtag"
diff --git a/code/modules/clothing/under/accessories/clothing.dm b/code/modules/clothing/under/accessories/clothing.dm
index 363476eb2b..3f117d6ade 100644
--- a/code/modules/clothing/under/accessories/clothing.dm
+++ b/code/modules/clothing/under/accessories/clothing.dm
@@ -3,27 +3,27 @@
desc = "Slick black suit vest."
icon_state = "det_vest"
-/obj/item/clothing/accessory/tan_jacket
+/obj/item/clothing/accessory/jacket/
name = "tan suit jacket"
desc = "Cozy suit jacket."
icon_state = "tan_jacket"
-/obj/item/clothing/accessory/charcoal_jacket
+/obj/item/clothing/accessory/jacket/charcoal
name = "charcoal suit jacket"
desc = "Strict suit jacket."
icon_state = "charcoal_jacket"
-/obj/item/clothing/accessory/navy_jacket
+/obj/item/clothing/accessory/jacket/navy
name = "navy suit jacket"
desc = "Official suit jacket."
icon_state = "navy_jacket"
-/obj/item/clothing/accessory/burgundy_jacket
+/obj/item/clothing/accessory/jacket/burgundy
name = "burgundy suit jacket"
desc = "Expensive suit jacket."
icon_state = "burgundy_jacket"
-/obj/item/clothing/accessory/checkered_jacket
+/obj/item/clothing/accessory/jacket/checkered
name = "checkered suit jacket"
desc = "Lucky suit jacket."
icon_state = "checkered_jacket"
diff --git a/code/modules/clothing/under/jobs/civilian.dm b/code/modules/clothing/under/jobs/civilian.dm
index 87e6fa5bf9..a9757e3026 100644
--- a/code/modules/clothing/under/jobs/civilian.dm
+++ b/code/modules/clothing/under/jobs/civilian.dm
@@ -101,7 +101,7 @@
icon_state = "internalaffairs"
item_state_slots = list(slot_r_hand_str = "ba_suit", slot_l_hand_str = "ba_suit")
rolled_sleeves = 0
- starting_accessories = list(/obj/item/clothing/accessory/black)
+ starting_accessories = list(/obj/item/clothing/accessory/tie/black)
/obj/item/clothing/under/rank/internalaffairs/skirt
desc = "The plain, professional attire of an Internal Affairs Agent. The top button is sewn shut."
@@ -156,7 +156,7 @@
desc = "A classy suit."
icon_state = "bluesuit"
item_state_slots = list(slot_r_hand_str = "lawyer_blue", slot_l_hand_str = "lawyer_blue")
- starting_accessories = list(/obj/item/clothing/accessory/red)
+ starting_accessories = list(/obj/item/clothing/accessory/tie/red)
/obj/item/clothing/under/lawyer/bluesuit/skirt
name = "blue skirt suit"
diff --git a/code/modules/clothing/under/jobs/security.dm b/code/modules/clothing/under/jobs/security.dm
index 02dde0f815..9680de4884 100644
--- a/code/modules/clothing/under/jobs/security.dm
+++ b/code/modules/clothing/under/jobs/security.dm
@@ -73,7 +73,7 @@
armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
siemens_coefficient = 0.9
rolled_sleeves = 0
- starting_accessories = list(/obj/item/clothing/accessory/blue_clip)
+ starting_accessories = list(/obj/item/clothing/accessory/tie/blue_clip)
/*
/obj/item/clothing/under/det/verb/rollup()
@@ -89,13 +89,13 @@
/obj/item/clothing/under/det/grey
icon_state = "detective2"
desc = "A serious-looking tan dress shirt paired with freshly-pressed black slacks."
- starting_accessories = list(/obj/item/clothing/accessory/red_long)
+ starting_accessories = list(/obj/item/clothing/accessory/tie/red_long)
/obj/item/clothing/under/det/black
icon_state = "detective3"
item_state_slots = list(slot_r_hand_str = "sl_suit", slot_l_hand_str = "sl_suit")
desc = "An immaculate white dress shirt, paired with a pair of dark grey dress pants, a red tie, and a charcoal vest."
- starting_accessories = list(/obj/item/clothing/accessory/red_long, /obj/item/clothing/accessory/vest)
+ starting_accessories = list(/obj/item/clothing/accessory/tie/red_long, /obj/item/clothing/accessory/vest)
/obj/item/clothing/under/det/corporate
name = "detective's jumpsuit"
@@ -106,12 +106,12 @@
/obj/item/clothing/under/det/waistcoat
icon_state = "detective"
desc = "A rumpled white dress shirt paired with well-worn grey slacks, complete with a blue striped tie, faux-gold tie clip, and waistcoat."
- starting_accessories = list(/obj/item/clothing/accessory/blue_clip, /obj/item/clothing/accessory/wcoat)
+ starting_accessories = list(/obj/item/clothing/accessory/tie/blue_clip, /obj/item/clothing/accessory/wcoat)
/obj/item/clothing/under/det/grey/waistcoat
icon_state = "detective2"
desc = "A serious-looking tan dress shirt paired with freshly-pressed black slacks, complete with a red striped tie and waistcoat."
- starting_accessories = list(/obj/item/clothing/accessory/red_long, /obj/item/clothing/accessory/wcoat)
+ starting_accessories = list(/obj/item/clothing/accessory/tie/red_long, /obj/item/clothing/accessory/wcoat)
/obj/item/clothing/under/det/skirt
name = "detective's skirt"
diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm
index 7f9586b6a0..f9a0a9ab37 100644
--- a/code/modules/clothing/under/miscellaneous.dm
+++ b/code/modules/clothing/under/miscellaneous.dm
@@ -101,7 +101,7 @@
icon_state = "greensuit"
item_state_slots = list(slot_r_hand_str = "centcom", slot_l_hand_str = "centcom")
rolled_sleeves = 0
- starting_accessories = list(/obj/item/clothing/accessory/darkgreen)
+ starting_accessories = list(/obj/item/clothing/accessory/tie/darkgreen)
/obj/item/clothing/under/gov/skirt
name = "Green formal skirt uniform"
@@ -161,7 +161,7 @@
icon_state = "gentlesuit"
item_state_slots = list(slot_r_hand_str = "grey", slot_l_hand_str = "grey")
rolled_sleeves = 0
- starting_accessories = list(/obj/item/clothing/accessory/white, /obj/item/clothing/accessory/wcoat/gentleman)
+ starting_accessories = list(/obj/item/clothing/accessory/tie/white, /obj/item/clothing/accessory/wcoat/gentleman)
/obj/item/clothing/under/gentlesuit/skirt
name = "lady's suit"
@@ -472,7 +472,7 @@
desc = "A charcoal suit and red tie. Very professional."
icon_state = "charcoal_suit"
item_state_slots = list(slot_r_hand_str = "lawyer_black", slot_l_hand_str = "lawyer_black")
- starting_accessories = list(/obj/item/clothing/accessory/navy, /obj/item/clothing/accessory/charcoal_jacket)
+ starting_accessories = list(/obj/item/clothing/accessory/tie/navy, /obj/item/clothing/accessory/jacket/charcoal)
/obj/item/clothing/under/suit_jacket/charcoal/skirt
name = "charcoal skirt"
@@ -483,7 +483,7 @@
desc = "A navy suit and red tie, intended for the station's finest."
icon_state = "navy_suit"
item_state_slots = list(slot_r_hand_str = "lawyer_blue", slot_l_hand_str = "lawyer_blue")
- starting_accessories = list(/obj/item/clothing/accessory/red, /obj/item/clothing/accessory/navy_jacket)
+ starting_accessories = list(/obj/item/clothing/accessory/tie/red, /obj/item/clothing/accessory/jacket/navy)
/obj/item/clothing/under/suit_jacket/navy/skirt
name = "navy skirt"
@@ -494,7 +494,7 @@
desc = "A burgundy suit and black tie. Somewhat formal."
icon_state = "burgundy_suit"
item_state_slots = list(slot_r_hand_str = "lawyer_red", slot_l_hand_str = "lawyer_red")
- starting_accessories = list(/obj/item/clothing/accessory/black, /obj/item/clothing/accessory/burgundy_jacket)
+ starting_accessories = list(/obj/item/clothing/accessory/tie/black, /obj/item/clothing/accessory/jacket/burgundy)
/obj/item/clothing/under/suit_jacket/burgundy/skirt
name = "burgundy skirt"
@@ -505,7 +505,7 @@
desc = "That's a very nice suit you have there. Shame if something were to happen to it, eh?"
icon_state = "checkered_suit"
item_state_slots = list(slot_r_hand_str = "lawyer_black", slot_l_hand_str = "lawyer_black")
- starting_accessories = list(/obj/item/clothing/accessory/black, /obj/item/clothing/accessory/checkered_jacket)
+ starting_accessories = list(/obj/item/clothing/accessory/tie/black, /obj/item/clothing/accessory/jacket/checkered)
/obj/item/clothing/under/suit_jacket/checkered/skirt
name = "checkered skirt"
@@ -516,7 +516,7 @@
desc = "A tan suit. Smart, but casual."
icon_state = "tan_suit"
item_state_slots = list(slot_r_hand_str = "tan_suit", slot_l_hand_str = "tan_suit")
- starting_accessories = list(/obj/item/clothing/accessory/yellow, /obj/item/clothing/accessory/tan_jacket)
+ starting_accessories = list(/obj/item/clothing/accessory/tie/yellow, /obj/item/clothing/accessory/jacket)
/obj/item/clothing/under/suit_jacket/tan/skirt
name = "tan skirt"
diff --git a/code/modules/customitems/item_spawning.dm b/code/modules/customitems/item_spawning.dm
index 54c3ee4e5c..ef2333a0af 100644
--- a/code/modules/customitems/item_spawning.dm
+++ b/code/modules/customitems/item_spawning.dm
@@ -222,6 +222,8 @@
existing_item = M.wear_id
else if(citem.item_path == /obj/item/device/pda)
existing_item = locate(/obj/item/device/pda) in M.contents
+ else if(citem.item_path == /obj/item/weapon/storage/backpack)
+ existing_item = locate(/obj/item/weapon/storage/backpack) in M.contents
// Spawn and equip the item.
if(existing_item)
diff --git a/code/modules/examine/stat_icons.dm b/code/modules/examine/stat_icons.dm
index b2ed64032a..1ece266f0c 100644
--- a/code/modules/examine/stat_icons.dm
+++ b/code/modules/examine/stat_icons.dm
@@ -29,4 +29,6 @@ var/global/list/description_icons = list(
"power cell" = image(icon='icons/obj/power.dmi',icon_state="hcell"),
"device cell" = image(icon='icons/obj/power.dmi',icon_state="dcell"),
"weapon cell" = image(icon='icons/obj/power.dmi',icon_state="wcell"),
+
+ "hatchet" = image(icon='icons/obj/weapons.dmi',icon_state="hatchet"),
)
diff --git a/code/modules/games/cardemon.dm b/code/modules/games/cardemon.dm
index 23e8d6e251..a99e656add 100644
--- a/code/modules/games/cardemon.dm
+++ b/code/modules/games/cardemon.dm
@@ -2,6 +2,7 @@
name = "cardemon booster pack"
desc = "Finally! A children's card game in space!"
icon_state = "card_pack_cardemon"
+ parentdeck = "cardemon"
/obj/item/weapon/pack/cardemon/New()
..()
@@ -28,4 +29,4 @@
P.name = "[rarity] [P.name]"
P.card_icon += "_[rarity]"
P.back_icon = "card_back_cardemon"
- cards += P
\ No newline at end of file
+ cards += P
diff --git a/code/modules/games/cards.dm b/code/modules/games/cards.dm
index 0eba340761..68aef108ec 100644
--- a/code/modules/games/cards.dm
+++ b/code/modules/games/cards.dm
@@ -7,6 +7,7 @@
w_class = ITEMSIZE_SMALL
icon = 'icons/obj/playing_cards.dmi'
var/list/cards = list()
+ var/cooldown = 0 // to prevent spam shuffle
/obj/item/weapon/deck/holder
name = "card box"
@@ -43,7 +44,7 @@
P.back_icon = "card_back"
cards += P
- for(var/i = 0,i<2,i++)
+ for(var/i = 0, i<2, i++)
P = new()
P.name = "joker"
P.card_icon = "joker"
@@ -52,13 +53,20 @@
/obj/item/weapon/deck/attackby(obj/O as obj, mob/user as mob)
if(istype(O,/obj/item/weapon/hand))
var/obj/item/weapon/hand/H = O
- for(var/datum/playingcard/P in H.cards)
- cards += P
- qdel(O)
- user << "You place your cards on the bottom of \the [src]."
- return
+ if(H.parentdeck == src)
+ for(var/datum/playingcard/P in H.cards)
+ cards += P
+ qdel(H)
+ to_chat(user,"You place your cards on the bottom of \the [src].")
+ return
+ else
+ to_chat(user,"You can't mix cards from other decks!")
+ return
..()
+/obj/item/weapon/deck/attack_hand(mob/user as mob)
+ draw_card()
+
/obj/item/weapon/deck/verb/draw_card()
set category = "Object"
@@ -66,18 +74,26 @@
set desc = "Draw a card from a deck."
set src in view(1)
+ var/mob/living/carbon/user = usr
+
if(usr.stat || !Adjacent(usr)) return
+ if(user.hands_are_full()) // Safety check lest the card disappear into oblivion
+ to_chat(user,"Your hands are full!")
+ return
+
if(!istype(usr,/mob/living/carbon))
return
- var/mob/living/carbon/user = usr
-
if(!cards.len)
- usr << "There are no cards in the deck."
+ to_chat(user,"There are no cards in the deck.")
return
var/obj/item/weapon/hand/H = user.get_type_in_hands(/obj/item/weapon/hand)
+ if(H && !(H.parentdeck == src))
+ to_chat(user,"You can't mix cards from different decks!")
+ return
+
if(!H)
H = new(get_turf(src))
user.put_in_hands(H)
@@ -87,9 +103,10 @@
var/datum/playingcard/P = cards[1]
H.cards += P
cards -= P
+ H.parentdeck = src
H.update_icon()
- user.visible_message("\The [user] draws a card.")
- user << "It's the [P]."
+ user.visible_message("\The [user] draws a card.")
+ to_chat(user,"It's the [P].")
/obj/item/weapon/deck/verb/deal_card()
@@ -101,7 +118,7 @@
if(usr.stat || !Adjacent(usr)) return
if(!cards.len)
- usr << "There are no cards in the deck."
+ to_chat(usr,"There are no cards in the deck.")
return
var/list/players = list()
@@ -113,26 +130,56 @@
var/mob/living/M = input("Who do you wish to deal a card?") as null|anything in players
if(!usr || !src || !M) return
- deal_at(usr, M)
+ deal_at(usr, M, 1)
-/obj/item/weapon/deck/proc/deal_at(mob/user, mob/target)
+/obj/item/weapon/deck/verb/deal_card_multi()
+
+ set category = "Object"
+ set name = "Deal Multiple Cards"
+ set desc = "Deal multiple cards from a deck."
+ set src in view(1)
+
+ if(usr.stat || !Adjacent(usr)) return
+
+ if(!cards.len)
+ to_chat(usr,"There are no cards in the deck.")
+ return
+
+ var/list/players = list()
+ for(var/mob/living/player in viewers(3))
+ if(!player.stat)
+ players += player
+ //players -= usr
+ var/maxcards = max(min(cards.len,10),1)
+ var/dcard = input("How many card(s) do you wish to deal? You may deal up to [maxcards] cards.") as num
+ if(dcard > maxcards)
+ return
+ var/mob/living/M = input("Who do you wish to deal [dcard] card(s)?") as null|anything in players
+ if(!usr || !src || !M) return
+
+ deal_at(usr, M, dcard)
+
+/obj/item/weapon/deck/proc/deal_at(mob/user, mob/target, dcard) // Take in the no. of card to be dealt
var/obj/item/weapon/hand/H = new(get_step(user, user.dir))
-
- H.cards += cards[1]
- cards -= cards[1]
- H.concealed = 1
- H.update_icon()
+ var/i
+ for(i = 0, i < dcard, i++)
+ H.cards += cards[1]
+ cards -= cards[1]
+ H.parentdeck = src
+ H.concealed = 1
+ H.update_icon()
if(user==target)
- user.visible_message("\The [user] deals a card to \himself.")
+ user.visible_message("\The [user] deals [dcard] card(s) to \himself.")
else
- user.visible_message("\The [user] deals a card to \the [target].")
+ user.visible_message("\The [user] deals [dcard] card(s) to \the [target].")
H.throw_at(get_step(target,target.dir),10,1,H)
+
/obj/item/weapon/hand/attackby(obj/O as obj, mob/user as mob)
if(cards.len == 1 && istype(O, /obj/item/weapon/pen))
var/datum/playingcard/P = cards[1]
if(P.name != "Blank Card")
- user << "You cannot write on that card."
+ to_chat(user,"You cannot write on that card.")
return
var/cardtext = sanitize(input(user, "What do you wish to write on the card?", "Card Editing") as text|null, MAX_PAPER_MESSAGE_LEN)
if(!cardtext)
@@ -143,36 +190,81 @@
update_icon()
else if(istype(O,/obj/item/weapon/hand))
var/obj/item/weapon/hand/H = O
- for(var/datum/playingcard/P in cards)
- H.cards += P
- H.concealed = src.concealed
- user.drop_from_inventory(src)
- qdel(src)
- H.update_icon()
- return
+ if(H.parentdeck == src.parentdeck) // Prevent cardmixing
+ for(var/datum/playingcard/P in cards)
+ H.cards += P
+ H.concealed = src.concealed
+ user.drop_from_inventory(src)
+ qdel(src)
+ H.update_icon()
+ return
+ else
+ to_chat(user,"You cannot mix cards from other decks!")
+ return
+
..()
-/obj/item/weapon/deck/attack_self(var/mob/user as mob)
+/obj/item/weapon/deck/attack_self()
+ shuffle()
- var/list/newcards = list()
- while(cards.len)
- var/datum/playingcard/P = pick(cards)
- newcards += P
- cards -= P
- cards = newcards
- user.visible_message("\The [user] shuffles [src].")
-/obj/item/weapon/deck/MouseDrop(atom/over)
- if(!usr || !over) return
- if(!Adjacent(usr) || !over.Adjacent(usr)) return // should stop you from dragging through windows
+/obj/item/weapon/deck/verb/verb_shuffle()
+ set category = "Object"
+ set name = "Shuffle"
+ set desc = "Shuffle the cards in the deck."
+ set src in view(1)
+ shuffle()
- if(!ishuman(over) || !(over in viewers(3))) return
-
- if(!cards.len)
- usr << "There are no cards in the deck."
+/obj/item/weapon/deck/proc/shuffle()
+ var/mob/living/user = usr
+ if (cooldown < world.time - 10) // 15 ticks cooldown
+ var/list/newcards = list()
+ while(cards.len)
+ var/datum/playingcard/P = pick(cards)
+ newcards += P
+ cards -= P
+ cards = newcards
+ user.visible_message("\The [user] shuffles [src].")
+ playsound(user, 'sound/items/cardshuffle.ogg', 50, 1)
+ cooldown = world.time
+ else
return
- deal_at(usr, over)
+
+/obj/item/weapon/deck/MouseDrop(mob/user as mob) // Code from Paper bin, so you can still pick up the deck
+ if((user == usr && (!( usr.restrained() ) && (!( usr.stat ) && (usr.contents.Find(src) || in_range(src, usr))))))
+ if(!istype(usr, /mob/living/simple_animal))
+ if( !usr.get_active_hand() ) //if active hand is empty
+ var/mob/living/carbon/human/H = user
+ var/obj/item/organ/external/temp = H.organs_by_name["r_hand"]
+
+ if (H.hand)
+ temp = H.organs_by_name["l_hand"]
+ if(temp && !temp.is_usable())
+ to_chat(user,"You try to move your [temp.name], but cannot!")
+ return
+
+ to_chat(user,"You pick up [src].")
+ user.put_in_hands(src)
+
+ return
+
+/obj/item/weapon/deck/verb_pickup(mob/user as mob) // Snowflaked so pick up verb work as intended
+ if((user == usr && (!( usr.restrained() ) && (!( usr.stat ) && (usr.contents.Find(src) || in_range(src, usr))))))
+ if(!istype(usr, /mob/living/simple_animal))
+ if( !usr.get_active_hand() ) //if active hand is empty
+ var/mob/living/carbon/human/H = user
+ var/obj/item/organ/external/temp = H.organs_by_name["r_hand"]
+
+ if (H.hand)
+ temp = H.organs_by_name["l_hand"]
+ if(temp && !temp.is_usable())
+ to_chat(user,"You try to move your [temp.name], but cannot!")
+ return
+
+ to_chat(user,"You pick up [src].")
+ user.put_in_hands(src)
+ return
/obj/item/weapon/pack/
name = "Card Pack"
@@ -182,13 +274,15 @@
icon = 'icons/obj/playing_cards.dmi'
w_class = ITEMSIZE_TINY
var/list/cards = list()
+ var/parentdeck = null // This variable is added here so that card pack dependent card can be mixed together by defining a "parentdeck" for them
/obj/item/weapon/pack/attack_self(var/mob/user as mob)
- user.visible_message("[user] rips open \the [src]!")
+ user.visible_message("[user] rips open \the [src]!")
var/obj/item/weapon/hand/H = new()
H.cards += cards
+ H.parentdeck = src.parentdeck
cards.Cut();
user.drop_item()
qdel(src)
@@ -205,31 +299,39 @@
var/concealed = 0
var/list/cards = list()
+ var/parentdeck = null
/obj/item/weapon/hand/verb/discard()
set category = "Object"
set name = "Discard"
- set desc = "Place a card from your hand in front of you."
+ set desc = "Place (a) card(s) from your hand in front of you."
- var/list/to_discard = list()
- for(var/datum/playingcard/P in cards)
- to_discard[P.name] = P
- var/discarding = input("Which card do you wish to put down?") as null|anything in to_discard
+ var/i
+ var/maxcards = min(cards.len,5) // Maximum of 5 cards at once
+ var/discards = input("How many cards do you want to discard? You may discard up to [maxcards] card(s)") as num
+ if(discards > maxcards)
+ return
+ for (i = 0;i < discards;i++)
+ var/list/to_discard = list()
+ for(var/datum/playingcard/P in cards)
+ to_discard[P.name] = P
+ var/discarding = input("Which card do you wish to put down?") as null|anything in to_discard
- if(!discarding || !to_discard[discarding] || !usr || !src) return
+ if(!discarding || !to_discard[discarding] || !usr || !src) return
- var/datum/playingcard/card = to_discard[discarding]
- to_discard.Cut()
+ var/datum/playingcard/card = to_discard[discarding]
+ to_discard.Cut()
- var/obj/item/weapon/hand/H = new(src.loc)
- H.cards += card
- cards -= card
- H.concealed = 0
- H.update_icon()
- src.update_icon()
- usr.visible_message("\The [usr] plays \the [discarding].")
- H.loc = get_step(usr,usr.dir)
+ var/obj/item/weapon/hand/H = new(src.loc)
+ H.cards += card
+ cards -= card
+ H.concealed = 0
+ H.parentdeck = src.parentdeck
+ H.update_icon()
+ src.update_icon()
+ usr.visible_message("\The [usr] plays \the [discarding].")
+ H.loc = get_step(usr,usr.dir)
if(!cards.len)
qdel(src)
@@ -237,14 +339,51 @@
/obj/item/weapon/hand/attack_self(var/mob/user as mob)
concealed = !concealed
update_icon()
- user.visible_message("\The [user] [concealed ? "conceals" : "reveals"] their hand.")
+ user.visible_message("\The [user] [concealed ? "conceals" : "reveals"] their hand.")
/obj/item/weapon/hand/examine(mob/user)
..(user)
- if((!concealed || src.loc == user) && cards.len)
- user << "It contains: "
+ if((!concealed) && cards.len)
+ to_chat(user,"It contains: ")
for(var/datum/playingcard/P in cards)
- user << "\The [P.name]."
+ to_chat(user,"\The [P.name].")
+
+/obj/item/weapon/hand/verb/Removecard()
+
+ set category = "Object"
+ set name = "Remove card"
+ set desc = "Remove a card from the hand."
+ set src in view(1)
+
+ var/mob/living/carbon/user = usr
+
+ if(user.stat || !Adjacent(user)) return
+
+ if(user.hands_are_full()) // Safety check lest the card disappear into oblivion
+ to_chat(usr,"Your hands are full!")
+ return
+
+ var/pickablecards = list()
+ for(var/datum/playingcard/P in cards)
+ pickablecards[P.name] += P
+ var/pickedcard = input("Which card do you want to remove from the hand?") as null|anything in pickablecards
+
+ if(!pickedcard || !pickablecards[pickedcard] || !usr || !src) return
+
+ var/datum/playingcard/card = pickablecards[pickedcard]
+
+ var/obj/item/weapon/hand/H = new(get_turf(src))
+ user.put_in_hands(H)
+ H.cards += card
+ cards -= card
+ H.parentdeck = src.parentdeck
+ H.concealed = src.concealed
+ H.update_icon()
+ src.update_icon()
+
+ if(!cards.len)
+ qdel(src)
+ return
/obj/item/weapon/hand/update_icon(var/direction = 0)
@@ -308,4 +447,4 @@
update_icon()
/obj/item/weapon/hand/pickup(mob/user as mob)
- src.update_icon()
\ No newline at end of file
+ src.update_icon()
diff --git a/code/modules/games/spaceball_cards.dm b/code/modules/games/spaceball_cards.dm
index 57a28fa1a2..146317a720 100644
--- a/code/modules/games/spaceball_cards.dm
+++ b/code/modules/games/spaceball_cards.dm
@@ -2,6 +2,7 @@
name = "spaceball booster pack"
desc = "Officially licensed to take your money."
icon_state = "card_pack_spaceball"
+ parentdeck = "spaceball"
/obj/item/weapon/pack/spaceball/New()
..()
diff --git a/code/modules/games/tarot.dm b/code/modules/games/tarot.dm
index f5727a0c43..cae71540cb 100644
--- a/code/modules/games/tarot.dm
+++ b/code/modules/games/tarot.dm
@@ -24,14 +24,20 @@
P.back_icon = "card_back_tarot"
cards += P
-/obj/item/weapon/deck/tarot/attack_self(var/mob/user as mob)
- var/list/newcards = list()
- while(cards.len)
- var/datum/playingcard/P = pick(cards)
- P.name = replacetext(P.name," reversed","")
- if(prob(50))
- P.name += " reversed"
- newcards += P
- cards -= P
- cards = newcards
- user.visible_message("\The [user] shuffles [src].")
\ No newline at end of file
+/obj/item/weapon/deck/tarot/shuffle()
+ var/mob/living/user = usr
+ if (cooldown < world.time - 10)
+ var/list/newcards = list()
+ while(cards.len)
+ var/datum/playingcard/P = pick(cards)
+ P.name = replacetext(P.name," reversed","")
+ if(prob(50))
+ P.name += " reversed"
+ newcards += P
+ cards -= P
+ cards = newcards
+ playsound(user, 'sound/items/cardshuffle.ogg', 50, 1)
+ user.visible_message("\The [user] shuffles [src].")
+ cooldown = world.time
+ else
+ return
diff --git a/code/modules/integrated_electronics/subtypes/converters.dm b/code/modules/integrated_electronics/subtypes/converters.dm
index 343890af56..b9f5c912d4 100644
--- a/code/modules/integrated_electronics/subtypes/converters.dm
+++ b/code/modules/integrated_electronics/subtypes/converters.dm
@@ -67,6 +67,40 @@
push_data()
activate_pin(2)
+/obj/item/integrated_circuit/converter/refcode
+ name = "reference encoder"
+ desc = "This circuit can encode a reference into a string, which can then be read by an EPV2 circuit."
+ icon_state = "ref-string"
+ inputs = list("input" = IC_PINTYPE_REF)
+ outputs = list("output" = IC_PINTYPE_STRING)
+ spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
+
+/obj/item/integrated_circuit/converter/refcode/do_work()
+ var/result = null
+ pull_data()
+ var/atom/A = get_pin_data(IC_INPUT, 1)
+ if(A && istype(A))
+ result = "\ref[A]"
+
+ set_pin_data(IC_OUTPUT, 1, result)
+ push_data()
+ activate_pin(2)
+
+/obj/item/integrated_circuit/converter/refdecode
+ name = "reference decoder"
+ desc = "This circuit can convert an encoded reference to actual reference."
+ icon_state = "ref-string"
+ inputs = list("input" = IC_PINTYPE_STRING)
+ outputs = list("output" = IC_PINTYPE_REF)
+ spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
+
+
+/obj/item/integrated_circuit/converter/refdecode/do_work()
+ pull_data()
+ set_pin_data(IC_OUTPUT, 1, weakref(locate(get_pin_data(IC_INPUT, 1))))
+ 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."
@@ -168,6 +202,56 @@
activate_pin(2)
+/obj/item/integrated_circuit/converter/findstring
+ name = "find text"
+ desc = "This gives position of sample in the string. Or returns 0."
+ extended_desc = "The first pin is the string to be examined. The second pin is the sample to be found. \
+ For example, 'eat this burger',' ' will give you position 4. This circuit isn't case sensitive."
+ complexity = 4
+ inputs = list(
+ "string" = IC_PINTYPE_STRING,
+ "sample" = IC_PINTYPE_STRING,
+ )
+ outputs = list(
+ "position" = IC_PINTYPE_NUMBER
+ )
+ activators = list("search" = IC_PINTYPE_PULSE_IN, "after search" = IC_PINTYPE_PULSE_OUT)
+ spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
+
+
+
+/obj/item/integrated_circuit/converter/findstring/do_work()
+
+ set_pin_data(IC_OUTPUT, 1, findtext(get_pin_data(IC_INPUT, 1),get_pin_data(IC_INPUT, 2)) )
+ push_data()
+
+ activate_pin(2)
+
+/obj/item/integrated_circuit/converter/exploders
+ name = "string exploder"
+ desc = "This splits a single string into a list of strings."
+ extended_desc = "This circuit splits a given string into a list of strings based on the string and given delimiter. \
+ For example, 'eat this burger',' ' will be converted to list('eat','this','burger')."
+ complexity = 4
+ inputs = list(
+ "string to split" = IC_PINTYPE_STRING,
+ "delimiter" = IC_PINTYPE_STRING,
+ )
+ outputs = list(
+ "list" = IC_PINTYPE_LIST
+ )
+ activators = list("separate" = IC_PINTYPE_PULSE_IN, "on separated" = IC_PINTYPE_PULSE_OUT)
+ spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
+
+
+
+/obj/item/integrated_circuit/converter/exploders/do_work()
+ var/strin = get_pin_data(IC_INPUT, 1)
+ var/sample = get_pin_data(IC_INPUT, 2)
+ set_pin_data(IC_OUTPUT, 1, splittext( strin ,sample ))
+ push_data()
+
+ activate_pin(2)
/obj/item/integrated_circuit/converter/radians2degrees
name = "radians to degrees converter"
diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm
index 95ed94b813..d752f0d5cd 100644
--- a/code/modules/integrated_electronics/subtypes/input.dm
+++ b/code/modules/integrated_electronics/subtypes/input.dm
@@ -17,6 +17,8 @@
activators = list("on pressed" = IC_PINTYPE_PULSE_IN)
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.
to_chat(user, "You press the button labeled '[src.name]'.")
activate_pin(1)
@@ -105,9 +107,11 @@
push_data()
activate_pin(2)
+
+
/obj/item/integrated_circuit/input/adv_med_scanner
name = "integrated advanced medical analyser"
- desc = "A very small version of the common medical analyser. This allows the machine to know how healthy someone is. \
+ desc = "A very small version of the medbot's medical analyser. This allows the machine to know how healthy someone is. \
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
@@ -130,7 +134,7 @@
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.
+ if(H in view(get_turf(H))) // Like medbot's analyzer it can be used in range..
var/total_health = round(H.health/H.getMaxHealth(), 0.01)*100
var/missing_health = H.getMaxHealth() - H.health
@@ -145,6 +149,53 @@
push_data()
activate_pin(2)
+/obj/item/integrated_circuit/input/examiner
+ name = "examiner"
+ desc = "It's a little machine vision system. It can return the name, description, distance,\
+ relative coordinates, total amount of reagents, and maximum amount of reagents of the referenced object."
+ icon_state = "video_camera"
+ complexity = 6
+ inputs = list("\[ target" = IC_PINTYPE_REF)
+ outputs = list(
+ "name" = IC_PINTYPE_STRING,
+ "description" = IC_PINTYPE_STRING,
+ "X" = IC_PINTYPE_NUMBER,
+ "Y" = IC_PINTYPE_NUMBER,
+ "distance" = IC_PINTYPE_NUMBER,
+ "max reagents" = IC_PINTYPE_NUMBER,
+ "amount of reagents" = IC_PINTYPE_NUMBER,
+ )
+ activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT, "not scanned" = IC_PINTYPE_PULSE_OUT)
+ 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/examiner/do_work()
+ var/atom/movable/H = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
+ var/turf/T = get_turf(src)
+ if(!istype(H)) //Invalid input
+ return
+
+ if(H in view(T)) // This is a camera. It can't examine thngs,that it can't see.
+
+
+ set_pin_data(IC_OUTPUT, 1, H.name)
+ set_pin_data(IC_OUTPUT, 2, H.desc)
+ set_pin_data(IC_OUTPUT, 3, H.x-T.x)
+ set_pin_data(IC_OUTPUT, 4, H.y-T.y)
+ set_pin_data(IC_OUTPUT, 5, sqrt((H.x-T.x)*(H.x-T.x)+ (H.y-T.y)*(H.y-T.y)))
+ var/mr = 0
+ var/tr = 0
+ if(H.reagents)
+ mr = H.reagents.maximum_volume
+ tr = H.reagents.total_volume
+ set_pin_data(IC_OUTPUT, 6, mr)
+ set_pin_data(IC_OUTPUT, 7, tr)
+ push_data()
+ activate_pin(2)
+ else
+ activate_pin(3)
+
/obj/item/integrated_circuit/input/local_locator
name = "local locator"
desc = "This is needed for certain devices that demand a reference for a target to act upon. This type only locates something \
@@ -173,7 +224,8 @@
random."
inputs = list("desired type ref")
outputs = list("located ref")
- activators = list("locate" = IC_PINTYPE_PULSE_IN)
+ activators = list("locate" = IC_PINTYPE_PULSE_IN,"found" = IC_PINTYPE_PULSE_OUT,
+ "not found" = IC_PINTYPE_PULSE_OUT)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
power_draw_per_use = 30
@@ -197,8 +249,64 @@
valid_things.Add(thing)
if(valid_things.len)
O.data = weakref(pick(valid_things))
+ activate_pin(2)
+ else
+ activate_pin(3)
O.push_data()
+/obj/item/integrated_circuit/input/advanced_locator
+ complexity = 6
+ name = "advanced locator"
+ desc = "This is needed for certain devices that demand a reference for a target to act upon. This type locates something \
+ that is standing in given radius of up to 8 meters"
+ extended_desc = "The first pin requires a ref to a kind of object that you want the locator to acquire. This means that it will \
+ give refs to nearby objects that are similar to given sample. If this pin is a string, the locator will search for\
+ item by matching desired text in name + description. If more than one valid object is found nearby, it will choose one of them at \
+ random. The second pin is a radius."
+ inputs = list("desired type" = IC_PINTYPE_ANY, "radius" = IC_PINTYPE_NUMBER)
+ outputs = list("located ref")
+ activators = list("locate" = IC_PINTYPE_PULSE_IN,"found" = IC_PINTYPE_PULSE_OUT,"not found" = IC_PINTYPE_PULSE_OUT)
+ spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
+ power_draw_per_use = 30
+ var/radius = 1
+
+/obj/item/integrated_circuit/input/advanced_locator/on_data_written()
+ var/rad = get_pin_data(IC_INPUT, 2)
+ if(isnum(rad))
+ rad = Clamp(rad, 0, 8)
+ radius = rad
+
+/obj/item/integrated_circuit/input/advanced_locator/do_work()
+ var/datum/integrated_io/I = inputs[1]
+ var/datum/integrated_io/O = outputs[1]
+ O.data = null
+ var/turf/T = get_turf(src)
+ var/list/nearby_things = range(radius, T) & view(T)
+ var/list/valid_things = list()
+ if(isweakref(I.data))
+ var/atom/A = I.data.resolve()
+ var/desired_type = A.type
+ if(desired_type)
+ for(var/atom/thing in nearby_things)
+ if(thing.type == desired_type)
+ valid_things.Add(thing)
+ else if(istext(I.data))
+ var/DT = I.data
+ for(var/atom/thing in nearby_things)
+ if(findtext(addtext(thing.name," ",thing.desc), DT, 1, 0) )
+ valid_things.Add(thing)
+ if(valid_things.len)
+ O.data = weakref(pick(valid_things))
+ O.push_data()
+ activate_pin(2)
+ else
+ O.push_data()
+ activate_pin(3)
+
+
+
+
+
/obj/item/integrated_circuit/input/signaler
name = "integrated signaler"
desc = "Signals from a signaler can be received with this, allowing for remote control. Additionally, it can send signals as well."
@@ -431,3 +539,83 @@
activate_pin(1)
return TRUE
+/obj/item/integrated_circuit/input/internalbm
+ name = "internal battery monitor"
+ desc = "This monitors the charge level of an internal battery."
+ icon_state = "internalbm"
+ extended_desc = "This circuit will give you values of charge, max charge and percentage of the internal battery on demand."
+ w_class = ITEMSIZE_TINY
+ complexity = 1
+ inputs = list()
+ outputs = list(
+ "cell charge" = IC_PINTYPE_NUMBER,
+ "max charge" = IC_PINTYPE_NUMBER,
+ "percentage" = IC_PINTYPE_NUMBER,
+ "refference to assembly" = IC_PINTYPE_REF
+ )
+ activators = list("read" = IC_PINTYPE_PULSE_IN, "on read" = IC_PINTYPE_PULSE_OUT)
+ spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
+ origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_POWER = 4, TECH_MAGNET = 3)
+ power_draw_per_use = 1
+
+/obj/item/integrated_circuit/input/internalbm/do_work()
+ set_pin_data(IC_OUTPUT, 1, null)
+ set_pin_data(IC_OUTPUT, 2, null)
+ set_pin_data(IC_OUTPUT, 3, null)
+ set_pin_data(IC_OUTPUT, 4, weakref(assembly))
+ if(assembly)
+ if(assembly.battery)
+
+ set_pin_data(IC_OUTPUT, 1, assembly.battery.charge)
+ set_pin_data(IC_OUTPUT, 2, assembly.battery.maxcharge)
+ set_pin_data(IC_OUTPUT, 3, 100*assembly.battery.charge/assembly.battery.maxcharge)
+ push_data()
+ activate_pin(2)
+
+/obj/item/integrated_circuit/input/externalbm
+ name = "external battery monitor"
+ desc = "This can help watch the battery level of any device in range."
+ icon_state = "externalbm"
+ extended_desc = "This circuit will give you values of charge, max charge and percentage of any device or battery in view"
+ w_class = ITEMSIZE_TINY
+ complexity = 2
+ inputs = list("target" = IC_PINTYPE_REF)
+ outputs = list(
+ "cell charge" = IC_PINTYPE_NUMBER,
+ "max charge" = IC_PINTYPE_NUMBER,
+ "percentage" = IC_PINTYPE_NUMBER
+ )
+ activators = list("read" = IC_PINTYPE_PULSE_IN, "on read" = IC_PINTYPE_PULSE_OUT)
+ spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
+ origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_POWER = 4, TECH_MAGNET = 3)
+ power_draw_per_use = 1
+
+/obj/item/integrated_circuit/input/externalbm/do_work()
+
+ var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
+ set_pin_data(IC_OUTPUT, 1, null)
+ set_pin_data(IC_OUTPUT, 2, null)
+ set_pin_data(IC_OUTPUT, 3, null)
+ if(AM)
+
+
+ var/obj/item/weapon/cell/cell = null
+ if(istype(AM, /obj/item/weapon/cell)) // Is this already a cell?
+ cell = AM
+ else // If not, maybe there's a cell inside it?
+ for(var/obj/item/weapon/cell/C in AM.contents)
+ if(C) // Find one cell to charge.
+ cell = C
+ break
+ if(cell)
+
+ var/turf/A = get_turf(src)
+ if(AM in view(A))
+ push_data()
+ set_pin_data(IC_OUTPUT, 1, cell.charge)
+ set_pin_data(IC_OUTPUT, 2, cell.maxcharge)
+ set_pin_data(IC_OUTPUT, 3, cell.percent())
+ push_data()
+ activate_pin(2)
+
+
diff --git a/code/modules/integrated_electronics/subtypes/logic.dm b/code/modules/integrated_electronics/subtypes/logic.dm
index 4bbffede35..82667634a1 100644
--- a/code/modules/integrated_electronics/subtypes/logic.dm
+++ b/code/modules/integrated_electronics/subtypes/logic.dm
@@ -55,6 +55,98 @@
/obj/item/integrated_circuit/logic/binary/equals/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B)
return A.data == B.data
+/obj/item/integrated_circuit/logic/binary/jklatch
+ name = "JK latch"
+ desc = "This gate is a synchronysed JK latch."
+ icon_state = "jklatch"
+ inputs = list("J","K")
+ outputs = list("Q","!Q")
+ activators = list("pulse in C" = IC_PINTYPE_PULSE_IN, "pulse out Q" = IC_PINTYPE_PULSE_OUT, "pulse out !Q" = IC_PINTYPE_PULSE_OUT)
+ spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
+ var/lstate=FALSE
+
+/obj/item/integrated_circuit/logic/binary/jklatch/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]
+ var/datum/integrated_io/Q = outputs[2]
+ if(A.data)
+ if(B.data)
+ lstate=!lstate
+ else
+ lstate = TRUE
+ else
+ if(B.data)
+ lstate=FALSE
+ O.data = lstate ? TRUE : FALSE
+ Q.data = !lstate ? TRUE : FALSE
+ if(get_pin_data(IC_OUTPUT, 1))
+ activate_pin(2)
+ else
+ activate_pin(3)
+ push_data()
+
+/obj/item/integrated_circuit/logic/binary/rslatch
+ name = "RS latch"
+ desc = "This gate is synchronysed a RS latch. If both R and S are true, the state will not change."
+ icon_state = "sr_nor"
+ inputs = list("S","R")
+ outputs = list("Q","!Q")
+ activators = list("pulse in C" = IC_PINTYPE_PULSE_IN, "pulse out Q" = IC_PINTYPE_PULSE_OUT, "pulse out !Q" = IC_PINTYPE_PULSE_OUT)
+ spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
+ var/lstate=FALSE
+
+/obj/item/integrated_circuit/logic/binary/rslatch/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]
+ var/datum/integrated_io/Q = outputs[2]
+ if(A.data)
+ if(!B.data)
+ lstate=TRUE
+ else
+ if(B.data)
+ lstate=FALSE
+ O.data = lstate ? TRUE : FALSE
+ Q.data = !lstate ? TRUE : FALSE
+ if(get_pin_data(IC_OUTPUT, 1))
+ activate_pin(2)
+ else
+ activate_pin(3)
+ push_data()
+
+/obj/item/integrated_circuit/logic/binary/gdlatch
+ name = "gated D latch"
+ desc = "This gate is a synchronysed gated D latch."
+ icon_state = "gated_d"
+ inputs = list("D","E")
+ outputs = list("Q","!Q")
+ activators = list("pulse in C" = IC_PINTYPE_PULSE_IN, "pulse out Q" = IC_PINTYPE_PULSE_OUT, "pulse out !Q" = IC_PINTYPE_PULSE_OUT)
+ spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
+ var/lstate=FALSE
+
+/obj/item/integrated_circuit/logic/binary/gdlatch/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]
+ var/datum/integrated_io/Q = outputs[2]
+ if(B.data)
+ if(A.data)
+ lstate=TRUE
+ else
+ lstate=FALSE
+
+ O.data = lstate ? TRUE : FALSE
+ Q.data = !lstate ? TRUE : FALSE
+ if(get_pin_data(IC_OUTPUT, 1))
+ activate_pin(2)
+ else
+ activate_pin(3)
+ push_data()
+
/obj/item/integrated_circuit/logic/binary/not_equals
name = "not equal gate"
desc = "This gate compares two values, and outputs the number one if both are different."
diff --git a/code/modules/integrated_electronics/subtypes/smart.dm b/code/modules/integrated_electronics/subtypes/smart.dm
index 14aa9b6eab..0e16cd4079 100644
--- a/code/modules/integrated_electronics/subtypes/smart.dm
+++ b/code/modules/integrated_electronics/subtypes/smart.dm
@@ -25,8 +25,10 @@
if(!A)
return
if(!(A in view(get_turf(src))))
+ push_data()
return // Can't see the target.
- var/desired_dir = get_dir(get_turf(src), A)
+ var/desired_dir = get_dir(get_turf(src), get_turf(A))
set_pin_data(IC_OUTPUT, 1, desired_dir)
- push_data()
\ No newline at end of file
+ push_data()
+ activate_pin(2)
\ No newline at end of file
diff --git a/code/modules/lore_codex/lore_data/species.dm b/code/modules/lore_codex/lore_data/species.dm
index 54d72e0718..1027b602a8 100644
--- a/code/modules/lore_codex/lore_data/species.dm
+++ b/code/modules/lore_codex/lore_data/species.dm
@@ -7,6 +7,8 @@
/datum/lore/codex/page/unathi,
/datum/lore/codex/page/tajaran,
/datum/lore/codex/page/diona,
+ /datum/lore/codex/page/promethean,
+ /datum/lore/codex/page/vatborn,
/datum/lore/codex/category/teshari,
/datum/lore/codex/category/positronic,
/datum/lore/codex/category/drone
@@ -125,6 +127,27 @@
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."
+// Promethean Lore
+/datum/lore/codex/page/promethean/add_content()
+ name = "Promethean"
+ keywords += list("slime", "promethean")
+ data = "Prometheans are an artificial species created by the Humans sometime in the 2540s, aboard the NRS Prometheus, while experimenting with \
+ the Aetolian giant slime, or ‘Macrolimus vulgaris’. They themselves are considered sapient beings and given protection under prior Human legislation, \
+ though often only appear to serve as aides or inferior positions when kept as staff. Aetolus, the official ‘Home world’ of the Prometheans and giant slime, \
+ is an obnoxiously warm, humid planet requiring structures to be built within large, atmospherically-filtered ‘tent-like’ domes. \
+ Prometheans take on vague visual and vocal features of the species they cohabitate with, sharing their predecessors’ tendency to mimic nearby entities, \
+ though in physical form additionally; this is seemingly more important in their own development, as well. Despite their taken appearances, \
+ there is no known existence of a divergence between a biologically ‘male’ or ‘female’ form of the species, leading most to believe they are in fact asexual, \
+ as their predecessors are."
+
+// Vatborn Lore
+/datum/lore/codex/page/vatborn/add_content()
+ name = "Vatborn"
+ keywords += list("vatborn")
+ data = "A genetically modified type of human, Vatborn humans are cloned from a template and grown in special tubes. They look like pale \
+ but otherwise normal humans, but their bodies have a few internal changes. For one, they lack an appendix. On top of that, they are frequently \
+ hungry, as their metabolisms are faster than standard."
+
// Posi lore
/datum/lore/codex/category/positronic/add_content()
name = "Positronics"
diff --git a/code/modules/materials/material_recipes.dm b/code/modules/materials/material_recipes.dm
index ccda4fc9f6..c0c1eecd9e 100644
--- a/code/modules/materials/material_recipes.dm
+++ b/code/modules/materials/material_recipes.dm
@@ -139,6 +139,9 @@
recipes += new/datum/stack_recipe("wooden bucket", /obj/item/weapon/reagent_containers/glass/bucket/wood, 2, time = 4, one_per_turf = 0, on_floor = 0)
recipes += new/datum/stack_recipe("coilgun stock", /obj/item/weapon/coilgun_assembly, 5)
+/material/wood/log/generate_recipes()
+ return // Feel free to add log-only recipes here later if desired.
+
/material/cardboard/generate_recipes()
..()
recipes += new/datum/stack_recipe("box", /obj/item/weapon/storage/box)
diff --git a/code/modules/materials/material_sheets.dm b/code/modules/materials/material_sheets.dm
index 7ba518f6ef..f66d2425c6 100644
--- a/code/modules/materials/material_sheets.dm
+++ b/code/modules/materials/material_sheets.dm
@@ -203,6 +203,35 @@
icon_state = "sheet-wood"
default_type = "wood"
+/obj/item/stack/material/log
+ name = "log"
+ icon_state = "sheet-log"
+ default_type = "log"
+ no_variants = FALSE
+ color = "#824B28"
+ max_amount = 25
+ w_class = ITEMSIZE_HUGE
+
+/obj/item/stack/material/log/sif
+ name = "alien log"
+ color = "#0099cc"
+
+/obj/item/stack/material/log/attackby(var/obj/item/W, var/mob/user)
+ if(!istype(W))
+ return ..()
+ if(W.sharp && W.edge && use(1))
+ to_chat(user, "You cut up a log into planks.")
+ playsound(get_turf(src), 'sound/effects/woodcutting.ogg', 50, 1)
+ var/obj/item/stack/material/wood/existing_wood = locate() in user.loc
+ var/obj/item/stack/material/wood/new_wood = new(user.loc)
+ new_wood.amount = 2
+ if(existing_wood)
+ if(new_wood.transfer_to(existing_wood))
+ to_chat(user, "You add the newly-formed wood to the stack. It now contains [existing_wood.amount] planks.")
+ else
+ return ..()
+
+
/obj/item/stack/material/cloth
name = "cloth"
icon_state = "sheet-cloth"
diff --git a/code/modules/materials/materials.dm b/code/modules/materials/materials.dm
index 2daa7501c0..0db3a1016e 100644
--- a/code/modules/materials/materials.dm
+++ b/code/modules/materials/materials.dm
@@ -680,6 +680,18 @@ var/list/name_to_material
sheet_singular_name = "plank"
sheet_plural_name = "planks"
+/material/wood/log
+ name = "log"
+ icon_base = "log"
+ stack_type = /obj/item/stack/material/log
+ sheet_singular_name = "log"
+ sheet_plural_name = "logs"
+
+/material/wood/log/sif
+ name = "alien log"
+ icon_colour = "#0099cc" // Cyan-ish
+ stack_origin_tech = list(TECH_MATERIAL = 2, TECH_BIO = 2)
+
/material/wood/holographic
name = "holowood"
display_name = "wood"
diff --git a/code/modules/mining/abandonedcrates.dm b/code/modules/mining/abandonedcrates.dm
index a017476af3..8fcba9aee3 100644
--- a/code/modules/mining/abandonedcrates.dm
+++ b/code/modules/mining/abandonedcrates.dm
@@ -54,7 +54,7 @@
if(46 to 50)
new/obj/item/clothing/under/chameleon(src)
for(var/i = 0, i < 7, i++)
- new/obj/item/clothing/accessory/horrible(src)
+ new/obj/item/clothing/accessory/tie/horrible(src)
if(51 to 52) // Uncommon, 2% each
new/obj/item/weapon/melee/classic_baton(src)
if(53 to 54)
diff --git a/code/modules/mob/_modifiers/traits_phobias.dm b/code/modules/mob/_modifiers/traits_phobias.dm
index 58e35fea03..290875c5d6 100644
--- a/code/modules/mob/_modifiers/traits_phobias.dm
+++ b/code/modules/mob/_modifiers/traits_phobias.dm
@@ -268,7 +268,8 @@
total_lum += T.get_lumcount()
total_tiles++
- average_lum = total_lum / total_tiles
+ if(total_tiles)
+ average_lum = total_lum / total_tiles
if(average_lum > fear_threshold)
switch(average_lum)
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 27d83bd1a2..4fe77323f2 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -315,7 +315,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(!client)
return
- var/mentor = is_mentor(usr.client)
+ var/mentor = is_eventM(usr.client)
if(!config.antag_hud_allowed && (!client.holder || mentor))
src << "Admins have disabled this for this round."
return
diff --git a/code/modules/mob/hear_say.dm b/code/modules/mob/hear_say.dm
index 3a451bff44..c2a7b5668a 100644
--- a/code/modules/mob/hear_say.dm
+++ b/code/modules/mob/hear_say.dm
@@ -88,6 +88,8 @@
// Checks if the mob's own name is included inside message. Handles both first and last names.
/mob/proc/check_mentioned(var/message)
var/list/valid_names = splittext(real_name, " ") // Should output list("John", "Doe") as an example.
+ var/list/nicknames = splittext(nickname, " ")
+ valid_names += nicknames
valid_names += special_mentions()
for(var/name in valid_names)
if(findtext(message, regex("\\b[name]\\b", "i"))) // This is to stop 'ai' from triggering if someone says 'wait'.
diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm
index 51491f9f08..d18b7c538e 100644
--- a/code/modules/mob/living/carbon/human/emote.dm
+++ b/code/modules/mob/living/carbon/human/emote.dm
@@ -175,9 +175,11 @@
if ("clap")
if (!src.restrained())
message = "claps."
+ playsound(src.loc, 'sound/misc/clapping.ogg')
m_type = 2
if(miming)
m_type = 1
+
if ("flap")
if (!src.restrained())
message = "flaps [get_visible_gender() == MALE ? "his" : get_visible_gender() == FEMALE ? "her" : "their"] wings."
@@ -701,6 +703,20 @@
vomit()
return
+ if("whistle" || "whistles")
+ if(!muzzled)
+ message = "whistles a tune."
+ playsound(loc, 'sound/misc/longwhistle.ogg') //praying this doesn't get abused
+ else
+ message = "makes a light spitting noise, a poor attempt at a whistle."
+
+ if("qwhistle")
+ if(!muzzled)
+ message = "whistles quietly."
+ playsound(loc, 'sound/misc/shortwhistle.ogg')
+ else
+ message = "makes a light spitting noise, a poor attempt at a whistle."
+
if ("help")
src << "blink, blink_r, blush, bow-(none)/mob, burp, choke, chuckle, clap, collapse, cough, cry, custom, deathgasp, drool, eyebrow, fastsway/qwag, \
frown, gasp, giggle, glare-(none)/mob, grin, groan, grumble, handshake, hug-(none)/mob, laugh, look-(none)/mob, moan, mumble, nod, pale, point-atom, \
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index b375cfbac7..d4b6e58912 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -724,8 +724,6 @@
var/obj/item/clothing/glasses/sunglasses/sechud/aviator/S = src.glasses
if(!S.on)
number += 1
- else if(istype(src.glasses, /obj/item/clothing/glasses/sunglasses/medhud/aviator))
- number += 0
else
number += 1
if(istype(src.glasses, /obj/item/clothing/glasses/welding))
@@ -1280,7 +1278,7 @@
W.message = message
W.add_fingerprint(src)
-/mob/living/carbon/human/can_inject(var/mob/user, var/error_msg, var/target_zone)
+/mob/living/carbon/human/can_inject(var/mob/user, var/error_msg, var/target_zone, var/ignore_thickness = FALSE)
. = 1
if(!target_zone)
@@ -1300,10 +1298,10 @@
else
switch(target_zone)
if(BP_HEAD)
- if(head && head.item_flags & THICKMATERIAL)
+ if(head && (head.item_flags & THICKMATERIAL) && !ignore_thickness)
. = 0
else
- if(wear_suit && wear_suit.item_flags & THICKMATERIAL)
+ if(wear_suit && (wear_suit.item_flags & THICKMATERIAL) && !ignore_thickness)
. = 0
if(!. && error_msg && user)
if(!fail_msg)
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index e37be0e032..87246e3fe4 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -149,22 +149,26 @@ emp_act
if(!type || !def_zone) return 0
var/protection = 0
var/list/protective_gear = list(head, wear_mask, wear_suit, w_uniform, gloves, shoes)
- for(var/gear in protective_gear)
- if(gear && istype(gear ,/obj/item/clothing))
- var/obj/item/clothing/C = gear
- if(istype(C) && C.body_parts_covered & def_zone.body_part)
- protection += C.armor[type]
+ for(var/obj/item/clothing/gear in protective_gear)
+ if(gear.body_parts_covered & def_zone.body_part)
+ protection += gear.armor[type]
+ if(gear.accessories.len)
+ for(var/obj/item/clothing/accessory/bling in gear.accessories)
+ if(bling.body_parts_covered & def_zone.body_part)
+ protection += bling.armor[type]
return protection
/mob/living/carbon/human/proc/getsoak_organ(var/obj/item/organ/external/def_zone, var/type)
if(!type || !def_zone) return 0
var/soaked = 0
var/list/protective_gear = list(head, wear_mask, wear_suit, w_uniform, gloves, shoes)
- for(var/gear in protective_gear)
- if(gear && istype(gear ,/obj/item/clothing))
- var/obj/item/clothing/C = gear
- if(istype(C) && C.body_parts_covered & def_zone.body_part)
- soaked += C.armorsoak[type]
+ for(var/obj/item/clothing/gear in protective_gear)
+ if(gear.body_parts_covered & def_zone.body_part)
+ soaked += gear.armorsoak[type]
+ if(gear.accessories.len)
+ for(var/obj/item/clothing/accessory/bling in gear.accessories)
+ if(bling.body_parts_covered & def_zone.body_part)
+ soaked += bling.armorsoak[type]
return soaked
/mob/living/carbon/human/proc/check_head_coverage()
diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm
index 334302f0c6..93f583c5ab 100644
--- a/code/modules/mob/living/carbon/human/human_movement.dm
+++ b/code/modules/mob/living/carbon/human/human_movement.dm
@@ -182,14 +182,23 @@
var/S = pick(footstep_sounds)
if(!S) return
- // Only play every other step while running
- if(m_intent == "run" && step_count++ % 2 == 0)
+ // Play every 20 steps while walking, for the sneak
+ if(m_intent == "walk" && step_count++ % 20 != 0)
+ return
+
+ // Play every other step while running
+ if(m_intent == "run" && step_count++ % 2 != 0)
return
var/volume = config.footstep_volume
+
// Reduce volume while walking or barefoot
- if(!shoes || m_intent != "run")
+ if(!shoes || m_intent == "walk")
volume *= 0.5
+ else if(shoes)
+ var/obj/item/clothing/shoes/feet = shoes
+ if(feet)
+ volume *= feet.step_volume_mod
if(!has_organ(BP_L_FOOT) && !has_organ(BP_R_FOOT))
return // no feet = no footsteps
diff --git a/code/modules/mob/living/carbon/human/species/outsider/vox.dm b/code/modules/mob/living/carbon/human/species/outsider/vox.dm
index ef6bf12729..6e95330bf3 100644
--- a/code/modules/mob/living/carbon/human/species/outsider/vox.dm
+++ b/code/modules/mob/living/carbon/human/species/outsider/vox.dm
@@ -5,6 +5,7 @@
deform = 'icons/mob/human_races/r_def_vox.dmi'
default_language = LANGUAGE_VOX
language = LANGUAGE_GALCOM
+ species_language = LANGUAGE_VOX
num_alternate_languages = 1
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws/strong, /datum/unarmed_attack/bite/strong)
rarity_value = 4
diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm
index cf380d8ab3..a2b38e4c22 100644
--- a/code/modules/mob/living/carbon/human/species/species.dm
+++ b/code/modules/mob/living/carbon/human/species/species.dm
@@ -47,6 +47,7 @@
// Language/culture vars.
var/default_language = LANGUAGE_GALCOM // Default language is used when 'say' is used without modifiers.
var/language = LANGUAGE_GALCOM // Default racial language, if any.
+ var/species_language = LANGUAGE_GALCOM // Used on the Character Setup screen
var/list/secondary_langs = list() // The names of secondary languages that are available to this species.
var/list/speech_sounds // A list of sounds to potentially play when speaking.
var/list/speech_chance // The likelihood of a speech sound playing.
diff --git a/code/modules/mob/living/carbon/human/species/station/human_subspecies.dm b/code/modules/mob/living/carbon/human/species/station/human_subspecies.dm
index 89b1fc1bd7..d8f474d9ed 100644
--- a/code/modules/mob/living/carbon/human/species/station/human_subspecies.dm
+++ b/code/modules/mob/living/carbon/human/species/station/human_subspecies.dm
@@ -1,3 +1,4 @@
+/*
/datum/species/human/gravworlder
name = "grav-adapted Human"
name_plural = "grav-adapted Humans"
@@ -13,7 +14,9 @@
radiation_mod = 0.5
brute_mod = 0.85
slowdown = 1
+*/
+/*
/datum/species/human/spacer
name = "space-adapted Human"
name_plural = "space-adapted Humans"
@@ -27,23 +30,25 @@
flash_mod = 1.2
brute_mod = 1.1
burn_mod = 1.1
+*/
/datum/species/human/vatgrown
- name = "vat-grown Human"
- name_plural = "vat-grown Humans"
+ name = "Vatborn"
+ name_plural = "Vatborn"
blurb = "With cloning on the forefront of human scientific advancement, cheap mass production \
- of bodies is a very real and rather ethically grey industry. Vat-grown humans tend to be paler than \
- baseline, with no appendix and fewer inherited genetic disabilities, but a weakened metabolism."
+ of bodies is a very real and rather ethically grey industry. Vat-grown or Vatborn humans tend to be \
+ paler than baseline, with no appendix and fewer inherited genetic disabilities, but a more aggressive metabolism."
icobase = 'icons/mob/human_races/subspecies/r_vatgrown.dmi'
toxins_mod = 1.1
+ metabolic_rate = 1.15
has_organ = list(
- O_HEART = /obj/item/organ/heart,
- O_LUNGS = /obj/item/organ/lungs,
- O_LIVER = /obj/item/organ/liver,
- O_KIDNEYS = /obj/item/organ/kidneys,
- O_BRAIN = /obj/item/organ/brain,
- O_EYES = /obj/item/organ/eyes
+ O_HEART = /obj/item/organ/internal/heart,
+ O_LUNGS = /obj/item/organ/internal/lungs,
+ O_LIVER = /obj/item/organ/internal/liver,
+ O_KIDNEYS = /obj/item/organ/internal/kidneys,
+ O_BRAIN = /obj/item/organ/internal/brain,
+ O_EYES = /obj/item/organ/internal/eyes
)
/*
@@ -54,4 +59,4 @@
name_plural = "uplifted Chimpanzees"
blurb = "Ook ook."
icobase = 'icons/mob/human_races/subspecies/r_upliftedchimp.dmi'
-*/
+*/
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/species/station/prometheans.dm b/code/modules/mob/living/carbon/human/species/station/prometheans.dm
index 891825060d..db50586504 100644
--- a/code/modules/mob/living/carbon/human/species/station/prometheans.dm
+++ b/code/modules/mob/living/carbon/human/species/station/prometheans.dm
@@ -25,6 +25,7 @@ var/datum/species/shapeshifter/promethean/prometheans
spawn_flags = SPECIES_CAN_JOIN | SPECIES_IS_WHITELISTED
health_hud_intensity = 2
num_alternate_languages = 3
+ species_language = LANGUAGE_SOL_COMMON
breath_type = null
poison_type = null
diff --git a/code/modules/mob/living/carbon/human/species/station/seromi.dm b/code/modules/mob/living/carbon/human/species/station/seromi.dm
index cca023406e..0a6e1df9a4 100644
--- a/code/modules/mob/living/carbon/human/species/station/seromi.dm
+++ b/code/modules/mob/living/carbon/human/species/station/seromi.dm
@@ -9,6 +9,7 @@
num_alternate_languages = 3
secondary_langs = list(LANGUAGE_SCHECHI, LANGUAGE_SKRELLIAN)
name_language = LANGUAGE_SCHECHI
+ species_language = LANGUAGE_SCHECHI
min_age = 12
max_age = 45
health_hud_intensity = 3
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 c17b44c8b2..1f01aaa3b4 100644
--- a/code/modules/mob/living/carbon/human/species/station/station.dm
+++ b/code/modules/mob/living/carbon/human/species/station/station.dm
@@ -9,6 +9,7 @@
interests, rampant cyber and bio-augmentation and secretive factions make life on most human \
worlds tumultous at best."
num_alternate_languages = 3
+ species_language = LANGUAGE_SOL_COMMON
secondary_langs = list(LANGUAGE_SOL_COMMON)
name_language = null // Use the first-name last-name generator rather than a language scrambler
min_age = 17
@@ -41,6 +42,7 @@
num_alternate_languages = 3
secondary_langs = list(LANGUAGE_UNATHI)
name_language = LANGUAGE_UNATHI
+ species_language = LANGUAGE_UNATHI
health_hud_intensity = 2.5
min_age = 32
@@ -141,6 +143,7 @@
num_alternate_languages = 3
secondary_langs = list(LANGUAGE_SIIK)
name_language = LANGUAGE_SIIK
+ species_language = LANGUAGE_SIIK
health_hud_intensity = 2.5
min_age = 17
@@ -221,6 +224,7 @@
num_alternate_languages = 3
secondary_langs = list(LANGUAGE_SKRELLIAN, LANGUAGE_SCHECHI)
name_language = LANGUAGE_SKRELLIAN
+ species_language = LANGUAGE_SKRELLIAN
health_hud_intensity = 2
water_movement = -3
@@ -294,6 +298,7 @@
num_alternate_languages = 2
secondary_langs = list(LANGUAGE_ROOTGLOBAL)
name_language = LANGUAGE_ROOTLOCAL
+ species_language = LANGUAGE_ROOTLOCAL
health_hud_intensity = 2.5
item_slowdown_mod = 0.25
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index ffc02b4664..e8fc9893b5 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -303,7 +303,7 @@ proc/get_radio_key_from_channel(var/channel)
var/image/speech_bubble = image('icons/mob/talk.dmi',src,"[speech_type][speech_bubble_test]")
spawn(30) qdel(speech_bubble)
- // VOREStation Edit - Attempt Multi-Z Talking
+ // Attempt Multi-Z Talking
var/mob/above = src.shadow
while(!QDELETED(above))
var/turf/ST = get_turf(above)
@@ -316,7 +316,6 @@ proc/get_radio_key_from_channel(var/channel)
listening[item] = z_speech_bubble
listening_obj |= results["objs"]
above = above.shadow
- // VOREStation Edit End
//Main 'say' and 'whisper' message delivery
for(var/mob/M in listening)
@@ -326,12 +325,12 @@ proc/get_radio_key_from_channel(var/channel)
var/dst = get_dist(get_turf(M),get_turf(src))
if(dst <= message_range || (M.stat == DEAD && !forbid_seeing_deadchat)) //Inside normal message range, or dead with ears (handled in the view proc)
- M << (listening[M] || speech_bubble) // VOREStation Edit - Send the image attached to shadow mob if available
+ M << (listening[M] || speech_bubble) // Send the image attached to shadow mob if available
M.hear_say(message, verb, speaking, alt_name, italics, src, speech_sound, sound_vol)
if(whispering) //Don't even bother with these unless whispering
if(dst > message_range && dst <= w_scramble_range) //Inside whisper scramble range
- M << (listening[M] || speech_bubble) // VOREStation Edit - Send the image attached to shadow mob if available
+ M << (listening[M] || speech_bubble) // Send the image attached to shadow mob if available
M.hear_say(stars(message), verb, speaking, alt_name, italics, src, speech_sound, sound_vol*0.2)
if(dst > w_scramble_range && dst <= world.view) //Inside whisper 'visible' range
M.show_message("[src.name] [w_not_heard].", 2)
diff --git a/code/modules/mob/living/silicon/robot/robot_modules/station.dm b/code/modules/mob/living/silicon/robot/robot_modules/station.dm
index c6f869bf04..dd396f7f2d 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules/station.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules/station.dm
@@ -418,6 +418,8 @@ var/global/list/robot_modules = list(
var/datum/matter_synth/metal = new /datum/matter_synth/metal(40000)
var/datum/matter_synth/glass = new /datum/matter_synth/glass(40000)
var/datum/matter_synth/plasteel = new /datum/matter_synth/plasteel(20000)
+ var/datum/matter_synth/wood = new /datum/matter_synth/wood(40000)
+ var/datum/matter_synth/plastic = new /datum/matter_synth/plastic(40000)
var/datum/matter_synth/wire = new /datum/matter_synth/wire()
synths += metal
@@ -446,9 +448,9 @@ var/global/list/robot_modules = list(
C.synths = list(wire)
src.modules += C
- var/obj/item/stack/material/cyborg/plasteel/P = new (src)
- P.synths = list(plasteel)
- src.modules += P
+ var/obj/item/stack/material/cyborg/plasteel/PS = new (src)
+ PS.synths = list(plasteel)
+ src.modules += PS
var/obj/item/stack/tile/floor/cyborg/S = new /obj/item/stack/tile/floor/cyborg(src)
S.synths = list(metal)
@@ -458,6 +460,18 @@ var/global/list/robot_modules = list(
RG.synths = list(metal, glass)
src.modules += RG
+ var/obj/item/stack/tile/wood/cyborg/WT = new /obj/item/stack/tile/wood/cyborg(src)
+ WT.synths = list(wood)
+ src.modules += WT
+
+ var/obj/item/stack/material/cyborg/wood/W = new (src)
+ W.synths = list(wood)
+ src.modules += W
+
+ var/obj/item/stack/material/cyborg/plastic/PL = new (src)
+ PL.synths = list(plastic)
+ src.modules += PL
+
/obj/item/weapon/robot_module/robot/security
name = "security robot module"
channels = list("Security" = 1)
diff --git a/code/modules/mob/living/silicon/robot/robot_modules/syndicate.dm b/code/modules/mob/living/silicon/robot/robot_modules/syndicate.dm
index 2def8149ff..f769cb29ab 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules/syndicate.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules/syndicate.dm
@@ -26,12 +26,13 @@
)
var/id
+// All syndie modules get these, and the base borg items (flash, crowbar, etc).
/obj/item/weapon/robot_module/robot/syndicate/New(var/mob/living/silicon/robot/R)
..()
loc = R
+ src.modules += new /obj/item/weapon/pinpointer/shuttle/merc(src)
src.modules += new /obj/item/weapon/melee/energy/sword(src)
- src.modules += new /obj/item/weapon/gun/energy/pulse_rifle/destroyer(src)
- src.modules += new /obj/item/weapon/card/emag(src)
+
var/jetpack = new/obj/item/weapon/tank/jetpack/carbondioxide(src)
src.modules += jetpack
R.internals = jetpack
@@ -43,3 +44,141 @@
src.modules -= id
id = null
return ..()
+
+// Gets a big shield and a gun that shoots really fast to scare the opposing force.
+/obj/item/weapon/robot_module/robot/syndicate/protector
+ name = "protector robot module"
+ sprites = list(
+ "Cerberus - Treaded" = "syndie_treadhound",
+ "Cerberus" = "syndie_bloodhound",
+ "Ares" = "squats",
+ "XI-ALP" = "syndi-heavy"
+ )
+
+/obj/item/weapon/robot_module/robot/syndicate/protector/New(var/mob/living/silicon/robot/R)
+ ..()
+ src.modules += new /obj/item/shield_projector/rectangle/weak(src)
+ src.modules += new /obj/item/weapon/gun/energy/dakkalaser(src)
+ src.modules += new /obj/item/weapon/handcuffs/cyborg(src)
+ src.modules += new /obj/item/weapon/melee/baton/robot(src)
+
+// 95% engi-borg and 15% roboticist.
+/obj/item/weapon/robot_module/robot/syndicate/mechanist
+ name = "mechanist robot module"
+ sprites = list(
+ "XI-GUS" = "spidersyndi",
+ "WTOperator" = "sleekhos"
+ )
+
+/obj/item/weapon/robot_module/robot/syndicate/mechanist/New(var/mob/living/silicon/robot/R)
+ ..()
+ // General engineering/hacking.
+ src.modules += new /obj/item/borg/sight/meson(src)
+ src.modules += new /obj/item/weapon/weldingtool/electric/mounted/cyborg(src)
+ src.modules += new /obj/item/weapon/screwdriver/cyborg(src)
+ src.modules += new /obj/item/weapon/wrench/cyborg(src)
+ src.modules += new /obj/item/weapon/wirecutters/cyborg(src)
+ src.modules += new /obj/item/device/multitool/ai_detector(src)
+ src.modules += new /obj/item/weapon/pickaxe/plasmacutter(src)
+ src.modules += new /obj/item/weapon/rcd/borg/lesser(src) // Can't eat rwalls to prevent AI core cheese.
+ src.modules += new /obj/item/weapon/melee/energy/sword/ionic_rapier(src)
+
+ // FBP repair.
+ src.modules += new /obj/item/device/robotanalyzer(src)
+ src.modules += new /obj/item/weapon/shockpaddles/robot/jumper(src)
+ src.modules += new /obj/item/weapon/gripper/no_use/organ/robotics(src)
+
+ // Hacking other things.
+ src.modules += new /obj/item/weapon/card/robot(src)
+ src.modules += new /obj/item/weapon/card/emag(src)
+
+ // Materials.
+ var/datum/matter_synth/nanite = new /datum/matter_synth/nanite(10000)
+ synths += nanite
+ var/datum/matter_synth/wire = new /datum/matter_synth/wire()
+ synths += wire
+ var/datum/matter_synth/metal = new /datum/matter_synth/metal(40000)
+ synths += metal
+ var/datum/matter_synth/glass = new /datum/matter_synth/glass(40000)
+ synths += glass
+
+ var/obj/item/stack/nanopaste/N = new /obj/item/stack/nanopaste(src)
+ N.uses_charge = 1
+ N.charge_costs = list(1000)
+ N.synths = list(nanite)
+ src.modules += N
+
+ var/obj/item/stack/material/cyborg/steel/M = new (src)
+ M.synths = list(metal)
+ src.modules += M
+
+ var/obj/item/stack/material/cyborg/glass/G = new (src)
+ G.synths = list(glass)
+ src.modules += G
+
+ var/obj/item/stack/rods/cyborg/rods = new /obj/item/stack/rods/cyborg(src)
+ rods.synths = list(metal)
+ src.modules += rods
+
+ var/obj/item/stack/cable_coil/cyborg/C = new /obj/item/stack/cable_coil/cyborg(src)
+ C.synths = list(wire)
+ src.modules += C
+
+ var/obj/item/stack/material/cyborg/glass/reinforced/RG = new (src)
+ RG.synths = list(metal, glass)
+ src.modules += RG
+
+
+
+
+// Mediborg optimized for on-the-field healing, but can also do surgery if needed.
+/obj/item/weapon/robot_module/robot/syndicate/combat_medic
+ name = "combat medic robot module"
+ sprites = list(
+ "Telemachus" = "toiletbotantag"
+ )
+
+/obj/item/weapon/robot_module/robot/syndicate/combat_medic/New(var/mob/living/silicon/robot/R)
+ ..()
+ src.modules += new /obj/item/borg/sight/hud/med(src)
+ src.modules += new /obj/item/device/healthanalyzer(src)
+ src.modules += new /obj/item/weapon/reagent_containers/borghypo/merc(src)
+
+ // Surgery things.
+ src.modules += new /obj/item/weapon/surgical/scalpel/cyborg(src)
+ src.modules += new /obj/item/weapon/surgical/hemostat/cyborg(src)
+ src.modules += new /obj/item/weapon/surgical/retractor/cyborg(src)
+ src.modules += new /obj/item/weapon/surgical/cautery/cyborg(src)
+ src.modules += new /obj/item/weapon/surgical/bonegel/cyborg(src)
+ src.modules += new /obj/item/weapon/surgical/FixOVein/cyborg(src)
+ src.modules += new /obj/item/weapon/surgical/bonesetter/cyborg(src)
+ src.modules += new /obj/item/weapon/surgical/circular_saw/cyborg(src)
+ src.modules += new /obj/item/weapon/surgical/surgicaldrill/cyborg(src)
+ src.modules += new /obj/item/weapon/gripper/no_use/organ(src)
+
+ // General healing.
+ src.modules += new /obj/item/weapon/gripper/medical(src)
+ src.modules += new /obj/item/weapon/shockpaddles/robot/combat(src)
+ src.modules += new /obj/item/weapon/reagent_containers/dropper(src) // Allows borg to fix necrosis apparently
+ src.modules += new /obj/item/weapon/reagent_containers/syringe(src)
+ src.modules += new /obj/item/roller_holder(src)
+
+ // Materials.
+ var/datum/matter_synth/medicine = new /datum/matter_synth/medicine(15000)
+ synths += medicine
+
+ var/obj/item/stack/medical/advanced/ointment/O = new /obj/item/stack/medical/advanced/ointment(src)
+ var/obj/item/stack/medical/advanced/bruise_pack/B = new /obj/item/stack/medical/advanced/bruise_pack(src)
+ var/obj/item/stack/medical/splint/S = new /obj/item/stack/medical/splint(src)
+ O.uses_charge = 1
+ O.charge_costs = list(1000)
+ O.synths = list(medicine)
+ B.uses_charge = 1
+ B.charge_costs = list(1000)
+ B.synths = list(medicine)
+ S.uses_charge = 1
+ S.charge_costs = list(1000)
+ S.synths = list(medicine)
+ src.modules += O
+ src.modules += B
+ src.modules += S
diff --git a/code/modules/mob/living/silicon/robot/subtypes/gravekeeper.dm b/code/modules/mob/living/silicon/robot/subtypes/gravekeeper.dm
index 9cc09b286a..d722027ad3 100644
--- a/code/modules/mob/living/silicon/robot/subtypes/gravekeeper.dm
+++ b/code/modules/mob/living/silicon/robot/subtypes/gravekeeper.dm
@@ -6,6 +6,7 @@
lawchannel = "State"
braintype = "Drone"
idcard_type = /obj/item/weapon/card/id
+ icon_selected = FALSE
/mob/living/silicon/robot/gravekeeper/init()
aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src)
diff --git a/code/modules/mob/living/silicon/robot/subtypes/lost_drone.dm b/code/modules/mob/living/silicon/robot/subtypes/lost_drone.dm
index ba6890e835..281e158a92 100644
--- a/code/modules/mob/living/silicon/robot/subtypes/lost_drone.dm
+++ b/code/modules/mob/living/silicon/robot/subtypes/lost_drone.dm
@@ -6,6 +6,7 @@
lawchannel = "State"
braintype = "Drone"
idcard_type = /obj/item/weapon/card/id
+ icon_selected = FALSE
/mob/living/silicon/robot/lost/init()
aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src)
diff --git a/code/modules/mob/living/silicon/robot/subtypes/syndicate.dm b/code/modules/mob/living/silicon/robot/subtypes/syndicate.dm
new file mode 100644
index 0000000000..76496f4d4c
--- /dev/null
+++ b/code/modules/mob/living/silicon/robot/subtypes/syndicate.dm
@@ -0,0 +1,46 @@
+/mob/living/silicon/robot/syndicate
+ lawupdate = 0
+ scrambledcodes = 1
+ icon_state = "syndie_bloodhound"
+ modtype = "Syndicate"
+ lawchannel = "State"
+ braintype = "Drone"
+ idcard_type = /obj/item/weapon/card/id/syndicate
+ icon_selected = FALSE
+
+/mob/living/silicon/robot/syndicate/init()
+ aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src)
+
+ mmi = new /obj/item/device/mmi/digital/robot(src) // Explicitly a drone.
+ overlays.Cut()
+ init_id()
+
+ updatename("Syndicate")
+
+ if(!cell)
+ cell = new /obj/item/weapon/cell/high(src) // 15k cell, because Antag.
+
+ laws = new /datum/ai_laws/syndicate_override()
+
+ radio.keyslot = new /obj/item/device/encryptionkey/syndicate(radio)
+ radio.recalculateChannels()
+
+ playsound(loc, 'sound/mecha/nominalsyndi.ogg', 75, 0)
+
+/mob/living/silicon/robot/syndicate/protector/init()
+ ..()
+ module = new /obj/item/weapon/robot_module/robot/syndicate/protector(src)
+ updatename("Protector")
+
+/mob/living/silicon/robot/syndicate/mechanist/init()
+ ..()
+ module = new /obj/item/weapon/robot_module/robot/syndicate/mechanist(src)
+ updatename("Mechanist")
+
+/mob/living/silicon/robot/syndicate/combat_medic/init()
+ ..()
+ module = new /obj/item/weapon/robot_module/robot/syndicate/combat_medic(src)
+ updatename("Combat Medic")
+
+/mob/living/silicon/robot/syndicate/speech_bubble_appearance()
+ return "synthetic_evil"
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/aliens/alien.dm b/code/modules/mob/living/simple_animal/aliens/alien.dm
index f756b31798..dbe990e366 100644
--- a/code/modules/mob/living/simple_animal/aliens/alien.dm
+++ b/code/modules/mob/living/simple_animal/aliens/alien.dm
@@ -66,6 +66,19 @@
projectiletype = /obj/item/projectile/energy/neurotoxin/toxic
projectilesound = 'sound/weapons/pierce.ogg'
+/mob/living/simple_animal/hostile/alien/sentinel/praetorian
+ name = "alien praetorian"
+ icon = 'icons/mob/64x64.dmi'
+ icon_state = "prat_s"
+ icon_living = "prat_s"
+ icon_dead = "prat_dead"
+ move_to_delay = 5
+ maxHealth = 200
+ health = 200
+
+ pixel_x = -16
+ old_x = -16
+ meat_amount = 5
/mob/living/simple_animal/hostile/alien/queen
name = "alien queen"
@@ -83,15 +96,36 @@
rapid = 1
status_flags = 0
-/mob/living/simple_animal/hostile/alien/queen/large
+/mob/living/simple_animal/hostile/alien/queen/empress
name = "alien empress"
- icon = 'icons/mob/alienqueen.dmi'
+ icon = 'icons/mob/64x64.dmi'
icon_state = "queen_s"
icon_living = "queen_s"
icon_dead = "queen_dead"
move_to_delay = 4
maxHealth = 400
health = 400
+ meat_amount = 5
+ speed = 1
+
+ pixel_x = -16
+ old_x = -16
+
+/mob/living/simple_animal/hostile/alien/queen/empress/mother
+ name = "alien mother"
+ icon = 'icons/mob/96x96.dmi'
+ icon_state = "empress_s"
+ icon_living = "empress_s"
+ icon_dead = "empress_dead"
+ maxHealth = 600
+ health = 600
+ meat_amount = 10
+ melee_damage_lower = 15
+ melee_damage_upper = 25
+ speed = 2
+
+ pixel_x = -32
+ old_x = -32
/mob/living/simple_animal/hostile/alien/death()
..()
diff --git a/code/modules/mob/living/simple_animal/animals/carp.dm b/code/modules/mob/living/simple_animal/animals/carp.dm
index ff626e5eab..9126642197 100644
--- a/code/modules/mob/living/simple_animal/animals/carp.dm
+++ b/code/modules/mob/living/simple_animal/animals/carp.dm
@@ -36,6 +36,43 @@
meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat
+/mob/living/simple_animal/hostile/carp/large
+ name = "elder carp"
+ desc = "An older, more matured carp. Few survive to this age due to their aggressiveness."
+ icon = 'icons/mob/64x32.dmi'
+ icon_state = "shark"
+ icon_living = "shark"
+ icon_dead = "shark_dead"
+ turns_per_move = 2
+ move_to_delay = 2
+ mob_size = MOB_LARGE
+
+ pixel_x = -16
+ old_x = -16
+
+ health = 50
+ maxHealth = 50
+
+
+/mob/living/simple_animal/hostile/carp/large/huge
+ name = "great white carp"
+ desc = "A very rare breed of carp- and a very aggressive one."
+ icon = 'icons/mob/64x64.dmi'
+ icon_dead = "megacarp_dead"
+ icon_living = "megacarp"
+ icon_state = "megacarp"
+ maxHealth = 230
+ health = 230
+ attack_same = 1
+ speed = 1
+
+ meat_amount = 10
+
+ melee_damage_lower = 15
+ melee_damage_upper = 25
+ old_y = -16
+ pixel_y = -16
+
/mob/living/simple_animal/hostile/carp/Process_Spacemove(var/check_drift = 0)
return 1 //No drifting in space for space carp! //original comments do not steal
@@ -50,4 +87,5 @@
if(istype(L))
if(prob(15))
L.Weaken(3)
- L.visible_message("\the [src] knocks down \the [L]!")
\ No newline at end of file
+ L.visible_message("\the [src] knocks down \the [L]!")
+
diff --git a/code/modules/mob/living/simple_animal/animals/giant_spider.dm b/code/modules/mob/living/simple_animal/animals/giant_spider.dm
index cd48f27f62..15dd010570 100644
--- a/code/modules/mob/living/simple_animal/animals/giant_spider.dm
+++ b/code/modules/mob/living/simple_animal/animals/giant_spider.dm
@@ -74,6 +74,27 @@
var/atom/cocoon_target
var/egg_inject_chance = 5
+/mob/living/simple_animal/hostile/giant_spider/nurse/queen
+ desc = "Absolutely gigantic, this creature is horror itself."
+ icon = 'icons/mob/64x64.dmi'
+ icon_state = "spider_queen"
+ icon_living = "spider_queen"
+ icon_dead = "spider_queen_dead"
+
+ maxHealth = 320
+ health = 320
+
+ melee_damage_lower = 15
+ melee_damage_upper = 25
+ poison_per_bite = 10
+
+ egg_inject_chance = 10
+
+ pixel_x = -16
+ pixel_y = -16
+ old_x = -16
+ old_y = -16
+
//hunters have the most poison and move the fastest, so they can find prey
/mob/living/simple_animal/hostile/giant_spider/hunter
desc = "Furry and black, it makes you shudder to look at it. This one has sparkling purple eyes."
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 7ca7cae45c..a7307a8fad 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -67,6 +67,7 @@
var/stuttering = null //Carbon
var/slurring = null //Carbon
var/real_name = null
+ var/nickname = null
var/flavor_text = ""
var/med_record = ""
var/sec_record = ""
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 07be025ffb..2ccbc8cea7 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -400,7 +400,7 @@ proc/is_blind(A)
return // Can't talk in deadchat if you can't see it.
for(var/mob/M in player_list)
- if(M.client && ((!istype(M, /mob/new_player) && M.stat == DEAD) || (M.client.holder && !is_mentor(M.client))) && M.is_preference_enabled(/datum/client_preference/show_dsay))
+ if(M.client && ((!istype(M, /mob/new_player) && M.stat == DEAD) || (M.client.holder && !is_eventM(M.client))) && M.is_preference_enabled(/datum/client_preference/show_dsay))
var/follow
var/lname
if(M.forbid_seeing_deadchat && !M.client.holder)
diff --git a/code/modules/mob/new_player/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories.dm
index 0f780b561f..f301a36848 100644
--- a/code/modules/mob/new_player/sprite_accessories.dm
+++ b/code/modules/mob/new_player/sprite_accessories.dm
@@ -29,7 +29,7 @@
var/gender = NEUTER
// Restrict some styles to specific species
- var/list/species_allowed = list("Human","Promethean")
+ var/list/species_allowed = list("Human","Promethean","Vatborn")
// Whether or not the accessory can be affected by colouration
var/do_colouration = 1
@@ -51,7 +51,7 @@
name = "Bald"
icon_state = "bald"
gender = MALE
- species_allowed = list("Human","Unathi","Promethean")
+ species_allowed = list("Human","Unathi","Promethean","Vatborn")
short
name = "Short Hair" // try to capatilize the names please~
@@ -203,12 +203,12 @@
bobcurl
name = "Bobcurl"
icon_state = "hair_bobcurl"
- species_allowed = list("Human","Unathi")
+ species_allowed = list("Human","Promethean","Vatborn","Unathi")
bob
name = "Bob"
icon_state = "hair_bobcut"
- species_allowed = list("Human","Unathi")
+ species_allowed = list("Human","Promethean","Vatborn","Unathi")
bobcutalt
name = "Chin Length Bob"
@@ -233,7 +233,7 @@
buzz
name = "Buzzcut"
icon_state = "hair_buzzcut"
- species_allowed = list("Human","Unathi")
+ species_allowed = list("Human","Promethean","Vatborn","Unathi")
shavehair
name = "Shaved Hair"
@@ -338,7 +338,7 @@
mohawk
name = "Mohawk"
icon_state = "hair_d"
- species_allowed = list("Human","Unathi")
+ species_allowed = list("Human","Promethean","Vatborn","Unathi")
jensen
name = "Adam Jensen Hair"
@@ -355,7 +355,7 @@
spiky
name = "Spiky"
icon_state = "hair_spikey"
- species_allowed = list("Human","Unathi")
+ species_allowed = list("Human","Promethean","Vatborn","Unathi")
kusangi
name = "Kusanagi Hair"
@@ -660,7 +660,7 @@
name = "Shaved"
icon_state = "bald"
gender = NEUTER
- species_allowed = list("Human","Unathi","Tajara","Skrell", "Machine","Teshari", "Vox","Promethean")
+ species_allowed = list("Human","Vatborn","Unathi","Tajara","Skrell", "Machine","Teshari", "Vox","Promethean")
watson
name = "Watson Mustache"
@@ -701,7 +701,7 @@
elvis
name = "Elvis Sideburns"
icon_state = "facial_elvis"
- species_allowed = list("Human","Unathi")
+ species_allowed = list("Human","Promethean","Vatborn","Unathi")
abe
name = "Abraham Lincoln Beard"
@@ -1342,12 +1342,12 @@
human
name = "Default human skin"
icon_state = "default"
- species_allowed = list("Human")
+ species_allowed = list("Human","Vatborn")
human_tatt01
name = "Tatt01 human skin"
icon_state = "tatt1"
- species_allowed = list("Human")
+ species_allowed = list("Human","Vatborn")
tajaran
name = "Default tajaran skin"
diff --git a/code/modules/multiz/movement.dm b/code/modules/multiz/movement.dm
index ff4da22fa0..ba05eec77e 100644
--- a/code/modules/multiz/movement.dm
+++ b/code/modules/multiz/movement.dm
@@ -57,10 +57,8 @@
if(!A.CanPass(src, start, 1.5, 0))
to_chat(src, "\The [A] blocks you.")
return 0
- //VOREStation Edit
if(!Move(destination))
return 0
- //VOREStation Edit End
return 1
/mob/observer/zMove(direction)
@@ -201,7 +199,7 @@
/obj/structure/catwalk/CanFallThru(atom/movable/mover as mob|obj, turf/target as turf)
if(target.z < z)
return FALSE // TODO - Technically should be density = 1 and flags |= ON_BORDER
- if(!isturf(mover.loc)) // VORESTATION EDIT. Feel free to do an upstream suggestion as well.
+ if(!isturf(mover.loc))
return FALSE // Only let loose floor items fall. No more snatching things off people's hands.
else
return TRUE
@@ -215,7 +213,7 @@
return TRUE // We don't block sideways or upward movement.
else if(istype(mover) && mover.checkpass(PASSGRILLE))
return TRUE // Anything small enough to pass a grille will pass a lattice
- if(!isturf(mover.loc)) // VORESTATION EDIT. Feel free to do an upstream suggestion as well.
+ if(!isturf(mover.loc))
return FALSE // Only let loose floor items fall. No more snatching things off people's hands.
else
return FALSE // TODO - Technically should be density = 1 and flags |= ON_BORDER
diff --git a/code/modules/multiz/turf.dm b/code/modules/multiz/turf.dm
index 0f574f4298..744e37945c 100644
--- a/code/modules/multiz/turf.dm
+++ b/code/modules/multiz/turf.dm
@@ -85,13 +85,12 @@
bottom_turf.plane = src.plane
bottom_turf.color = below.color
underlays = list(bottom_turf)
- // VOREStation Edit - Hack workaround to byond crash bug - Include the magic overlay holder object.
+ // Hack workaround to byond crash bug - Include the magic overlay holder object.
overlays += below.overlays
// if(below.overlay_holder)
// overlays += (below.overlays + below.overlay_holder.overlays)
// else
// overlays += below.overlays
- // VOREStation Edit End
// get objects (not mobs, they are handled by /obj/zshadow)
var/list/o_img = list()
diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm
index 97cc67e280..d066a8e802 100644
--- a/code/modules/organs/organ.dm
+++ b/code/modules/organs/organ.dm
@@ -146,9 +146,16 @@ var/list/organ_cache = list()
var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin")
+ var/infection_damage = 0
+
if((status & ORGAN_DEAD) && antibiotics < 30) //Sepsis from 'dead' organs
- var/sepsis_severity = 1 + round((germ_level - INFECTION_LEVEL_THREE)/200,0.25) //1 Tox plus a little based on germ level
- owner.adjustToxLoss(sepsis_severity)
+ infection_damage = min(1, 1 + round((germ_level - INFECTION_LEVEL_THREE)/200,0.25)) //1 Tox plus a little based on germ level
+
+ else if(germ_level > INFECTION_LEVEL_TWO && antibiotics < 30)
+ infection_damage = min(0.25, 0.25 + round((germ_level - INFECTION_LEVEL_TWO)/200,0.25))
+
+ if(infection_damage)
+ owner.adjustToxLoss(infection_damage)
if (germ_level > 0 && germ_level < INFECTION_LEVEL_ONE/2 && prob(30))
germ_level--
diff --git a/code/modules/organs/organ_internal.dm b/code/modules/organs/organ_internal.dm
index cfc0910901..c67a3235d0 100644
--- a/code/modules/organs/organ_internal.dm
+++ b/code/modules/organs/organ_internal.dm
@@ -34,246 +34,9 @@
..()
// Brain is defined in brain_item.dm.
-/obj/item/organ/internal/heart
- name = "heart"
- icon_state = "heart-on"
- organ_tag = O_HEART
- parent_organ = BP_TORSO
- dead_icon = "heart-off"
-
-/obj/item/organ/internal/lungs
- name = "lungs"
- icon_state = "lungs"
- gender = PLURAL
- organ_tag = O_LUNGS
- parent_organ = BP_TORSO
-
-/obj/item/organ/internal/lungs/process()
- ..()
-
- if(!owner)
- return
-
- if (germ_level > INFECTION_LEVEL_ONE)
- if(prob(5))
- owner.emote("cough") //respitory tract infection
-
- if(is_bruised())
- if(prob(2))
- spawn owner.emote("me", 1, "coughs up blood!")
- owner.drip(10)
- if(prob(4))
- spawn owner.emote("me", 1, "gasps for air!")
- owner.losebreath += 15
-
-/obj/item/organ/internal/kidneys
- name = "kidneys"
- icon_state = "kidneys"
- gender = PLURAL
- organ_tag = O_KIDNEYS
- parent_organ = BP_GROIN
-
-/obj/item/organ/internal/kidneys/process()
-
- ..()
-
- if(!owner)
- return
-
- // Coffee is really bad for you with busted kidneys.
- // This should probably be expanded in some way, but fucked if I know
- // what else kidneys can process in our reagent list.
- 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)
-
-/obj/item/organ/internal/eyes
- name = "eyeballs"
- icon_state = "eyes"
- gender = PLURAL
- organ_tag = O_EYES
- parent_organ = BP_HEAD
- var/list/eye_colour = list(0,0,0)
-
-/obj/item/organ/internal/eyes/robotize()
- ..()
- name = "optical sensor"
- icon = 'icons/obj/robot_component.dmi'
- icon_state = "camera"
- dead_icon = "camera_broken"
- verbs |= /obj/item/organ/internal/eyes/proc/change_eye_color
-
-/obj/item/organ/internal/eyes/robot
- name = "optical sensor"
-
-/obj/item/organ/internal/eyes/robot/New()
- ..()
- robotize()
-
-/obj/item/organ/internal/eyes/proc/change_eye_color()
- set name = "Change Eye Color"
- set desc = "Changes your robotic eye color instantly."
- set category = "IC"
- set src in usr
-
- var/current_color = rgb(eye_colour[1],eye_colour[2],eye_colour[3])
- var/new_color = input("Pick a new color for your eyes.","Eye Color", current_color) as null|color
- if(new_color && owner)
- // input() supplies us with a hex color, which we can't use, so we convert it to rbg values.
- var/list/new_color_rgb_list = hex2rgb(new_color)
- // First, update mob vars.
- owner.r_eyes = new_color_rgb_list[1]
- owner.g_eyes = new_color_rgb_list[2]
- owner.b_eyes = new_color_rgb_list[3]
- // Now sync the organ's eye_colour list.
- update_colour()
- // Finally, update the eye icon on the mob.
- owner.update_eyes()
-
-/obj/item/organ/internal/eyes/replaced(var/mob/living/carbon/human/target)
-
- // Apply our eye colour to the target.
- if(istype(target) && eye_colour)
- target.r_eyes = eye_colour[1]
- target.g_eyes = eye_colour[2]
- target.b_eyes = eye_colour[3]
- target.update_eyes()
- ..()
-
-/obj/item/organ/internal/eyes/proc/update_colour()
- if(!owner)
- return
- eye_colour = list(
- owner.r_eyes ? owner.r_eyes : 0,
- owner.g_eyes ? owner.g_eyes : 0,
- owner.b_eyes ? owner.b_eyes : 0
- )
-
-/obj/item/organ/internal/eyes/take_damage(amount, var/silent=0)
- var/oldbroken = is_broken()
- ..()
- if(is_broken() && !oldbroken && owner && !owner.stat)
- owner << "You go blind!"
-
-/obj/item/organ/internal/eyes/process() //Eye damage replaces the old eye_stat var.
- ..()
- if(!owner)
- return
- if(is_bruised())
- owner.eye_blurry = 20
- if(is_broken())
- owner.Blind(20)
-
-/obj/item/organ/internal/liver
- name = "liver"
- icon_state = "liver"
- organ_tag = "liver"
- parent_organ = BP_GROIN
-
-/obj/item/organ/internal/liver/process()
-
- ..()
-
- if(!owner)
- return
-
- if (germ_level > INFECTION_LEVEL_ONE)
- if(prob(1))
- owner << "Your skin itches."
- if (germ_level > INFECTION_LEVEL_TWO)
- if(prob(1))
- spawn owner.vomit()
-
- if(owner.life_tick % PROCESS_ACCURACY == 0)
-
- //High toxins levels are dangerous
- if(owner.getToxLoss() >= 60 && !owner.reagents.has_reagent("anti_toxin"))
- //Healthy liver suffers on its own
- if (src.damage < min_broken_damage)
- src.damage += 0.2 * PROCESS_ACCURACY
- //Damaged one shares the fun
- else
- var/obj/item/organ/internal/O = pick(owner.internal_organs)
- if(O)
- O.damage += 0.2 * PROCESS_ACCURACY
-
- //Detox can heal small amounts of damage
- if (src.damage && src.damage < src.min_bruised_damage && owner.reagents.has_reagent("anti_toxin"))
- src.damage -= 0.2 * PROCESS_ACCURACY
-
- if(src.damage < 0)
- src.damage = 0
-
- // Get the effectiveness of the liver.
- var/filter_effect = 3
- if(is_bruised())
- filter_effect -= 1
- if(is_broken())
- filter_effect -= 2
-
- // Do some reagent processing.
- if(owner.chem_effects[CE_ALCOHOL_TOXIC])
- if(filter_effect < 3)
- owner.adjustToxLoss(owner.chem_effects[CE_ALCOHOL_TOXIC] * 0.1 * PROCESS_ACCURACY)
- else
- take_damage(owner.chem_effects[CE_ALCOHOL_TOXIC] * 0.1 * PROCESS_ACCURACY, prob(1)) // Chance to warn them
-
-/obj/item/organ/internal/appendix
- name = "appendix"
- icon_state = "appendix"
- parent_organ = BP_GROIN
- organ_tag = "appendix"
- var/inflamed = 0
- var/inflame_progress = 0
-
-/mob/living/carbon/human/proc/appendicitis()
- if(stat == DEAD)
- return 0
- var/obj/item/organ/internal/appendix/A = internal_organs_by_name[O_APPENDIX]
- if(istype(A) && !A.inflamed)
- A.inflamed = 1
- return 1
- return 0
-
-/obj/item/organ/internal/appendix/process()
- if(!inflamed || !owner)
- return
-
- if(++inflame_progress > 200)
- ++inflamed
- inflame_progress = 0
-
- if(inflamed == 1)
- if(prob(5))
- if(owner.can_feel_pain())
- owner.custom_pain("You feel a stinging pain in your abdomen!", 25)
- if(inflamed > 1)
- if(prob(3))
- if(owner.can_feel_pain())
- owner.custom_pain("You feel a stabbing pain in your abdomen!", 50)
- owner.adjustToxLoss(1)
- if(inflamed > 2)
- if(prob(1))
- owner.vomit()
- if(owner.can_feel_pain())
- owner.custom_pain("You feel a horrible pain in your abdomen!", 70)
- if(inflamed > 3)
- if(prob(1))
- if(owner.can_feel_pain())
- owner.custom_pain("You feel a stinging pain in your abdomen!", 100)
- owner.Weaken(10)
-
- var/obj/item/organ/external/groin = owner.get_organ(BP_GROIN)
- var/datum/wound/W = new /datum/wound/internal_bleeding(20)
- owner.adjustToxLoss(25)
- groin.wounds += W
- inflamed = 0
-
-/obj/item/organ/internal/appendix/removed()
- if(inflamed)
- icon_state = "appendixinflamed"
- name = "inflamed appendix"
- ..()
+// Heart is defined in heart.dm
+// Lungs are defined in lungs.dm
+// Kidneys is defined in kidneys.dm
+// Eyes are defined in eyes.dm
+// Liver is defined in liver.dm. The process here was different than the process in liver.dm, so I just kept the one in liver.dm
+// Appendix is defined in appendix.dm
diff --git a/code/modules/power/cable_heavyduty.dm b/code/modules/power/cable_heavyduty.dm
index 9c0aab68dc..99c91a6b74 100644
--- a/code/modules/power/cable_heavyduty.dm
+++ b/code/modules/power/cable_heavyduty.dm
@@ -8,7 +8,7 @@
name = "large power cable"
desc = "This cable is tough. It cannot be cut with simple hand tools."
layer = 2.39 //Just below pipes, which are at 2.4
- color = null //VOREStation Edit
+ color = null
/obj/structure/cable/heavyduty/attackby(obj/item/W, mob/user)
diff --git a/code/modules/power/fusion/fuel_assembly/fuel_compressor.dm b/code/modules/power/fusion/fuel_assembly/fuel_compressor.dm
index 469f32135f..97afe227c4 100644
--- a/code/modules/power/fusion/fuel_assembly/fuel_compressor.dm
+++ b/code/modules/power/fusion/fuel_assembly/fuel_compressor.dm
@@ -25,9 +25,9 @@
thing.reagents.remove_reagent(R.id, R.volume)
user.put_in_hands(F)
- else if(istype(thing, /obj/machinery/power/supermatter/shard))
+ else if(istype(thing, /obj/machinery/power/supermatter))
var/obj/item/weapon/fuel_assembly/F = new(get_turf(src), "supermatter")
- visible_message("\The [src] compresses the \[thing] into a new fuel assembly.")
+ visible_message("\The [src] compresses \the [thing] into a new fuel assembly.")
qdel(thing)
user.put_in_hands(F)
return 1
diff --git a/code/modules/power/smes_construction.dm b/code/modules/power/smes_construction.dm
index f6a40da0c3..bb1603b570 100644
--- a/code/modules/power/smes_construction.dm
+++ b/code/modules/power/smes_construction.dm
@@ -85,7 +85,7 @@
// Proc: process()
// Parameters: None
// Description: Uses parent process, but if grounding wire is cut causes sparks to fly around.
-// This also causes the SMES to quickly discharge, and has small chance of damaging output APCs.
+// This also causes the SMES to quickly discharge, and has small chance of breaking lights connected to APCs in the powernet.
/obj/machinery/power/smes/buildable/process()
if(!grounding && (Percentage() > 5))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
@@ -93,7 +93,7 @@
s.start()
charge -= (output_level_max * SMESRATE)
if(prob(1)) // Small chance of overload occuring since grounding is disabled.
- apcs_overload(5,10)
+ apcs_overload(0,10)
..()
diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm
index 60078127ad..b28c8f2993 100644
--- a/code/modules/projectiles/ammunition.dm
+++ b/code/modules/projectiles/ammunition.dm
@@ -7,6 +7,7 @@
slot_flags = SLOT_BELT | SLOT_EARS
throwforce = 1
w_class = ITEMSIZE_TINY
+ preserve_item = 1
var/leaves_residue = 1
var/caliber = "" //Which kind of guns it can be loaded into
@@ -75,6 +76,7 @@
w_class = ITEMSIZE_SMALL
throw_speed = 4
throw_range = 10
+ preserve_item = 1
var/list/stored_ammo = list()
var/mag_type = SPEEDLOADER //ammo_magazines can only be used with compatible guns. This is not a bitflag, the load_method var on guns is.
diff --git a/code/modules/projectiles/ammunition/magnetic.dm b/code/modules/projectiles/ammunition/magnetic.dm
index fc299adf0b..b3e9c3a7c8 100644
--- a/code/modules/projectiles/ammunition/magnetic.dm
+++ b/code/modules/projectiles/ammunition/magnetic.dm
@@ -7,6 +7,7 @@
matter = list(DEFAULT_WALL_MATERIAL = 1800)
origin_tech = list(TECH_COMBAT = 1)
var/remaining = 9
+ preserve_item = 1
/obj/item/weapon/magnetic_ammo/examine(mob/user)
. = ..()
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 74b107e9bc..b279908b79 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -46,6 +46,7 @@
throw_speed = 4
throw_range = 5
force = 5
+ preserve_item = 1
origin_tech = list(TECH_COMBAT = 1)
attack_verb = list("struck", "hit", "bashed")
zoomdevicename = "scope"
diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm
index 46988c9934..d613f1f206 100644
--- a/code/modules/projectiles/guns/energy/special.dm
+++ b/code/modules/projectiles/guns/energy/special.dm
@@ -177,4 +177,24 @@ obj/item/weapon/gun/energy/staff/focus
charge_cost = 200
user << "The [src.name] will now strike only a single person."
projectile_type = "/obj/item/projectile/forcebolt"
- */
\ No newline at end of file
+ */
+
+/obj/item/weapon/gun/energy/dakkalaser
+ name = "suppression gun"
+ desc = "A massive weapon, designed to pressure the opposition by raining down a torrent of energy pellets."
+ icon_state = "dakkalaser"
+ item_state = "dakkalaser"
+ fire_sound = 'sound/weapons/Laser.ogg'
+ w_class = ITEMSIZE_HUGE
+ charge_cost = 24 // 100 shots, it's a spray and pray (to RNGesus) weapon.
+ projectile_type = /obj/item/projectile/energy/blue_pellet
+ self_recharge = 1
+ accuracy = 5 // Suppressive weapons don't work too well if there's no risk of being hit.
+ burst_delay = 1 // Burst faster than average.
+ origin_tech = list(TECH_COMBAT = 6, TECH_MAGNET = 6, TECH_ILLEGAL = 6)
+
+ firemodes = list(
+ list(mode_name="single shot", burst = 1, burst_accuracy = list(5), dispersion = list(0), charge_cost = 24),
+ list(mode_name="five shot burst", burst = 5, burst_accuracy = list(5,5,5,5,5), dispersion = list(1,1,1,1,1)),
+ list(mode_name="ten shot burst", burst = 10, burst_accuracy = list(5,5,5,5,5,5,5,5,5,5), dispersion = list(2,2,2,2,2,2,2,2,2,2)),
+ )
\ No newline at end of file
diff --git a/code/modules/projectiles/guns/magnetic/magnetic.dm b/code/modules/projectiles/guns/magnetic/magnetic.dm
index 130f4410df..ae45454a42 100644
--- a/code/modules/projectiles/guns/magnetic/magnetic.dm
+++ b/code/modules/projectiles/guns/magnetic/magnetic.dm
@@ -4,7 +4,7 @@
icon_state = "coilgun"
item_state = "coilgun"
icon = 'icons/obj/railgun.dmi'
-// one_hand_penalty = 1
+// one_handed_penalty = 1
origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 4, TECH_ILLEGAL = 2, TECH_MAGNET = 4)
w_class = ITEMSIZE_LARGE
@@ -193,3 +193,66 @@
qdel(src)
return new projectile_type(src)
+
+/obj/item/weapon/gun/magnetic/fuelrod
+ name = "Fuel-Rod Cannon"
+ desc = "A bulky weapon designed to fire reactor core fuel rods at absurd velocities... who thought this was a good idea?!"
+ description_antag = "This device is capable of firing reactor fuel assemblies, acquired from a R-UST fuel compressor and an appropriate fueltype. Be warned, Supermatter rods may have unforseen consequences."
+ description_fluff = "Morpheus' second entry into the arms manufacturing field, the Morpheus B.F.G, or 'Big Fuel-rod Gun' made some noise when it was initially sent to the market. By noise, they mean it was rapidly declared 'incredibly dangerous to the wielder and civilians within a mile radius alike'."
+ icon_state = "fuelrodgun"
+ item_state = "coilgun"
+ icon = 'icons/obj/railgun.dmi'
+ origin_tech = list(TECH_COMBAT = 6, TECH_MATERIAL = 4, TECH_PHORON = 4, TECH_ILLEGAL = 5, TECH_MAGNET = 4)
+ w_class = ITEMSIZE_LARGE
+
+ removable_components = TRUE
+ gun_unreliable = 0
+
+ load_type = /obj/item/weapon/fuel_assembly
+ projectile_type = /obj/item/projectile/bullet/magnetic/fuelrod
+
+ power_cost = 500
+
+/obj/item/weapon/gun/magnetic/fuelrod/consume_next_projectile()
+ if(!check_ammo() || !capacitor || capacitor.charge < power_cost)
+ return
+
+ if(loaded) //Safety.
+ if(istype(loaded, /obj/item/weapon/fuel_assembly))
+ var/obj/item/weapon/fuel_assembly/rod = loaded
+ if(rod.fuel_type == "composite" || rod.fuel_type == "deuterium") //Safety check for rods spawned in without a fueltype.
+ projectile_type = /obj/item/projectile/bullet/magnetic/fuelrod
+ else if(rod.fuel_type == "tritium")
+ projectile_type = /obj/item/projectile/bullet/magnetic/fuelrod/tritium
+ else if(rod.fuel_type == "phoron")
+ projectile_type = /obj/item/projectile/bullet/magnetic/fuelrod/phoron
+ else if(rod.fuel_type == "supermatter")
+ projectile_type = /obj/item/projectile/bullet/magnetic/fuelrod/supermatter
+ visible_message("The barrel of \the [src] glows a blinding white!")
+ spawn(5)
+ visible_message("\The [src] begins to rattle, its acceleration chamber collapsing in on itself!")
+ removable_components = FALSE
+ spawn(15)
+ audible_message("\The [src]'s power supply begins to overload as the device crumples!") //Why are you still holding this?
+ playsound(loc, 'sound/effects/grillehit.ogg', 10, 1)
+ var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread()
+ var/turf/T = get_turf(src)
+ sparks.set_up(2, 1, T)
+ sparks.start()
+ spawn(15)
+ visible_message("\The [src] explodes in a blinding white light!")
+ explosion(src.loc, -1, 1, 2, 3)
+ qdel(src)
+ else
+ projectile_type = /obj/item/projectile/bullet/magnetic/fuelrod
+
+ use_ammo()
+ capacitor.use(power_cost)
+ update_icon()
+
+ return new projectile_type(src)
+
+/obj/item/weapon/gun/magnetic/fuelrod/New()
+ cell = new /obj/item/weapon/cell/high
+ capacitor = new /obj/item/weapon/stock_parts/capacitor
+ . = ..()
diff --git a/code/modules/projectiles/guns/magnetic/magnetic_railgun.dm b/code/modules/projectiles/guns/magnetic/magnetic_railgun.dm
index d731512bfa..fe9aa576ef 100644
--- a/code/modules/projectiles/guns/magnetic/magnetic_railgun.dm
+++ b/code/modules/projectiles/guns/magnetic/magnetic_railgun.dm
@@ -67,9 +67,9 @@
w_class = ITEMSIZE_NO_CONTAINER
firemodes = list(
- list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, one_hand_penalty=1, burst_accuracy=null, dispersion=null),
- list(mode_name="short bursts", burst=3, fire_delay=null, move_delay=5, one_hand_penalty=2, burst_accuracy=list(0,-1,-1), dispersion=list(0.0, 0.6, 1.0)),
- list(mode_name="long bursts", burst=6, fire_delay=null, move_delay=10, one_hand_penalty=2, burst_accuracy=list(0,-1,-1,-1,-2), dispersion=list(0.6, 0.6, 1.0, 1.0, 1.2)),
+ list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, one_handed_penalty=1, burst_accuracy=null, dispersion=null),
+ list(mode_name="short bursts", burst=3, fire_delay=null, move_delay=5, one_handed_penalty=2, burst_accuracy=list(0,-1,-1), dispersion=list(0.0, 0.6, 1.0)),
+ list(mode_name="long bursts", burst=6, fire_delay=null, move_delay=10, one_handed_penalty=2, burst_accuracy=list(0,-1,-1,-1,-2), dispersion=list(0.6, 0.6, 1.0, 1.0, 1.2)),
)
/obj/item/weapon/gun/magnetic/railgun/automatic/examine(var/mob/user)
@@ -94,8 +94,8 @@
fire_sound = 'sound/weapons/rapidslice.ogg'
firemodes = list(
- list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, one_hand_penalty=1, burst_accuracy=null, dispersion=null),
- list(mode_name="short bursts", burst=3, fire_delay=null, move_delay=5, one_hand_penalty=2, burst_accuracy=list(0,-1,-1), dispersion=list(0.0, 0.6, 1.0)),
+ list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, one_handed_penalty=1, burst_accuracy=null, dispersion=null),
+ list(mode_name="short bursts", burst=3, fire_delay=null, move_delay=5, one_handed_penalty=2, burst_accuracy=list(0,-1,-1), dispersion=list(0.0, 0.6, 1.0)),
)
/obj/item/weapon/gun/magnetic/railgun/flechette/out_of_ammo()
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index 5e599230cf..fdc5a445b9 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -333,9 +333,11 @@
else if(!bumped)
tracer_effect(effect_transform)
- if(incendiary >= 2)
- var/trail_volume = (flammability * 0.10)
- new /obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel(src.loc, trail_volume, src.dir)
+ if(incendiary >= 2) //This should cover the bases of 'Why is there fuel here?' in a much cleaner way than previous.
+ if(src && src.loc) //Safety.
+ if(!src.loc.density)
+ var/trail_volume = (flammability * 0.20)
+ new /obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel(src.loc, trail_volume, src.dir)
if(!hitscan)
sleep(step_delay) //add delay between movement iterations if it's not a hitscan weapon
diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm
index 5b95ee6639..283e487272 100644
--- a/code/modules/projectiles/projectile/bullets.dm
+++ b/code/modules/projectiles/projectile/bullets.dm
@@ -272,6 +272,7 @@
flammability = 4
agony = 30
kill_count = 4
+ vacuum_traversal = 0
/obj/item/projectile/bullet/incendiary/flamethrower/large
damage = 15
diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm
index 42be84f2ac..dbc54fc432 100644
--- a/code/modules/projectiles/projectile/energy.dm
+++ b/code/modules/projectiles/projectile/energy.dm
@@ -182,4 +182,17 @@
/obj/item/projectile/energy/plasmastun/on_hit(var/atom/target)
bang(target)
- . = ..()
\ No newline at end of file
+ . = ..()
+
+/obj/item/projectile/energy/blue_pellet
+ name = "suppressive pellet"
+ icon_state = "blue_pellet"
+ damage = 5
+ armor_penetration = 75
+ pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
+ damage_type = BURN
+ check_armour = "energy"
+ light_color = "#0000FF"
+
+ embed_chance = 0
+ muzzle_type = /obj/effect/projectile/pulse/muzzle
\ No newline at end of file
diff --git a/code/modules/projectiles/projectile/magnetic.dm b/code/modules/projectiles/projectile/magnetic.dm
index 35f98833ef..b4a60a55d7 100644
--- a/code/modules/projectiles/projectile/magnetic.dm
+++ b/code/modules/projectiles/projectile/magnetic.dm
@@ -18,4 +18,100 @@
name = "flechette"
icon_state = "flechette"
damage = 20
- armor_penetration = 100
\ No newline at end of file
+ armor_penetration = 100
+
+/obj/item/projectile/bullet/magnetic/fuelrod
+ name = "fuel rod"
+ icon_state = "fuel-deuterium"
+ damage = 30
+ stun = 1
+ weaken = 0
+ agony = 30
+ incendiary = 1
+ flammability = 0 //Deuterium and Tritium are both held in water, but the object moving so quickly will ignite the target.
+ penetrating = 2
+ embed_chance = 0
+ armor_penetration = 40
+ kill_count = 20
+
+ var/searing = 0 //Does this fuelrod ignore shields?
+ var/detonate_travel = 0 //Will this fuelrod explode when it reaches maximum distance?
+ var/detonate_mob = 0 //Will this fuelrod explode when it hits a mob?
+ var/energetic_impact = 0 //Does this fuelrod cause a bright flash on impact with a mob?
+
+/obj/item/projectile/bullet/magnetic/fuelrod/on_hit(var/atom/target, var/blocked = 0, var/def_zone = null) //Future-proofing. Special effects for impact.
+ if(istype(target,/mob/living))
+ var/mob/living/V = target
+ if(detonate_mob)
+ if(V.loc)
+ explosion(V.loc, -1, -1, 2, 3)
+
+ if(energetic_impact)
+ var/eye_coverage = 0
+ for(var/mob/living/carbon/M in viewers(world.view, location))
+ eye_coverage = 0
+ if(iscarbon(M))
+ eye_coverage = M.eyecheck()
+ if(eye_coverage < 2)
+ M.flash_eyes()
+ M.Stun(2)
+ M.Weaken(10)
+
+ if(searing)
+ if(blocked)
+ blocked = 0
+
+ return ..(target, blocked, def_zone)
+
+/obj/item/projectile/bullet/magnetic/fuelrod/on_impact(var/atom/A) //Future-proofing, again. In the event new fuel rods are introduced, and have special effects for when they stop flying.
+ if(src.loc)
+ if(detonate_travel && detonate_mob)
+ visible_message("\The [src] shatters in a violent explosion!")
+ explosion(src.loc, 1, 1, 3, 4)
+ else if(detonate_travel)
+ visible_message("\The [src] explodes in a shower of embers!")
+ explosion(src.loc, -1, 1, 2, 3)
+ ..(A)
+
+/obj/item/projectile/bullet/magnetic/fuelrod/tritium
+ icon_state = "fuel-tritium"
+ damage = 40
+ flammability = -1
+ armor_penetration = 50
+ penetrating = 3
+
+/obj/item/projectile/bullet/magnetic/fuelrod/phoron
+ name = "blazing fuel rod"
+ icon_state = "fuel-phoron"
+ damage = 35
+ incendiary = 2
+ flammability = 2
+ armor_penetration = 60
+ penetrating = 5
+ irradiate = 20
+ detonate_mob = 1
+
+/obj/item/projectile/bullet/magnetic/fuelrod/supermatter
+ name = "painfully incandescent fuel rod"
+ icon_state = "fuel-supermatter"
+ damage = 15
+ incendiary = 2
+ flammability = 4
+ weaken = 2
+ armor_penetration = 100
+ penetrating = 100 //Theoretically, this shouldn't stop flying for a while, unless someone lines it up with a wall or fires it into a mountain.
+ irradiate = 120
+ kill_count = 75
+ searing = 1
+ detonate_travel = 1
+ detonate_mob = 1
+ energetic_impact = 1
+
+/obj/item/projectile/bullet/magnetic/fuelrod/supermatter/on_hit(var/atom/target, var/blocked = 0, var/def_zone = null) //You cannot touch the supermatter without disentigrating. Assumedly, this is true for condensed rods of it flying at relativistic speeds.
+ if(istype(target,/turf/simulated/wall) || istype(target,/mob/living))
+ target.visible_message("The [src] burns a perfect hole through \the [target] with a blinding flash!")
+ playsound(target.loc, 'sound/effects/teleport.ogg', 40, 0)
+ return ..(target, blocked, def_zone)
+
+/obj/item/projectile/bullet/magnetic/fuelrod/supermatter/check_penetrate()
+ return 1
\ No newline at end of file
diff --git a/code/modules/projectiles/targeting/targeting_overlay.dm b/code/modules/projectiles/targeting/targeting_overlay.dm
index 9e399c10de..00a380dedf 100644
--- a/code/modules/projectiles/targeting/targeting_overlay.dm
+++ b/code/modules/projectiles/targeting/targeting_overlay.dm
@@ -74,7 +74,7 @@
owner << "[aiming_at ? "\The [aiming_at] is" : "Your targets are"] [message]."
if(aiming_at)
- aiming_at << "You are [message]."
+ to_chat(aiming_at, "You are [message].")
/obj/aiming_overlay/process()
if(!owner)
@@ -109,25 +109,25 @@ obj/aiming_overlay/proc/update_aiming_deferred()
if(!locked && lock_time <= world.time)
locked = 1
- owner << "You are locked onto your target."
- aiming_at << "The gun is trained on you!"
+ to_chat(owner, "You are locked onto your target.")
+ to_chat(aiming_at, "The gun is trained on you!")
update_icon()
var/cancel_aim = 1
var/mob/living/carbon/human/H = owner
if(!(aiming_with in owner) || (istype(H) && !H.item_is_in_hands(aiming_with)))
- owner << "You must keep hold of your weapon!"
+ to_chat(owner, "You must keep hold of your weapon!")
else if(owner.eye_blind)
- owner << "You are blind and cannot see your target!"
+ to_chat(owner, "You are blind and cannot see your target!")
else if(!aiming_at || !istype(aiming_at.loc, /turf))
- owner << "You have lost sight of your target!"
+ to_chat(owner, "You have lost sight of your target!")
else if(owner.incapacitated() || owner.lying || owner.restrained())
- owner << "You must be conscious and standing to keep track of your target!"
- else if(aiming_at.alpha == 0 || (aiming_at.invisibility > owner.see_invisible))
- owner << "Your target has become invisible!"
+ to_chat(owner, "You must be conscious and standing to keep track of your target!")
+ else if(aiming_at.alpha <= 50 || (aiming_at.invisibility > owner.see_invisible))
+ to_chat(owner, "Your target has become invisible!")
else if(get_dist(get_turf(owner), get_turf(aiming_at)) > 7) // !(owner in viewers(aiming_at, 7))
- owner << "Your target is too far away to track!"
+ to_chat(owner, "Your target is too far away to track!")
else
cancel_aim = 0
@@ -147,13 +147,16 @@ obj/aiming_overlay/proc/update_aiming_deferred()
return
if(owner.incapacitated())
- owner << "You cannot aim a gun in your current state."
+ to_chat(owner, "You cannot aim a gun in your current state.")
return
if(owner.lying)
- owner << "You cannot aim a gun while prone."
+ to_chat(owner, "You cannot aim a gun while prone.")
return
if(owner.restrained())
- owner << "You cannot aim a gun while handcuffed."
+ to_chat(owner, "You cannot aim a gun while handcuffed.")
+ return
+ if(target.alpha <= 50)
+ to_chat(owner, "You cannot aim at something you cannot see.")
return
if(aiming_at)
@@ -167,7 +170,7 @@ obj/aiming_overlay/proc/update_aiming_deferred()
if(owner.client)
owner.client.add_gun_icons()
- target << "You now have a gun pointed at you. No sudden moves!"
+ to_chat(target, "You now have a gun pointed at you. No sudden moves!")
aiming_with = thing
aiming_at = target
if(istype(aiming_with, /obj/item/weapon/gun))
@@ -200,10 +203,10 @@ obj/aiming_overlay/proc/update_aiming_deferred()
if(owner.client)
if(active)
- owner << "You will now aim rather than fire."
+ to_chat(owner, "You will now aim rather than fire.")
owner.client.add_gun_icons()
else
- owner << "You will no longer aim rather than fire."
+ to_chat(owner, "You will no longer aim rather than fire.")
owner.client.remove_gun_icons()
owner.gun_setting_icon.icon_state = "gun[active]"
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm
index 44d231a683..f17a211d82 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm
@@ -105,7 +105,6 @@
reagent_state = LIQUID
color = "#0064C877"
metabolism = REM * 10
- mrate_static = TRUE
glass_name = "water"
glass_desc = "The father of all refreshments."
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm
index d0be0469c1..51ba5d3782 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm
@@ -16,7 +16,6 @@
reagent_state = SOLID
color = "#1C1300"
ingest_met = REM * 5
- mrate_static = TRUE
/datum/reagent/carbon/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_DIONA)
@@ -74,8 +73,6 @@
var/targ_temp = 310
var/halluci = 0
- mrate_static = TRUE
-
glass_name = "ethanol"
glass_desc = "A well-known alcohol with a variety of applications."
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 953ad42535..50bdd413d2 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm
@@ -7,7 +7,6 @@
taste_mult = 4
reagent_state = SOLID
metabolism = REM * 4
- mrate_static = TRUE
var/nutriment_factor = 30 // Per unit
var/injectable = 0
color = "#664330"
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm
index a5fcab4430..84639e1c39 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm
@@ -9,7 +9,6 @@
color = "#00BFFF"
overdose = REAGENTS_OVERDOSE * 2
metabolism = REM * 0.5
- mrate_static = TRUE
scannable = 1
/datum/reagent/inaprovaline/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
@@ -35,7 +34,7 @@
/datum/reagent/bicaridine/overdose(var/mob/living/carbon/M, var/alien, var/removed)
..()
var/wound_heal = 1.5 * removed
- M.eye_blurry += (wound_heal)
+ M.eye_blurry = min(M.eye_blurry + wound_heal, 250)
if(ishuman(M))
var/mob/living/carbon/human/H = M
for(var/obj/item/organ/external/O in H.bad_external_organs)
@@ -141,7 +140,6 @@
taste_description = "bitterness"
reagent_state = LIQUID
color = "#0040FF"
- mrate_static = TRUE //Until it's not crazy strong, at least
overdose = REAGENTS_OVERDOSE * 0.5
scannable = 1
@@ -693,4 +691,21 @@
else
if(world.time > data + ANTIDEPRESSANT_MESSAGE_DELAY)
data = world.time
- to_chat(M, "You feel invigorated and calm.")
\ No newline at end of file
+ to_chat(M, "You feel invigorated and calm.")
+
+// This exists to cut the number of chemicals a merc borg has to juggle on their hypo.
+/datum/reagent/healing_nanites
+ name = "Restorative Nanites"
+ id = "healing_nanites"
+ description = "Miniature medical robots that swiftly restore bodily damage."
+ taste_description = "metal"
+ reagent_state = SOLID
+ color = "#555555"
+ metabolism = REM * 4 // Nanomachines gotta go fast.
+ scannable = 1
+
+/datum/reagent/healing_nanites/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
+ M.heal_organ_damage(2 * removed, 2 * removed)
+ M.adjustOxyLoss(-4 * removed)
+ M.adjustToxLoss(-2 * removed)
+ M.adjustCloneLoss(-2 * removed)
\ No newline at end of file
diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm
index 5c4a6bdce6..d0cd3cf9e6 100644
--- a/code/modules/reagents/reagent_containers/borghydro.dm
+++ b/code/modules/reagents/reagent_containers/borghydro.dm
@@ -12,6 +12,7 @@
var/charge_cost = 50
var/charge_tick = 0
var/recharge_time = 5 //Time it takes for shots to recharge (in seconds)
+ var/bypass_protection = FALSE // If true, can inject through things like spacesuits and armor.
var/list/reagent_ids = list("tricordrazine", "inaprovaline", "anti_toxin", "tramadol", "dexalin" ,"spaceacillin")
var/list/reagent_volumes = list()
@@ -26,6 +27,13 @@
/obj/item/weapon/reagent_containers/borghypo/lost
reagent_ids = list("tricordrazine", "bicaridine", "dexalin", "anti_toxin", "tramadol", "spaceacillin")
+/obj/item/weapon/reagent_containers/borghypo/merc
+ name = "advanced cyborg hypospray"
+ desc = "An advanced nanite and chemical synthesizer and injection system, designed for heavy-duty medical equipment. This type is capable of safely bypassing \
+ thick materials that other hyposprays would struggle with."
+ bypass_protection = TRUE // Because mercs tend to be in spacesuits.
+ reagent_ids = list("healing_nanites", "hyperzine", "tramadol", "oxycodone", "spaceacillin", "peridaxon", "osteodaxon", "myelamine")
+
/obj/item/weapon/reagent_containers/borghypo/New()
..()
@@ -72,7 +80,7 @@
user << "You cannot inject a robotic limb."
return
- if (M.can_inject(user, 1))
+ if(M.can_inject(user, 1, ignore_thickness = bypass_protection))
user << "You inject [M] with the injector."
M << "You feel a tiny prick!"
diff --git a/code/modules/reagents/reagent_containers/drinkingglass/drinkingglass.dm b/code/modules/reagents/reagent_containers/drinkingglass/drinkingglass.dm
index 1aae5b4a94..d4c8389a51 100644
--- a/code/modules/reagents/reagent_containers/drinkingglass/drinkingglass.dm
+++ b/code/modules/reagents/reagent_containers/drinkingglass/drinkingglass.dm
@@ -157,8 +157,7 @@
user << "You splash the solution onto [target]."
reagents.splash(target, reagents.total_volume)
return 1
- else
- return
+ ..()
/obj/item/weapon/reagent_containers/food/drinks/glass2/standard_feed_mob(var/mob/user, var/mob/target)
if(afterattack(target, user)) //Check to see if harm intent & splash.
diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm
index 1c3151fee9..5c5d0cc3a6 100644
--- a/code/modules/reagents/reagent_containers/hypospray.dm
+++ b/code/modules/reagents/reagent_containers/hypospray.dm
@@ -14,6 +14,7 @@
possible_transfer_amounts = null
flags = OPENCONTAINER
slot_flags = SLOT_BELT
+ preserve_item = 1
var/reusable = 1
var/used = 0
var/filled = 0
@@ -70,6 +71,7 @@
reusable = 0
filled = 1
filled_reagents = list("inaprovaline" = 5)
+ preserve_item = 0
/obj/item/weapon/reagent_containers/hypospray/autoinjector/on_reagent_change()
..()
diff --git a/code/modules/research/circuitprinter.dm b/code/modules/research/circuitprinter.dm
index 4a936c6014..97942f0d02 100644
--- a/code/modules/research/circuitprinter.dm
+++ b/code/modules/research/circuitprinter.dm
@@ -170,10 +170,10 @@ using metal and glass, it uses glass and reagents (usually sulphuric acid).
/obj/machinery/r_n_d/circuit_imprinter/proc/canBuild(var/datum/design/D)
for(var/M in D.materials)
- if(materials[M] < D.materials[M])
+ if(materials[M] < (D.materials[M] * mat_efficiency))
return 0
for(var/C in D.chemicals)
- if(!reagents.has_reagent(C, D.chemicals[C]))
+ if(!reagents.has_reagent(C, D.chemicals[C] * mat_efficiency))
return 0
return 1
diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm
index c34f8d9454..708cc4e081 100644
--- a/code/modules/research/designs.dm
+++ b/code/modules/research/designs.dm
@@ -639,6 +639,13 @@ other types of metals and chemistry for reagents).
build_path = /obj/item/ammo_casing/chemdart
sort_string = "TACAF"
+/datum/design/item/weapon/fuelrod
+ id = "fuelrod_gun"
+ req_tech = list(TECH_COMBAT = 6, TECH_MATERIAL = 4, TECH_PHORON = 4, TECH_ILLEGAL = 5, TECH_MAGNET = 5)
+ materials = list(DEFAULT_WALL_MATERIAL = 10000, "glass" = 2000, "gold" = 500, "silver" = 500, "uranium" = 1000, "phoron" = 3000, "diamond" = 1000)
+ build_path = /obj/item/weapon/gun/magnetic/fuelrod
+ sort_string = "TACBA"
+
/datum/design/item/weapon/flora_gun
id = "flora_gun"
req_tech = list(TECH_MATERIAL = 2, TECH_BIO = 3, TECH_POWER = 3)
diff --git a/code/modules/research/prosfab_designs.dm b/code/modules/research/prosfab_designs.dm
index 081ba95662..7462935e75 100644
--- a/code/modules/research/prosfab_designs.dm
+++ b/code/modules/research/prosfab_designs.dm
@@ -339,4 +339,12 @@
id = "borg_syndicate_module"
req_tech = list(TECH_COMBAT = 4, TECH_ILLEGAL = 3)
materials = list(DEFAULT_WALL_MATERIAL = 7500, "glass" = 11250, "diamond" = 7500)
- build_path = /obj/item/borg/upgrade/syndicate
\ No newline at end of file
+ build_path = /obj/item/borg/upgrade/syndicate
+
+/datum/design/item/prosfab/robot_upgrade/language
+ name = "language module"
+ desc = "Used to let cyborgs other than clerical or service speak a variety of languages."
+ id = "borg_language_module"
+ req_tech = list(TECH_DATA = 6, TECH_MATERIAL = 6)
+ materials = list(DEFAULT_WALL_MATERIAL = 25000, "glass" = 3000, "gold" = 350)
+ build_path = /obj/item/borg/upgrade/language
\ No newline at end of file
diff --git a/code/modules/research/protolathe.dm b/code/modules/research/protolathe.dm
index be489f9637..2333482761 100644
--- a/code/modules/research/protolathe.dm
+++ b/code/modules/research/protolathe.dm
@@ -164,10 +164,10 @@
/obj/machinery/r_n_d/protolathe/proc/canBuild(var/datum/design/D)
for(var/M in D.materials)
- if(materials[M] < D.materials[M])
+ if(materials[M] < (D.materials[M] * mat_efficiency))
return 0
for(var/C in D.chemicals)
- if(!reagents.has_reagent(C, D.chemicals[C]))
+ if(!reagents.has_reagent(C, D.chemicals[C] * mat_efficiency))
return 0
return 1
diff --git a/code/modules/shieldgen/emergency_shield.dm b/code/modules/shieldgen/emergency_shield.dm
index 6bf1ea58ef..b67e6f70a2 100644
--- a/code/modules/shieldgen/emergency_shield.dm
+++ b/code/modules/shieldgen/emergency_shield.dm
@@ -141,7 +141,6 @@
idle_power_usage = 0
var/global/list/blockedturfs = list(
/turf/space,
- /turf/simulated/open,
/turf/simulated/floor/outdoors,
)
diff --git a/code/modules/shieldgen/shield_gen_external.dm b/code/modules/shieldgen/shield_gen_external.dm
index 2d7dd383d9..27b1def271 100644
--- a/code/modules/shieldgen/shield_gen_external.dm
+++ b/code/modules/shieldgen/shield_gen_external.dm
@@ -5,7 +5,6 @@
name = "hull shield generator"
var/global/list/blockedturfs = list(
/turf/space,
- /turf/simulated/open,
/turf/simulated/floor/outdoors,
)
/obj/machinery/shield_gen/external/New()
@@ -24,6 +23,8 @@
T = locate(gen_turf.x + x_offset, gen_turf.y + y_offset, gen_turf.z)
if (is_type_in_list(T,blockedturfs))
//check neighbors of T
- if (locate(/turf/simulated/) in orange(1, T))
- out += T
+ for(var/i in orange(1, T))
+ if(istype(i, /turf/simulated) && !is_type_in_list(i,blockedturfs))
+ out += T
+ break
return out
\ No newline at end of file
diff --git a/code/modules/xenoarcheaology/finds/misc.dm b/code/modules/xenoarcheaology/finds/misc.dm
index 4037de5176..2729872876 100644
--- a/code/modules/xenoarcheaology/finds/misc.dm
+++ b/code/modules/xenoarcheaology/finds/misc.dm
@@ -6,10 +6,15 @@
name = "Crystal"
icon = 'icons/obj/mining.dmi'
icon_state = "crystal"
+ density = TRUE
+ anchored = TRUE
/obj/machinery/crystal/New()
if(prob(50))
icon_state = "crystal2"
+ set_light(3, 3, "#CC00CC")
+ else
+ set_light(3, 3, "#33CC33")
//large finds
/*
diff --git a/code/stylesheet.dm b/code/stylesheet.dm
index 4b771b2ab2..351d2b99a1 100644
--- a/code/stylesheet.dm
+++ b/code/stylesheet.dm
@@ -73,6 +73,7 @@ h1.alert, h2.alert {color: #000000;}
.disarm {color: #990000;}
.passive {color: #660000;}
+.critical {color: #ff0000; font-weight: bold; font-size: 150%;}
.danger {color: #ff0000; font-weight: bold;}
.warning {color: #ff0000; font-style: italic;}
.rose {color: #ff5050;}
diff --git a/icons/mecha/mech_bay.dmi b/icons/mecha/mech_bay.dmi
index e696042ecd..19ca94f3b9 100644
Binary files a/icons/mecha/mech_bay.dmi and b/icons/mecha/mech_bay.dmi differ
diff --git a/icons/mob/64x32.dmi b/icons/mob/64x32.dmi
new file mode 100644
index 0000000000..615fd87a01
Binary files /dev/null and b/icons/mob/64x32.dmi differ
diff --git a/icons/mob/64x64.dmi b/icons/mob/64x64.dmi
new file mode 100644
index 0000000000..a829ee2c6f
Binary files /dev/null and b/icons/mob/64x64.dmi differ
diff --git a/icons/mob/96x96.dmi b/icons/mob/96x96.dmi
new file mode 100644
index 0000000000..7368d30bb1
Binary files /dev/null and b/icons/mob/96x96.dmi differ
diff --git a/icons/mob/alienqueen.dmi b/icons/mob/alienqueen.dmi
deleted file mode 100644
index 1562152023..0000000000
Binary files a/icons/mob/alienqueen.dmi and /dev/null differ
diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi
index 1469c3e3ba..f723644373 100644
Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ
diff --git a/icons/mob/human_races/subspecies/r_vatgrown.dmi b/icons/mob/human_races/subspecies/r_vatgrown.dmi
index 8cb165b127..b2dcbd78ac 100644
Binary files a/icons/mob/human_races/subspecies/r_vatgrown.dmi and b/icons/mob/human_races/subspecies/r_vatgrown.dmi differ
diff --git a/icons/mob/light_overlays.dmi b/icons/mob/light_overlays.dmi
index 9f1232ff95..e54ec778cd 100644
Binary files a/icons/mob/light_overlays.dmi and b/icons/mob/light_overlays.dmi differ
diff --git a/icons/mob/modular_armor.dmi b/icons/mob/modular_armor.dmi
new file mode 100644
index 0000000000..2c7d8ea841
Binary files /dev/null and b/icons/mob/modular_armor.dmi differ
diff --git a/icons/mob/robots.dmi b/icons/mob/robots.dmi
index d32d479e3f..35e6df449f 100644
Binary files a/icons/mob/robots.dmi and b/icons/mob/robots.dmi differ
diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi
index d259faec57..9db8ef1fc5 100644
Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ
diff --git a/icons/mob/ties.dmi b/icons/mob/ties.dmi
index 4105a9f68e..2c17ab4a32 100644
Binary files a/icons/mob/ties.dmi and b/icons/mob/ties.dmi differ
diff --git a/icons/obj/card.dmi b/icons/obj/card.dmi
index 7d917849b1..833e9b99cf 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 7b1b1b4085..fa9ea15dc7 100644
Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ
diff --git a/icons/obj/clothing/modular_armor.dmi b/icons/obj/clothing/modular_armor.dmi
new file mode 100644
index 0000000000..89ef66aa8c
Binary files /dev/null and b/icons/obj/clothing/modular_armor.dmi differ
diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi
index f16399d6db..52ae865f92 100644
Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ
diff --git a/icons/obj/electronic_assemblies.dmi b/icons/obj/electronic_assemblies.dmi
index 6ad2b65b2f..6da1794a54 100644
Binary files a/icons/obj/electronic_assemblies.dmi and b/icons/obj/electronic_assemblies.dmi differ
diff --git a/icons/obj/flora/deadtrees.dmi b/icons/obj/flora/deadtrees.dmi
index 2ae1a5a6e0..7a0b164619 100644
Binary files a/icons/obj/flora/deadtrees.dmi and b/icons/obj/flora/deadtrees.dmi differ
diff --git a/icons/obj/flora/jungleflora.dmi b/icons/obj/flora/jungleflora.dmi
new file mode 100644
index 0000000000..9a266e9226
Binary files /dev/null and b/icons/obj/flora/jungleflora.dmi differ
diff --git a/icons/obj/flora/jungletree.dmi b/icons/obj/flora/jungletree.dmi
new file mode 100644
index 0000000000..51f3141399
Binary files /dev/null and b/icons/obj/flora/jungletree.dmi differ
diff --git a/icons/obj/flora/jungletreesmall.dmi b/icons/obj/flora/jungletreesmall.dmi
new file mode 100644
index 0000000000..3abd375cc9
Binary files /dev/null and b/icons/obj/flora/jungletreesmall.dmi differ
diff --git a/icons/obj/flora/largejungleflora.dmi b/icons/obj/flora/largejungleflora.dmi
new file mode 100644
index 0000000000..bba0fd29f6
Binary files /dev/null and b/icons/obj/flora/largejungleflora.dmi differ
diff --git a/icons/obj/flora/palmtrees.dmi b/icons/obj/flora/palmtrees.dmi
new file mode 100644
index 0000000000..b8708b36d2
Binary files /dev/null and b/icons/obj/flora/palmtrees.dmi differ
diff --git a/icons/obj/flora/pinetrees.dmi b/icons/obj/flora/pinetrees.dmi
index 9ee04a5baf..63073046f0 100644
Binary files a/icons/obj/flora/pinetrees.dmi and b/icons/obj/flora/pinetrees.dmi differ
diff --git a/icons/obj/flora/rocks.dmi b/icons/obj/flora/rocks.dmi
index a1f6a0df0a..0974360e27 100644
Binary files a/icons/obj/flora/rocks.dmi and b/icons/obj/flora/rocks.dmi differ
diff --git a/icons/obj/gun.dmi b/icons/obj/gun.dmi
index 1550d6bf4b..e037ce6f9b 100644
Binary files a/icons/obj/gun.dmi and b/icons/obj/gun.dmi differ
diff --git a/icons/obj/projectiles.dmi b/icons/obj/projectiles.dmi
index 61cb6a6a8f..90d6dcd1ea 100644
Binary files a/icons/obj/projectiles.dmi and b/icons/obj/projectiles.dmi differ
diff --git a/icons/obj/radio.dmi b/icons/obj/radio.dmi
index 3452ac3524..86e39f0c58 100644
Binary files a/icons/obj/radio.dmi and b/icons/obj/radio.dmi differ
diff --git a/icons/obj/railgun.dmi b/icons/obj/railgun.dmi
index 0b00e7a156..404aa1ea60 100644
Binary files a/icons/obj/railgun.dmi and b/icons/obj/railgun.dmi differ
diff --git a/icons/obj/robotics.dmi b/icons/obj/robotics.dmi
index 85d5a8d0a0..e45848975b 100644
Binary files a/icons/obj/robotics.dmi and b/icons/obj/robotics.dmi differ
diff --git a/icons/obj/stacks.dmi b/icons/obj/stacks.dmi
index 1713cacb67..5cdff4a1f3 100644
Binary files a/icons/obj/stacks.dmi and b/icons/obj/stacks.dmi differ
diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi
index 53044228a9..3e39c77171 100644
Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ
diff --git a/icons/turf/outdoors.dmi b/icons/turf/outdoors.dmi
index bcd81c28c9..31fab0ec95 100644
Binary files a/icons/turf/outdoors.dmi and b/icons/turf/outdoors.dmi differ
diff --git a/icons/turf/outdoors_edge.dmi b/icons/turf/outdoors_edge.dmi
index 02a52195c2..fb0b04168e 100644
Binary files a/icons/turf/outdoors_edge.dmi and b/icons/turf/outdoors_edge.dmi differ
diff --git a/maps/northern_star/polaris-1.dmm b/maps/northern_star/polaris-1.dmm
index 4f8aedb853..9204eb5c68 100644
--- a/maps/northern_star/polaris-1.dmm
+++ b/maps/northern_star/polaris-1.dmm
@@ -5177,7 +5177,7 @@
"bVC" = (/obj/machinery/ai_status_display{pixel_y = 32},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/captain)
"bVD" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/captain)
"bVE" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/secure/safe{pixel_x = 5; pixel_y = 28},/obj/machinery/recharger{pixel_y = 4},/turf/simulated/floor/wood,/area/crew_quarters/captain)
-"bVF" = (/obj/machinery/computer/card,/obj/item/weapon/card/id/captains_spare,/turf/simulated/floor/wood,/area/crew_quarters/captain)
+"bVF" = (/obj/machinery/computer/card,/obj/item/weapon/card/id/gold/captain/spare,/turf/simulated/floor/wood,/area/crew_quarters/captain)
"bVG" = (/obj/machinery/computer/communications,/obj/machinery/status_display{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/wood,/area/crew_quarters/captain)
"bVH" = (/obj/machinery/keycard_auth{pixel_x = 0; pixel_y = 24},/turf/simulated/floor/wood,/area/crew_quarters/captain)
"bVI" = (/obj/structure/table/rack,/obj/item/weapon/tank/jetpack/oxygen,/obj/item/clothing/mask/gas,/obj/item/clothing/suit/armor/captain,/obj/item/clothing/head/helmet/space/capspace,/obj/machinery/newscaster/security_unit{pixel_x = 32; pixel_y = 0},/turf/simulated/floor/wood,/area/crew_quarters/captain)
diff --git a/maps/northern_star/polaris-2.dmm b/maps/northern_star/polaris-2.dmm
index ee935ce4b0..0adca3afa9 100644
--- a/maps/northern_star/polaris-2.dmm
+++ b/maps/northern_star/polaris-2.dmm
@@ -988,7 +988,7 @@
"sZ" = (/obj/structure/table/rack,/obj/item/device/flashlight/maglight,/obj/item/device/flashlight/maglight,/obj/item/device/flashlight/maglight,/obj/item/device/flashlight/maglight,/obj/item/device/flashlight/maglight,/obj/item/device/flashlight/maglight,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership)
"ta" = (/obj/structure/table/rack,/obj/item/device/camera_film,/obj/item/device/camera_film,/obj/item/device/camera_film,/obj/item/device/camera_film,/obj/item/device/camera_film,/obj/item/device/camera_film,/obj/item/device/camera,/obj/item/device/camera,/obj/item/device/camera,/obj/item/device/camera,/obj/item/device/camera,/obj/item/device/camera,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership)
"tb" = (/obj/structure/table/rack,/obj/item/ammo_magazine/m10mm,/obj/item/ammo_magazine/m10mm,/obj/item/ammo_magazine/m10mm,/obj/item/ammo_magazine/m10mm,/obj/item/ammo_magazine/m10mm,/obj/item/ammo_magazine/m10mm,/obj/item/weapon/gun/projectile/automatic/c20r,/obj/item/weapon/gun/projectile/automatic/c20r,/obj/item/weapon/gun/projectile/automatic/c20r,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership)
-"tc" = (/obj/structure/table/rack,/obj/item/ammo_magazine/m762,/obj/item/ammo_magazine/m762,/obj/item/ammo_magazine/m762,/obj/item/ammo_magazine/m762,/obj/item/weapon/gun/projectile/automatic/sts35,/obj/item/weapon/gun/projectile/automatic/sts35,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership)
+"tc" = (/obj/structure/table/rack,/obj/item/ammo_magazine/m545,/obj/item/ammo_magazine/m545,/obj/item/ammo_magazine/m545,/obj/item/ammo_magazine/m545,/obj/item/weapon/gun/projectile/automatic/sts35,/obj/item/weapon/gun/projectile/automatic/sts35,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership)
"td" = (/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/specops)
"te" = (/obj/machinery/vending/boozeomat,/turf/simulated/shuttle/wall/dark,/area/shuttle/administration/centcom)
"tf" = (/obj/machinery/vending/coffee,/turf/simulated/shuttle/floor/red,/area/shuttle/administration/centcom)
@@ -1329,7 +1329,7 @@
"zD" = (/obj/structure/bed/chair{dir = 8},/obj/effect/floor_decal/corner/white/diagonal,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/restaurant)
"zE" = (/obj/machinery/door/airlock/centcom{name = "Bridge"; opacity = 1; req_access = list(109)},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/command)
"zF" = (/obj/structure/table/reinforced,/obj/item/device/pda/captain,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/command)
-"zG" = (/obj/structure/table/reinforced,/obj/item/weapon/card/id/captains_spare,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/command)
+"zG" = (/obj/structure/table/reinforced,/obj/item/weapon/card/id/gold/captain/spare,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/command)
"zH" = (/obj/structure/table/reinforced,/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/command)
"zI" = (/obj/structure/table/reinforced,/obj/machinery/recharger{pixel_y = 4},/turf/unsimulated/floor{icon_state = "steel"},/area/centcom/command)
"zJ" = (/turf/simulated/shuttle/wall,/area/shuttle/transport1/centcom)
diff --git a/maps/southern_cross/shuttles/crew_shuttles.dm b/maps/southern_cross/shuttles/crew_shuttles.dm
index 764c7bccd7..202284bd1d 100644
--- a/maps/southern_cross/shuttles/crew_shuttles.dm
+++ b/maps/southern_cross/shuttles/crew_shuttles.dm
@@ -32,7 +32,6 @@
destination_class = /datum/shuttle_destination/shuttle2
starting_destination = /datum/shuttle_destination/shuttle2/root
-
/datum/shuttle_destination/shuttle1/root
name = "Southern Cross Hangar One"
my_area = /area/shuttle/shuttle1/start
diff --git a/maps/southern_cross/southern_cross-7.dmm b/maps/southern_cross/southern_cross-7.dmm
index 9b1384c2f5..d3cf67b594 100644
--- a/maps/southern_cross/southern_cross-7.dmm
+++ b/maps/southern_cross/southern_cross-7.dmm
@@ -87,6 +87,41 @@
"bI" = (/turf/space/transit/north,/area/shuttle/shuttle2/transit)
"bJ" = (/turf/space/transit/north,/turf/space/transit/south,/area/shuttle/shuttle1/transit)
"bK" = (/turf/space,/area/shuttle/shuttle1/orbit)
+"bL" = (/turf/simulated/shuttle/wall,/area/shuttle/arrival/pre_game)
+"bM" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "arrivals_shuttle"; pixel_x = 0; pixel_y = 25; req_one_access = list(13); tag_door = "arrivals_shuttle_hatch"},/turf/simulated/shuttle/floor{tag = "icon-floor_red"; icon_state = "floor_red"},/area/shuttle/arrival/pre_game)
+"bN" = (/turf/simulated/shuttle/floor{tag = "icon-floor_red"; icon_state = "floor_red"},/area/shuttle/arrival/pre_game)
+"bO" = (/obj/structure/showcase{desc = "So that's how the shuttle moves on its own."; icon = 'icons/mob/AI.dmi'; icon_state = "ai-red"; name = "Arrivals Announcement Computer"},/turf/simulated/shuttle/floor{tag = "icon-floor_red"; icon_state = "floor_red"},/area/shuttle/arrival/pre_game)
+"bP" = (/obj/machinery/light,/obj/structure/bed/chair{dir = 8},/turf/simulated/shuttle/floor{tag = "icon-floor_red"; icon_state = "floor_red"},/area/shuttle/arrival/pre_game)
+"bQ" = (/obj/machinery/computer/shuttle_control/arrivals,/turf/simulated/shuttle/floor{tag = "icon-floor_red"; icon_state = "floor_red"},/area/shuttle/arrival/pre_game)
+"bR" = (/obj/machinery/light,/obj/structure/bed/chair{dir = 4},/turf/simulated/shuttle/floor{tag = "icon-floor_red"; icon_state = "floor_red"},/area/shuttle/arrival/pre_game)
+"bS" = (/obj/structure/table/steel,/obj/structure/flora/pottedplant{icon_state = "plant-09"; name = "Dave"; pixel_y = 15; tag = "icon-plant-09"},/turf/simulated/shuttle/floor{tag = "icon-floor_red"; icon_state = "floor_red"},/area/shuttle/arrival/pre_game)
+"bT" = (/obj/structure/sign/warning/secure_area,/turf/simulated/shuttle/wall,/area/shuttle/arrival/pre_game)
+"bU" = (/obj/machinery/status_display,/turf/simulated/shuttle/wall,/area/shuttle/arrival/pre_game)
+"bV" = (/obj/machinery/door/airlock/silver{icon_state = "door_locked"; locked = 1; name = "Employees Only"; secured_wires = 1},/turf/simulated/shuttle/floor,/area/shuttle/arrival/pre_game)
+"bW" = (/obj/machinery/ai_status_display,/turf/simulated/shuttle/wall,/area/shuttle/arrival/pre_game)
+"bX" = (/turf/simulated/shuttle/floor,/area/shuttle/arrival/pre_game)
+"bY" = (/turf/simulated/shuttle/wall/hard_corner,/area/shuttle/arrival/pre_game)
+"bZ" = (/obj/machinery/light{dir = 1},/turf/simulated/shuttle/floor,/area/shuttle/arrival/pre_game)
+"ca" = (/obj/structure/closet/emcloset,/turf/simulated/shuttle/floor/white,/area/shuttle/arrival/pre_game)
+"cb" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "arrivals_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access = list(13)},/turf/simulated/shuttle/floor,/area/shuttle/arrival/pre_game)
+"cc" = (/obj/structure/bed/chair{dir = 4},/obj/structure/window/reinforced{dir = 8; health = 1e+006},/obj/effect/landmark{name = "JoinLate"},/turf/simulated/shuttle/floor/white,/area/shuttle/arrival/pre_game)
+"cd" = (/obj/structure/bed/chair{dir = 8},/obj/structure/window/reinforced{dir = 4; health = 1e+006},/obj/effect/landmark{name = "JoinLate"},/turf/simulated/shuttle/floor/white,/area/shuttle/arrival/pre_game)
+"ce" = (/turf/simulated/shuttle/wall/no_join,/area/shuttle/arrival/pre_game)
+"cf" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/shuttle/floor/white,/area/shuttle/arrival/pre_game)
+"cg" = (/obj/effect/landmark/start,/turf/simulated/shuttle/floor,/area/shuttle/arrival/pre_game)
+"ch" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/shuttle/floor/white,/area/shuttle/arrival/pre_game)
+"ci" = (/obj/structure/shuttle/window,/obj/structure/grille,/turf/simulated/shuttle/plating,/area/shuttle/arrival/pre_game)
+"cj" = (/obj/structure/bed/chair{dir = 4},/obj/effect/landmark{name = "JoinLate"},/turf/simulated/shuttle/floor/white,/area/shuttle/arrival/pre_game)
+"ck" = (/obj/structure/bed/chair{dir = 4},/obj/structure/window/reinforced{dir = 8; health = 1e+006},/turf/simulated/shuttle/floor/white,/area/shuttle/arrival/pre_game)
+"cl" = (/obj/structure/bed/chair{dir = 8},/obj/structure/window/reinforced{dir = 4; health = 1e+006},/turf/simulated/shuttle/floor/white,/area/shuttle/arrival/pre_game)
+"cm" = (/obj/structure/bed/chair{dir = 8},/obj/effect/landmark{name = "JoinLate"},/turf/simulated/shuttle/floor/white,/area/shuttle/arrival/pre_game)
+"cn" = (/obj/structure/bed/chair{dir = 4},/obj/effect/landmark{name = "JoinLate"},/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/shuttle/floor/white,/area/shuttle/arrival/pre_game)
+"co" = (/obj/machinery/hologram/holopad,/turf/simulated/shuttle/floor,/area/shuttle/arrival/pre_game)
+"cp" = (/obj/structure/bed/chair{dir = 8},/obj/effect/landmark{name = "JoinLate"},/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/shuttle/floor/white,/area/shuttle/arrival/pre_game)
+"cq" = (/obj/machinery/light,/turf/simulated/shuttle/floor,/area/shuttle/arrival/pre_game)
+"cr" = (/obj/structure/shuttle/engine/heater,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/airless,/area/shuttle/arrival/pre_game)
+"cs" = (/turf/space,/obj/structure/shuttle/engine/propulsion,/turf/simulated/shuttle/plating/airless/carry,/area/shuttle/arrival/pre_game)
+"ct" = (/obj/structure/shuttle/engine/heater,/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/plating/airless,/area/shuttle/arrival/pre_game)
(1,1,1) = {"
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababab
@@ -160,38 +195,38 @@ ahajajajajajajalalalalalalalajajajajajajahajajajajajajalalalalalalalajajajajajaj
ahajajajajajajalaAaAaAaAaAalajajajajajajahajajajajajajalaBaBaBaBaBalajajajajajajaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaaapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
ahajajajajajajalaAaAaAaAaAalajajajajajajahajajajajajajalaBaBaBaBaBalajajajajajajaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
ahajajajajajajalaAaAaAaAaAalajajajajajajahajajajajajajalaBaBaBaBaBalajajajajajajaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahaaaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahajajajajajajalalalalalalalajajajajajajahajajajajajajalalalalalalalajajajajajajaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahajajajajajajajajajajajajajajajajajajajahajajajajajajajajajajajajajajajajajajajaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahajajajajajajajajajajajajajajajajajajajahajajajajajajajajajajajajajajajajajajajaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahajajajajajajajajajajajajajajajajajajajahajajajajajajajajajajajajajajajajajajajaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahajajajajajajajajajajajajajajajajajajajahajajajajajajajajajajajajajajajajajajajaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahajajajajajajajajajajajajajajajajajajajahajajajajajajajajajajajajajajajajajajajaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahajajajajajajajajajajajajajajajajajajajahajajajajajajajajajajajajajajajajajajajaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahaiaiaiaiaiaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahajajajajajajajajajajajajajajajajajajajajajahajajajajajajajajajajajajajajajajajajajajajajahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajaDaDaDaDaDaDaDaDaDaDaDaDaDajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaEaEaEaEaEaEaEaEaEaEaEaEaEaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahajajajajajajajajajajajajajajajajajajajajajahajajalalalalalalalalalalalalalajajajajajajajahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajaDaFaFaFaFaFaFaFaFaFaFaFaDaDajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaEaGaGaGaGaGaGaGaGaGaGaGaEaEaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahajajajajajajajajajajajajajajajajajajajajajahajajalaHaHaHaHaHaHaHaHaHaHaHalalajajajajajajahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajaDaFaFaFaFaFaFaFaFaFaFaFaFaDajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaEaGaGaGaGaGaGaGaGaGaGaGaGaEaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahajajajajajajajajajajajajajajajajajajajajajahajajalaHaHaHaHaHaHaHaHaHaHaHaHalajajajajajajahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajaDaFaFaFaFaFaFaFaFaFaFaFaFaDajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaEaGaGaGaGaGaGaGaGaGaGaGaGaEaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahajajajajajajajajajajajajajajajajajajajajajahajajalaHaHaHaHaHaHaHaHaHaHaHaHalajajajajajajahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajaIaFaFaFaFaFaFaFaFaFaFaFaFaIajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaJaGaGaGaGaGaGaGaGaGaGaGaGaJaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahajajajajajajajajajajajajajajajajajajajajajahajajalaHaHaHaHaHaHaHaHaHaHaHaHalajajajajajajahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajaIaFaFaFaFaFaFaFaFaFaFaFaIaIajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaJaGaGaGaGaGaGaGaGaGaGaGaJaJaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahajajajajajajalalalalalalalalalajajajajajajahajajalaHaHaHaHaHaHaHaHaHaHaHalalajajajajajajahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajaIaIaIaIaIaIaIaIaIaIaIaIaIajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaJaJaJaJaJaJaJaJaJaJaJaJaJaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahajajajajajajalaKaKaKaKaKaKaKalajajajajajajahajajalalalalalalalalalalalalalajajajajajajajahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahajajajajajajalaKaKaKaKaKaKaKalajajajajajajahajajajajajajajajajajajajajajajajajajajajajajahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahajajajajajajalaKaKaKaKaKaKaKalajajajajajajahajajajajajajajajajajajajajajajajajajajajajajahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahajajajajajajalaKaKaKaKaKaKaKalajajajajajajahajajajajajajajajajajajajajajajajajajajajajajahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahajajajajajajalaKaKaKaKaKaKaKalajajajajajajahajajajajajajajajajajajajajajajajajajajajajajahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahajajajajajajalaKaKaKaKaKaKaKalajajajajajajahajajajajajajajajajajajajajajajajajajajajajajahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahajajajajajajalaKaKaKaKaKaKaKalajajajajajajahajajajalalalalalalalalalalalalalajajajajajajahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahajajajajajajalaKaKaKaKaKaKaKalajajajajajajahajajalalaLaLaLaLaLaLaLaLaLaLaLalajajajajajajahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahajajajajajajalalalalalalalalalajajajajajajahajajalaLaLaLaLaLaLaLaLaLaLaLaLalajajajajajajahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaaaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahajajajajajajajajajajajajajajajajajajajajajahajajalaLaLaLaLaLaLaLaLaLaLaLaLalajajajajajajahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahajajajajajajajajajajajajajajajajajajajajajahajajalaLaLaLaLaLaLaLaLaLaLaLaLalajajajajajajahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaaaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahajajajajajajajajajajajajajajajajajajajajajahajajalalaLaLaLaLaLaLaLaLaLaLaLalajajajajajajahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaMaaaNaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahajajajajajajajajajajajajajajajajajajajajajahajajajalalalalalalalalalalalalalajajajajajajahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaMaaaNaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahajajajajajajajajajajajajajajajajajajajajajahajajajajajajajajajajajajajajajajajajajajajajahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaMaaaNaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahajajajajajajajajajajajajajajajajajajajajajahajajajajajajajajajajajajajajajajajajajajajajahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaMaaaNaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-ahahahahahahahahahahahahahahahahahahahahahahahajajajajajajajajajajajajajajajajajajajajajajahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaMaaaNaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaMaaaNaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahajajajajajajalalalalalalalajajajajajajahajajajajajajalalalalalalalajajajajajajaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahajajajajajajajajajajajajajajajajajajajahajajajajajajajajajajajajajajajajajajajaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaagacacacacacacacacacacacacacacacacacacacacacacacacacacacagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahajajajajajajajajajajajajajajajajajajajahajajajajajajajajajajajajajajajajajajajaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaagacacacacacacacacacacacacacacacacacacacacacacacacacacacagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahajajajajajajajajajajajajajajajajajajajahajajajajajajajajajajajajajajajajajajajaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaagacacacacacacacacacacacacacacacacacacacacacacacacacacacagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahajajajajajajajajajajajajajajajajajajajahajajajajajajajajajajajajajajajajajajajaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaagacacacacacacacacacacacacacacacacacacacacacacacacacacacagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahajajajajajajajajajajajajajajajajajajajahajajajajajajajajajajajajajajajajajajajaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaagacacacacacacacacacacabababababababacacacacacacacacacacagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahajajajajajajajajajajajajajajajajajajajahajajajajajajajajajajajajajajajajajajajaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacacacacacacacababbLbLbLbLbLababacacacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahahaiaiaiaiaiaiaaaaaaaaaaaaaaaaaaabacacacacacacacacacabbLbLbMbObNbLbLabacacacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahajajajajajajajajajajajajajajajajajajajajajahajajajajajajajajajajajajajajajajajajajajajajahaaaaaaaaaaaaaaaaaaagacacacacacacacacababbLbQbPbNbRbSbLababacacacacacacacacagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajaDaDaDaDaDaDaDaDaDaDaDaDaDajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaEaEaEaEaEaEaEaEaEaEaEaEaEaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahajajajajajajajajajajajajajajajajajajajajajahajajalalalalalalalalalalalalalajajajajajajajahaaaaaaaaaaaaaaaaaaagacacacacacacacababbLbLbUbTbVbLbWbLbLababacacacacacacacagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajaDaFaFaFaFaFaFaFaFaFaFaFaDaDajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaEaGaGaGaGaGaGaGaGaGaGaGaEaEaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahajajajajajajajajajajajajajajajajajajajajajahajajalaHaHaHaHaHaHaHaHaHaHaHalalajajajajajajahaaaaaaaaaaaaaaaaaaagacacacacacacacabbLbYbXbZbXbXbXbZbXbYbLabacacacacacacacagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajaDaFaFaFaFaFaFaFaFaFaFaFaFaDajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaEaGaGaGaGaGaGaGaGaGaGaGaGaEaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahajajajajajajajajajajajajajajajajajajajajajahajajalaHaHaHaHaHaHaHaHaHaHaHaHalajajajajajajahaaaaaaaaaaaaaaaaaaagacacacacacacacabbLcabXbXbXbXbXbXbXcabLabacacacacacacacagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajaDaFaFaFaFaFaFaFaFaFaFaFaFaDajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaEaGaGaGaGaGaGaGaGaGaGaGaGaEaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahajajajajajajajajajajajajajajajajajajajajajahajajalaHaHaHaHaHaHaHaHaHaHaHaHalajajajajajajahaaaaaaaaaaaaaaaaaaagacacacacacacacabcbbXbXbXbXbXbXbXbXbXcbabacacacacacacacagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajaIaFaFaFaFaFaFaFaFaFaFaFaFaIajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaJaGaGaGaGaGaGaGaGaGaGaGaGaJaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahajajajajajajajajajajajajajajajajajajajajajahajajalaHaHaHaHaHaHaHaHaHaHaHaHalajajajajajajahaaaaaaaaaaaaaaaaaaagacacacacacacacabcbbXbXcdccbXcdccbXbXcbabacacacacacacacagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajaIaFaFaFaFaFaFaFaFaFaFaFaIaIajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaJaGaGaGaGaGaGaGaGaGaGaGaJaJaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahajajajajajajalalalalalalalalalajajajajajajahajajalaHaHaHaHaHaHaHaHaHaHaHalalajajajajajajahaaaaaaaaaaaaaaaaaaabacacacacacacacabcecfbXcdcccgcdccbXchceabacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajaIaIaIaIaIaIaIaIaIaIaIaIaIajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaJaJaJaJaJaJaJaJaJaJaJaJaJaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahajajajajajajalaKaKaKaKaKaKaKalajajajajajajahajajalalalalalalalalalalalalalajajajajajajajahaaaaaaaaaaaaaaaaaaabacacacacacacacabcicjbXcdckbXclccbXcmciabacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahajajajajajajalaKaKaKaKaKaKaKalajajajajajajahajajajajajajajajajajajajajajajajajajajajajajahaaaaaaaaaaaaaaaaaaagacacacacacacacabcicnbXcdckcoclccbXcpciabacacacacacacacagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahajajajajajajalaKaKaKaKaKaKaKalajajajajajajahajajajajajajajajajajajajajajajajajajajajajajahaaaaaaaaaaaaaaaaaaagacacacacacacacabcicjbXcdckbXclccbXcmciabacacacacacacacagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahajajajajajajalaKaKaKaKaKaKaKalajajajajajajahajajajajajajajajajajajajajajajajajajajajajajahaaaaaaaaaaaaaaaaaaagacacacacacacacabcecfbXcdccbXcdccbXchceabacacacacacacacagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahajajajajajajalaKaKaKaKaKaKaKalajajajajajajahajajajajajajajajajajajajajajajajajajajajajajahaaaaaaaaaaaaaaaaaaagacacacacacacacabcbbXbXcdccbXcdccbXbXcbabacacacacacacacagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahajajajajajajalaKaKaKaKaKaKaKalajajajajajajahajajajajajajajajajajajajajajajajajajajajajajahaaaaaaaaaaaaaaaaaaagacacacacacacacabcbbXbXbXbXbXbXbXbXbXcbabacacacacacacacagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahajajajajajajalaKaKaKaKaKaKaKalajajajajajajahajajajalalalalalalalalalalalalalajajajajajajahaaaaaaaaaaaaaaaaaaagacacacacacacacabbLcabXcqbXbXbXcqbXcabLabacacacacacacacagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahajajajajajajalaKaKaKaKaKaKaKalajajajajajajahajajalalaLaLaLaLaLaLaLaLaLaLaLalajajajajajajahaaaaaaaaaaaaaaaaaaabacacacacacacacabbLcrcrbYbLbLbLbYcrcrbLabacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajajajajajajajajajahaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahajajajajajajalalalalalalalalalajajajajajajahajajalaLaLaLaLaLaLaLaLaLaLaLaLalajajajajajajahaaaaaaaaaaaaaaaaaaabacacacacacacacabbLcscsbLctctctbLcscsbLabacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaiaaaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahajajajajajajajajajajajajajajajajajajajajajahajajalaLaLaLaLaLaLaLaLaLaLaLaLalajajajajajajahaaaaaaaaaaaaaaaaaaagacacacacacacacababababbLcscscsbLababababacacacacacacacagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahajajajajajajajajajajajajajajajajajajajajajahajajalaLaLaLaLaLaLaLaLaLaLaLaLalajajajajajajahaaaaaaaaaaaaaaaaaaagacacacacacacacacacacabababababababacacacacacacacacacacagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaaaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahajajajajajajajajajajajajajajajajajajajajajahajajalalaLaLaLaLaLaLaLaLaLaLaLalajajajajajajahaaaaaaaaaaaaaaaaaaagacacacacacacacacacacacacacacacacacacacacacacacacacacacagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaMaaaNaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahajajajajajajajajajajajajajajajajajajajajajahajajajalalalalalalalalalalalalalajajajajajajahaaaaaaaaaaaaaaaaaaagacacacacacacacacacacacacacacacacacacacacacacacacacacacagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaMaaaNaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahajajajajajajajajajajajajajajajajajajajajajahajajajajajajajajajajajajajajajajajajajajajajahaaaaaaaaaaaaaaaaaaagacacacacacacacacacacacacacacacacacacacacacacacacacacacagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaMaaaNaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahajajajajajajajajajajajajajajajajajajajajajahajajajajajajajajajajajajajajajajajajajajajajahaaaaaaaaaaaaaaaaaaabacacacacacacacacacacacacacacacacacacacacacacacacacacacagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaMaaaNaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ahahahahahahahahahahahahahahahahahahahahahahahajajajajajajajajajajajajajajajajajajajajajajahaaaaaaaaaaaaaaaaaaabacacacacacacacacacacacacacacacacacacacacacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaMaaaNaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajahaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaMaaaNaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaOaMaaaNaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaPaNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahajajajajajajajajajajajajajajajajajajajajajajahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMaOaOaOaOaOaOaOaQaQaQaQaQaQaOaQaQaQaOaOaOaQaQaQaOaQaQaQaQaQaQaOaOaOaOaOaOaOaMaaaNaPaPaPaPaPaPaPaRaRaRaRaRaRaPaRaRaRaPaPaPaRaRaRaPaRaRaRaRaRaRaPaPaPaPaPaPaPaNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahahahahahahahahahahahahahahahahahahahahahahahahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMaOaOaOaOaOaOaOaQaSaSaSaSaQaOaQaSaQaQaQaQaQaSaQaOaQaSaSaSaSaQaOaOaOaOaOaOaOaMaaaNaPaPaPaPaPaPaPaRaTaTaTaTaRaPaRaTaRaRaRaRaRaTaRaPaRaTaTaTaTaRaPaPaPaPaPaPaPaNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -345,3 +380,4 @@ aabDbEbEbEbEbEbEbEbEbEbEbEbEbEbEbEbEbEbEbEbEbEbEbEbDaaaCaaaaaaaaaaaaaaaaaaaaaaaa
aabDbEbEbEbEbEbEbEbEbEbEbEbEbEbEbEbEbEbEbEbEbEbEbEbDaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabvbvbvbvbvbvbvbvbvbvbvbvbvbvbvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaaabababababababababababababababababababababababababaa
aabDbDbDbDbDbDbDbDbDbDbDbDbDbDbDbDbDbDbDbDbDbDbDbDbDaaaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
"}
+
diff --git a/sound/items/cardshuffle.ogg b/sound/items/cardshuffle.ogg
new file mode 100644
index 0000000000..1fe763af5b
Binary files /dev/null and b/sound/items/cardshuffle.ogg differ
diff --git a/sound/misc/clapping.ogg b/sound/misc/clapping.ogg
new file mode 100644
index 0000000000..4ecdc2aa22
Binary files /dev/null and b/sound/misc/clapping.ogg differ
diff --git a/sound/misc/longwhistle.ogg b/sound/misc/longwhistle.ogg
new file mode 100644
index 0000000000..0a2e822515
Binary files /dev/null and b/sound/misc/longwhistle.ogg differ
diff --git a/sound/misc/shortwhistle.ogg b/sound/misc/shortwhistle.ogg
new file mode 100644
index 0000000000..82ef01af3d
Binary files /dev/null and b/sound/misc/shortwhistle.ogg differ
]