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:

" + 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