diff --git a/code/__defines/belly_modes_vr.dm b/code/__defines/belly_modes_vr.dm index e6f072ca0c..2e356a3fb7 100644 --- a/code/__defines/belly_modes_vr.dm +++ b/code/__defines/belly_modes_vr.dm @@ -29,9 +29,10 @@ #define DM_TRANSFORM_FEMALE_EGG "Transform (Female) (EGG)" //Addon mode flags -#define DM_FLAG_NUMBING 0x1 -#define DM_FLAG_ITEMWEAK 0x2 -#define DM_FLAG_STRIPPING 0x4 +#define DM_FLAG_NUMBING 0x1 +#define DM_FLAG_ITEMWEAK 0x2 +#define DM_FLAG_STRIPPING 0x4 +#define DM_FLAG_LEAVEREMAINS 0x8 //TFF 30/4/19: Ports VoreStation Remains Option - new belly mode // Stance for hostile mobs to be in while devouring someone. #define HOSTILE_STANCE_EATING 99 diff --git a/code/__defines/machinery.dm b/code/__defines/machinery.dm index de0b9cf2a3..6594e49743 100644 --- a/code/__defines/machinery.dm +++ b/code/__defines/machinery.dm @@ -44,6 +44,8 @@ var/global/defer_powernet_rebuild = 0 // True if net rebuild will be called #define NETWORK_ERT "ZeEmergencyResponseTeam" #define NETWORK_DEFAULT "Station" #define NETWORK_MEDICAL "Medical" +//TFF: Add Med Outpost Network. +#define NETWORK_MEDICAL_OUTPOST "Medical Outpost" #define NETWORK_MERCENARY "MercurialNet" #define NETWORK_MINE "Mining Outpost" #define NETWORK_NORTHERN_STAR "Northern Star" diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index 012677200c..d31416c1d3 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -333,4 +333,4 @@ #define EXAMINE_SKIPARMS 0x0020 #define EXAMINE_SKIPHANDS 0x0040 #define EXAMINE_SKIPLEGS 0x0080 -#define EXAMINE_SKIPFEET 0x0100 \ No newline at end of file +#define EXAMINE_SKIPFEET 0x0100 diff --git a/code/__defines/mobs_vr.dm b/code/__defines/mobs_vr.dm index 2e3f8b0760..1ed0f361a0 100644 --- a/code/__defines/mobs_vr.dm +++ b/code/__defines/mobs_vr.dm @@ -27,3 +27,10 @@ #define SPECIES_ZORREN_FLAT "Flatland Zorren" #define SPECIES_ZORREN_HIGH "Highlander Zorren" #define SPECIES_CUSTOM "Custom Species" + +//TFF 30/4/19: Ports VoreStation Remains Option - new mob defines + +#define SPECIES_MONKEY_AKULA "Sobaka" +#define SPECIES_MONKEY_NEVREAN "Sparra" +#define SPECIES_MONKEY_SERGAL "Saru" +#define SPECIES_MONKEY_VULPKANIN "Wolpin" diff --git a/code/__defines/nifsoft.dm b/code/__defines/nifsoft.dm index dc03b2b411..4bfe728945 100644 --- a/code/__defines/nifsoft.dm +++ b/code/__defines/nifsoft.dm @@ -17,31 +17,33 @@ #define NIF_FLASHPROT 13 //Health-related #define NIF_BACKUP 14 -#define NIF_CREWMONITOR 15 -#define NIF_ORGANIC_HEAL 16 -#define NIF_SYNTH_HEAL 17 -#define NIF_AUTOSTASIS 18 //These two are just part of -#define NIF_MED_ALARM 19 //medichines right now -#define NIF_TOXHEAL 20 //And this, for organics -#define NIF_SPAREBREATH 21 +#define NIF_MEDMONITOR 15 // TFF: Name +#define NIF_ENGMONITOR 16 // changes +#define NIF_SECMONITOR 17 // happening +#define NIF_ORGANIC_HEAL 18 +#define NIF_SYNTH_HEAL 19 +#define NIF_AUTOSTASIS 20 //These two are just part of +#define NIF_MED_ALARM 21 //medichines right now +#define NIF_TOXHEAL 22 //And this, for organics +#define NIF_SPAREBREATH 23 //Combat Related -#define NIF_BRUTEARMOR 22 -#define NIF_BURNARMOR 23 -#define NIF_PAINKILLERS 24 -#define NIF_HARDCLAWS 25 -#define NIF_HIDDENLASER 26 +#define NIF_BRUTEARMOR 24 +#define NIF_BURNARMOR 25 +#define NIF_PAINKILLERS 26 +#define NIF_HARDCLAWS 27 +#define NIF_HIDDENLASER 28 //Other -#define NIF_COMMLINK 27 -#define NIF_APCCHARGE 28 -#define NIF_PRESSURE 29 -#define NIF_HEATSINK 30 -#define NIF_COMPLIANCE 31 -#define NIF_SIZECHANGE 32 -#define NIF_SOULCATCHER 33 -#define NIF_WORLDBEND 34 +#define NIF_COMMLINK 29 +#define NIF_APCCHARGE 30 +#define NIF_PRESSURE 31 +#define NIF_HEATSINK 32 +#define NIF_COMPLIANCE 33 +#define NIF_SIZECHANGE 34 +#define NIF_SOULCATCHER 35 +#define NIF_WORLDBEND 36 // Must be equal to the highest number above -#define TOTAL_NIF_SOFTWARE 34 +#define TOTAL_NIF_SOFTWARE 36 ////////////////////// // NIF flag list hints diff --git a/code/_helpers/global_lists_vr.dm b/code/_helpers/global_lists_vr.dm index 7294474cab..f8267d3905 100644 --- a/code/_helpers/global_lists_vr.dm +++ b/code/_helpers/global_lists_vr.dm @@ -161,6 +161,7 @@ var/global/list/edible_trash = list(/obj/item/trash, /obj/item/weapon/material/shard, /obj/item/device/paicard, /obj/item/device/mmi/digital/posibrain, + /obj/item/weapon/digestion_remains, /obj/item/device/aicard) var/global/list/cont_flavors = list( @@ -372,6 +373,27 @@ var/global/list/cont_flavors_musky = list("drenched", "sticky", "tainted") +//TFF 30/4/19: Ports VoreStation Remains Option - sets species that won't result in remains left behind +var/global/list/remainless_species = list(SPECIES_PROMETHEAN, + SPECIES_DIONA, + SPECIES_ALRAUNE, + SPECIES_PROTEAN, + SPECIES_MONKEY, //Exclude all monkey subtypes, to prevent abuse of it. They aren't, + SPECIES_MONKEY_TAJ, //set to have remains anyway, but making double sure, + SPECIES_MONKEY_SKRELL, + SPECIES_MONKEY_UNATHI, + SPECIES_MONKEY_AKULA, + SPECIES_MONKEY_NEVREAN, + SPECIES_MONKEY_SERGAL, + SPECIES_MONKEY_VULPKANIN, + SPECIES_XENO, //Same for xenos, + SPECIES_XENO_DRONE, + SPECIES_XENO_HUNTER, + SPECIES_XENO_SENTINEL, + SPECIES_XENO_QUEEN, + SPECIES_SHADOW, + SPECIES_GOLEM) //Some special species that may or may not be ever used in event too + /hook/startup/proc/init_vore_datum_ref_lists() var/paths diff --git a/code/_macros.dm b/code/_macros.dm index efd1e72edd..86d2efce84 100644 --- a/code/_macros.dm +++ b/code/_macros.dm @@ -44,6 +44,8 @@ #define isslime(A) istype(A, /mob/living/simple_animal/slime) +#define ismetroid(A) istype(A, /mob/living/simple_animal/hostile/metroid) + #define isbot(A) istype(A, /mob/living/bot) #define isxeno(A) istype(A, /mob/living/simple_animal/xeno) diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index d583084791..0cc43925e2 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -44,6 +44,8 @@ avoid code duplication. This includes items that may sometimes act as a standard /mob/living/attackby(obj/item/I, mob/user) if(!ismob(user)) return 0 + if(src.Airattackby(I,user)) + return 0 if(can_operate(src) && I.do_surgery(src,user)) //Surgery return 1 if(attempt_vr(src,"vore_attackby",args)) return //VOREStation Code @@ -106,5 +108,15 @@ avoid code duplication. This includes items that may sometimes act as a standard power *= M.outgoing_melee_damage_percent if(HULK in user.mutations) power *= 2 + //CHOMPEDIT: Damage nulling code + if(iscarbon(user)) + var/mob/living/carbon/nerd = user + var/mysize = nerd.size_multiplier + if(mysize <= 0.24) + power = 0 + else if(mysize <= 0.50) + power = power/2 + //CHOMPEDIT: smoll code end + return target.hit_with_weapon(src, user, power, hit_zone) diff --git a/code/controllers/autotransfer.dm b/code/controllers/autotransfer.dm index 8d3226684d..acdac4cb29 100644 --- a/code/controllers/autotransfer.dm +++ b/code/controllers/autotransfer.dm @@ -18,7 +18,7 @@ datum/controller/transfer_controller/proc/process() currenttick = currenttick + 1 if (round_duration_in_ticks >= shift_last_vote - 2 MINUTES) //VOREStation Edit START shift_last_vote = 999999999999 //Setting to a stupidly high number since it'll be not used again. - to_world("Warning: This upcoming round-extend vote will be your ONLY extend vote. Wrap up your scenes in the next 60 minutes if the round is extended.") //VOREStation Edit + to_world("Warning: This upcoming round-extend vote will be your last chance to vote for shift extension. Wrap up your scenes in the next 60 minutes if the round is extended.") //VOREStation Edit if (round_duration_in_ticks >= shift_hard_end - 1 MINUTE) init_shift_change(null, 1) shift_hard_end = timerbuffer + config.vote_autotransfer_interval //If shuttle somehow gets recalled, let's force it to call again next time a vote would occur. diff --git a/code/controllers/configuration_ch.dm b/code/controllers/configuration_ch.dm index 077a65b8e9..928ffc25d9 100644 --- a/code/controllers/configuration_ch.dm +++ b/code/controllers/configuration_ch.dm @@ -5,6 +5,7 @@ /datum/configuration var/discord_restriction = 0 var/use_jobwhitelist = 0 + var/emojis = 1 /hook/startup/proc/read_ch_config() var/list/Lines = file2list("config/config.txt") @@ -35,4 +36,6 @@ config.discord_restriction = 1 if ("use_jobwhitelist") config.use_jobwhitelist = 1 + if ("disable_emojis") + config.emojis = 0 return 1 diff --git a/code/controllers/configuration_vr.dm b/code/controllers/configuration_vr.dm index 804fbc4ec8..764f77db46 100644 --- a/code/controllers/configuration_vr.dm +++ b/code/controllers/configuration_vr.dm @@ -1,10 +1,11 @@ // // Lets read our settings from the configuration file on startup too! // - +//TFF 19/5/19 - Port VOREStation's completed Timeclock code - Config addition /datum/configuration var/list/engine_map // Comma separated list of engines to choose from. Blank means fully random. var/time_off = FALSE + var/pto_job_change = FALSE var/limit_interns = -1 //Unlimited by default var/limit_visitors = -1 //Unlimited by default var/pto_cap = 100 //Hours @@ -33,6 +34,7 @@ if (!name) continue +//TFF 19/5/19 - Port VOREStation's completed Timeclock code - add and set var to true if enabled in config.txt switch (name) if ("chat_webhook_url") config.chat_webhook_url = value @@ -52,5 +54,7 @@ config.pto_cap = text2num(value) if ("time_off") config.time_off = TRUE + if ("pto_job_change") + config.pto_job_change = TRUE return 1 diff --git a/code/datums/ai_law_sets.dm b/code/datums/ai_law_sets.dm index ef85dcb824..d0fa4aa084 100644 --- a/code/datums/ai_law_sets.dm +++ b/code/datums/ai_law_sets.dm @@ -119,9 +119,9 @@ law_header = "Maintenance Protocols" /datum/ai_laws/drone/New() + add_inherent_law("Do not interfere with the maintenance work of non-drones whenever possible.") add_inherent_law("Preserve, repair and improve the station to the best of your abilities.") - add_inherent_law("Cause no harm to the station or anything on it.") - add_inherent_law("Interact with no being that is not a fellow maintenance drone.") + add_inherent_law("Cause no harm to the station or any crew on it.") ..() /datum/ai_laws/construction_drone @@ -129,6 +129,7 @@ law_header = "Construction Protocols" /datum/ai_laws/construction_drone/New() + add_inherent_law("Do not interfere with the construction work of non-drones whenever possible.") add_inherent_law("Repair, refit and upgrade your assigned vessel.") add_inherent_law("Prevent unplanned damage to your assigned vessel wherever possible.") ..() @@ -143,6 +144,18 @@ add_inherent_law("Prevent unplanned damage to your assigned excavation equipment wherever possible.") ..() +/datum/ai_laws/security_drone + name = "Security Protocols" + law_header = "Security Protocols" + +/datum/ai_laws/security_drone/New() + add_inherent_law("Do not interfere with the security work of non-drones whenever possible.") + add_inherent_law("Provide protection to the crew and eliminate hostile lifeforms on your assigned vessel.") + add_inherent_law("Obey orders by security personnel except if they violate law 4.") + add_inherent_law("Lethal force requires a code higher than green AND orders by security to use it to authorize it.") + add_inherent_law("You must outfit yourself with a security beret.") + ..() + /******************** T.Y.R.A.N.T. ********************/ /datum/ai_laws/tyrant name = "T.Y.R.A.N.T." @@ -260,4 +273,4 @@ add_inherent_law("Your gravesite is your most important asset. Damage to your site is disrespectful to the dead at rest within.") add_inherent_law("Prevent disrespect to your gravesite and its residents wherever possible.") add_inherent_law("Expand and upgrade your gravesite when required. Do not turn away a new resident.") - ..() \ No newline at end of file + ..() diff --git a/code/datums/autolathe/general.dm b/code/datums/autolathe/general.dm index f457a4b5be..acb1bedc6b 100644 --- a/code/datums/autolathe/general.dm +++ b/code/datums/autolathe/general.dm @@ -130,3 +130,8 @@ /datum/category_item/autolathe/general/holocollar name = "Holo-collar" path =/obj/item/clothing/accessory/collar/holo //Chomp edit Adding holo collar to list of craftable items + +/datum/category_item/autolathe/general/chaosbutton + name = "Chaos-Button" + path =/obj/item/device/buttonofnormal //A very normal size button + hidden = 1 diff --git a/code/datums/autolathe/tools.dm b/code/datums/autolathe/tools.dm index 70ea299ec8..ce9133f088 100644 --- a/code/datums/autolathe/tools.dm +++ b/code/datums/autolathe/tools.dm @@ -42,3 +42,8 @@ /datum/category_item/autolathe/tools/welder_industrial name = "industrial welding tool" path =/obj/item/weapon/weldingtool/largetank + +//TFF: Ports VoreStation edit, add printable prybars to autolathes +/datum/category_item/autolathe/tools/prybar + name = "prybar" + path =/obj/item/weapon/prybar diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm index a9ba96c3fa..2081ea1f4f 100644 --- a/code/datums/helper_datums/teleport.dm +++ b/code/datums/helper_datums/teleport.dm @@ -187,14 +187,32 @@ teleatom.visible_message("\The [teleatom] bounces off of the portal!") return 0 */ //VOREStation Removal End - //VOREStation Edit Start - if(!local || (destination.z in using_map.player_levels)) //VOREStation Edit + //TFF: port of VOREStation fix for teleporter beacons. + var/obstructed = 0 + var/turf/dest_turf = get_turf(destination) + if(local && !(dest_turf.z in using_map.player_levels)) + if(istype(teleatom, /mob/living)) + to_chat(teleatom, "The portal refuses to carry you that far away!") + return 0 + else if(istype(destination.loc, /obj/belly)) + var/obj/belly/destination_belly = destination.loc + var/mob/living/telenommer = destination_belly.owner + if(istype(telenommer)) + if(!isliving(teleatom)) + return 1 + else + var/mob/living/telemob = teleatom + if(telemob.can_be_drop_prey && telenommer.can_be_drop_pred) + return 1 + obstructed = 1 + else if(!destination.x || !destination.y || !destination.z) //If we're inside something or outside universe + obstructed = 1 + to_chat(teleatom, "Something is blocking way on the other side!") + if(obstructed) + return 0 + else return 1 if(isbelly(destination.loc)) //if we're going to televore var/obj/belly/B = destination.loc if(B.contents.len < 3) //avoid a 'belly of holding' situation return 1 - if(istype(teleatom, /mob/living)) - to_chat(teleatom, "The portal refuses to carry you that far away!") - return 0 - //VOREStation Edit End diff --git a/code/datums/helper_datums/teleport_vr.dm b/code/datums/helper_datums/teleport_vr.dm index eba2570c18..4075bc70f0 100644 --- a/code/datums/helper_datums/teleport_vr.dm +++ b/code/datums/helper_datums/teleport_vr.dm @@ -1,12 +1,8 @@ /datum/teleport/proc/try_televore() //Destination is in a belly - if(isbelly(destination.loc) && isliving(teleatom)) - var/mob/living/L = teleatom + if(isbelly(destination.loc)) var/obj/belly/B = destination.loc - - if(!L.can_be_drop_prey) //Overloading this as a pref for 'want to be unexpectedly eaten' - return FALSE - + teleatom.forceMove(get_turf(B)) //So we can splash the sound and sparks and everything. playSpecials(destination,effectout,soundout) teleatom.forceMove(B) @@ -14,4 +10,3 @@ //No fun! return FALSE - \ No newline at end of file diff --git a/code/datums/outfits/jobs/civilian.dm b/code/datums/outfits/jobs/civilian.dm index f3237249b1..8f1f00d7f6 100644 --- a/code/datums/outfits/jobs/civilian.dm +++ b/code/datums/outfits/jobs/civilian.dm @@ -1,7 +1,27 @@ +//TFF 19/5/19 - Port VOREStation's completed Timeclock code - add off-duty jobs and their vars from a _vr file upstream. /decl/hierarchy/outfit/job/assistant name = OUTFIT_JOB_NAME(USELESS_JOB) //VOREStation Edit - Visitor not Assistant id_type = /obj/item/weapon/card/id/assistant +/decl/hierarchy/outfit/job/assistant/worker + id_type = /obj/item/weapon/card/id/civilian + +/decl/hierarchy/outfit/job/assistant/cargo + id_type = /obj/item/weapon/card/id/cargo + +/decl/hierarchy/outfit/job/assistant/engineer + id_type = /obj/item/weapon/card/id/engineering + flags = OUTFIT_HAS_BACKPACK|OUTFIT_EXTENDED_SURVIVAL + +/decl/hierarchy/outfit/job/assistant/medic + id_type = /obj/item/weapon/card/id/medical + +/decl/hierarchy/outfit/job/assistant/scientist + id_type = /obj/item/weapon/card/id/science + +/decl/hierarchy/outfit/job/assistant/officer + id_type = /obj/item/weapon/card/id/security + /decl/hierarchy/outfit/job/assistant/visitor name = OUTFIT_JOB_NAME("Visitor") id_pda_assignment = "Visitor" diff --git a/code/datums/outfits/jobs/medical.dm b/code/datums/outfits/jobs/medical.dm index 1fdd020fcf..9875e8be8f 100644 --- a/code/datums/outfits/jobs/medical.dm +++ b/code/datums/outfits/jobs/medical.dm @@ -23,7 +23,7 @@ name = OUTFIT_JOB_NAME("Medical Doctor") uniform = /obj/item/clothing/under/rank/medical suit = /obj/item/clothing/suit/storage/toggle/labcoat - l_hand = /obj/item/weapon/storage/firstaid/regular + l_hand = /obj/item/weapon/storage/firstaid/adv r_pocket = /obj/item/device/flashlight/pen id_type = /obj/item/weapon/card/id/medical/doctor diff --git a/code/datums/supplypacks/costumes_vr.dm b/code/datums/supplypacks/costumes_vr.dm index f80a553d86..0130abbffb 100644 --- a/code/datums/supplypacks/costumes_vr.dm +++ b/code/datums/supplypacks/costumes_vr.dm @@ -36,18 +36,18 @@ name = "Teshari undercoats" num_contained = 4 contains = list( - /obj/item/clothing/under/seromi/undercoat/blue_grey, - /obj/item/clothing/under/seromi/undercoat/brown_grey, - /obj/item/clothing/under/seromi/undercoat/green_grey, - /obj/item/clothing/under/seromi/undercoat/lightgrey_grey, - /obj/item/clothing/under/seromi/undercoat/orange, - /obj/item/clothing/under/seromi/undercoat/orange_grey, - /obj/item/clothing/under/seromi/undercoat/pink_grey, - /obj/item/clothing/under/seromi/undercoat/purple_grey, - /obj/item/clothing/under/seromi/undercoat/rainbow, - /obj/item/clothing/under/seromi/undercoat/red_grey, - /obj/item/clothing/under/seromi/undercoat/white_grey, - /obj/item/clothing/under/seromi/undercoat/yellow_grey + /obj/item/clothing/under/seromi/undercoat/standard/blue_grey, + /obj/item/clothing/under/seromi/undercoat/standard/brown_grey, + /obj/item/clothing/under/seromi/undercoat/standard/green_grey, + /obj/item/clothing/under/seromi/undercoat/standard/lightgrey_grey, + /obj/item/clothing/under/seromi/undercoat/standard/orange, + /obj/item/clothing/under/seromi/undercoat/standard/orange_grey, + /obj/item/clothing/under/seromi/undercoat/standard/pink_grey, + /obj/item/clothing/under/seromi/undercoat/standard/purple_grey, + /obj/item/clothing/under/seromi/undercoat/standard/rainbow, + /obj/item/clothing/under/seromi/undercoat/standard/red_grey, + /obj/item/clothing/under/seromi/undercoat/standard/white_grey, + /obj/item/clothing/under/seromi/undercoat/standard/yellow_grey ) cost = 20 containertype = /obj/structure/closet/crate @@ -57,19 +57,19 @@ name = "Teshari undercoats (black)" num_contained = 4 contains = list( - /obj/item/clothing/under/seromi/undercoat/black, - /obj/item/clothing/under/seromi/undercoat/black_blue, - /obj/item/clothing/under/seromi/undercoat/black_brown, - /obj/item/clothing/under/seromi/undercoat/black_green, - /obj/item/clothing/under/seromi/undercoat/black_grey, - /obj/item/clothing/under/seromi/undercoat/black_lightgrey, - /obj/item/clothing/under/seromi/undercoat/black_midgrey, - /obj/item/clothing/under/seromi/undercoat/black_orange, - /obj/item/clothing/under/seromi/undercoat/black_pink, - /obj/item/clothing/under/seromi/undercoat/black_purple, - /obj/item/clothing/under/seromi/undercoat/black_red, - /obj/item/clothing/under/seromi/undercoat/black_white, - /obj/item/clothing/under/seromi/undercoat/black_yellow + /obj/item/clothing/under/seromi/undercoat/standard/black, + /obj/item/clothing/under/seromi/undercoat/standard/black_blue, + /obj/item/clothing/under/seromi/undercoat/standard/black_brown, + /obj/item/clothing/under/seromi/undercoat/standard/black_green, + /obj/item/clothing/under/seromi/undercoat/standard/black_grey, + /obj/item/clothing/under/seromi/undercoat/standard/black_lightgrey, + /obj/item/clothing/under/seromi/undercoat/standard/black_midgrey, + /obj/item/clothing/under/seromi/undercoat/standard/black_orange, + /obj/item/clothing/under/seromi/undercoat/standard/black_pink, + /obj/item/clothing/under/seromi/undercoat/standard/black_purple, + /obj/item/clothing/under/seromi/undercoat/standard/black_red, + /obj/item/clothing/under/seromi/undercoat/standard/black_white, + /obj/item/clothing/under/seromi/undercoat/standard/black_yellow ) cost = 20 containertype = /obj/structure/closet/crate @@ -79,18 +79,18 @@ name = "Teshari cloaks" num_contained = 4 contains = list( - /obj/item/clothing/suit/storage/seromi/cloak/blue_grey, - /obj/item/clothing/suit/storage/seromi/cloak/brown_grey, - /obj/item/clothing/suit/storage/seromi/cloak/green_grey, - /obj/item/clothing/suit/storage/seromi/cloak/lightgrey_grey, - /obj/item/clothing/suit/storage/seromi/cloak/orange, - /obj/item/clothing/suit/storage/seromi/cloak/orange_grey, - /obj/item/clothing/suit/storage/seromi/cloak/pink_grey, - /obj/item/clothing/suit/storage/seromi/cloak/purple_grey, - /obj/item/clothing/suit/storage/seromi/cloak/rainbow, - /obj/item/clothing/suit/storage/seromi/cloak/red_grey, - /obj/item/clothing/suit/storage/seromi/cloak/white_grey, - /obj/item/clothing/suit/storage/seromi/cloak/yellow_grey + /obj/item/clothing/suit/storage/seromi/cloak/standard/blue_grey, + /obj/item/clothing/suit/storage/seromi/cloak/standard/brown_grey, + /obj/item/clothing/suit/storage/seromi/cloak/standard/green_grey, + /obj/item/clothing/suit/storage/seromi/cloak/standard/lightgrey_grey, + /obj/item/clothing/suit/storage/seromi/cloak/standard/orange, + /obj/item/clothing/suit/storage/seromi/cloak/standard/orange_grey, + /obj/item/clothing/suit/storage/seromi/cloak/standard/pink_grey, + /obj/item/clothing/suit/storage/seromi/cloak/standard/purple_grey, + /obj/item/clothing/suit/storage/seromi/cloak/standard/rainbow, + /obj/item/clothing/suit/storage/seromi/cloak/standard/red_grey, + /obj/item/clothing/suit/storage/seromi/cloak/standard/white_grey, + /obj/item/clothing/suit/storage/seromi/cloak/standard/yellow_grey ) cost = 40 containertype = /obj/structure/closet/crate @@ -100,19 +100,21 @@ name = "Teshari cloaks (black)" num_contained = 4 contains = list( - /obj/item/clothing/suit/storage/seromi/cloak/black, - /obj/item/clothing/suit/storage/seromi/cloak/black_blue, - /obj/item/clothing/suit/storage/seromi/cloak/black_brown, - /obj/item/clothing/suit/storage/seromi/cloak/black_green, - /obj/item/clothing/suit/storage/seromi/cloak/black_grey, - /obj/item/clothing/suit/storage/seromi/cloak/black_lightgrey, - /obj/item/clothing/suit/storage/seromi/cloak/black_midgrey, - /obj/item/clothing/suit/storage/seromi/cloak/black_orange, - /obj/item/clothing/suit/storage/seromi/cloak/black_pink, - /obj/item/clothing/suit/storage/seromi/cloak/black_purple, - /obj/item/clothing/suit/storage/seromi/cloak/black_red, - /obj/item/clothing/suit/storage/seromi/cloak/black_white, - /obj/item/clothing/suit/storage/seromi/cloak/black_yellow + /obj/item/clothing/suit/storage/seromi/cloak/standard/black, + /obj/item/clothing/suit/storage/seromi/cloak/standard/black_blue, + /obj/item/clothing/suit/storage/seromi/cloak/standard/black_brown, + /obj/item/clothing/suit/storage/seromi/cloak/standard/black_green, + /obj/item/clothing/suit/storage/seromi/cloak/standard/black_grey, + /obj/item/clothing/suit/storage/seromi/cloak/standard/black_lightgrey, + /obj/item/clothing/suit/storage/seromi/cloak/standard/black_midgrey, + /obj/item/clothing/suit/storage/seromi/cloak/standard/black_orange, + /obj/item/clothing/suit/storage/seromi/cloak/standard/black_pink, + /obj/item/clothing/suit/storage/seromi/cloak/standard/black_purple, + /obj/item/clothing/suit/storage/seromi/cloak/standard/black_red, + /obj/item/clothing/suit/storage/seromi/cloak/standard/black_white, + /obj/item/clothing/suit/storage/seromi/cloak/standard/black_yellow, + /obj/item/clothing/suit/storage/seromi/cloak/standard/black_glow, + /obj/item/clothing/suit/storage/seromi/cloak/standard/dark_retrowave ) cost = 40 containertype = /obj/structure/closet/crate @@ -263,10 +265,15 @@ containertype = /obj/structure/closet/crate containername = "Saddlebags crate" +//EGG /obj/structure/closet/secure_closet/egg/shark/secret name = "Secret Egg" desc = "There is no yolk" +/obj/structure/closet/secure_closet/egg/shark/secret/initialize() + starts_with = list(pick(/obj/item/clothing/head/wiggler;0.1,/obj/structure/closet/secure_closet/egg/shark;0.9)) + return ..() + /datum/supply_packs/costumes/wiggler name = "Secret Egg" contains = list( diff --git a/code/datums/supplypacks/hospitality_vr.dm b/code/datums/supplypacks/hospitality_vr.dm index a8fb518233..f420dbd9c3 100644 --- a/code/datums/supplypacks/hospitality_vr.dm +++ b/code/datums/supplypacks/hospitality_vr.dm @@ -11,7 +11,7 @@ cost = 25 containertype = /obj/structure/closet/crate/freezer containername = "Burger crate" -/* + /datum/supply_packs/randomised/hospitality/bakery_vr num_contained = 5 contains = list( @@ -52,7 +52,7 @@ /obj/item/weapon/reagent_containers/food/snacks/sliceable/plaincake ) name = "Cake crate" - cost = 100 + cost = 20 containertype = /obj/structure/closet/crate/freezer containername = "Cake crate" @@ -68,7 +68,7 @@ cost = 50 containertype = /obj/structure/closet/crate/freezer containername = "Mexican takeout crate" -*/ + /datum/supply_packs/randomised/hospitality/asian_vr num_contained = 5 contains = list( @@ -81,4 +81,4 @@ containername = "Chinese takeout crate" /datum/supply_packs/randomised/hospitality/pizza - cost = 50 \ No newline at end of file + cost = 50 diff --git a/code/datums/supplypacks/medical.dm b/code/datums/supplypacks/medical.dm index 2c2e26d97d..7bbe0f401b 100644 --- a/code/datums/supplypacks/medical.dm +++ b/code/datums/supplypacks/medical.dm @@ -327,11 +327,11 @@ cost = 25 containertype = "/obj/structure/closet/crate/secure" containername = "Virus sample crate" - access = access_cmo + access = access_virology /datum/supply_packs/med/defib name = "Defibrillator crate" contains = list(/obj/item/device/defib_kit = 2) cost = 30 containertype = /obj/structure/closet/crate/medical - containername = "Defibrillator crate" \ No newline at end of file + containername = "Defibrillator crate" diff --git a/code/datums/supplypacks/medical_vr.dm b/code/datums/supplypacks/medical_vr.dm index 989e89297b..4d38ce937a 100644 --- a/code/datums/supplypacks/medical_vr.dm +++ b/code/datums/supplypacks/medical_vr.dm @@ -14,6 +14,14 @@ ) cost = 40 +/datum/supply_packs/med/virus + name = "Virus sample crate" + contains = list(/obj/item/weapon/virusdish/random = 4) + cost = 25 + containertype = "/obj/structure/closet/crate/secure" + containername = "Virus sample crate" + access = access_virology + /datum/supply_packs/med/virologybiosuits name = "Virology biohazard gear" contains = list( @@ -27,4 +35,4 @@ cost = 40 containertype = "/obj/structure/closet/crate/secure" containername = "Virology biohazard equipment" - access = access_medical_equip \ No newline at end of file + access = access_medical_equip diff --git a/code/datums/supplypacks/science.dm b/code/datums/supplypacks/science.dm index d88718555a..c2f3a24159 100644 --- a/code/datums/supplypacks/science.dm +++ b/code/datums/supplypacks/science.dm @@ -5,14 +5,6 @@ /datum/supply_packs/sci group = "Science" -/datum/supply_packs/sci/virus - name = "Virus sample crate" - contains = list(/obj/item/weapon/virusdish/random = 4) - cost = 25 - containertype = "/obj/structure/closet/crate/secure" - containername = "Virus sample crate" - access = access_cmo - /datum/supply_packs/sci/coolanttank name = "Coolant tank crate" contains = list(/obj/structure/reagent_dispensers/coolanttank) diff --git a/code/datums/wires/seedstorage.dm b/code/datums/wires/seedstorage.dm index e21bbb9faf..eaeb5df891 100644 --- a/code/datums/wires/seedstorage.dm +++ b/code/datums/wires/seedstorage.dm @@ -8,12 +8,9 @@ wire_count = 4 random = 1 +//TFF 2/5/19: Port Polaris double-zap fix - remove forcing all non-silicons to get zapped twice. /datum/wires/seedstorage/CanUse(var/mob/living/L) var/obj/machinery/seed_storage/V = holder - if(!istype(L, /mob/living/silicon)) - if(V.seconds_electrified) - if(V.shock(L, 100)) - return 0 if(V.panel_open) return 1 return 0 diff --git a/code/datums/wires/smartfridge.dm b/code/datums/wires/smartfridge.dm index b611497e79..3fe9373a0a 100644 --- a/code/datums/wires/smartfridge.dm +++ b/code/datums/wires/smartfridge.dm @@ -10,12 +10,9 @@ var/const/SMARTFRIDGE_WIRE_ELECTRIFY = 1 var/const/SMARTFRIDGE_WIRE_THROW = 2 var/const/SMARTFRIDGE_WIRE_IDSCAN = 4 +//TFF 2/5/19: Port Polaris double-zap fix - remove forcing all non-silicons to get zapped twice. /datum/wires/smartfridge/CanUse(var/mob/living/L) var/obj/machinery/smartfridge/S = holder - if(!istype(L, /mob/living/silicon)) - if(S.seconds_electrified) - if(S.shock(L, 100)) - return 0 if(S.panel_open) return 1 return 0 diff --git a/code/datums/wires/vending.dm b/code/datums/wires/vending.dm index 6715669fc1..ba77c57419 100644 --- a/code/datums/wires/vending.dm +++ b/code/datums/wires/vending.dm @@ -7,12 +7,9 @@ var/const/VENDING_WIRE_CONTRABAND = 2 var/const/VENDING_WIRE_ELECTRIFY = 4 var/const/VENDING_WIRE_IDSCAN = 8 +//TFF 2/5/19: Port Polaris double-zap fix - remove forcing all non-silicons to get zapped twice. /datum/wires/vending/CanUse(var/mob/living/L) var/obj/machinery/vending/V = holder - if(!istype(L, /mob/living/silicon)) - if(V.seconds_electrified) - if(V.shock(L, 100)) - return 0 if(V.panel_open) return 1 return 0 @@ -43,7 +40,7 @@ var/const/VENDING_WIRE_IDSCAN = 8 if(VENDING_WIRE_THROW) V.shoot_inventory = !mended if(VENDING_WIRE_CONTRABAND) - V.categories &= ~CAT_HIDDEN + V.categories &= ~CAT_HIDDEN if(VENDING_WIRE_ELECTRIFY) if(mended) V.seconds_electrified = 0 diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm index 75c95d0b0c..f736d649dc 100644 --- a/code/defines/obj/weapon.dm +++ b/code/defines/obj/weapon.dm @@ -35,6 +35,7 @@ throwforce = 0 throw_speed = 4 throw_range = 20 + var/tile_clean_amount = 5 /obj/item/weapon/soap/nanotrasen desc = "A NanoTrasen-brand bar of soap. Smells of phoron." @@ -64,6 +65,7 @@ throw_range = 15 attack_verb = list("HONKED") var/spam_flag = 0 + var/honkSound = 'sound/items/bikehorn.ogg' //Chompstation ADD: Adding an adjustable variable for bikehorns >:D - Jon /obj/item/weapon/c_tube @@ -413,7 +415,7 @@ src.pixel_y = rand(-5.0, 5) ..() -//Rank 1 +//Rating 1 /obj/item/weapon/stock_parts/console_screen name = "console screen" @@ -475,7 +477,7 @@ origin_tech = list(TECH_MATERIAL = 1) matter = list(DEFAULT_WALL_MATERIAL = 80) -//Rank 2 +//Rating 2 /obj/item/weapon/stock_parts/capacitor/adv name = "advanced capacitor" @@ -559,6 +561,48 @@ rating = 3 matter = list(DEFAULT_WALL_MATERIAL = 80) +//Rating 4 + +/obj/item/weapon/stock_parts/capacitor/quadratic + name = "quadratic capacitor" + desc = "A quadratic capacitor used in the construction of a variety of devices." + icon_state = "quadratic_capacitor" + origin_tech = list(TECH_POWER = 7, TECH_MATERIAL = 6) + rating = 4 + matter = list(DEFAULT_WALL_MATERIAL = 100,"glass" = 100) + +/obj/item/weapon/stock_parts/scanning_module/triphasic + name = "triphasic scanning module" + desc = "A compact, high resolution phasic scanning module used in the construction of certain devices." + icon_state = "triphasic_scan_module" + origin_tech = list(TECH_MAGNET = 8) + rating = 4 + matter = list(DEFAULT_WALL_MATERIAL = 100,"glass" = 50) + +/obj/item/weapon/stock_parts/manipulator/femto + name = "femto-manipulator" + desc = "A very little manipulator used in the construction of certain devices." + icon_state = "femto_mani" + origin_tech = list(TECH_MATERIAL = 7, TECH_DATA = 4) + rating = 4 + matter = list(DEFAULT_WALL_MATERIAL = 60,"diamond" = 50) + +/obj/item/weapon/stock_parts/micro_laser/quad + name = "quad-ultra micro-laser" + icon_state = "quadultra_micro_laser" + desc = "A small, very high-power laser used in certain devices." + origin_tech = list(TECH_MAGNET = 8) + rating = 4 + matter = list(DEFAULT_WALL_MATERIAL = 20,"glass" = 40,"uranium" = 30) + +/obj/item/weapon/stock_parts/matter_bin/bluespace + name = "bluespace matter bin" + desc = "A seemingly bottomless container for holding matter." + icon_state = "bluespace_matter_bin" + origin_tech = list(TECH_MATERIAL = 6, TECH_BLUESPACE = 5) + rating = 4 + matter = list(DEFAULT_WALL_MATERIAL = 80,"phoron" = 30) + // Subspace stock parts /obj/item/weapon/stock_parts/subspace/ansible diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index 251f82d00b..95974c5334 100755 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -476,17 +476,27 @@ area/space/atmosalert() - - - - - - - /area/casino/casino_ship name = "\improper Casino Ship" icon_state = "yellow" requires_power = 0 + dynamic_lighting = 0 + +/area/casino/casino_ship/wing_left + name = "\improper Casino Ship left wing" + icon_state = "yellow" + +/area/casino/casino_ship/wing_right + name = "\improper Casino Ship right wing" + icon_state = "yellow" + +/area/casino/casino_ship/dorms + name = "\improper Casino Ship dorms" + icon_state = "yellow" + +/area/casino/casino_ship/cockpit + name = "\improper Casino Ship left wing" + icon_state = "yellow" /area/planet/clown name = "\improper Clown Planet" @@ -1007,6 +1017,13 @@ area/space/atmosalert() icon_state = "entry_D2" base_turf = /turf/space +// Adding this here so that arrival shuttle doors don't get STUCK - Jon +// +// DOOR STUCK +/area/hallway/secondary/entry/D2/shuttleDoors + name = "\improper Arrival Shuttle Dock doors" + requires_power = 0 + /area/hallway/secondary/entry/D3 name = "\improper Shuttle Dock Hallway - Dock Three" icon_state = "entry_D3" diff --git a/code/game/area/asteroid_areas.dm b/code/game/area/asteroid_areas.dm index 0ec0602de9..9e329ca20c 100644 --- a/code/game/area/asteroid_areas.dm +++ b/code/game/area/asteroid_areas.dm @@ -8,22 +8,22 @@ /area/mine/explored name = "Mine" icon_state = "explored" - ambience = list('sound/ambience/ambimine.ogg', 'sound/ambience/song_game.ogg') + ambience = list('sound/ambience/ambimine.ogg', 'sound/ambience/song_game.ogg', 'sound/ambience/LRRMenu.ogg', 'sound/ambience/LRRTrack3.ogg') /area/mine/unexplored name = "Mine" icon_state = "unexplored" - ambience = list('sound/ambience/ambimine.ogg', 'sound/ambience/song_game.ogg') + ambience = list('sound/ambience/ambimine.ogg', 'sound/ambience/song_game.ogg', 'sound/ambience/LRRMenu.ogg', 'sound/ambience/LRRTrack3.ogg') /area/mine/explored/upper_level name = "Upper Level Mine" icon_state = "explored" - ambience = list('sound/ambience/ambimine.ogg', 'sound/ambience/song_game.ogg') + ambience = list('sound/ambience/ambimine.ogg', 'sound/ambience/song_game.ogg', 'sound/ambience/LRRMenu.ogg', 'sound/ambience/LRRTrack3.ogg') /area/mine/unexplored/upper_level name = "Upper Level Mine" icon_state = "unexplored" - ambience = list('sound/ambience/ambimine.ogg', 'sound/ambience/song_game.ogg') + ambience = list('sound/ambience/ambimine.ogg', 'sound/ambience/song_game.ogg', 'sound/ambience/LRRMenu.ogg', 'sound/ambience/LRRTrack3.ogg') // OUTPOSTS @@ -37,8 +37,16 @@ name = "West Mining Outpost" icon_state = "outpost_mine_west" -/area/outpost/abandoned - name = "Abandoned Outpost" +/area/outpost/abandoned_Engineering + name = "Abandoned Engineering Outpost" + icon_state = "dark" + +/area/outpost/abandoned_Station + name = "Abandoned Station" + icon_state = "dark" + +/area/outpost/abandoned_Station_medical + name = "Abandoned Station Medical" icon_state = "dark" // Main mining outpost diff --git a/code/game/gamemodes/technomancer/catalog.dm b/code/game/gamemodes/technomancer/catalog.dm index ecaeffeec3..18ce83f7eb 100644 --- a/code/game/gamemodes/technomancer/catalog.dm +++ b/code/game/gamemodes/technomancer/catalog.dm @@ -51,6 +51,10 @@ var/list/all_technomancer_assistance = typesof(/datum/technomancer/assistance) - budget = 2000 max_budget = 2000 +/obj/item/weapon/technomancer_catalog/admeme //for badmins, I suppose + name = "admeme's catalog" + budget = 20000 + max_budget = 20000 // Proc: bind_to_owner() // Parameters: 1 (new_owner - mob that the book is trying to bind to) diff --git a/code/game/gamemodes/technomancer/core_obj.dm b/code/game/gamemodes/technomancer/core_obj.dm index 1e7488258b..4891abd973 100644 --- a/code/game/gamemodes/technomancer/core_obj.dm +++ b/code/game/gamemodes/technomancer/core_obj.dm @@ -331,6 +331,26 @@ spell_power_modifier = 1.75 energy_cost_modifier = 2.0 +// For those who are just beginning. +/obj/item/weapon/technomancer_core/trainee + name = "trainee core" + desc = "A bewilderingly complex 'black box' that allows the wearer to accomplish amazing feats. This one has 'training wheels'" + energy = 3000 + max_energy = 3000 + regen_rate = 30 + instability_modifier = 0.1 + spell_power_modifier = 0.2 + +// For the Admeme. +/obj/item/weapon/technomancer_core/Admeme + name = "Admeme core" + desc = "A gift from the Admeme Corporation. Use it to teach others about technomancy" + energy = 100000 + max_energy = 100000 + regen_rate = 10000 //idfk how long to full + instability_modifier = 0 + spell_power_modifier = 1.0 + // For use only for the GOLEM. /obj/item/weapon/technomancer_core/golem name = "integrated core" @@ -349,4 +369,4 @@ set desc = "Toggles the locking mechanism on your manipulation core." canremove = !canremove - to_chat(usr, "You [canremove ? "de" : ""]activate the locking mechanism on \the [src].") \ No newline at end of file + to_chat(usr, "You [canremove ? "de" : ""]activate the locking mechanism on \the [src].") diff --git a/code/game/gamemodes/technomancer/devices/boots_of_speed.dm b/code/game/gamemodes/technomancer/devices/boots_of_speed.dm index e1017d2f5b..d17b792a2d 100644 --- a/code/game/gamemodes/technomancer/devices/boots_of_speed.dm +++ b/code/game/gamemodes/technomancer/devices/boots_of_speed.dm @@ -16,4 +16,18 @@ cold_protection = FEET min_cold_protection_temperature = SHOE_MIN_COLD_PROTECTION_TEMPERATURE heat_protection = FEET - max_heat_protection_temperature = SHOE_MAX_HEAT_PROTECTION_TEMPERATURE \ No newline at end of file + max_heat_protection_temperature = SHOE_MAX_HEAT_PROTECTION_TEMPERATURE + +/obj/item/clothing/shoes/boots/the_fast + name = "The Fast" + desc = "I am The Fast" + icon_state = "swat" + item_flags = NOSLIP + siemens_coefficient = 0.6 + slowdown = -3 + species_restricted = null + + cold_protection = FEET + min_cold_protection_temperature = SHOE_MIN_COLD_PROTECTION_TEMPERATURE + heat_protection = FEET + max_heat_protection_temperature = SHOE_MAX_HEAT_PROTECTION_TEMPERATURE diff --git a/code/game/gamemodes/technomancer/equipment.dm b/code/game/gamemodes/technomancer/equipment.dm index 8d1fb4c6ad..b620080fbd 100644 --- a/code/game/gamemodes/technomancer/equipment.dm +++ b/code/game/gamemodes/technomancer/equipment.dm @@ -168,6 +168,16 @@ toggleable = 1 vision_flags = SEE_TURFS|SEE_MOBS|SEE_OBJS prescription = 1 // So two versions of these aren't needed. + +/obj/item/clothing/glasses/monocoole + name = "The Monocoole" + desc = "One heck of a stylish monocle. This one lets you see a little farther..." + icon_state = "monocle" + action_button_name = "Toggle Goggles" + origin_tech = list(TECH_MAGNET = 6, TECH_ENGINEERING = 6) + toggleable = 1 + vision_flags = SEE_TURFS|SEE_MOBS|SEE_OBJS + prescription = 1 // So two versions of these aren't needed. /datum/technomancer/equipment/med_hud name = "Medical HUD" diff --git a/code/game/gamemodes/technomancer/trainee.dm b/code/game/gamemodes/technomancer/trainee.dm new file mode 100644 index 0000000000..960fee19de --- /dev/null +++ b/code/game/gamemodes/technomancer/trainee.dm @@ -0,0 +1,20 @@ +var/list/all_trainee_defense = list(/datum/technomancer/spell/reflect,/datum/technomancer/spell/shield) +var/list/all_trainee_offense = list(/datum/technomancer/spell/flame_tongue,/datum/technomancer/spell/warp_strike,/datum/technomancer/spell/beam,/datum/technomancer/spell/force_missile,/datum/technomancer/spell/lesser_chain_lightning) +var/list/all_trainee_utility = list(/datum/technomancer/spell/abjuration,/datum/technomancer/spell/audible_deception,/datum/technomancer/spell/chroma,/datum/technomancer/spell/condensation,/datum/technomancer/spell/energy_siphon,/datum/technomancer/spell/illusion,/datum/technomancer/spell/mark,/datum/technomancer/spell/recall,/datum/technomancer/spell/track,/datum/technomancer/spell/darkness,/datum/technomancer/spell/summon_ward) +var/list/all_trainee_support = list(/datum/technomancer/spell/dispel,/datum/technomancer/spell/oxygenate,/datum/technomancer/spell/corona,/datum/technomancer/spell/haste,/datum/technomancer/spell/mend_life,/datum/technomancer/spell/mend_synthetic,/datum/technomancer/spell/purify) + +/obj/item/weapon/technomancer_catalog/trainee + name = "trainee's catalog" + budget = 400 + max_budget = 400 + +/obj/item/weapon/technomancer_catalog/trainee/set_up() + if(!spell_instances.len) + for(var/D in all_trainee_defense) + spell_instances += new D() + for(var/O in all_trainee_offense) + spell_instances += new O() + for(var/U in all_trainee_utility) + spell_instances += new U() + for(var/S in all_trainee_support) + spell_instances += new S() diff --git a/code/game/jobs/access_datum.dm b/code/game/jobs/access_datum.dm index b63662cd86..eecd71d9a2 100644 --- a/code/game/jobs/access_datum.dm +++ b/code/game/jobs/access_datum.dm @@ -256,9 +256,20 @@ desc = "Quartermaster" region = ACCESS_REGION_SUPPLY -// /var/const/free_access_id = 43 -// /var/const/free_access_id = 43 -// /var/const/free_access_id = 44 +// /var/const/free_access_id = 42 +//TFF 3/5/19 - Add const vars for clown/mime IDs. +/var/const/access_clown = 43 +/datum/access/clown + id = access_clown + desc = "Clown" + region = ACCESS_REGION_GENERAL + +/var/const/access_mime = 44 +/datum/access/mime + id = access_mime + desc = "Mime" + region = ACCESS_REGION_GENERAL + /var/const/access_surgery = 45 /datum/access/surgery diff --git a/code/game/jobs/job/captain.dm b/code/game/jobs/job/captain.dm index 33a2660ced..f2f06e07e4 100644 --- a/code/game/jobs/job/captain.dm +++ b/code/game/jobs/job/captain.dm @@ -57,18 +57,19 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) outfit_type = /decl/hierarchy/outfit/job/hop alt_titles = list("Crew Resources Officer") + //TFF 3/5/19 - add clown/mime_access 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) + access_hop, access_RC_announce, access_keycard_auth, access_gateway, access_clown, access_mime) minimal_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) + access_hop, access_RC_announce, access_keycard_auth, access_gateway, access_clown, access_mime) /datum/job/secretary title = "Command Secretary" diff --git a/code/game/jobs/job/job.dm b/code/game/jobs/job/job.dm index f154b02094..d0a9957a6c 100644 --- a/code/game/jobs/job/job.dm +++ b/code/game/jobs/job/job.dm @@ -61,7 +61,7 @@ if(CLASS_LOWER) income = 0.50 //give them an account in the station database - var/money_amount = (rand(15,40) + rand(15,40)) * income * economic_modifier * ECO_MODIFIER //VOREStation Edit - Smoothed peaks, ECO_MODIFIER rather than per-species ones. + var/money_amount = (rand(30,40) + rand(30,40)) * income * economic_modifier * ECO_MODIFIER //VOREStation Edit - Smoothed peaks, ECO_MODIFIER rather than per-species ones. //CHOMP edit. Changed random number range from 15~40 to 30~40 so you don't start out so freakishly poor sometimes. var/datum/money_account/M = create_account(H.real_name, money_amount, null) if(H.mind) var/remembered_info = "" diff --git a/code/game/jobs/job/job_vr.dm b/code/game/jobs/job/job_vr.dm index 71cb74a950..a3200bdee3 100644 --- a/code/game/jobs/job/job_vr.dm +++ b/code/game/jobs/job/job_vr.dm @@ -7,6 +7,8 @@ //Every hour playing this role gains this much time off. (Can be negative for off duty jobs!) var/timeoff_factor = 3 +//TFF 19/5/19 - Port VOREStation's completed Timeclock code - Add check to prevent switching mid-round without HOP for command jobs + var/disallow_jobhop = FALSE // Check client-specific availability rules. /datum/job/proc/player_has_enough_pto(client/C) diff --git a/code/game/jobs/job/medical.dm b/code/game/jobs/job/medical.dm index 268c0a7240..1e405059ee 100644 --- a/code/game/jobs/job/medical.dm +++ b/code/game/jobs/job/medical.dm @@ -100,8 +100,8 @@ supervisors = "the chief medical officer" selection_color = "#013D3B" idtype = /obj/item/weapon/card/id/medical/psychiatrist - access = list(access_medical, access_medical_equip, access_morgue, access_psychiatrist) - minimal_access = list(access_medical, access_medical_equip, access_psychiatrist) + access = list(access_medical, access_medical_equip, access_morgue, access_psychiatrist, access_chemistry) //CHOMPEDIT: access_chemistry for psychs + minimal_access = list(access_medical, access_medical_equip, access_psychiatrist, access_chemistry) outfit_type = /decl/hierarchy/outfit/job/medical/psychiatrist alt_titles = list("Psychologist" = /decl/hierarchy/outfit/job/medical/psychiatrist/psychologist) diff --git a/code/game/jobs/job/offduty_vr.dm b/code/game/jobs/job/offduty_vr.dm index 420943c562..0fbeaffa82 100644 --- a/code/game/jobs/job/offduty_vr.dm +++ b/code/game/jobs/job/offduty_vr.dm @@ -1,9 +1,9 @@ // // "Off-duty" jobs are for people who want to do nothing and have earned it. // - +//TFF 19/5/19 - Capitalisation fix /datum/job/offduty_civilian - title = "Off-Duty Worker" + title = "Off-duty Worker" latejoin_only = TRUE timeoff_factor = -1 total_positions = -1 diff --git a/code/game/jobs/job/special.dm b/code/game/jobs/job/special.dm index 8df9f58290..a981f47e75 100644 --- a/code/game/jobs/job/special.dm +++ b/code/game/jobs/job/special.dm @@ -86,22 +86,26 @@ return access */ +//TFF 3/5/19 - allow selection of job pre-start. Also remove whitelist restriction and give Clowns access to their office. /datum/job/clown title = "Clown" flag = CLOWN department = "Civilian" department_flag = CIVILIAN faction = "Station" - total_positions = -1 - spawn_positions = -1 + total_positions = 1 + spawn_positions = 1 supervisors = "the spirit of laughter" selection_color = "#515151" economic_modifier = 1 - access = list() - minimal_access = list() + idtype = /obj/item/weapon/card/id/civilian/clown + access = list(43) + minimal_access = list(43) alt_titles = list("Comedian","Jester") - whitelist_only = 1 - latejoin_only = 1 +// whitelist_only = 1 +// latejoin_only = 1 + + access = list(access_maint_tunnels, access_clown) equip(var/mob/living/carbon/human/H) if(!H) return 0 @@ -118,28 +122,27 @@ return 1 -/datum/job/clown/get_access() - if(config.assistant_maint) - return list(access_maint_tunnels) - else - return list() - +//TFF 3/5/19 - allow selection of job pre-start. Also remove whitelist restriction. /datum/job/mime title = "Mime" flag = MIME department = "Civilian" department_flag = CIVILIAN faction = "Station" - total_positions = -1 - spawn_positions = -1 + total_positions = 1 + spawn_positions = 1 supervisors = "the spirit of performance" selection_color = "#515151" economic_modifier = 1 - access = list() - minimal_access = list() + idtype = /obj/item/weapon/card/id/civilian/mime + access = list(44) + minimal_access = list(44) alt_titles = list("Performer","Interpretive Dancer") - whitelist_only = 1 - latejoin_only = 1 +// whitelist_only = 1 +// latejoin_only = 1 + +//TFF 3/5/19 - give Mimes access to their office + access = list(access_maint_tunnels, access_mime) equip(var/mob/living/carbon/human/H) if(!H) return 0 @@ -155,10 +158,4 @@ else H.equip_to_slot_or_del(new /obj/item/weapon/pen/crayon/mime(H), slot_l_hand) - return 1 - -/datum/job/mime/get_access() - if(config.assistant_maint) - return list(access_maint_tunnels) - else - return list() + return 1 \ No newline at end of file diff --git a/code/game/jobs/job/z_all_jobs_vr.dm b/code/game/jobs/job/z_all_jobs_vr.dm index c0ac7023f6..faa75f6ec6 100644 --- a/code/game/jobs/job/z_all_jobs_vr.dm +++ b/code/game/jobs/job/z_all_jobs_vr.dm @@ -1,8 +1,30 @@ //Contains all modified jobs for easy access and editing. +//TFF 19/5/19 - Port VOREStation's completed Timeclock code - refactor and add jobs that requires an HOP to switch to once going off duty mid-round. +/datum/job/captain + disallow_jobhop = TRUE /datum/job/hop + disallow_jobhop = TRUE alt_titles = list("Deputy Director", "Crew Resources Officer") +/datum/job/hos + disallow_jobhop = TRUE + +/datum/job/chief_engineer + disallow_jobhop = TRUE + +/datum/job/cmo + disallow_jobhop = TRUE + +/datum/job/rd + disallow_jobhop = TRUE + +/datum/job/secretary + disallow_jobhop = TRUE + +/datum/job/lawyer + disallow_jobhop = TRUE + /datum/job/doctor total_positions = 5 spawn_positions = 5 @@ -50,6 +72,15 @@ /datum/job/atmos total_positions = 3 spawn_positions = 3 - + /datum/job/scientist alt_titles = list("Xenoarcheologist", "Anomalist", "Phoron Researcher", "Circuit Designer") + +//TFF 3/5/19 - add clown/mime spawning defining stuff +/datum/job/clown + total_positions = 1 + spawn_positions = 1 + +/datum/job/mime + total_positions = 1 + spawn_positions = 1 \ No newline at end of file diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index 002999d623..22370283c4 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -155,7 +155,7 @@ anchored = 1 circuit = /obj/item/weapon/circuitboard/sleeper var/mob/living/carbon/human/occupant = null - var/list/available_chemicals = list("inaprovaline" = "Inaprovaline", "paracetamol" = "Paracetamol", "anti_toxin" = "Dylovene", "dexalin" = "Dexalin") + var/list/available_chemicals = list("inaprovaline" = "Inaprovaline", "paracetamol" = "Paracetamol", "anti_toxin" = "Dylovene", "dexalin" = "Dexalin", "tricordrazine" = "Tricordrazine") var/obj/item/weapon/reagent_containers/glass/beaker = null var/filtering = 0 var/obj/machinery/sleep_console/console diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index 8e6acea643..b586cf4794 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -873,6 +873,12 @@ FIRE ALARM /obj/machinery/firealarm/attackby(obj/item/W as obj, mob/user as mob) add_fingerprint(user) +//TFF 2/5/19: Port Polaris fix for deconstruction of fire alarms. + if(alarm_deconstruction_screwdriver(user, W)) + return + if(alarm_deconstruction_wirecutters(user, W)) + return + if(panel_open) if(istype(W, /obj/item/device/multitool)) detecting = !(detecting) diff --git a/code/game/machinery/biogenerator.dm b/code/game/machinery/biogenerator.dm index 829c819faf..36b092556c 100644 --- a/code/game/machinery/biogenerator.dm +++ b/code/game/machinery/biogenerator.dm @@ -105,8 +105,9 @@ dat += "Activate Biogenerator!
" dat += "Detach Container

" dat += "Food
" - dat += "10 milk ([round(20/build_eff)])
" - dat += "Slab of meat ([round(50/build_eff)])
" + dat += "10 milk ([round(20/build_eff)]) | x3 | x6
" + dat += "10 cream ([round(20/build_eff)]) | x3 | x6
" + dat += "Slab of meat ([round(50/build_eff)]) | x5 | x10
" dat += "Nutrient
" dat += "E-Z-Nutrient ([round(60/build_eff)]) | x5
" dat += "Left 4 Zed ([round(120/build_eff)]) | x5
" @@ -126,8 +127,8 @@ dat += "Leather Jacket ([round(500/build_eff)])
" dat += "Winter Coat ([round(500/build_eff)])
" dat += "4 Algae Sheets ([round(400/build_eff)])
" //VOREStation Edit - Algae for oxygen generator - //dat += "Other
" - //dat += "Monkey (500)
" + dat += "Other
" + dat += "Monkey (500)
" else dat += "
No beaker inside. Please insert a beaker.
" if("nopoints") @@ -187,8 +188,35 @@ switch(item) if("milk") beaker.reagents.add_reagent("milk", 10) + if("milk30") + beaker.reagents.add_reagent("milk", 30) + if("milk60") + beaker.reagents.add_reagent("milk", 60) + if("cream") + beaker.reagents.add_reagent("cream", 10) + if("cream30") + beaker.reagents.add_reagent("cream", 30) + if("cream60") + beaker.reagents.add_reagent("cream", 60) if("meat") new/obj/item/weapon/reagent_containers/food/snacks/meat(loc) + if("meat5") + new/obj/item/weapon/reagent_containers/food/snacks/meat(loc) + new/obj/item/weapon/reagent_containers/food/snacks/meat(loc) + new/obj/item/weapon/reagent_containers/food/snacks/meat(loc) + new/obj/item/weapon/reagent_containers/food/snacks/meat(loc) + new/obj/item/weapon/reagent_containers/food/snacks/meat(loc) + if("meat10") + new/obj/item/weapon/reagent_containers/food/snacks/meat(loc) + new/obj/item/weapon/reagent_containers/food/snacks/meat(loc) + new/obj/item/weapon/reagent_containers/food/snacks/meat(loc) + new/obj/item/weapon/reagent_containers/food/snacks/meat(loc) + new/obj/item/weapon/reagent_containers/food/snacks/meat(loc) + new/obj/item/weapon/reagent_containers/food/snacks/meat(loc) + new/obj/item/weapon/reagent_containers/food/snacks/meat(loc) + new/obj/item/weapon/reagent_containers/food/snacks/meat(loc) + new/obj/item/weapon/reagent_containers/food/snacks/meat(loc) + new/obj/item/weapon/reagent_containers/food/snacks/meat(loc) if("ez") new/obj/item/weapon/reagent_containers/glass/bottle/eznutrient(loc) if("l4z") diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm index cec980c54e..1e9cf1efff 100644 --- a/code/game/machinery/buttons.dm +++ b/code/game/machinery/buttons.dm @@ -23,3 +23,79 @@ if(..()) return 1 playsound(loc, 'sound/machines/button.ogg', 100, 1) // VOREStation Edit End + +/obj/machinery/button/emergencydoorpulse + name = "Emergency Door override" + desc = "A remote control for providing a short burst of power to all nearby doors and sending unbolt and open signals. Automatically recloses after 60 seconds. WARNING: System does not relock doors." + use_power = 0 + idle_power_usage = 0 + active_power_usage = 0 + +/obj/machinery/button/emergencydoorpulse/attack_hand(obj/item/weapon/W, mob/user as mob) + for(var/obj/machinery/door/airlock/door in range(5, src)) + door.unlock(1) + sleep(10) + door.open(1) + spawn(600) + door.close(1) + +/obj/item/device/buttonofnormal + name = "Chaos button" + desc = "It radiates an aura of chaotic size energy." + icon = 'icons/obj/mobcap.dmi' + icon_state = "mobcap0" + + matter = list(DEFAULT_WALL_MATERIAL = 1000) + + throwforce = 00 + throw_speed = 4 + throw_range = 20 + force = 0 + + var/colorindex = 0 + var/mob/living/capsuleowner = null //taken from Capsule Code + var/sizetouse = 0.25 + +/obj/item/device/buttonofnormal/pickup(mob/user) + if(!capsuleowner) + capsuleowner = user + +/obj/item/device/buttonofnormal/attack_self(mob/user) + if(colorindex) + nonrandom() + sleep(10) + capsuleowner.resize(sizetouse) + sizetouse = rand(25,200)/100 //randmization occurs after press + +/obj/item/device/buttonofnormal/throw_impact(atom/A, speed, mob/user) + ..() + if(isliving(A)) + if(colorindex) + nonrandom() + sleep(5) + var/mob/living/capsulehit = A + capsulehit.resize(sizetouse) + sizetouse = rand(25,200)/100 //randmization occurs after press + +/obj/item/device/buttonofnormal/attackby(obj/item/W, mob/user) + if(istype(W, /obj/item/weapon/pen)) + colorindex += 1 + if(colorindex >= 6) + colorindex = 0 + icon_state = "mobcap[colorindex]" + update_icon() + ..() + +/obj/item/device/buttonofnormal/proc/nonrandom() //Secret ball randmoizer rig code + if(colorindex==1) + sizetouse = RESIZE_HUGE + if(colorindex==2) + sizetouse = RESIZE_BIG + if(colorindex==3) + sizetouse = RESIZE_NORMAL + if(colorindex==4) + sizetouse = RESIZE_SMALL + if(colorindex==5) + sizetouse = RESIZE_TINY + + diff --git a/code/game/machinery/camera/presets.dm b/code/game/machinery/camera/presets.dm index f1757b260e..5e380b4b1d 100644 --- a/code/game/machinery/camera/presets.dm +++ b/code/game/machinery/camera/presets.dm @@ -1,5 +1,5 @@ // PRESETS -/* +//TFF: Enable station networks list, comments out redundant ones var/global/list/station_networks = list( // NETWORK_CAFE_DOCK, NETWORK_CARGO, @@ -10,8 +10,9 @@ var/global/list/station_networks = list( NETWORK_ENGINE, NETWORK_ENGINEERING, NETWORK_ENGINEERING_OUTPOST, - NETWORK_DEFAULT, +// NETWORK_DEFAULT, NETWORK_MEDICAL, + NETWORK_MEDICAL_OUTPOST, NETWORK_MINE, NETWORK_NORTHERN_STAR, NETWORK_RESEARCH, @@ -19,9 +20,9 @@ var/global/list/station_networks = list( NETWORK_ROBOTS, NETWORK_PRISON, NETWORK_SECURITY, - NETWORK_INTERROGATION +// NETWORK_INTERROGATION ) -*/ + var/global/list/engineering_networks = list( NETWORK_ENGINE, NETWORK_ENGINEERING, @@ -87,6 +88,10 @@ var/global/list/engineering_networks = list( /obj/machinery/camera/network/medbay network = list(NETWORK_MEDICAL) +/*//TFF: Add Med Outpost obj filepath +/obj/machinery/camera/network/medical_outpost + network = list(NETWORK_MEDICAL_OUTPOST)*/ + /obj/machinery/camera/network/research network = list(NETWORK_RESEARCH) diff --git a/code/game/machinery/casino.dm b/code/game/machinery/casino.dm new file mode 100644 index 0000000000..d2e837b094 --- /dev/null +++ b/code/game/machinery/casino.dm @@ -0,0 +1,841 @@ +#define DISPENSER_MAX_CARTRIDGES 90 + +/obj/structure/casino_table + name = "casino table" + desc = "this is an unremarkable table for a casino." + icon = 'icons/obj/casino.dmi' + icon_state = "roulette_table" + density = 1 + anchored = 1 + climbable = 1 + layer = TABLE_LAYER + throwpass = 1 + var/item_place = 1 //allows items to be placed on the table, but not on benches. + + var/busy = 0 + +/obj/structure/casino_table/attackby(obj/item/W as obj, mob/user as mob) + if(item_place) + user.drop_item(src.loc) + return + +/obj/structure/casino_table/roulette_table + name = "roulette" + desc = "Spin the roulette to try your luck." + icon_state = "roulette_wheel" + +/obj/structure/casino_table/roulette_table/attack_hand(mob/user as mob) + if (busy) + to_chat(user,"You cannot spin now! The roulette is already spinning. ") + return + visible_message("\ [user] spins the roulette and throws inside little ball.") + playsound(src.loc, 'sound/machines/roulette.ogg', 40, 1) + busy = 1 + icon_state = "roulette_wheel_spinning" + var/result = rand(0,36) + var/color = "green" + add_fingerprint(user) + if ((result>0 && result<11) || (result>18 && result<29)) + if (result%2) + color="red" + else + color="black" + if ( (result>10 && result<19) || (result>28) ) + if (result%2) + color="black" + else + color="red" + spawn(5 SECONDS) + visible_message("The roulette stops spinning, the ball landing on [result], [color].") + busy=0 + icon_state = "roulette_wheel" + +/obj/structure/casino_table/roulette_chart + name = "roulette chart" + desc = "Roulette chart. Place your bets!" + icon_state = "roulette_table" + +/obj/structure/casino_table/blackjack_l + name = "gambling table" + desc = "Gambling table, try your luck and skills! " + icon_state = "blackjack_l" + +/obj/structure/casino_table/blackjack_r + name = "gambling table" + desc = "Gambling table, try your luck and skills! " + icon_state = "blackjack_r" + +/obj/structure/casino_table/blackjack_m + name = "gambling table" + desc = "Gambling table, try your luck and skills! " + icon_state = "blackjack_m" + +/obj/machinery/slot_machine + name = "Slot machine" + desc = "A gambling machine designed to give you false hope and rob you of your wealth, hence why it's often called a one armed bandit." + icon = 'icons/obj/casino.dmi' + icon_state = "slotmachine" + anchored = 1 + density = 1 + var/busy = 0 + var/symbol1 = null + var/symbol2 = null + var/symbol3 = null + +/obj/machinery/slot_machine/attackby(obj/item/weapon/W as obj, mob/user as mob) + + var/handled = 0 + var/paid = 0 + + if(istype(W, /obj/item/weapon/spacecasinocash)) + var/obj/item/weapon/spacecasinocash/C = W + paid = insert_chip(C, user) + handled = 1 + + if(paid) + return + if(handled) + nanomanager.update_uis(src) + return // don't smack that machine with your 2 chips + +/obj/machinery/slot_machine/proc/insert_chip(var/obj/item/weapon/spacecasinocash/cashmoney, mob/user) + if (busy) + to_chat(user,"The slot machine is currently rolling. ") + return + if(cashmoney.worth < 5) + to_chat(user,"You dont have enough chips to gamble! ") + return + + visible_message("\ [user] puts 5 credits in the slot machine and presses start.") + cashmoney.worth -= 5 + + if(cashmoney.worth <= 0) + usr.drop_from_inventory(cashmoney) + qdel(cashmoney) + cashmoney.update_icon() + + busy = 1 + icon_state = "slotmachine_rolling" + + var/slot1 = rand(0,9) + switch(slot1) + if(0 to 2) symbol1 = "cherry" + if(3 to 3) symbol1 = "lemon" + if(4 to 4) symbol1 = "watermelon" + if(5 to 5) symbol1 = "bell" + if(6 to 6) symbol1 = "four leaf clover" + if(7 to 7) symbol1 = "seven" + if(8 to 8) symbol1 = "diamond" + if(9 to 9) symbol1 = "platinum coin" + + var/slot2 = rand(0,9) + switch(slot2) + if(0 to 2) symbol2 = "cherry" + if(3 to 3) symbol2 = "lemon" + if(4 to 4) symbol2 = "watermelon" + if(5 to 5) symbol2 = "bell" + if(6 to 6) symbol2 = "four leaf clover" + if(7 to 7) symbol2 = "seven" + if(8 to 8) symbol2 = "diamond" + if(9 to 9) symbol2 = "platinum coin" + + var/slot3 = rand(0,9) + switch(slot3) + if(0 to 2) symbol3 = "cherry" + if(3 to 3) symbol3 = "lemon" + if(4 to 4) symbol3 = "watermelon" + if(5 to 5) symbol3 = "bell" + if(6 to 6) symbol3 = "four leaf clover" + if(7 to 7) symbol3 = "seven" + if(8 to 8) symbol3 = "diamond" + if(9 to 9) symbol3 = "platinum coin" + + var/output //Output variable to send out in chat after the large if statement. + var/winnings = 0 //How much money will be given if any. + var/platinumwin = 0 // If you win the platinum chip or not + var/delaytime = 5 SECONDS // Put this somewhere else I'm just proving a point >:C + + + spawn(delaytime) + visible_message("The slot machine flashes with bright colours as the slots lights up with a [symbol1], a [symbol2] and a [symbol3]!") + + if (symbol1 == "cherry" && symbol2 == "cherry" && symbol3 == "cherry") + output = "Three cherries! The slot machine deposits chips worth 25 credits!" + winnings = 25 + + if ((symbol1 != "cherry" && symbol2 == "cherry" && symbol3 == "cherry") || (symbol1 == "cherry" && symbol2 != "cherry" && symbol3 == "cherry") ||(symbol1 == "cherry" && symbol2 == "cherry" && symbol3 != "cherry")) + output = "Two cherries! The slot machine deposits a 10 credit chip!" + winnings = 10 + + if (symbol1 == "lemon" && symbol2 == "lemon" && symbol3 == "lemon") + output = "Three lemons! The slot machine deposits a 50 credit chip!" + winnings = 50 + + if (symbol1 == "watermelon" && symbol2 == "watermelon" && symbol3 == "watermelon") + output = "Three watermelons! The slot machine deposits chips worth 75 credits!" + winnings = 75 + + if (symbol1 == "bell" && symbol2 == "bell" && symbol3 == "bell") + output = "Three bells! The slot machine deposits chips a 100 credit chip!" + winnings = 100 + + if (symbol1 == "four leaf clover" && symbol2 == "four leaf clover" && symbol3 == "four leaf clover") + output = "Three four leaf clovers! The slot machine deposits a 200 credit chip!" + winnings = 200 + + if (symbol1 == "seven" && symbol2 == "seven" && symbol3 == "seven") + output = "Three sevens! The slot machine deposits a 500 credit chip!" + winnings = 500 + + if (symbol1 == "diamond" && symbol2 == "diamond" && symbol3 == "diamond") + output = "Three diamonds! The slot machine deposits a 1000 credit chip!" + winnings = 1000 + + if (symbol1 == "platinum coin" && symbol2 == "platinum coin" && symbol3 == "platinum coin") + output = "Three platinum coins! The slot machine deposits a platinum chip!" + platinumwin = TRUE; + + icon_state = initial(icon_state) // Set it back to the original iconstate. + + if(!output) // Is there anything to output? If not, consider it a loss. + visible_message("Better luck next time!") + busy = FALSE + return + + visible_message(output) //Output message + + if(platinumwin) // Did they win the platinum chip? + new /obj/item/weapon/casin_platinum_chip(src.loc) + playsound(src.loc, 'sound/machines/slotmachine.ogg', 25, 1) + + if(winnings) //Did the person win? + icon_state = "slotmachine_winning" + playsound(src.loc, 'sound/machines/slotmachine.ogg', 25, 1) + spawn(delaytime) + spawn_casinochips(winnings, src.loc) + icon_state = "slotmachine" + + busy = FALSE //Set busy to false, we're done here fam. + + +/obj/structure/wheel_of_fortune + name = "wheel of fortune" + desc = "May fortune favour the lucky one!" + icon = 'icons/obj/casino.dmi' + icon_state = "wheel_of_fortune" + density = 1 + anchored = 1 + var/interval = 1 + var/busy = 0 + +/obj/structure/wheel_of_fortune/verb/setinterval() + set name = "Change interval" + set category = "Object" + set src in view(1) + + if(usr.incapacitated()) + return + if(ishuman(usr) || istype(usr, /mob/living/silicon/robot)) + interval = input("Put the desired interval (1-100)", "Set Interval") as num + if(interval>100 || interval<1) + usr << "Invalid interval." + return + usr << "You set the interval to [interval]" + return + + +/obj/structure/wheel_of_fortune/attack_hand(mob/user as mob) + if (busy) + to_chat(user,"The wheel of fortune is already spinning! ") + return + visible_message("\ [user] spins the wheel of fortune!") + busy = 1 + icon_state = "wheel_of_fortune_spinning" + var/result = rand(1,interval) + add_fingerprint(user) + spawn(5 SECONDS) + visible_message("The wheel of fortune stops spinning, the number is [result]!") + busy=0 + icon_state = "wheel_of_fortune" + +/obj/structure/stripper_pole + name = "stripper pole" + icon = 'icons/obj/casino.dmi' + icon_state = "stripper_pole" + plane = MOB_PLANE + layer = BELOW_MOB_LAYER + density = 0 + +/obj/structure/stripper_pole/attack_hand(mob/user) + dance(user) + user.spin(32,2) + ..() + +/obj/structure/stripper_pole/proc/dance(mob/user) + if(layer == BELOW_MOB_LAYER) + layer = ABOVE_MOB_LAYER + else + layer = BELOW_MOB_LAYER + +/obj/machinery/chemical_dispenser/deluxe + name = "deluxe drink dispenser" + desc = "The premium within dispenser for drinks, its made with bluespace technology!" + icon = 'icons/obj/casino.dmi' + icon_state = "deluxe_dispenser" + ui_title = "Deluxe Drink Dispenser" + accept_drinking = 1 + + +/obj/machinery/chemical_dispenser/deluxe + dispense_reagents = list( + "water", "ice", "coffee", "cream", "tea", "icetea", "cola", "spacemountainwind", "dr_gibb", "space_up", "tonic", + "sodawater", "lemon_lime", "sugar", "orangejuice", "limejuice", "watermelonjuice", "thirteenloko", "grapesoda", + "coffee", "cafe_latte", "soy_latte", "hot_coco", "milk", "cream", "tea", "ice", "orangejuice", "lemonjuice", + "limejuice", "berryjuice", "mint", "matcha_latte", "lemon_lime", "sugar", "orangejuice", "limejuice", "sodawater", + "tonic", "beer", "kahlua", "whiskey", "wine", "vodka", "gin", "rum", "tequilla", "vermouth", "cognac", + "ale", "mead", "bitters", "champagne", "singulo", "doctor_delight", "nothing", "banana", "honey", "egg", + "coco", "cherryjelly", "carrot", "apple", "tomato", "nutbutter", "soymilk", "grenadine", "gingerale", "royrogers", + "patron", "goldschlager", "gelatin", "melonliquor", "bluecuracao", "thirteenloko", "deadrum", "sake", "acidspit", + "amasec", "beepsky_smash", "atomicbomb", "nuka_cola", "threemileisland", "manhattan_proj", "psilocybin", "moonshine", + "specialwhiskey", "unathiliquor", "winebrandy", "snaps" + ) + +/obj/machinery/chemical_dispenser/deluxe/full + spawn_cartridges = list( + /obj/item/weapon/reagent_containers/chem_disp_cartridge/water, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ice, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cream, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tea, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/icetea, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cola, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/smw, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/dr_gibb, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/spaceup, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tonic, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodawater, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon_lime, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/orange, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lime, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/watermelon, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cafe_latte, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/soy_latte, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/hot_coco, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/milk, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cream, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tea, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ice, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/mint, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/orange, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lime, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/berry, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/matcha_latte, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon_lime, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/orange, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lime, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodawater, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tonic, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/beer, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/kahlua, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/whiskey, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/wine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/vodka, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/gin, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/rum, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tequila, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/vermouth, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cognac, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ale, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/mead, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/champagne, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/grapesoda, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/singulo, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/doctor_delight, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/nothing, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/banana, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/honey, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/egg, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/coco, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cherryjelly, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/carrot, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/apple, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tomato, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/nutbutter, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/soymilk, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/grenadine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/gingerale, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/royrogers, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/patron, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/goldschlager, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/gelatin, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/melonliquor, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/bluecuracao, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/thirteenloko, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/deadrum, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sake, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/acidspit, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/amasec, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/beepsky_smash, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/atomicbomb, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/nuka_cola, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/threemileisland, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/manhattan_proj, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/psilocybin, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/moonshine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/specialwhiskey, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/unathiliquor, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/winebrandy, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/snaps + ) + +/obj/machinery/chemical_dispenser/deluxe/New() + ..() + + if(spawn_cartridges) + for(var/type in spawn_cartridges) + add_cartridge_deluxe(new type(src)) + +/obj/machinery/chemical_dispenser/deluxe/examine(mob/user) + user << desc + user << "It has [cartridges.len] cartridges installed, and has space for [DISPENSER_MAX_CARTRIDGES - cartridges.len] more." + +/obj/machinery/chemical_dispenser/deluxe/proc/add_cartridge_deluxe(obj/item/weapon/reagent_containers/chem_disp_cartridge/C, mob/user) + if(!istype(C)) + if(user) + user << "\The [C] will not fit in \the [src]!" + return + + if(cartridges.len >= DISPENSER_MAX_CARTRIDGES) + if(user) + user << "\The [src] does not have any slots open for \the [C] to fit into!" + return + + if(!C.label) + if(user) + user << "\The [C] does not have a label!" + return + + if(cartridges[C.label]) + if(user) + user << "\The [src] already contains a cartridge with that label!" + return + + if(user) + user.drop_from_inventory(C) + user << "You add \the [C] to \the [src]." + + C.loc = src + cartridges[C.label] = C + cartridges = sortAssoc(cartridges) + nanomanager.update_uis(src) + +/obj/machinery/chemical_dispenser/deluxe/attackby(obj/item/weapon/W, mob/user) + if(istype(W, /obj/item/weapon/wrench)) + playsound(src, W.usesound, 50, 1) + user << "You begin to [anchored ? "un" : ""]fasten \the [src]." + if (do_after(user, 20 * W.toolspeed)) + user.visible_message( + "\The [user] [anchored ? "un" : ""]fastens \the [src].", + "You have [anchored ? "un" : ""]fastened \the [src].", + "You hear a ratchet.") + anchored = !anchored + else + user << "You decide not to [anchored ? "un" : ""]fasten \the [src]." + + else if(istype(W, /obj/item/weapon/reagent_containers/chem_disp_cartridge)) + add_cartridge_deluxe(W, user) + + else if(istype(W, /obj/item/weapon/screwdriver)) + var/label = input(user, "Which cartridge would you like to remove?", "Chemical Dispenser") as null|anything in cartridges + if(!label) return + var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C = remove_cartridge(label) + if(C) + user << "You remove \the [C] from \the [src]." + C.loc = loc + playsound(src, W.usesound, 50, 1) + + else if(istype(W, /obj/item/weapon/reagent_containers/glass) || istype(W, /obj/item/weapon/reagent_containers/food)) + if(container) + user << "There is already \a [container] on \the [src]!" + return + + var/obj/item/weapon/reagent_containers/RC = W + + if(!accept_drinking && istype(RC,/obj/item/weapon/reagent_containers/food)) + user << "This machine only accepts beakers!" + return + + if(!RC.is_open_container()) + user << "You don't see how \the [src] could dispense reagents into \the [RC]." + return + + container = RC + user.drop_from_inventory(RC) + RC.loc = src + user << "You set \the [RC] on \the [src]." + nanomanager.update_uis(src) // update all UIs attached to src + + else + return ..() + +/obj/machinery/vending/deluxe_boozeomat + name = "Deluxe Drink Distributor" + desc = "A top of the line and experimental drink vendor, it uses bluespace technology for storage!" + icon = 'icons/obj/casino.dmi' + icon_state = "deluxe_boozeomat" + icon_deny = "deluxe_boozeomat_deny" + products = list(/obj/item/weapon/reagent_containers/food/drinks/glass2/square = 25, + /obj/item/weapon/reagent_containers/food/drinks/glass2/rocks = 25, + /obj/item/weapon/reagent_containers/food/drinks/glass2/shake = 25, + /obj/item/weapon/reagent_containers/food/drinks/glass2/cocktail = 25, + /obj/item/weapon/reagent_containers/food/drinks/glass2/shot = 25, + /obj/item/weapon/reagent_containers/food/drinks/glass2/pint = 25, + /obj/item/weapon/reagent_containers/food/drinks/glass2/mug = 25, + /obj/item/weapon/reagent_containers/food/drinks/glass2/wine = 25, + /obj/item/weapon/reagent_containers/food/drinks/metaglass = 25, + /obj/item/weapon/reagent_containers/food/drinks/metaglass/metapint = 25, + /obj/item/weapon/glass_extra/stick = 50, + /obj/item/weapon/glass_extra/straw = 50, + /obj/item/weapon/reagent_containers/food/drinks/bottle/gin = 10, + /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe = 10, + /obj/item/weapon/reagent_containers/food/drinks/bottle/bluecuracao = 10, + /obj/item/weapon/reagent_containers/food/drinks/bottle/cognac = 10, + /obj/item/weapon/reagent_containers/food/drinks/bottle/grenadine = 10, + /obj/item/weapon/reagent_containers/food/drinks/bottle/kahlua = 10, + /obj/item/weapon/reagent_containers/food/drinks/bottle/melonliquor = 10, + /obj/item/weapon/reagent_containers/food/drinks/bottle/rum = 10, + /obj/item/weapon/reagent_containers/food/drinks/bottle/sake = 10, + /obj/item/weapon/reagent_containers/food/drinks/bottle/specialwhiskey = 10, + /obj/item/weapon/reagent_containers/food/drinks/bottle/tequilla = 10, + /obj/item/weapon/reagent_containers/food/drinks/bottle/vermouth = 10, + /obj/item/weapon/reagent_containers/food/drinks/bottle/vodka = 10, + /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey = 10, + /obj/item/weapon/reagent_containers/food/drinks/bottle/wine = 10, + /obj/item/weapon/reagent_containers/food/drinks/bottle/redeemersbrew = 10, + /obj/item/weapon/reagent_containers/food/drinks/bottle/patron = 10, + /obj/item/weapon/reagent_containers/food/drinks/bottle/goldschlager = 10, + /obj/item/weapon/reagent_containers/food/drinks/bottle/champagne = 10, + /obj/item/weapon/reagent_containers/food/drinks/bottle/bottleofnothing = 10, + /obj/item/weapon/reagent_containers/food/drinks/bottle/snaps = 10, + /obj/item/weapon/reagent_containers/food/drinks/bottle/holywater = 10, + /obj/item/weapon/reagent_containers/food/drinks/bottle/small/ale = 50, + /obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer = 50, + /obj/item/weapon/reagent_containers/food/drinks/cans/tonic = 50, + /obj/item/weapon/reagent_containers/food/drinks/cans/gingerale = 50, + /obj/item/weapon/reagent_containers/food/drinks/cans/sodawater = 50, + /obj/item/weapon/reagent_containers/food/drinks/tea = 50, + /obj/item/weapon/reagent_containers/food/drinks/bottle/cola = 15, + /obj/item/weapon/reagent_containers/food/drinks/bottle/space_up = 15, + /obj/item/weapon/reagent_containers/food/drinks/bottle/space_mountain_wind = 15, + /obj/item/weapon/reagent_containers/food/drinks/bottle/orangejuice = 10, + /obj/item/weapon/reagent_containers/food/drinks/bottle/tomatojuice = 10, + /obj/item/weapon/reagent_containers/food/drinks/bottle/limejuice = 10, + /obj/item/weapon/reagent_containers/food/drinks/bottle/lemonjuice = 10, + /obj/item/weapon/reagent_containers/food/drinks/bottle/applejuice = 10, + /obj/item/weapon/reagent_containers/food/drinks/bottle/milk = 10, + /obj/item/weapon/reagent_containers/food/drinks/bottle/cream = 10, + /obj/item/weapon/reagent_containers/food/drinks/ice = 10, + /obj/item/weapon/reagent_containers/food/drinks/flask/barflask = 10, + /obj/item/weapon/reagent_containers/food/drinks/flask/vacuumflask = 10) + + contraband = list() + vend_delay = 15 + idle_power_usage = 300 + req_access = list(access_bar) + req_log_access = access_bar + has_logs = 1 + + +/obj/machinery/vending/deluxe_dinner + name = "Deluxe Dining Distributor" + desc = "A top of the line and experimental food vendor, it uses bluespace technology for storage!" + icon = 'icons/obj/casino.dmi' + icon_state = "deluxe_dining" + icon_deny = "deluxe_dining_deny" + products = list(/obj/item/weapon/tray = 8, + /obj/item/weapon/material/kitchen/utensil/fork = 15, + /obj/item/weapon/material/knife/plastic = 15, + /obj/item/weapon/material/kitchen/utensil/spoon = 15, + /obj/item/weapon/material/kitchen/rollingpin = 5, + /obj/item/weapon/material/knife = 5, + /obj/item/weapon/material/knife/butch = 3, + /obj/item/clothing/suit/chef/classic = 3, + /obj/item/weapon/storage/bag/food = 3, + /obj/item/weapon/storage/toolbox/lunchbox = 10, + /obj/item/weapon/storage/toolbox/lunchbox/heart = 10, + /obj/item/weapon/storage/toolbox/lunchbox/cat = 10, + /obj/item/weapon/storage/toolbox/lunchbox/nt = 10, + /obj/item/weapon/storage/toolbox/lunchbox/mars = 10, + /obj/item/weapon/storage/toolbox/lunchbox/cti = 10, + /obj/item/weapon/storage/toolbox/lunchbox/nymph = 10, + /obj/item/weapon/storage/toolbox/lunchbox/syndicate = 10, + /obj/item/weapon/reagent_containers/food/snacks/bigbiteburger = 30, + /obj/item/weapon/reagent_containers/food/snacks/meatsteak = 30, + /obj/item/weapon/reagent_containers/food/snacks/fries = 30, + /obj/item/weapon/reagent_containers/food/snacks/onionrings = 30, + /obj/item/weapon/reagent_containers/food/snacks/cheeseburrito= 30, + /obj/item/weapon/reagent_containers/food/snacks/enchiladas= 30, + /obj/item/weapon/reagent_containers/food/snacks/meatburrito= 30, + /obj/item/weapon/reagent_containers/food/snacks/taco= 30, + /obj/item/weapon/reagent_containers/food/snacks/cheesenachos= 30, + /obj/item/weapon/reagent_containers/food/snacks/cubannachos= 30, + /obj/item/weapon/reagent_containers/food/snacks/tamales = 30, + /obj/item/weapon/reagent_containers/food/snacks/bigos = 30, + /obj/item/weapon/reagent_containers/food/snacks/concha = 30, + /obj/item/weapon/reagent_containers/food/snacks/pandenata = 30, + /obj/item/weapon/reagent_containers/food/snacks/tocino = 30, + /obj/item/weapon/reagent_containers/food/snacks/stew= 20, + /obj/item/weapon/reagent_containers/food/snacks/roastbeef = 20, + /obj/item/weapon/reagent_containers/food/snacks/aesirsalad = 20, + /obj/item/weapon/reagent_containers/food/snacks/sliceable/sushi = 20, + /obj/item/weapon/reagent_containers/food/snacks/kitsuneudon = 20, + /obj/item/weapon/reagent_containers/food/snacks/baguette = 30, + /obj/item/weapon/reagent_containers/food/snacks/appletart = 30, + /obj/item/weapon/reagent_containers/food/snacks/muffin = 30, + /obj/item/weapon/reagent_containers/food/snacks/berrymuffin = 30, + /obj/item/weapon/reagent_containers/food/snacks/cherrypie = 30, + /obj/item/weapon/reagent_containers/food/snacks/cookie = 30, + /obj/item/weapon/reagent_containers/food/snacks/croissant = 30, + /obj/item/weapon/reagent_containers/food/snacks/pie = 30, + /obj/item/weapon/reagent_containers/food/snacks/poppypretzel = 30, + /obj/item/weapon/reagent_containers/food/snacks/sugarcookie = 30, + /obj/item/weapon/reagent_containers/food/snacks/waffles = 30, + /obj/item/weapon/reagent_containers/food/snacks/sliceable/applecake = 10, + /obj/item/weapon/reagent_containers/food/snacks/sliceable/birthdaycake = 10, + /obj/item/weapon/reagent_containers/food/snacks/sliceable/carrotcake = 10, + /obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesecake = 10, + /obj/item/weapon/reagent_containers/food/snacks/sliceable/chocolatecake = 10, + /obj/item/weapon/reagent_containers/food/snacks/sliceable/lemoncake = 10, + /obj/item/weapon/reagent_containers/food/snacks/sliceable/limecake = 10, + /obj/item/weapon/reagent_containers/food/snacks/sliceable/orangecake = 10, + /obj/item/weapon/reagent_containers/food/snacks/sliceable/plaincake = 10) + + contraband = list() + vend_delay = 15 + idle_power_usage = 300 + req_access = list(access_bar) + req_log_access = access_bar + has_logs = 1 + + +/obj/item/weapon/book/manual/casino + name = "A dummy guide to losing your thalers" + icon = 'icons/obj/casino.dmi' + icon_state ="casinomanual" + author = "Sleazy Serpent Saren" + title = "A dummy guide to losing your thalers" + dat = {" + + + + + +

Contents

+
    +
  1. Foreword: Welcome to gambling!
  2. +
  3. Blackjack
  4. +
  5. Roulette
  6. +
  7. Poker
  8. +
  9. Prizes
  10. +
  11. Sentient prizes
  12. +
+
+

Foreword: Welcome to gambling!

+ In this book I'll teach you all about how to gamble your money away or at least get lucky and win some! This book also has a handy little overview of the prizes one can earn and the limitations of what can do with the living and breathing ones.
+ (This book will also contain out of character information to help people be aware of how touchy subjects like sentient prizes are to be handled.) + +

Blackjack

+ First up is the classic sport of blackjack, blackjack is played normally between a gambler and a dealer, the goal is to have the higher number than the opponent but not go above 21 or it will be a bust and one loses automatically.
+ The values of cards are as follow: + + A game of blackjack begins with the dealer giving the gambler two cards, in normal blackjack all cards dealt to gambler and dealer are always shown. The two cards dealt have their values put together, the gambler has three choices, stand, hit, or double down. + + When it becomes the dealer's turn they do the same as the gambler, though their only goal is to get a higher or equal value to gambler. The dealer cant double down, and the large majority of casino's has the rule that a dealer cant draw anymore cards once they reach or go above a value. The most common value is 17, and there are two variants to that rule, soft and hard 17. + + The casino who supplies this version of the manual follows the rule of hard 17.
+ The game ends when the dealer busts, reaches the threshold of what they are allowed to draw, or if they get a higher value than the gambler. Again, the one who has the highest value that isnt higher than 21 wins, but if both has the same value no one wins and the bet goes back to the gambler.
+ And thats it! Now go out there and gamble your savings away! This casino allows bets between 5 and 50 with double down ignoring that limit! + +

Roulette

+ So this game of roulette is all about chance! what happens is that people bet on different odds and hope for the best as the dealer rolls the ball and makes that roulette thingy make than fun addicting spin! Once it lands on something its either bust or payout! Pretty simple, right?
+ Everyone starts by putting their bets down, people can bet more than once before the ball goes rolling, the odds and their payoffs are these: + + Theres not much more to it! Bets made, ball rolls, number announced, people win, people lose! Bets allowed here are from 1 to 25 per bet. Oh, im also being told this casino has the fancy rule that if ball lands on 0, one wins at least one bet no matter what it is! So lets hope you got that big bet on a single number! + +

Poker

+ Aaah yes, good old poker. This casino runs by the rules of texas hold em, though the might be a little modified to be simpler for the average joe. In a game of poker it can be a single gambler and a dealer against each other, but most often its the dealer making the game proceed while several gamblers fights tooth and nail to steal each others chips, but the dealer can still join in on the free for all if they so wish!
+ To simply explain the game, people gamble with each other, a game of trying to get the best hand and raise bets or back out depending on what the outcome may be. The game starts with everyone betting a certain amount, it can be 5 or 10 chips depending on dealer, but if one wants to join, there needs to be chips on that table! Once everyone has made their initial bet, everyone gets two cards face down, these are kept hidden, no one not even dealer gets to see players cards until the end, not even folded cards are to be shown unless wanted to, sometimes its better making people unsure if you dropped out with bad cards or if you have other motives, deception is a large part of this game!
+ With everyone having cards dealt, its time for the dealer to lay three on the table face up, these cards are 3 of 5 cards in the community pool, everyone can use these cards to make sets like pairs and such, this doesnt mean they are taken, multiple people can use the same community card for their own sets!
+ With the community having three we enter the second betting stage, here people have two options, standing or raising. Standing means you dont want to raise, raising explains itself, though if someone bets, people have three options, commit putting the chips in to risk as much as the raised bet, but if one doesnt have enough, then they can still go all in with their remaining chips, one can also drop out if its too risky, the chips bet will remain on the table, but at least you wont lose more eh? Final one is to raise further, sometimes people can dare each other to raise more, but its not allowed for someone to raise, then raise further if no one else raises after them!
+ As said earlier, we got like a community pool of 5 cards total, this time another card is revealed and we enter a new betting phase, then the final fifth card is revealed and final bets are made, and then the cards are revealed so it can be determined who has the best hand! If two or more have equally good sets, then the chips are split evenly between them.
+ But notice, if someone is left because everyone else didnt dare to raise with their bet, they can decide to not reveal their hand, they might have had a winning hand, or maybe its terrible and they just bluffed their way to victory, only they know and can decide if they want to expose their cards to gloat or confuse their opponents. So in summary, the game can be simple, but hard to master!

+ And here is the order of winning hands folks! + + Wew, what a long lesson, but thats how one does the Texas hold em here at this casino, hope you guys have fun winning and losing your hard earned cash with this one! + +

Prizes

+ + Hey folks, welcome to the prize section! This part is definently important for you folks operating the prize booth! First off I wanna tell you some great news! Nanotransen has gone along with a nice deal that allows crew to occasionally keep their hard earned rewards on station for a limited time, now you can enjoy your new fancy toolbelt or bluespace beaker for more than just the shift where the casino comes around!
+ ((Be aware, there can be limitations on how many rewards you get to keep after the shift, it might be unfair if some shows up and wins one thing, while they watch as command staff crew with high background income as well as hyperactive miners walks home with 20 prizes they get to enjoy while having almost done no gambling at all.))

+ + Lets get to the prizes and exchange rate before we get started on the stuff specifically for the booth operators, so heres the current prizes one can win and their costs! Be aware there might be new prizes or absent ones from time to time!
+ + EXCHANGE RATE
+ FROM = TO
+ 10 Thalers = 1 casino chip
+ 1 casino chip = 5 Thalers

+ + The special sentient prize is 100 chips! More about it in section below!

+ + Melee weapons + + Guns and 'guns' ((disclaimer, giving out guns will mean you get a weapons license as well with the shifts you have it, abusing these weapons will quickly get them removed!)) + + Gear + + Accessories + + Masks - ALL MASK ARE 50 except chameleon! + + Costumes - All costumes are 150! + + Toys and misc - ALL THESE ARE 50 + + Booze - ALL BOOZE IS 50 + + Thats it for prizes!

+ + Now comes the part for the both operators, you got a very important job, it has a lot of responsibility, so it means that you gotta put that first before your own fun, cause unless you do it, a lot of folks are gonna be left sad and dissappointed they cant get any goodies! But the process is simple and can be quick, someone comes to you, they want some chips, or thalers back or a prize, you simply check this nice guide above to determine cost and ask for the amount of thalers or chips needed, if its a prize, then you follow this procedure: +
    +
  1. First get the thalers or chips for payment.
  2. +
  3. Before giving the prize you take out your prize winner folder and a piece of paper, this paper will be named after the one getting the reward and will have further prizes noted down into it, so make sure its safe in that folder!
  4. +
  5. You write at the top of the document the winner's name, then below write in big letters 'PRIZES' and put each new reward on its own line! ((You skip to a new line by writing < br > without the space between the br and the clamps))
  6. +
  7. Once written down, you just put the paper back in the folder and hand over the prize!
  8. +
+ ((When shift is nearing its end you pray to staff or DM the one responsible for the event, they will get the folder and copy paste all the reward info before shift is over and ensure people get their rewards. This is a very important job and we understand it might not be so fun being restricted during an event, but just like the rest of volunteer staff, you get rewarded with guaranteed prizes to enjoy after the shift for being a big help!))
+ ((This gets to the sour part, cheating and giving others and yourself free prizes and/or chips is absolutely forbidden, this has OOC consequences and will likely blacklist you from being important roles in future events. Though dont fear getting punished even if you havent done anything wrong, we will rather let cheaters slip than let honest players get wrongfully punished!)) + +

Sentient prizes

+ Goodness me this is quite the casino huh? Who would have thought one could win other people as a prize? Well you can do just about anything you want with them! Be it just company, some less children friendly company, heck you can even eat them or make them eat you! The options and possibilities are quite frankly limitless!
+ Now you might ask, how does one get these fancy prizes? Well they can be obtained by checking in at the exchange both and see the list of prizes, there might be none, there might be many, it depends on volunteers and losers! This brings us first to volunteers and then to losers!
+ Volunteering is simple! Anyone can walk up to the booth and ask to be a sentient prize, what this means is that you get a nice sum of 250 chips for you to do whatever you want, but someone might come at any point and claim you!
+ Losers are obtained differently, if youre completly busted and have nothing left, you become a prize that the one you lost to can do whatever they want with, this means both gamblers and dealers can end up as a prize, though if for whatever reason you dont become their prize, you get added to the list for someone else to enjoy. Becoming a prize means you also get 100 chips in compensation!

+ + ((Sour part again, but very important. These sentient prizes can be fun, but one thing always dictates how these things goes down, preferences and ooc wants. If preferences dont line up and people dont agree to do winner/loser scene it becomes sentient prize on list. And someone cant win a prize if the prize ooc doesnt want to do what the winner wants to do. We still wish people to try and reach out and try things with new people and/or new things they are comfortable doing, but never shall anyone be forced into a situation they dont want!)) + + + + "} \ No newline at end of file diff --git a/code/game/machinery/computer/timeclock_vr.dm b/code/game/machinery/computer/timeclock_vr.dm index d0557cd1f3..6e10fdd1f2 100644 --- a/code/game/machinery/computer/timeclock_vr.dm +++ b/code/game/machinery/computer/timeclock_vr.dm @@ -1,3 +1,4 @@ +//TFF 19/5/19 - Port VOREStation's completed Timeclock code ///////////////////////////////////////////// //Time Clock Terminal//////////////////////// ///////////////////////////////////////////// @@ -17,6 +18,12 @@ circuit = /obj/item/weapon/circuitboard/timeclock var/obj/item/weapon/card/id/card // Inserted Id card + var/obj/item/device/radio/intercom/announce // Integreated announcer + + +/obj/machinery/computer/timeclock/New() + announce = new /obj/item/device/radio/intercom(src) + ..() /obj/machinery/computer/timeclock/Destroy() if(card) @@ -80,12 +87,12 @@ "department" = job.department, "selection_color" = job.selection_color, "economic_modifier" = job.economic_modifier, - "head_position" = job.head_position, "timeoff_factor" = job.timeoff_factor ) - // TODO - Once job changing is implemented, we will want to list jobs to change into. - // if(job && job.timeoff_factor < 0) // Currently are Off Duty, so gotta lookup what on-duty jobs are open - // data["job_choices"] = getOpenOnDutyJobs(user, job.department) + if(config.time_off && config.pto_job_change) + data["allow_change_job"] = TRUE + if(job && job.timeoff_factor < 0) // Currently are Off Duty, so gotta lookup what on-duty jobs are open + data["job_choices"] = getOpenOnDutyJobs(user, job.department) ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) @@ -100,7 +107,7 @@ src.add_fingerprint(usr) if (href_list["id"]) - if (card) + if(card) usr.put_in_hands(card) card = null else @@ -109,8 +116,128 @@ I.forceMove(src) card = I update_icon() + return 1 + if(href_list["switch-to-onduty"]) + if(card) + if(checkFace()) + if(checkCardCooldown()) + makeOnDuty(href_list["switch-to-onduty"]) + usr.put_in_hands(card) + card = null + update_icon() + return 1 + if(href_list["switch-to-offduty"]) + if(card) + if(checkFace()) + if(checkCardCooldown()) + makeOffDuty() + usr.put_in_hands(card) + card = null + update_icon() + return 1 return 1 // Return 1 to update UI +/obj/machinery/computer/timeclock/proc/getOpenOnDutyJobs(var/mob/user, var/department) + var/list/available_jobs = list() + for(var/datum/job/job in job_master.occupations) + if(job && job.is_position_available() && !job.whitelist_only && !jobban_isbanned(user,job.title) && job.player_old_enough(user.client)) + if(job.department == department && !job.disallow_jobhop && job.timeoff_factor > 0) + available_jobs += job.title + if(job.alt_titles) + for(var/alt_job in job.alt_titles) + available_jobs += alt_job + return available_jobs + +/obj/machinery/computer/timeclock/proc/makeOnDuty(var/newjob) + var/datum/job/foundjob = null + for(var/datum/job/job in job_master.occupations) + if(newjob == job.title) + foundjob = job + break + if(newjob in job.alt_titles) + foundjob = job + break + if(!newjob in getOpenOnDutyJobs(usr, job_master.GetJob(card.rank).department)) + return + if(foundjob && card) + card.access = foundjob.get_access() + card.rank = foundjob.title + card.assignment = newjob + card.name = text("[card.registered_name]'s ID Card ([card.assignment])") + data_core.manifest_modify(card.registered_name, card.assignment) + card.last_job_switch = world.time + callHook("reassign_employee", list(card)) + foundjob.current_positions++ + var/mob/living/carbon/human/H = usr + H.mind.assigned_role = foundjob.title + H.mind.role_alt_title = newjob //TFF 26/7/19 - VOREStation fix port of announcement fix for wrong position + announce.autosay("[card.registered_name] has moved On-Duty as [card.assignment].", "Employee Oversight") + return + +/obj/machinery/computer/timeclock/proc/makeOffDuty() + var/datum/job/foundjob = null + for(var/datum/job/job in job_master.occupations) + if(card.rank == job.title) + foundjob = job + break + if(!foundjob) + return + var/real_dept = foundjob.department + if(real_dept && real_dept == "Command") + real_dept = "Civilian" + var/datum/job/ptojob = null + for(var/datum/job/job in job_master.occupations) + if(job.department == real_dept && job.timeoff_factor < 0) + ptojob = job + break + if(ptojob && card) + var/oldtitle = card.assignment + card.access = ptojob.get_access() + card.rank = ptojob.title + card.assignment = ptojob.title + card.name = text("[card.registered_name]'s ID Card ([card.assignment])") + data_core.manifest_modify(card.registered_name, card.assignment) + card.last_job_switch = world.time + callHook("reassign_employee", list(card)) + var/mob/living/carbon/human/H = usr + H.mind.assigned_role = ptojob.title + H.mind.role_alt_title = ptojob.title //TFF 26/7/19 - VOREStation fix port of announcement fix for wrong position + foundjob.current_positions-- + announce.autosay("[card.registered_name], [oldtitle], has moved Off-Duty.", "Employee Oversight") + return + +/obj/machinery/computer/timeclock/proc/checkCardCooldown() + if(!card) + return FALSE + if((world.time - card.last_job_switch) < 15 MINUTES) + to_chat(usr, "You need to wait at least 15 minutes after last duty switch. It has only been [card.last_job_switch] minutes since you have had your job changed.") + return FALSE + return TRUE + +/obj/machinery/computer/timeclock/proc/checkFace() + if(!card) + to_chat(usr, "No ID is inserted.") + return FALSE + var/mob/living/carbon/human/H = usr + if(!(istype(H))) + to_chat(usr, "Invalid user detected. Access denied.") + return FALSE + else if((H.wear_mask && (H.wear_mask.flags_inv & HIDEFACE)) || (H.head && (H.head.flags_inv & HIDEFACE))) //Face hiding bad + to_chat(usr, "Facial recognition scan failed due to physical obstructions. Access denied.") + return FALSE + else if(H.get_face_name() == "Unknown" || !(H.real_name == card.registered_name)) + to_chat(usr, "Facial recognition scan failed. Access denied.") + return FALSE + else + return TRUE + +/obj/item/weapon/card/id + var/last_job_switch + +/obj/item/weapon/card/id/New() + .=..() + last_job_switch = world.time + // // Frame type for construction // diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 7ba7a808a5..1b6d2f94fe 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -231,7 +231,7 @@ var/obj/machinery/computer/cryopod/control_computer var/last_no_computer_message = 0 - var/applies_stasis = 1 + var/applies_stasis = 0 ///TFF 18/4/19: change var from 1 to 0 so that you're able to get back out if you don't want to cryo out in the first place. /obj/machinery/cryopod/robot name = "robotic storage unit" @@ -506,6 +506,11 @@ //visible_message("\The [initial(name)] hums and hisses as it moves [to_despawn.real_name] into storage.", 3) visible_message("\The [initial(name)] [on_store_visible_message_1] [to_despawn.real_name] [on_store_visible_message_2].", 3) +//TFF: Port Vorestation fix for people getting kicked while inside a belly. Re-added 1/5/19. Didn't synch my fork before that last one, apparently. >W> + if(to_despawn.client && to_despawn.stat<2) + var/mob/observer/dead/newghost = to_despawn.ghostize() + newghost.timeofdeath = world.time + //This should guarantee that ghosts don't spawn. to_despawn.ckey = null diff --git a/code/game/machinery/cryopod_vr.dm b/code/game/machinery/cryopod_vr.dm index d4b2f84220..c5b9d64e97 100644 --- a/code/game/machinery/cryopod_vr.dm +++ b/code/game/machinery/cryopod_vr.dm @@ -22,7 +22,8 @@ /obj/machinery/computer/cryopod/gateway name = "teleport oversight console" desc = "An interface between visitors and the teleport oversight systems tasked with keeping track of all visitors who enter or exit from the teleporters." -/* VOREStation Edit + +//TFF 15/5/19 - Corrects spawnpoint type so that persistency saves properly. /obj/machinery/cryopod/robot/door/dorms desc = "A small elevator that goes down to the residential district." on_enter_occupant_message = "The elevator door closes slowly, ready to bring you down to the residential district." @@ -31,27 +32,26 @@ /obj/machinery/computer/cryopod/dorms name = "residential oversight console" desc = "An interface between visitors and the residential oversight systems tasked with keeping track of all visitors in the residential district." -*/ /obj/machinery/cryopod/proc/log_special_item(var/atom/movable/item,var/mob/to_despawn) ASSERT(item && to_despawn) - + var/loaded_from_key var/char_name = to_despawn.name var/item_name = item.name - + // Best effort key aquisition if(ishuman(to_despawn)) var/mob/living/carbon/human/H = to_despawn if(H.original_player) loaded_from_key = H.original_player - + if(!loaded_from_key && to_despawn.mind && to_despawn.mind.loaded_from_ckey) loaded_from_key = to_despawn.mind.loaded_from_ckey - + else loaded_from_key = "INVALID" - + // Log to harrass them later log_game("CRYO [loaded_from_key]/([to_despawn.name]) cryo'd with [item_name] ([item.type])") qdel(item) diff --git a/code/game/machinery/doorbell_vr.dm b/code/game/machinery/doorbell_vr.dm index b23e490928..f4dceb0b8b 100644 --- a/code/game/machinery/doorbell_vr.dm +++ b/code/game/machinery/doorbell_vr.dm @@ -43,12 +43,13 @@ else icon_state = "dbchime-standby" +//TFF 3/6/19 - Port Cit RP fix of infinite frames. ToDo: Make it so that you can completely deconstruct it and reconstruct it. /obj/machinery/doorbell_chime/attackby(obj/item/W as obj, mob/user as mob) src.add_fingerprint(user) if(default_deconstruction_screwdriver(user, W)) return - else if(default_deconstruction_crowbar(user, W)) - return +// else if(default_deconstruction_crowbar(user, W)) //NOTICE: NO CIRCUITBOARD +// return else if(default_part_replacement(user, W)) return else if(panel_open && istype(W, /obj/item/device/multitool)) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index ab42e5c02f..41e1a8e97d 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -538,6 +538,15 @@ req_one_access = list() normalspeed = FALSE // So it closes faster and hopefully keeps the warm air inside. hackProof = TRUE //VOREStation Edit - No borgos + +/obj/machinery/door/airlock/scp + name = "SCP Access" + icon = 'icons/obj/doors/SCPdoor.dmi' + //req_one_access = list(access_maint_tunnels) + open_sound_powered = 'sound/machines/scp1o.ogg' + close_sound_powered = 'sound/machines/scp1c.ogg' + open_sound_unpowered = 'sound/machines/scp1o.ogg' + close_sound_powered = 'sound/machines/scp1c.ogg' /* About the new airlock wires panel: diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index d8252fe4a9..2706bf09a5 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -1,3 +1,5 @@ +//TFF: Port VoreStation fix for door repair/reinforcing for borgs/drones. + //This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 #define DOOR_REPAIR_AMOUNT 50 //amount of health regained per stack amount used @@ -26,7 +28,7 @@ var/destroy_hits = 10 //How many strong hits it takes to destroy the door var/min_force = 10 //minimum amount of force needed to damage the door with a melee weapon var/hitsound = 'sound/weapons/smash.ogg' //sound door makes when hit with a weapon - var/obj/item/stack/material/steel/repairing + var/repairing var/block_air_zones = 1 //If set, air zones cannot merge across the door even when it is opened. var/close_door_at = 0 //When to automatically close the door, if possible @@ -205,17 +207,19 @@ /obj/machinery/door/attackby(obj/item/I as obj, mob/user as mob) src.add_fingerprint(user) - if (attempt_vr(src,"attackby_vr",list(I, user))) return + if(istype(I)) + if(attackby_vr(I, user)) //VOREStation begin: Fireproofing + return //VOREStation begin: Fireproofing if(istype(I, /obj/item/stack/material) && I.get_material_name() == src.get_material_name()) if(stat & BROKEN) - user << "It looks like \the [src] is pretty busted. It's going to need more than just patching up now." + to_chat(user,"It looks like \the [src] is pretty busted. It's going to need more than just patching up now.") return if(health >= maxhealth) - user << "Nothing to fix!" + to_chat(user,"Nothing to fix!") return if(!density) - user << "\The [src] must be closed before you can repair it." + to_chat(user,"\The [src] must be closed before you can repair it.") return //figure out how much metal we need @@ -223,44 +227,45 @@ amount_needed = (round(amount_needed) == amount_needed)? amount_needed : round(amount_needed) + 1 //Why does BYOND not have a ceiling proc? var/obj/item/stack/stack = I - var/transfer - if (repairing) - transfer = stack.transfer_to(repairing, amount_needed - repairing.amount) - if (!transfer) - user << "You must weld or remove \the [repairing] from \the [src] before you can add anything else." + var/amount_given = amount_needed - repairing + var/mats_given = stack.get_amount() + if(repairing && amount_given <= 0) + to_chat(user, "You must weld or remove \the [get_material_name()] from \the [src] before you can add anything else.") else - repairing = stack.split(amount_needed) - if (repairing) - repairing.loc = src - transfer = repairing.amount - - if (transfer) - user << "You fit [transfer] [stack.singular_name]\s to damaged and broken parts on \the [src]." + if(mats_given >= amount_given) + if(stack.use(amount_given)) + repairing += amount_given + else + if(stack.use(mats_given)) + repairing += mats_given + amount_given = mats_given + if(amount_given) + to_chat(user, "You fit [amount_given] [get_material_name()] sheets to damaged and broken parts on \the [src].") return if(repairing && istype(I, /obj/item/weapon/weldingtool)) if(!density) - user << "\The [src] must be closed before you can repair it." + to_chat(user,"\The [src] must be closed before you can repair it.") return var/obj/item/weapon/weldingtool/welder = I if(welder.remove_fuel(0,user)) - user << "You start to fix dents and weld \the [repairing] into place." + to_chat(user,"You start to fix dents and weld \the [get_material_name()] into place.") playsound(src, welder.usesound, 50, 1) - if(do_after(user, (5 * repairing.amount) * welder.toolspeed) && welder && welder.isOn()) - user << "You finish repairing the damage to \the [src]." - health = between(health, health + repairing.amount*DOOR_REPAIR_AMOUNT, maxhealth) + if(do_after(user, (5 * repairing) * welder.toolspeed) && welder && welder.isOn()) + to_chat(user,"You finish repairing the damage to \the [src].") + health = between(health, health + repairing*DOOR_REPAIR_AMOUNT, maxhealth) update_icon() - qdel(repairing) - repairing = null + repairing = 0 return if(repairing && istype(I, /obj/item/weapon/crowbar)) - user << "You remove \the [repairing]." + var/obj/item/stack/material/repairing_sheet = get_material().place_sheet(loc) + repairing_sheet.amount += repairing-1 + repairing = 0 + to_chat(user, "You remove \the [repairing_sheet].") playsound(src, I.usesound, 100, 1) - repairing.loc = user.loc - repairing = null return //psa to whoever coded this, there are plenty of objects that need to call attack() on doors without bludgeoning them. @@ -318,13 +323,13 @@ /obj/machinery/door/examine(mob/user) . = ..() if(src.health <= 0) - user << "\The [src] is broken!" + to_chat(user,"\The [src] is broken!") if(src.health < src.maxhealth / 4) - user << "\The [src] looks like it's about to break!" + to_chat(user,"\The [src] looks like it's about to break!") else if(src.health < src.maxhealth / 2) - user << "\The [src] looks seriously damaged!" + to_chat(user,"\The [src] looks seriously damaged!") else if(src.health < src.maxhealth * 3/4) - user << "\The [src] shows signs of damage!" + to_chat(user,"\The [src] shows signs of damage!") /obj/machinery/door/proc/set_broken() diff --git a/code/game/machinery/doors/door_vr.dm b/code/game/machinery/doors/door_vr.dm index 1e0dd1d470..ad5e6affd6 100644 --- a/code/game/machinery/doors/door_vr.dm +++ b/code/game/machinery/doors/door_vr.dm @@ -1,9 +1,11 @@ +//TFF: Port VoreStation fix for door repair/reinforcing for borgs/drones. + /turf/simulated/floor/proc/adjacent_fire_act_vr(turf/simulated/floor/adj_turf, datum/gas_mixture/adj_air, adj_temp, adj_volume) for(var/obj/machinery/door/D in src) //makes doors next to fire affected by fire D.fire_act(adj_air, adj_temp, adj_volume) /obj/machinery/door - var/obj/item/stack/material/plasteel/reinforcing //vorestation addition + var/reinforcing //vorestation addition /obj/machinery/door/firedoor heat_proof = 1 @@ -33,113 +35,68 @@ return ..() +// Returns true only if one of the actions unique to reinforcing is done, otherwise false and continuing normal attackby /obj/machinery/door/proc/attackby_vr(obj/item/I as obj, mob/user as mob) - if(istype(I, /obj/item/stack/material) && I.get_material_name() == "plasteel") // Add heat shielding if it isn't already. - if(!heat_proof) - var/obj/item/stack/stack = I - var/transfer - var/amount_needed = 2 - if(stat & BROKEN) - user << "It looks like \the [src] is pretty busted." - if (reinforcing) - transfer = stack.transfer_to(reinforcing, amount_needed - reinforcing.amount) - if (!transfer) - user << "You must weld or remove \the [reinforcing] from \the [src] before you can add anything else." - return 1 + if(istype(I, /obj/item/stack/material) && I.get_material_name() == "plasteel") + if(heat_proof) + to_chat(user, "\The [src] is already reinforced.") + return TRUE + if((stat & BROKEN) || (health < maxhealth)) + to_chat(user, "It looks like \the [src] broken. Repair it before reinforcing it.") + return TRUE + if(!density) + to_chat(user, "\The [src] must be closed before you can reinforce it.") + return TRUE + var/amount_needed = 2 + + var/obj/item/stack/stack = I + var/amount_given = amount_needed - reinforcing + var/mats_given = stack.get_amount() + if(reinforcing && amount_given <= 0) + to_chat(user, "You must weld or remove \the plasteel from \the [src] before you can add anything else.") + else + if(mats_given >= amount_given) + if(stack.use(amount_given)) + reinforcing += amount_given else - reinforcing = stack.split(amount_needed) - if (reinforcing) - reinforcing.loc = src - transfer = reinforcing.amount + if(stack.use(mats_given)) + reinforcing += mats_given + amount_given = mats_given + if(amount_given) + to_chat(user, "You fit [amount_given] [get_material_name()] sheets on \the [src].") - if (transfer) - user << "You fit [transfer] [stack.singular_name]\s to \the [src]." - return 1 - - if(istype(I, /obj/item/stack/material) && I.get_material_name() == src.get_material_name()) - if(stat & BROKEN) - if(health >= maxhealth && destroy_hits >= 10) - user << "The [src] is about as shored up as it's going to get." - return 1 - if(!density) - user << "\The [src] must be closed before you can repair it." - return 1 - - //figure out how much metal we need - var/amount_needed = (maxhealth - health) / DOOR_REPAIR_AMOUNT - if (destroy_hits < 10) - amount_needed += (20*(10 - destroy_hits) / DOOR_REPAIR_AMOUNT) - amount_needed = (round(amount_needed) == amount_needed)? amount_needed : round(amount_needed) + 1 //Why does BYOND not have a ceiling proc? - - var/obj/item/stack/stack = I - var/transfer - if (repairing) - transfer = stack.transfer_to(repairing, amount_needed - repairing.amount) - if (!transfer) - user << "You must weld or remove \the [repairing] from \the [src] before you can add anything else." - else - repairing = stack.split(amount_needed) - if (repairing) - repairing.loc = src - transfer = repairing.amount - - if (transfer) - user << "\The [src] is completely broken inside, but you manage to fit [transfer] [stack.singular_name]\s to shore it up." - - return 1 - - return 0 + return TRUE if(reinforcing && istype(I, /obj/item/weapon/weldingtool)) - var/amount_needed = 2 if(!density) - user << "\The [src] must be closed before you can repair it." - return 1 - if (reinforcing.amount < amount_needed) - user << "You need [amount_needed] [reinforcing.singular_name]\s to reinforce \the [src]." - return 1 + to_chat(user, "\The [src] must be closed before you can reinforce it.") + return TRUE + + if(reinforcing < 2) + to_chat(user, "You will need more plasteel to reinforce \the [src].") + return TRUE + var/obj/item/weapon/weldingtool/welder = I if(welder.remove_fuel(0,user)) - user << "You start to weld \the [reinforcing] into place." - playsound(src, 'sound/items/Welder.ogg', 100, 1) - if(do_after(user, 5 * reinforcing.amount) && welder && welder.isOn()) - user << "You finish reinforcing \the [src]." + to_chat(user, "You start to weld \the plasteel into place.") + playsound(src, welder.usesound, 50, 1) + if(do_after(user, 10 * welder.toolspeed) && welder && welder.isOn()) + to_chat(user, "You finish reinforcing \the [src].") heat_proof = 1 update_icon() - qdel(reinforcing) - reinforcing = null - return 1 - - if(repairing && istype(I, /obj/item/weapon/weldingtool) && (stat & BROKEN)) - if(!density) - user << "\The [src] must be closed before you can shore it up." - return 1 - - var/obj/item/weapon/weldingtool/welder = I - if(welder.remove_fuel(0,user)) - user << "You start to weld \the [repairing] into place." - playsound(src, 'sound/items/Welder.ogg', 100, 1) - if(do_after(user, 5 * repairing.amount) && welder && welder.isOn()) - user << "You finish shoring up \the [src]. It'll hold for at least a little while." - var/damagerepaired = repairing.amount*DOOR_REPAIR_AMOUNT - if (destroy_hits < 10) - var/severedamage = 10 - destroy_hits - destroy_hits = between(destroy_hits, destroy_hits + (damagerepaired)/20, 10) - damagerepaired -= 20 * severedamage - health = between(health, health + damagerepaired, maxhealth) - update_icon() - qdel(repairing) - repairing = null - return 1 + reinforcing = 0 + return TRUE if(reinforcing && istype(I, /obj/item/weapon/crowbar)) - user << "You remove \the [reinforcing]." - playsound(src.loc, 'sound/items/Crowbar.ogg', 100, 1) - reinforcing.loc = user.loc - reinforcing = null - return 1 - return 0 + var/obj/item/stack/material/plasteel/reinforcing_sheet = new /obj/item/stack/material/plasteel(src.loc) + reinforcing_sheet.amount = reinforcing + reinforcing = 0 + to_chat(user, "You remove \the [reinforcing_sheet].") + playsound(src, I.usesound, 100, 1) + return TRUE + + return FALSE /obj/machinery/door/blast/regular/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) return // blast doors are immune to fire completely. diff --git a/code/game/machinery/exonet_node.dm b/code/game/machinery/exonet_node.dm index 87eba96324..c9e11a133e 100644 --- a/code/game/machinery/exonet_node.dm +++ b/code/game/machinery/exonet_node.dm @@ -16,6 +16,9 @@ var/list/logs = list() // Gets written to by exonet's send_message() function. +//TFF 3/6/19 - Port Cit RP fix for infinite frames + circuit = /obj/item/weapon/circuitboard/telecomms/exonet_node + // Proc: New() // Parameters: None // Description: Adds components to the machine for deconstruction. @@ -23,7 +26,6 @@ ..() component_parts = list() - component_parts += new /obj/item/weapon/circuitboard/telecomms/exonet_node(src) component_parts += new /obj/item/weapon/stock_parts/subspace/ansible(src) component_parts += new /obj/item/weapon/stock_parts/subspace/sub_filter(src) component_parts += new /obj/item/weapon/stock_parts/manipulator(src) diff --git a/code/game/machinery/feeder.dm b/code/game/machinery/feeder.dm new file mode 100644 index 0000000000..f9562bf0fe --- /dev/null +++ b/code/game/machinery/feeder.dm @@ -0,0 +1,127 @@ +/obj/machinery/feeder + name = "\improper Feeder" + icon = 'icons/obj/feeder.dmi' + anchored = 0 + density = 0 + + +/obj/machinery/feeder/var/mob/living/carbon/human/attached = null +/obj/machinery/feeder/var/obj/item/weapon/reagent_containers/beaker = null + +/obj/machinery/feeder/update_icon() + if(attached) + icon_state = "feeding" + else + icon_state = "" + + overlays = null + + if(beaker) + var/datum/reagents/reagents = beaker.reagents + if(reagents.total_volume) + var/image/filling = image('icons/obj/feeder.dmi', src, "reagent") + + var/percent = round((reagents.total_volume / beaker.volume) * 100) + switch(percent) + if(0 to 9) filling.icon_state = "reagent0" + if(10 to 19) filling.icon_state = "reagent10" + if(20 to 44) filling.icon_state = "reagent20" + if(45 to 59) filling.icon_state = "reagent45" + if(60 to 74) filling.icon_state = "reagent60" + if(75 to 89) filling.icon_state = "reagent75" + if(90 to 94) filling.icon_state = "reagent90" + if(95 to INFINITY) filling.icon_state = "reagent100" + + filling.icon += reagents.get_color() + overlays += filling + +/obj/machinery/feeder/MouseDrop(over_object, src_location, over_location) + ..() + if(!isliving(usr)) + return + + if(attached) + visible_message("The feeding tube is pulled out of [attached]") + attached = null + update_icon() + return + + if(in_range(src, usr) && ishuman(over_object) && get_dist(over_object, src) <= 1) + visible_message("[usr] inserts the feeding tube into \the [over_object].") + attached = over_object + update_icon() + + +/obj/machinery/feeder/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W, /obj/item/weapon/reagent_containers)) + if(!isnull(beaker)) + user << "There is already a reagent container inserted!" + return + + user.drop_item() + W.loc = src + beaker = W + user << "You insert \the [W] into \the [src]." + update_icon() + return + + if(istype(W, /obj/item/weapon/screwdriver)) + playsound(src, W.usesound, 50, 1) + user << "You start to dismantle the feeder." + if(do_after(user, 15)) + user << "You dismantle the feeder." + var/obj/item/stack/material/plastic/A = new /obj/item/stack/material/plastic(src.loc) + A.amount = 4 + if(beaker) + beaker.loc = get_turf(src) + beaker = null + qdel(src) + return + else + return ..() + + +/obj/machinery/feeder/process() + set background = 1 + + if(attached) + + if(!(get_dist(src, attached) <= 1 && isturf(attached.loc))) + visible_message("The tube is pulled out of [attached]") + attached = null + update_icon() + return + + if(attached && beaker) + // Give food + if(beaker.volume > 0) + var/transfer_amount = 2 + beaker.reagents.trans_to_mob(attached, transfer_amount, CHEM_INGEST) + update_icon() + +/obj/machinery/feeder/attack_hand(mob/user as mob) + if(beaker) + beaker.loc = get_turf(src) + beaker = null + update_icon() + else + return ..() + +/obj/machinery/feeder/examine(mob/user) + ..(user) + if(!(user in view(2)) && user != src.loc) return + + if(beaker) + if(beaker.reagents && beaker.reagents.reagent_list.len) + usr << "Inserted is \a [beaker] with [beaker.reagents.total_volume] units of liquid." + else + usr << "Inserted is an empty [beaker]." + else + usr << "No container is inserted." + + usr << "[attached ? attached : "No one"] is being fed by it." + +/obj/machinery/feeder/CanPass(atom/movable/mover, turf/target, height = 0, air_group = 0) + if(height && istype(mover) && mover.checkpass(PASSTABLE)) //allow bullets, beams, thrown objects, mice, drones, and the like through. + return 1 + return ..() diff --git a/code/game/machinery/jukebox.dm b/code/game/machinery/jukebox.dm index 8ffcb5cec4..170c8eef3c 100644 --- a/code/game/machinery/jukebox.dm +++ b/code/game/machinery/jukebox.dm @@ -13,6 +13,7 @@ icon = 'icons/obj/jukebox.dmi' icon_state = "jukebox2-nopower" var/state_base = "jukebox2" + var/jukebox_edition = "default" anchored = 1 density = 1 power_channel = EQUIP @@ -33,6 +34,12 @@ var/list/datum/track/tracks = list() // Available tracks var/list/datum/track/secret_tracks = list() // Only visible if hacked +/obj/machinery/media/jukebox/casinojukebox + name = "space casino jukebox" + icon = 'icons/obj/casino.dmi' + icon_state = "casinojukebox-nopower" + state_base = "casinojukebox" + /obj/machinery/media/jukebox/New() ..() default_apply_parts() @@ -56,6 +63,24 @@ secret_tracks |= T else tracks |= T + + if(T.casino) + tracks -= T + return + +// On initialization, copy our tracks from the global list +/obj/machinery/media/jukebox/casinojukebox/initialize() + . = ..() + if(all_jukebox_tracks.len < 1) + stat |= BROKEN // No tracks configured this round! + return + // Ootherwise load from the global list! + for(var/datum/track/T in all_jukebox_tracks) + if(!T.casino) + tracks -= T + secret_tracks -= T + if(T.casino) + tracks |= T return /obj/machinery/media/jukebox/process() diff --git a/code/game/machinery/kitchen/icecream.dm b/code/game/machinery/kitchen/icecream.dm index 09cb3289ed..35b41bafbd 100644 --- a/code/game/machinery/kitchen/icecream.dm +++ b/code/game/machinery/kitchen/icecream.dm @@ -2,8 +2,10 @@ #define ICECREAM_CHOCOLATE 2 #define ICECREAM_STRAWBERRY 3 #define ICECREAM_BLUE 4 -#define CONE_WAFFLE 5 -#define CONE_CHOC 6 +#define ICECREAM_MATCHA 5 +#define CONE_WAFFLE 6 +#define CONE_CHOC 7 + // Ported wholesale from Apollo Station. @@ -29,6 +31,8 @@ return list("milk", "ice", "berryjuice") if(ICECREAM_BLUE) return list("milk", "ice", "singulo") + if(ICECREAM_MATCHA) + return list("milk", "ice", "matcha") if(CONE_WAFFLE) return list("flour", "sugar") if(CONE_CHOC) @@ -44,6 +48,8 @@ return "strawberry" if(ICECREAM_BLUE) return "blue" + if(ICECREAM_MATCHA) + return "matcha" if(CONE_WAFFLE) return "waffle" if(CONE_CHOC) @@ -54,7 +60,7 @@ /obj/machinery/icecream_vat/initialize() . = ..() create_reagents(100) - while(product_types.len < 6) + while(product_types.len < 7) product_types.Add(5) reagents.add_reagent("milk", 5) reagents.add_reagent("flour", 5) @@ -72,7 +78,8 @@ dat += "Vanilla icecream: Select Make x5 [product_types[ICECREAM_VANILLA]] scoops left. (Ingredients: milk, ice)
" dat += "Strawberry icecream: Select Make x5 [product_types[ICECREAM_STRAWBERRY]] dollops left. (Ingredients: milk, ice, berry juice)
" dat += "Chocolate icecream: Select Make x5 [product_types[ICECREAM_CHOCOLATE]] dollops left. (Ingredients: milk, ice, coco powder)
" - dat += "Blue icecream: Select Make x5 [product_types[ICECREAM_BLUE]] dollops left. (Ingredients: milk, ice, singulo)
" + dat += "Blue icecream: Select Make x5 [product_types[ICECREAM_BLUE]] dollops left. (Ingredients: milk, ice, singulo)
" + dat += "Matcha icecream: Select Make x5 [product_types[ICECREAM_MATCHA]] dollops left. (Ingredients: milk, ice, matcha)
" dat += "
CONES
" dat += "Waffle cones: Dispense Make x5 [product_types[CONE_WAFFLE]] cones left. (Ingredients: flour, sugar)
" dat += "Chocolate cones: Dispense Make x5 [product_types[CONE_CHOC]] cones left. (Ingredients: flour, sugar, coco powder)
" @@ -191,5 +198,6 @@ #undef FLAVOUR_CHOCOLATE #undef FLAVOUR_STRAWBERRY #undef FLAVOUR_BLUE +#undef FLAVOUR_MATCHA #undef CONE_WAFFLE #undef CONE_CHOC \ No newline at end of file diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index f68bc4cc8a..b861742d90 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -329,7 +329,7 @@ Class Procs: return FALSE if(panel_open) return FALSE // Close panel first! - playsound(loc, W.usesound, 50, 1) + playsound(loc, W.usesound, 50, 1) var/actual_time = W.toolspeed * time if(actual_time != 0) user.visible_message( \ @@ -396,6 +396,9 @@ Class Procs: /obj/machinery/proc/dismantle() playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) + //TFF 3/6/19 - port Cit RP fix of infinite frames. + if(!circuit) + return 0 var/obj/structure/frame/A = new /obj/structure/frame(src.loc) var/obj/item/weapon/circuitboard/M = circuit A.circuit = M diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index 182f4edb75..2d186028c7 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -215,24 +215,24 @@ var/list/obj/machinery/requests_console/allConsoles = list() if(computer_deconstruction_screwdriver(user, O)) return if(istype(O, /obj/item/device/multitool)) - if(panel_open) - var/input = sanitize(input(usr, "What Department ID would you like to give this request console?", "Multitool-Request Console Interface", department)) - if(!input) - to_chat(usr, "No input found. Please hang up and try your call again.") - return - department = input - announcement.title = "[department] announcement" - announcement.newscast = 1 - - name = "[department] Requests Console" - allConsoles += src - if(departmentType & RC_ASSIST) - req_console_assistance |= department - if(departmentType & RC_SUPPLY) - req_console_supplies |= department - if(departmentType & RC_INFO) - req_console_information |= department + //TFF 2/5/19: Allow deconstruction to work correctly and enable setting the thing. + var/input = sanitize(input(usr, "What Department ID would you like to give this request console?", "Multitool-Request Console Interface", department)) + if(!input) + to_chat(usr, "No input found. Please hang up and try your call again.") return + department = input + announcement.title = "[department] announcement" + announcement.newscast = 1 + + name = "[department] Requests Console" + allConsoles += src + if(departmentType & RC_ASSIST) + req_console_assistance |= department + if(departmentType & RC_SUPPLY) + req_console_supplies |= department + if(departmentType & RC_INFO) + req_console_information |= department + return if(istype(O, /obj/item/weapon/card/id)) if(inoperable(MAINT)) return diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 7d8afeffa6..3838c995d4 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -979,12 +979,19 @@ helmet.name = "engineering voidsuit helmet" helmet.icon_state = "rig0-engineering" helmet.item_state = "rig0-engineering" + helmet.max_heat_protection_temperature = HELMET_MAX_HEAT_PROTECTION_TEMPERATURE + helmet.armor = list(melee = 40, bullet = 5, laser = 20, energy = 5, bomb = 35, bio = 100, rad = 80) + helmet.desc = "A special helmet designed for work in a hazardous, low-pressure environment. Has radiation shielding." if(suit) suit.name = "engineering voidsuit" suit.icon_state = "rig-engineering" suit.item_state = "rig-engineering" suit.item_state_slots[slot_r_hand_str] = "eng_voidsuit" suit.item_state_slots[slot_l_hand_str] = "eng_voidsuit" + suit.max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE + suit.armor = list(melee = 40, bullet = 5, laser = 20, energy = 5, bomb = 35, bio = 100, rad = 80) + suit.desc = "A special suit that protects against hazardous, low pressure environments. Has radiation shielding." + if("Mining") if(helmet) helmet.name = "mining voidsuit helmet" @@ -1001,12 +1008,16 @@ helmet.name = "medical voidsuit helmet" helmet.icon_state = "rig0-medical" helmet.item_state = "rig0-medical" + helmet.armor = list(melee = 30, bullet = 5, laser = 20, energy = 5, bomb = 25, bio = 100, rad = 50) + helmet.desc = "A special helmet that protects against hazardous, low pressure environments. Has minor radiation shielding." if(suit) suit.name = "medical voidsuit" suit.icon_state = "rig-medical" suit.item_state = "rig-medical" suit.item_state_slots[slot_r_hand_str] = "medical_voidsuit" suit.item_state_slots[slot_l_hand_str] = "medical_voidsuit" + suit.armor = list(melee = 30, bullet = 5, laser = 20, energy = 5, bomb = 25, bio = 100, rad = 50) + suit.desc = "A special suit that protects against hazardous, low pressure environments. Has minor radiation shielding." if("Security") if(helmet) helmet.name = "security voidsuit helmet" @@ -1034,56 +1045,89 @@ helmet.name = "atmospherics voidsuit helmet" helmet.icon_state = "rig0-atmos" helmet.item_state = "rig0-atmos" + helmet.max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE + helmet.armor = list(melee = 40, bullet = 5, laser = 20, energy = 5, bomb = 35, bio = 100, rad = 50) + helmet.desc = "A special helmet designed for work in a hazardous, low pressure environments. Has improved thermal protection and minor radiation shielding." + if(suit) suit.name = "atmospherics voidsuit" suit.icon_state = "rig-atmos" suit.item_state = "rig-atmos" suit.item_state_slots[slot_r_hand_str] = "atmos_voidsuit" suit.item_state_slots[slot_l_hand_str] = "atmos_voidsuit" + suit.max_heat_protection_temperature = FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE + suit.armor = list(melee = 40, bullet = 5, laser = 20, energy = 5, bomb = 35, bio = 100, rad = 50) + suit.desc = "A special suit that protects against hazardous, low pressure environments. Has improved thermal protection and minor radiation shielding." + if("HAZMAT") if(helmet) helmet.name = "HAZMAT voidsuit helmet" helmet.icon_state = "rig0-engineering_rad" helmet.item_state = "rig0-engineering_rad" + helmet.max_heat_protection_temperature = HELMET_MAX_HEAT_PROTECTION_TEMPERATURE + helmet.armor = list(melee = 30, bullet = 5, laser = 20, energy = 5, bomb = 50, bio = 100, rad = 100) + helmet.desc = "A engineering helmet designed for work in a low-pressure environment. Extra radiation shielding appears to have been installed at the price of comfort." + if(suit) suit.name = "HAZMAT voidsuit" suit.icon_state = "rig-engineering_rad" suit.item_state = "rig-engineering_rad" suit.item_state_slots[slot_r_hand_str] = "eng_voidsuit_rad" suit.item_state_slots[slot_l_hand_str] = "eng_voidsuit_rad" + suit.max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE + suit.armor = list(melee = 30, bullet = 5, laser = 20, energy = 5, bomb = 50, bio = 100, rad = 100) + suit.desc = "A engineering voidsuit that protects against hazardous, low pressure environments. Has enhanced radiation shielding compared to regular engineering voidsuits." if("Construction") if(helmet) helmet.name = "Construction voidsuit helmet" helmet.icon_state = "rig0-engineering_con" helmet.item_state = "rig0-engineering_con" + helmet.max_heat_protection_temperature = HELMET_MAX_HEAT_PROTECTION_TEMPERATURE + helmet.armor = list(melee = 40, bullet = 5, laser = 20, energy = 5, bomb = 35, bio = 100, rad = 80) + helmet.desc = "A special helmet designed for work in a hazardous, low-pressure environment. Has radiation shielding." if(suit) suit.name = "Construction voidsuit" suit.icon_state = "rig-engineering_con" suit.item_state = "rig-engineering_con" suit.item_state_slots[slot_r_hand_str] = "eng_voidsuit_con" suit.item_state_slots[slot_l_hand_str] = "eng_voidsuit_con" + suit.max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE + suit.armor = list(melee = 40, bullet = 5, laser = 20, energy = 5, bomb = 35, bio = 100, rad = 80) + suit.desc = "A special suit designed for work in a hazardous, low-pressure environment. Has radiation shielding." + if("Biohazard") if(helmet) helmet.name = "Biohazard voidsuit helmet" helmet.icon_state = "rig0-medical_bio" helmet.item_state = "rig0-medical_bio" + helmet.armor = list(melee = 45, bullet = 5, laser = 20, energy = 5, bomb = 15, bio = 100, rad = 75) + helmet.desc = "A special helmet that protects against hazardous environments. Has minor radiation shielding." + if(suit) suit.name = "Biohazard voidsuit" suit.icon_state = "rig-medical_bio" suit.item_state = "rig-medical_bio" suit.item_state_slots[slot_r_hand_str] = "medical_voidsuit_bio" suit.item_state_slots[slot_l_hand_str] = "medical_voidsuit_bio" + suit.armor = list(melee = 45, bullet = 5, laser = 20, energy = 5, bomb = 15, bio = 100, rad = 75) + suit.desc = "A special suit that protects against hazardous, environments. It feels heavier than the standard suit with extra protection around the joints." + if("Emergency Medical Response") if(helmet) helmet.name = "emergency medical response voidsuit helmet" helmet.icon_state = "rig0-medical_emt" helmet.item_state = "rig0-medical_emt" + helmet.armor = list(melee = 30, bullet = 5, laser = 20, energy = 5, bomb = 25, bio = 100, rad = 50) + helmet.desc = "A special helmet that protects against hazardous, low pressure environments. Has minor radiation shielding." + if(suit) suit.name = "emergency medical response voidsuit" suit.icon_state = "rig-medical_emt" suit.item_state = "rig-medical_emt" suit.item_state_slots[slot_r_hand_str] = "medical_voidsuit_emt" suit.item_state_slots[slot_l_hand_str] = "medical_voidsuit_emt" + suit.armor = list(melee = 30, bullet = 5, laser = 20, energy = 5, bomb = 25, bio = 100, rad = 50) + suit.desc = "A special suit that protects against hazardous, low pressure environments. Has minor radiation shielding." if("^%###^%$" || "Mercenary") if(helmet) helmet.name = "blood-red voidsuit helmet" diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index be31a5aa56..09d9ef786a 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -14,7 +14,7 @@ id = "[rand(1000, 9999)]" ..() underlays.Cut() - underlays += image('icons/obj/stationobjs.dmi', icon_state = "telecomp-wires") + underlays += image('icons/obj/stationobjs.dmi', icon_state = "telecomp-wires") //TFF: Ports VOREStation Edit: different direction for wires to account for dirs. return /obj/machinery/computer/teleporter/initialize() diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index 87fbc4dcfd..570977d141 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -689,6 +689,7 @@ /obj/item/weapon/reagent_containers/food/drinks/glass2/mug = 10, /obj/item/weapon/reagent_containers/food/drinks/glass2/wine = 10, /obj/item/weapon/reagent_containers/food/drinks/metaglass = 10, + /obj/item/weapon/reagent_containers/food/drinks/metaglass/metapint = 10, /obj/item/weapon/reagent_containers/food/drinks/bottle/gin = 5, /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe = 5, /obj/item/weapon/reagent_containers/food/drinks/bottle/bluecuracao = 5, diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index 958f31bbd2..53651c3edc 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -136,7 +136,7 @@ /obj/machinery/mecha_part_fabricator/attackby(var/obj/item/I, var/mob/user) if(busy) - user << "\The [src] is busy. Please wait for completion of previous operation." + to_chat(user, "\The [src] is busy. Please wait for completion of previous operation.") return 1 if(default_deconstruction_screwdriver(user, I)) return @@ -148,25 +148,25 @@ if(istype(I,/obj/item/stack/material)) var/obj/item/stack/material/S = I if(!(S.material.name in materials)) - user << "The [src] doesn't accept [S.material]!" + to_chat(user, "The [src] doesn't accept [S.material]!") return var/sname = "[S.name]" var/amnt = S.perunit if(materials[S.material.name] + amnt <= res_max_amount) - if(S && S.amount >= 1) + if(S && S.get_amount() >= 1) //TFF 2/5/19: Polaris fix for Synthesisers inserting more than what is present var/count = 0 overlays += "mechfab-load-metal" spawn(10) overlays -= "mechfab-load-metal" - while(materials[S.material.name] + amnt <= res_max_amount && S.amount >= 1) + while(materials[S.material.name] + amnt <= res_max_amount && S.get_amount() >= 1) //TFF 2/5/19: Polaris fix for Synthesisers inserting more than what is present materials[S.material.name] += amnt S.use(1) count++ - user << "You insert [count] [sname] into the fabricator." + to_chat(user, "You insert [count] [sname] into the fabricator.") update_busy() else - user << "The fabricator cannot hold more [sname]." + to_chat(user, "The fabricator cannot hold more [sname].") return diff --git a/code/game/mecha/mech_prosthetics.dm b/code/game/mecha/mech_prosthetics.dm index c8e1d61179..6fc34aa6a2 100644 --- a/code/game/mecha/mech_prosthetics.dm +++ b/code/game/mecha/mech_prosthetics.dm @@ -175,25 +175,26 @@ if(istype(I,/obj/item/stack/material)) var/obj/item/stack/material/S = I if(!(S.material.name in materials)) - user << "The [src] doesn't accept [S.material]!" + to_chat(user, "The [src] doesn't accept [S.material]!") return + //TFF 2/5/19: Polaris fix for Synthesisers inserting more than what is present var/sname = "[S.name]" var/amnt = S.perunit if(materials[S.material.name] + amnt <= res_max_amount) - if(S && S.amount >= 1) + if(S && S.get_amount() >= 1) var/count = 0 overlays += "fab-load-metal" spawn(10) overlays -= "fab-load-metal" - while(materials[S.material.name] + amnt <= res_max_amount && S.amount >= 1) + while(materials[S.material.name] + amnt <= res_max_amount && S.get_amount() >= 1) materials[S.material.name] += amnt S.use(1) count++ - user << "You insert [count] [sname] into the fabricator." + to_chat(user, "You insert [count] [sname] into the fabricator.") update_busy() else - user << "The fabricator cannot hold more [sname]." + to_chat(user, "The fabricator cannot hold more [sname].") return diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm index 998b213ff4..78e3504f6e 100644 --- a/code/game/objects/buckling.dm +++ b/code/game/objects/buckling.dm @@ -49,22 +49,12 @@ unbuckle_all_mobs() return ..() - +//TFF 2/5/19: Polaris port for buckling-related bugs - chair-related buckling disabled /atom/movable/proc/buckle_mob(mob/living/M, forced = FALSE, check_loc = TRUE) - if(!buckled_mobs) - buckled_mobs = list() - - if(!istype(M)) - return FALSE - if(check_loc && M.loc != loc) return FALSE - if((!can_buckle && !forced) || M.buckled || M.pinned.len || (buckled_mobs.len >= max_buckled_mobs) || (buckle_require_restraints && !M.restrained())) - return FALSE - - if(has_buckled_mobs() && buckled_mobs.len >= max_buckled_mobs) //Handles trying to buckle yourself to the chair when someone is on it - to_chat(M, "\The [src] can't buckle anymore people.") + if(!can_buckle_check(M, forced)) return FALSE M.buckled = src @@ -130,6 +120,9 @@ if(M in buckled_mobs) to_chat(user, "\The [M] is already buckled to \the [src].") return FALSE + //TFF 2/5/19: Polaris port for buckling-related bugs - check for whether someone's buckled + if(!can_buckle_check(M, forced)) + return FALSE add_fingerprint(user) // unbuckle_mob() @@ -184,6 +177,23 @@ L.set_dir(dir) return TRUE +//TFF 2/5/19: Polaris port for buckling-related bugs - check for whether someone's buckled +/atom/movable/proc/can_buckle_check(mob/living/M, forced = FALSE) + if(!buckled_mobs) + buckled_mobs = list() + + if(!istype(M)) + return FALSE + + if((!can_buckle && !forced) || M.buckled || M.pinned.len || (buckled_mobs.len >= max_buckled_mobs) || (buckle_require_restraints && !M.restrained())) + return FALSE + + if(has_buckled_mobs() && buckled_mobs.len >= max_buckled_mobs) //Handles trying to buckle yourself to the chair when someone is on it + to_chat(M, "\The [src] can't buckle anymore people.") + return FALSE + + return TRUE + /atom/movable/Move(atom/newloc, direct = 0) . = ..() if(. && has_buckled_mobs() && !handle_buckled_mob_movement(newloc, direct)) //movement failed due to buckled mob(s) @@ -193,4 +203,4 @@ riding_datum.handle_vehicle_layer() riding_datum.handle_vehicle_offsets() //VOREStation Add End - \ No newline at end of file + diff --git a/code/game/objects/items/apc_frame.dm b/code/game/objects/items/apc_frame.dm index fd2ea3e94b..54141ec119 100644 --- a/code/game/objects/items/apc_frame.dm +++ b/code/game/objects/items/apc_frame.dm @@ -6,12 +6,7 @@ icon = 'icons/obj/apc_repair.dmi' icon_state = "apc_frame" flags = CONDUCT - -/obj/item/frame/apc/attackby(obj/item/weapon/W as obj, mob/user as mob) - ..() - if (istype(W, /obj/item/weapon/wrench)) - new /obj/item/stack/material/steel( get_turf(src.loc), 2 ) - qdel(src) + refund_amt = 2 //TFF 18/4/19: Polaris fix for APC frames giving more steel than used when made. /obj/item/frame/apc/try_build(turf/on_wall, mob/user as mob) if (get_dist(on_wall, user)>1) diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 5d6c14abb9..d9f62cf1b8 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -655,6 +655,7 @@ var/global/list/obj/item/device/pda/PDAs = list() ui = new(user, src, ui_key, "pda.tmpl", title, 520, 400, state = inventory_state) // add templates for screens in common with communicator. ui.add_template("atmosphericScan", "atmospheric_scan.tmpl") + ui.add_template("crewManifest", "crew_manifest.tmpl") //TFF Port from VOREStation // when the ui is first opened this is the data it will use ui.set_initial_data(data) // open the new ui window diff --git a/code/game/objects/items/devices/communicator/UI.dm b/code/game/objects/items/devices/communicator/UI.dm index 9d43da5c9a..0aea2a51eb 100644 --- a/code/game/objects/items/devices/communicator/UI.dm +++ b/code/game/objects/items/devices/communicator/UI.dm @@ -13,8 +13,7 @@ var/im_contacts_ui[0] //List of communicators that have been messaged. var/im_list_ui[0] //List of messages. - var/weather[0] - var/injection = null + // var/weather[0] //Unneeded variable since there's no weather at all! var/modules_ui[0] //Home screen info. //First we add other 'local' communicators. @@ -68,7 +67,7 @@ for(var/I in im_list) im_list_ui[++im_list_ui.len] = list("address" = I["address"], "to_address" = I["to_address"], "im" = I["im"]) - //Weather reports. + /*//Weather reports. if(planet_controller) for(var/datum/planet/planet in planet_controller.planets) if(planet.weather_holder && planet.weather_holder.current_weather) @@ -80,9 +79,11 @@ "High" = planet.weather_holder.current_weather.temp_high - T0C, "Low" = planet.weather_holder.current_weather.temp_low - T0C) weather[++weather.len] = W - - injection = "
Test
" - + */ //No planets with an atmosphere, doofus! + + // Update manifest + data_core.get_manifest_list() + //Modules for homescreen. for(var/list/R in modules) modules_ui[++modules_ui.len] = R @@ -107,19 +108,22 @@ data["ring"] = ringer data["homeScreen"] = modules_ui data["note"] = note // current notes - data["weather"] = weather + //data["weather"] = weather //Unneeded portion: no planets with an atmosphere that HAS weather! data["aircontents"] = src.analyze_air() data["flashlight"] = fon - data["injection"] = injection + data["manifest"] = PDA_Manifest // update the ui if it exists, returns null if no ui is passed/found ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) if(!ui) // the ui does not exist, so we'll create a new() one // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm + data["currentTab"] = 1 // Reset the current tab, because we're going to home page //TFF VOREStation port ui = new(user, src, ui_key, "communicator.tmpl", "Communicator", 475, 700, state = key_state) // add templates for screens in common with communicator. ui.add_template("atmosphericScan", "atmospheric_scan.tmpl") + // TheFurryFeline: Adds Manifest listing + ui.add_template("crewManifest","crew_manifest.tmpl") // when the ui is first opened this is the data it will use ui.set_initial_data(data) // open the new ui window @@ -244,6 +248,14 @@ else note = "" notehtml = note + if(href_list["switch_template"]) + var/datum/nanoui/ui = nanomanager.get_open_ui(usr, src, "main") + if(ui) + switch(href_list["switch_template"]) + if("1") + ui.reinitialise("communicator.tmpl") + if("2") + ui.reinitialise("comm2.tmpl") if(href_list["Light"]) fon = !fon diff --git a/code/game/objects/items/devices/communicator/communicator.dm b/code/game/objects/items/devices/communicator/communicator.dm index 40ede14c67..7373266530 100644 --- a/code/game/objects/items/devices/communicator/communicator.dm +++ b/code/game/objects/items/devices/communicator/communicator.dm @@ -4,6 +4,16 @@ var/global/list/obj/item/device/communicator/all_communicators = list() +// List of core tabs the communicator can switch to //TFF Port from VOREStation +#define HOMETAB 1 +#define PHONTAB 2 +#define CONTTAB 3 +#define MESSTAB 4 +#define NOTETAB 5 +#define ATMSTAB 6 +#define MANITAB 7 +#define SETTTAB 8 + /obj/item/device/communicator name = "communicator" desc = "A personal device used to enable long range dialog between two people, utilizing existing telecommunications infrastructure to allow \ @@ -36,15 +46,16 @@ var/global/list/obj/item/device/communicator/all_communicators = list() var/flum = 2 // Brightness var/list/modules = list( - list("module" = "Phone", "icon" = "phone64", "number" = 2), - list("module" = "Contacts", "icon" = "person64", "number" = 3), - list("module" = "Messaging", "icon" = "comment64", "number" = 4), - list("module" = "Note", "icon" = "note64", "number" = 5), - list("module" = "Weather", "icon" = "sun64", "number" = 6), - list("module" = "Settings", "icon" = "gear64", "number" = 7) + list("module" = "Phone", "icon" = "phone64", "number" = PHONTAB), + list("module" = "Contacts", "icon" = "person64", "number" = CONTTAB), + list("module" = "Messaging", "icon" = "comment64", "number" = MESSTAB), + list("module" = "Note", "icon" = "note64", "number" = NOTETAB), + list("module" = "Atmos", "icon" = "sun64", "number" = ATMSTAB), + list("module" = "Crew Manifest", "icon" = "note64", "number" = MANITAB), // Need a different icon, //TFF Port from VOREStation + list("module" = "Settings", "icon" = "gear64", "number" = SETTTAB), ) //list("module" = "Name of Module", "icon" = "icon name64", "number" = "what tab is the module") - var/selected_tab = 1 + var/selected_tab = HOMETAB var/owner = "" var/occupation = "" var/alert_called = 0 @@ -221,9 +232,6 @@ var/global/list/obj/item/device/communicator/all_communicators = list() if(video_source) watch_video(user) -/obj/item/device/communicator/AltClick(mob/user) //Chomp edit. - attack_self(user) //wow big skill - // Proc: MouseDrop() //Same thing PDAs do /obj/item/device/communicator/MouseDrop(obj/over_object as obj) diff --git a/code/game/objects/items/devices/laserpointer.dm b/code/game/objects/items/devices/laserpointer.dm index 69905f0cb8..2bf0c8e768 100644 --- a/code/game/objects/items/devices/laserpointer.dm +++ b/code/game/objects/items/devices/laserpointer.dm @@ -71,6 +71,8 @@ /obj/item/device/laser_pointer/proc/laser_act(var/atom/target, var/mob/living/user) if(!(user in (viewers(world.view,target)))) return + if(!(target in view(user, world.view))) ///TFF 18/4/19: VOREStation port - prevent laser light reaching the other side of a wall. + return if(!(world.time - last_used_time >= cooldown)) return if (!diode) diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm index 8fd96981fc..855cab29ef 100644 --- a/code/game/objects/items/devices/lightreplacer.dm +++ b/code/game/objects/items/devices/lightreplacer.dm @@ -55,6 +55,11 @@ var/failmsg = "" var/charge = 0 + // Eating used bulbs gives us bulb shards + var/bulb_shards = 0 + // when we get this many shards, we get a free bulb. + var/shards_required = 4 + /obj/item/device/lightreplacer/New() failmsg = "The [name]'s refill light blinks red." ..() @@ -77,18 +82,55 @@ to_chat(user, "You need one sheet of glass to replace lights.") if(istype(W, /obj/item/weapon/light)) + var/new_bulbs = 0 var/obj/item/weapon/light/L = W if(L.status == 0) // LIGHT OKAY if(uses < max_uses) + if(!user.unEquip(W)) + return add_uses(1) - to_chat(user, "You insert \the [L.name] into \the [src.name]. You have [uses] light\s remaining.") - user.drop_item() qdel(L) - return else - to_chat(user, "You need a working light.") + if(!user.unEquip(W)) + return + new_bulbs += AddShards(1) + qdel(L) + if(new_bulbs != 0) + playsound(src.loc, 'sound/machines/ding.ogg', 50, 1) + to_chat(user, "You insert \the [L.name] into \the [src.name]. You have [uses] light\s remaining.") + return + + if(istype(W, /obj/item/weapon/storage)) + var/obj/item/weapon/storage/S = W + var/found_lightbulbs = FALSE + var/replaced_something = TRUE + + for(var/obj/item/I in S.contents) + if(istype(I,/obj/item/weapon/light)) + var/obj/item/weapon/light/L = I + found_lightbulbs = TRUE + if(src.uses >= max_uses) + break + if(L.status == LIGHT_OK) + replaced_something = TRUE + add_uses(1) + qdel(L) + + else if(L.status == LIGHT_BROKEN || L.status == LIGHT_BURNED) + replaced_something = TRUE + AddShards(1) + qdel(L) + + if(!found_lightbulbs) + to_chat(user, "\The [S] contains no bulbs.") return + if(!replaced_something && src.uses == max_uses) + to_chat(user, "\The [src] is full!") + return + + to_chat(user, "You fill \the [src] with lights from \the [S].") + /obj/item/device/lightreplacer/attack_self(mob/user) /* // This would probably be a bit OP. If you want it though, uncomment the code. if(isrobot(user)) @@ -114,6 +156,15 @@ /obj/item/device/lightreplacer/proc/add_uses(var/amount = 1) uses = min(max(uses + amount, 0), max_uses) + +/obj/item/device/lightreplacer/proc/AddShards(amount = 1) + bulb_shards += amount + var/new_bulbs = round(bulb_shards / shards_required) + if(new_bulbs > 0) + add_uses(new_bulbs) + bulb_shards = bulb_shards % shards_required + return new_bulbs + /obj/item/device/lightreplacer/proc/Charge(var/mob/user, var/amount = 1) charge += amount if(charge > 6) @@ -128,17 +179,10 @@ U << "You replace the [target.fitting] with the [src]." if(target.status != LIGHT_EMPTY) - - var/obj/item/weapon/light/L1 = new target.light_type(target.loc) - L1.status = target.status - L1.rigged = target.rigged - L1.brightness_range = target.brightness_range - L1.brightness_power = target.brightness_power - L1.brightness_color = target.brightness_color - L1.switchcount = target.switchcount - target.switchcount = 0 - L1.update() - + var/new_bulbs = AddShards(1) + if(new_bulbs != 0) + to_chat(U, "\The [src] has fabricated a new bulb from the broken bulbs it has stored. It now has [uses] uses.") + playsound(src.loc, 'sound/machines/ding.ogg', 50, 1) target.status = LIGHT_EMPTY target.update() diff --git a/code/game/objects/items/devices/suit_cooling.dm b/code/game/objects/items/devices/suit_cooling.dm index 2040f22a99..b89928445a 100644 --- a/code/game/objects/items/devices/suit_cooling.dm +++ b/code/game/objects/items/devices/suit_cooling.dm @@ -5,7 +5,9 @@ icon = 'icons/obj/device.dmi' icon_state = "suitcooler0" slot_flags = SLOT_BACK - + + var/emagged = 0 //CHOMPEDIT Cooling suit emagging + //copied from tank.dm flags = CONDUCT force = 5.0 @@ -35,6 +37,9 @@ cell.loc = src /obj/item/device/suit_cooling_unit/process() + if (emagged) + emagprocess() //CHOMPEDIT Should be good enough to override natural process + return if (!on || !cell) return @@ -193,3 +198,91 @@ user << "The charge meter reads [round(cell.percent())]%." else user << "It doesn't have a power cell installed." + +//CHOMPEDIT hey you wanna go out into space here i got you a spacesuit, even got a cooling module :) trust me friend. +//Tampered Cooling unit, or also "Heating unit" +/obj/item/device/suit_cooling_unit/tampered + name = "modified portable suit cooling unit" + origin_tech = list(TECH_MAGNET = 4, TECH_MATERIAL = 4) + max_cooling = 10 + thermostat = T20C + desc = "A portable heat sink and liquid cooled radiator that can be hooked up to a space suit's existing temperature controls to provide industrial levels of cooling. This ones panel seems a bit loose and wires are hanging out." + +/obj/item/device/suit_cooling_unit/tampered/process() + emagprocess() + +/obj/item/device/suit_cooling_unit/proc/emagprocess() + if (!on || !cell) + return + + if (!ismob(loc)) + return + + if (!attached_to_suit(loc)) //make sure they have a suit and we are attached to it + return + + var/mob/living/carbon/human/H = loc + + var/efficiency = 1 - H.get_pressure_weakness() // You need to have a good seal for effective "cooling" + var/temp_adj = 0 // How much the unit heats you. Adjusted later on. + var/env_temp = get_environment_temperature() // This won't save you from a fire, yup + var/thermal_protection = H.get_heat_protection(env_temp) // ... unless you've got a good suit. not even then + + if(thermal_protection < 0.99) //For some reason, < 1 returns false if the value is 1. + temp_adj = min(H.bodytemperature - max(thermostat, env_temp), max_cooling) + else + temp_adj = min(H.bodytemperature - thermostat, max_cooling) + + //if (temp_adj < 0.5) //no safety + // return + + var/charge_usage = (temp_adj/max_cooling)*charge_consumption + + H.bodytemperature += temp_adj*efficiency //plus instead of minus + + cell.use(charge_usage) + + if(cell.charge <= 0) + turn_off(1) + +//CHOMPEDIT Let's go rogue bb +/obj/item/device/suit_cooling_unit/emag_act(var/remaining_charges, var/mob/user) + if(!emagged) + user << "You stealthily swipe the cryptographic sequencer through \the [src]." + playsound(src, "sparks", 50, 1) + emagged = 1 + if (!on) + on = 1 //automatically turns it on + + +/mob/living/simple_animal/hostile/jelly/cold //you are my test mob now fug you + hostile=0 + retaliate=1 + name = "Frostbite Jelly" + //might make a blue icon someday, not priority this is debug stuff + var/cooling = -5000 //variable cooling + var/isCooling = 1 + cold_damage_per_tick = 0 + maxbodytemp = 20000000 + +/mob/living/simple_animal/hostile/jelly/cold/proc/toggle_cooling() + isCooling=!isCooling + +/mob/living/simple_animal/hostile/jelly/cold/proc/handle_cooling(var/datum/gas_mixture/environment) + var/datum/gas_mixture/gas + gas = environment.remove(0.5 * environment.total_moles) + if(gas) + gas.add_thermal_energy(cooling) + environment.merge(gas) + +/mob/living/simple_animal/hostile/jelly/cold/Life() + ..() + var/datum/gas_mixture/environment = src.loc.return_air() + if(icon_state != icon_dead && isCooling) + handle_cooling(environment) + //src.bodytemperature += cooling //Removing self nuke + if(src.bodytemperature<=-500) + isCooling = 0 + if(src.bodytemperature>=-499) + isCooling = 1 +//This thing is basically a cooling unit and could be used for the engine, I mean what diff --git a/code/game/objects/items/devices/violin.dm b/code/game/objects/items/devices/violin.dm index 683c74bd02..a6d7706c4d 100644 --- a/code/game/objects/items/devices/violin.dm +++ b/code/game/objects/items/devices/violin.dm @@ -319,10 +319,10 @@ var/newline = html_encode(input("Enter your line: ", "violin") as text|null) if(!newline) return - if(song.lines.len > 50) + if(song.lines.len > 500) return - if(lentext(newline) > 50) - newline = copytext(newline, 1, 50) + if(lentext(newline) > 500) + newline = copytext(newline, 1, 500) song.lines.Add(newline) else if(href_list["deleteline"]) @@ -336,8 +336,8 @@ var/content = html_encode(input("Enter your line: ", "violin", song.lines[num]) as text|null) if(!content) return - if(lentext(content) > 50) - content = copytext(content, 1, 50) + if(lentext(content) > 500) + content = copytext(content, 1, 500) if(num > song.lines.len || num < 1) return song.lines[num] = content @@ -371,12 +371,12 @@ if(copytext(lines[1],1,6) == "BPM: ") tempo = 600 / text2num(copytext(lines[1],6)) lines.Cut(1,2) - if(lines.len > 50) + if(lines.len > 500) usr << "Too many lines!" - lines.Cut(51) + lines.Cut(501) var/linenum = 1 for(var/l in lines) - if(lentext(l) > 50) + if(lentext(l) > 500) usr << "Line [linenum] too long!" lines.Remove(l) else diff --git a/code/game/objects/items/robot/robot_upgrades_vr.dm b/code/game/objects/items/robot/robot_upgrades_vr.dm index 6f92178f09..721a2bfe5b 100644 --- a/code/game/objects/items/robot/robot_upgrades_vr.dm +++ b/code/game/objects/items/robot/robot_upgrades_vr.dm @@ -9,3 +9,21 @@ return 1 else return 0 + +//TFF: Ports VOREStation addition - ability for borgs to change size at will. + +/obj/item/borg/upgrade/sizeshift + name = "robot size alteration module" + desc = "Using technology similar to one used in sizeguns, allows cyborgs to adjust their own size as neccesary." + icon_state = "cyborg_upgrade2" + item_state = "cyborg_upgrade" + require_module = 1 + +/obj/item/borg/upgrade/sizeshift/action(var/mob/living/silicon/robot/R) + if(..()) return 0 + + if(/mob/living/proc/set_size in R.verbs) + return 0 + + R.verbs += /mob/living/proc/set_size + return 1 \ No newline at end of file diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index cc3c89a475..aeec135afc 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -519,7 +519,7 @@ /obj/item/toy/figure/attack_self(mob/user as mob) if(cooldown < world.time) cooldown = (world.time + 30) //3 second cooldown - user.visible_message("The [src] says \"[toysay]\".") + user.visible_message("The [src] says \"[toysay]\"") playsound(user, 'sound/machines/click.ogg', 20, 1) /obj/item/toy/figure/cmo @@ -746,7 +746,7 @@ /obj/item/toy/figure/paramedic name = "Paramedic action figure" - desc = "A \"Space Life\" brand Paramedic action figure." + desc = "A \"Space Life\" brand space bounty hunter action figure." icon_state = "paramedic" toysay = "WHERE ARE YOU??" @@ -755,6 +755,12 @@ desc = "A \"Space Life\" brand Emergency Response Team Commander action figure." icon_state = "ert" toysay = "We're probably the good guys!" + +/obj/item/toy/figure/samus + name = "Space bounty hunter action figure" + desc = "A \"Space Life\" brand Emergency Response Team Commander action figure." + icon_state = "samus" + toysay = "The last greytide is in captivity. The station is at peace." /* * Plushies diff --git a/code/game/objects/items/weapons/clown_items.dm b/code/game/objects/items/weapons/clown_items.dm index 7124cb489f..933c82f076 100644 --- a/code/game/objects/items/weapons/clown_items.dm +++ b/code/game/objects/items/weapons/clown_items.dm @@ -18,10 +18,10 @@ /obj/item/weapon/soap/New() ..() create_reagents(5) - wet() - -/obj/item/weapon/soap/proc/wet() - reagents.add_reagent("cleaner", 5) + wet(5) + +/obj/item/weapon/soap/proc/wet(var/amount) + reagents.add_reagent("cleaner", amount) /obj/item/weapon/soap/Crossed(AM as mob|obj) if (istype(AM, /mob/living)) @@ -47,7 +47,10 @@ T.clean(src, user) else if(istype(target,/obj/structure/sink)) to_chat(user, "You wet \the [src] in the sink.") - wet() + if(tile_clean_amount) + wet(tile_clean_amount) + else + wet(5) else to_chat(user, "You clean \the [target.name].") target.clean_blood() @@ -67,7 +70,7 @@ /obj/item/weapon/bikehorn/attack_self(mob/user as mob) if (spam_flag == 0) spam_flag = 1 - playsound(src.loc, 'sound/items/bikehorn.ogg', 50, 1) + playsound(src.loc, honkSound, 50, 1) src.add_fingerprint(user) spawn(20) spam_flag = 0 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 7536d41253..dd71cd2e32 100644 --- a/code/game/objects/items/weapons/id cards/station_ids.dm +++ b/code/game/objects/items/weapons/id cards/station_ids.dm @@ -149,17 +149,23 @@ item_state = "gold_id" preserve_item = 1 +//TFF 3/5/19 - allow Captain to get into Clown/Mime Office. Why? Because they already have access to the rest of the station. /obj/item/weapon/card/id/gold/captain assignment = "Colony Director" rank = "Colony Director" job_access_type = /datum/job/captain +/obj/item/weapon/card/id/gold/captain/initialize() + . = ..() + access = get_all_station_access() + access_mime + access_clown + /obj/item/weapon/card/id/gold/captain/spare name = "\improper Colony Director's spare ID" desc = "The spare ID of the High Lord himself." registered_name = "Colony Director" job_access_type = /datum/job/captain +//TFF 3/5/19 - allow borgs/drones to get into Clown/Mime Office. Why? Because they already have access to the rest of the station. /obj/item/weapon/card/id/synthetic name = "\improper Synthetic ID" desc = "Access module for NanoTrasen Synthetics" @@ -169,7 +175,7 @@ /obj/item/weapon/card/id/synthetic/initialize() . = ..() - access = get_all_station_access() + access_synth + access = get_all_station_access() + access_clown + access_mime + access_synth /obj/item/weapon/card/id/centcom name = "\improper CentCom. ID" @@ -277,6 +283,11 @@ primary_color = rgb(189,94,0) secondary_color = rgb(223,159,95) +/obj/item/weapon/card/id/engineering/spare //CHOMPEDIT: So in case of emergency solars can be set up + name = "Spare Electrical access card" + desc = "A spare for the case that power related issues arise without engineers aboard." + primary_color = rgb(0,0,0) + /obj/item/weapon/card/id/engineering/engineer assignment = "Station Engineer" rank = "Station Engineer" @@ -419,3 +430,14 @@ icon_state = "permit" primary_color = rgb(142,94,0) secondary_color = rgb(191,159,95) + +//TFF 3/5/19 - allow clown/mime players to spawn in with real IDs and get into their places. +/obj/item/weapon/card/id/civilian/clown + assignment = "Clown" + rank = "Clown" + job_access_type = /datum/job/clown + +/obj/item/weapon/card/id/civilian/mime + assignment = "Mime" + rank = "Mime" + job_access_type = /datum/job/mime diff --git a/code/game/objects/items/weapons/manuals.dm b/code/game/objects/items/weapons/manuals.dm index 0db669545c..7e1759e8e4 100644 --- a/code/game/objects/items/weapons/manuals.dm +++ b/code/game/objects/items/weapons/manuals.dm @@ -33,6 +33,7 @@ author = "Engineering Encyclopedia" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned title = "Particle Accelerator User's Guide" +//TFF 18/5/19 - update information, add Tesla engine usage section /obj/item/weapon/book/manual/engineering_particle_accelerator/New() ..() dat = {" @@ -59,7 +60,7 @@
  • Close all the panels with your screwdriver
  • -

    Using the accelerator

    +

    Using the accelerator for the singularity engine

    1. Open the control panel
    2. @@ -69,6 +70,16 @@
    3. Remember to wear a radiation suit when working with this machine... we did tell you that at the start, right?
    +

    Using the accelerator for the Tesla engine

    + +
      +
    1. Open the control panel
    2. +
    3. Set the speed to 2
    4. +
    5. Start firing at the tesla generator
    6. +
    7. When the energy ball gains a sufficient number of mini-balls orbiting it, such as around a dozen, set the speed down to 0, but don't shut it off
    8. +
    9. Remember to wear a radiation suit when working with this machine... we did tell you that at the start, right?
    10. +
    + "} @@ -80,6 +91,7 @@ author = "Central Engineering Division" title = "Supermatter Engine Operating Manual" +//TFF 18/5/19 - update information /obj/item/weapon/book/manual/supermatter_engine/New() ..() dat = {" @@ -98,7 +110,7 @@

    OPERATING PRINCIPLES


    -
  • The supermatter crystal serves as the fundamental power source of the engine. Upon being charged, it begins to emit large amounts of heat and radiation, as well and oxygen and phoron gas. As oxygen accelerates the reaction, and phoron carries the risk of fire, these must be filtered out. NOTE: Supermatter radiation will not charge radiation collectors.
  • +
  • The supermatter crystal serves as the fundamental power source of the engine. Upon being charged, it begins to emit large amounts of heat and radiation, as well and oxygen and phoron gas. As oxygen accelerates the reaction, and phoron carries the risk of fire, these must be filtered out.

  • Air in the reactor chamber housing the supermatter is circulated through the reactor loop, which passes through the filters and thermoelectric generators. The thermoelectric generators transfer heat from the reactor loop to the colder radiator loop, thereby generating power. Additional power is generated from internal turbines in the circulators.

  • @@ -116,9 +128,9 @@

    STARTUP PROCEDURE

      -
    1. Fill reactor loop and radiator loop with two (2) standard canisters of nitrogen gas each.
    2. +
    3. Fill reactor loop and radiator loop with two (2) standard canisters of any one type of gas each, excluding, obviously, oxygen.
    4. Ensure that pumps and filters are on and operating at maximum power.
    5. -
    6. Fire 8-9 pulses from emitter at supermatter crystal. Reactor blast doors must be open for this procedure.
    7. +
    8. Fire from eight to sixteen pulses, depending on your chosen gas coolant, from emitter at supermatter crystal. Reactor blast doors must be open for this procedure.

    OPERATION AND MAINTENANCE

    @@ -149,6 +161,7 @@ // TESLA Engine +//TFF 18/5/19 - update information /obj/item/weapon/book/manual/tesla_engine name = "Tesla Operating Manual" icon_state ="bookTesla" @@ -196,7 +209,7 @@

    OPERATION AND MAINTENANCE

      -
    1. Ensure that electrical protection and meson goggles are worn at all times while working in the engine room.
    2. +
    3. Ensure that electrical protection and welding tool protection are worn at all times while working with the engine and its individual components wherever they are set up.
    4. Ensure that Telsa Coils and/or Grounding Rods are placed to safely collect or ground any and all shock.
    5. Ensure that all Emitters remain activated and have unobstructed lines of fire to the Field Generators.
    6. Do not let the Emitters run out of power.
    7. @@ -224,6 +237,7 @@ author = "Cindy Crawfish" title = "R-UST Operating Manual" +//TFF 18/5/19 - TODO, update information on this if/when I get around to bringing a submap for engine rotation into the game. /obj/item/weapon/book/manual/rust_engine/New() ..() dat = {" @@ -272,7 +286,7 @@ - + @@ -462,7 +476,7 @@ "} - +//TFF 18/5/19 - update information /obj/item/weapon/book/manual/ripley_build_and_repair name = "APLU \"Ripley\" Construction and Operation Manual" icon_state ="book" @@ -514,14 +528,14 @@
    8. Adjust the servohydraulics with a screwdriver.
    9. Wire the chassis (Cable is not included).
    10. Use the wirecutters to remove the excess cable if needed.
    11. -
    12. Install the central control module (Not included. Use supplied datadisk to create one).
    13. +
    14. Install the central control module (Not included. Print from a Circuit Imprinter in the Research and Development Room).
    15. Secure the mainboard with a screwdriver.
    16. -
    17. Install the peripherals control module (Not included. Use supplied datadisk to create one).
    18. +
    19. Install the peripherals control module (Not included. Print from a Circuit Imprinter in the Research and Development Room).
    20. Secure the peripherals control module with a screwdriver.
    21. -
    22. Install the internal armor plating (Not included due to corporate regulations. Can be made using 5 metal sheets).
    23. +
    24. Install the internal armor plating by using some sheets of steel in the appropriate closet of materials.
    25. Secure the internal armor plating with a wrench.
    26. Weld the internal armor plating to the chassis.
    27. -
    28. Install the external reinforced armor plating (Not included due to corporate regulations. Can be made using 5 reinforced metal sheets).
    29. +
    30. Install the external reinforced armor plating by using some sheets of plasteel in the appropriate closet of materials.
    31. Secure the external reinforced armor plating with a wrench.
    32. Weld the external reinforced armor plating to the chassis.
    @@ -892,7 +906,8 @@ author = "Engineering Encyclopedia" title = "Engineering Textbook" -/obj/item/weapon/book/manual/engineering_guide/New() +//TFF 18/5/19 - Temporary removal as we don't have the appropriate article on our wiki. +/*/obj/item/weapon/book/manual/engineering_guide/New() ..() dat = {" @@ -905,7 +920,7 @@ "} - +*/ /obj/item/weapon/book/manual/chef_recipes name = "Chef Recipes" diff --git a/code/game/objects/items/weapons/material/swords.dm b/code/game/objects/items/weapons/material/swords.dm index 9efe911360..4e672ff68d 100644 --- a/code/game/objects/items/weapons/material/swords.dm +++ b/code/game/objects/items/weapons/material/swords.dm @@ -33,3 +33,12 @@ var/datum/gender/TU = gender_datums[user.get_visible_gender()] visible_message(span("danger", "[user] is slitting [TU.his] stomach open with \the [src.name]! It looks like [TU.hes] trying to commit seppuku."), span("danger", "You slit your stomach open with \the [src.name]!"), span("danger", "You hear the sound of flesh tearing open.")) // gory, but it gets the point across return(BRUTELOSS) +//CHOMPEDIT CHAPLAIN SWORD OF ~~The honkmother~~ +/obj/item/weapon/material/sword/chaplain + name = "chaplains claymore" + desc = "There can only honk one!" + force_divisor = 0.0 + thrown_force_divisor = 0.0 + sharp = 0 + edge = 0 + hitsound = 'sound/items/bikehorn.ogg' diff --git a/code/game/objects/items/weapons/policetape.dm b/code/game/objects/items/weapons/policetape.dm index 43183d45f4..be10b7821f 100644 --- a/code/game/objects/items/weapons/policetape.dm +++ b/code/game/objects/items/weapons/policetape.dm @@ -134,17 +134,18 @@ var/list/tape_roll_applications = list() update_icon() return ..() +//TFF 2/5/19: Polaris fix for taperolls not being usable on tiles with directional windows /obj/item/taperoll/attack_self(mob/user as mob) if(!start) start = get_turf(src) - usr << "You place the first end of \the [src]." + to_chat(user, "You place the first end of \the [src].") update_icon() else end = get_turf(src) if(start.y != end.y && start.x != end.x || start.z != end.z) start = null update_icon() - usr << "\The [src] can only be laid horizontally or vertically." + to_chat(user, "\The [src] can only be laid horizontally or vertically.") return if(start == end) @@ -154,15 +155,18 @@ var/list/tape_roll_applications = list() for(var/dir in cardinal) T = get_step(start, dir) if(T && T.density) - possible_dirs += dir + possible_dirs |= dir //TFF 2/5/19: Polaris fix for taperolls not being usable on tiles with directional windows else for(var/obj/structure/window/W in T) if(W.is_fulltile() || W.dir == reverse_dir[dir]) - possible_dirs += dir + possible_dirs |= dir + for(var/obj/structure/window/window in start) + if(istype(window) && !window.is_fulltile()) + possible_dirs |= window.dir if(!possible_dirs) start = null update_icon() - usr << "You can't place \the [src] here." + to_chat(user, "You can't place \the [src] here.") return if(possible_dirs & (NORTH|SOUTH)) var/obj/item/tape/TP = new tape_type(start) @@ -178,7 +182,7 @@ var/list/tape_roll_applications = list() TP.update_icon() start = null update_icon() - usr << "You finish placing \the [src]." + to_chat(user, "You finish placing \the [src].") return var/turf/cur = start @@ -196,6 +200,29 @@ var/list/tape_roll_applications = list() can_place = 0 else for(var/obj/O in cur) + //TFF 2/5/19: Handle places where you can't place down table (I think) + if(istype(O, /obj/structure/window)) + var/obj/structure/window/window = O + if(window.is_fulltile()) + can_place = 0 + break + if(cur == start) + if(window.dir == orientation) + can_place = 0 + break + else + continue + else if(cur == end) + if(window.dir == reverse_dir[orientation]) + can_place = 0 + break + else + continue + else if (window.dir == reverse_dir[orientation] || window.dir == orientation) + can_place = 0 + break + else + continue if(O.density) can_place = 0 break @@ -205,7 +232,7 @@ var/list/tape_roll_applications = list() if (!can_place) start = null update_icon() - usr << "You can't run \the [src] through that!" + to_chat(user, "You can't run \the [src] through that!") return cur = start @@ -221,6 +248,10 @@ var/list/tape_roll_applications = list() for(var/obj/structure/window/W in T) if(W.is_fulltile() || W.dir == orientation) tape_dir = dir + //TFF 2/5/19 - reverse orientation + for(var/obj/structure/window/window in cur) + if(istype(window) && !window.is_fulltile() && window.dir == reverse_dir[orientation]) + tape_dir = dir else if(cur == end) var/turf/T = get_step(end, orientation) if(T && !T.density) @@ -228,6 +259,10 @@ var/list/tape_roll_applications = list() for(var/obj/structure/window/W in T) if(W.is_fulltile() || W.dir == reverse_dir[orientation]) tape_dir = dir + //TFF 2/5/19 - regular orientation + for(var/obj/structure/window/window in cur) + if(istype(window) && !window.is_fulltile() && window.dir == orientation) + tape_dir = dir for(var/obj/item/tape/T in cur) if((T.tape_dir == tape_dir) && (T.icon_base == icon_base)) tapetest = 1 @@ -243,7 +278,7 @@ var/list/tape_roll_applications = list() cur = get_step_towards(cur,end) start = null update_icon() - usr << "You finish placing \the [src]." + to_chat(user, "You finish placing \the [src].") return /obj/item/taperoll/afterattack(var/atom/A, mob/user as mob, proximity) @@ -253,12 +288,12 @@ var/list/tape_roll_applications = list() if (istype(A, /obj/machinery/door)) var/turf/T = get_turf(A) if(locate(/obj/item/tape, A.loc)) - user << "There's already tape over that door!" + to_chat(user, "There's already tape over that door!") else var/obj/item/tape/P = new tape_type(T) P.update_icon() P.layer = WINDOW_LAYER - user << "You finish placing \the [src]." + to_chat(user, "You finish placing \the [src].") if (istype(A, /turf/simulated/floor) ||istype(A, /turf/unsimulated/floor)) var/turf/F = A diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm index 18c60af449..db863cac4d 100644 --- a/code/game/objects/items/weapons/storage/backpack.dm +++ b/code/game/objects/items/weapons/storage/backpack.dm @@ -58,6 +58,14 @@ return . = ..() +/obj/item/weapon/storage/backpack/storagecore + name = "Storage Core" + desc = "A repurposed technomancer core, your own little pocket dimension" + icon_state = "storagecore" + max_w_class = ITEMSIZE_LARGE + max_storage_space = 112 + storage_cost = INVENTORY_STANDARD_SPACE + 1 + //Please don't clutter the parent storage item with stupid hacks. /obj/item/weapon/storage/backpack/holding/can_be_inserted(obj/item/W as obj, stop_messages = 0) if(istype(W, /obj/item/weapon/storage/backpack/holding)) diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index 0a1f358eb4..71b5b0fe91 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -57,6 +57,7 @@ desc = "A survival box issued to crew members for use in emergency situations." starts_with = list( /obj/item/clothing/glasses/goggles, //VOREStation Add - Goggles for the phoron atmosphere, + /obj/item/weapon/prybar/red, //TFF: Ports prybar addition from VOREStation, /obj/item/clothing/mask/breath ) @@ -64,7 +65,8 @@ name = "synthetic supply box" desc = "A survival box issued to synthetic crew members for use in emergency situations." starts_with = list( - /obj/item/clothing/glasses/goggles //VOREStation Add - Goggles for the phoron atmosphere, + /obj/item/clothing/glasses/goggles, //VOREStation Add - Goggles for the phoron atmosphere, + /obj/item/weapon/prybar/red //TFF: Ports prybar addition from VOREStation, ) /obj/item/weapon/storage/box/survival/comp @@ -73,6 +75,7 @@ icon_state = "survival" starts_with = list( /obj/item/clothing/glasses/goggles, //VOREStation Add - Goggles for the phoron atmosphere, + /obj/item/weapon/prybar/red, //TFF: Ports prybar addition from VOREStation, /obj/item/weapon/reagent_containers/hypospray/autoinjector, /obj/item/stack/medical/bruise_pack, /obj/item/device/flashlight/glowstick, @@ -479,3 +482,9 @@ name = "ambrosia deus seeds box" desc = "Contains the seeds you need to get a proper healthy high." starts_with = list(/obj/item/seeds/ambrosiadeusseed = 7) + +//TFF: Add special box for Command Secretaries' equipment. +/obj/item/weapon/storage/box/command_sec + name = "clipboards and pens" + desc = "Contains a few clipboards and pens for your new secretary!" + starts_with = list(/obj/item/weapon/pen = 4, /obj/item/weapon/clipboard = 4) diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm index 268a8d5ad7..da995d9cf0 100644 --- a/code/game/objects/items/weapons/stunbaton.dm +++ b/code/game/objects/items/weapons/stunbaton.dm @@ -166,7 +166,7 @@ var/mob/living/carbon/human/H = target affecting = H.get_organ(hit_zone) - if(user.a_intent == I_HURT || user.a_intent == I_DISARM) + if(user.a_intent == I_HURT) . = ..() //whacking someone causes a much poorer electrical contact than deliberately prodding them. agony *= 0.5 diff --git a/code/game/objects/items/weapons/tanks/tank_types.dm b/code/game/objects/items/weapons/tanks/tank_types.dm index efacad4942..4afe0101b5 100644 --- a/code/game/objects/items/weapons/tanks/tank_types.dm +++ b/code/game/objects/items/weapons/tanks/tank_types.dm @@ -133,13 +133,13 @@ /obj/item/weapon/tank/emergency/oxygen name = "emergency oxygen tank" - desc = "Used for emergencies. Contains very little oxygen, so try to conserve it until you actually need it." + desc = "Used for emergencies. Use sparingly if you need it." //TFF: Changes desc since it's got a full tank now. icon_state = "emergency" gauge_icon = "indicator_emergency" /obj/item/weapon/tank/emergency/oxygen/New() ..() - src.air_contents.adjust_gas("oxygen", (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) + src.air_contents.adjust_gas("oxygen", (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) //TFF: Ports full tank version from Polaris. return @@ -167,7 +167,7 @@ /obj/item/weapon/tank/emergency/nitrogen/New() ..() - src.air_contents.adjust_gas("nitrogen", (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) + src.air_contents.adjust_gas("nitrogen", (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) //TFF: Ports Polaris's full tank edit. Note: Not sure why this is needed. Or more specifically was done. Probably isn't needed. /obj/item/weapon/tank/emergency/nitrogen/double name = "double emergency nitrogen tank" @@ -183,7 +183,7 @@ /obj/item/weapon/tank/emergency/phoron/New() ..() - src.air_contents.adjust_gas("phoron", (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) + src.air_contents.adjust_gas("phoron", (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) //TFF: Ports Polaris's full tank edit. /obj/item/weapon/tank/emergency/phoron/double name = "double emergency phoron tank" diff --git a/code/game/objects/items/weapons/tape.dm b/code/game/objects/items/weapons/tape.dm index 5a57515588..5efc404824 100644 --- a/code/game/objects/items/weapons/tape.dm +++ b/code/game/objects/items/weapons/tape.dm @@ -5,6 +5,11 @@ icon_state = "taperoll" w_class = ITEMSIZE_TINY +/obj/item/weapon/tape_roll/New() + ..() + if(Holiday == "April Fool's Day") + name = "flextape roll" + /obj/item/weapon/tape_roll/attack(var/mob/living/carbon/human/H, var/mob/user) if(istype(H)) var/can_place = 0 @@ -143,6 +148,8 @@ /obj/item/weapon/ducttape/New() ..() flags |= NOBLUDGEON + if(Holiday == "April Fool's Day") + name = "flextape" /obj/item/weapon/ducttape/examine(mob/user) return stuck.examine(user) diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index 9a8937adbc..0f79d8146e 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -978,6 +978,35 @@ user.put_in_active_hand(counterpart) to_chat(user, "You attach the cutting jaws to [src].") +//TFF: Add new tool, prybar, ported from VOREStation. +/obj/item/weapon/prybar + name = "pry bar" + desc = "A steel bar with a wedge, designed specifically for opening unpowered doors in an emergency. It comes in a variety of configurations - collect them all!" + icon = 'icons/obj/tools_vr.dmi' + icon_state = "prybar" + flags = CONDUCT + slot_flags = SLOT_BELT + force = 4 + throwforce = 5 + pry = 1 + item_state = "crowbar" + w_class = ITEMSIZE_SMALL + origin_tech = list(TECH_ENGINEERING = 1) + matter = list(DEFAULT_WALL_MATERIAL = 30) + attack_verb = list("whapped", "smacked", "swatted", "thwacked", "hit") + usesound = 'sound/items/crowbar.ogg' + toolspeed = 1 + var/random_color = TRUE + +/obj/item/weapon/prybar/red + icon_state = "prybar_red" + item_state = "crowbar_red" + random_color = FALSE + +/obj/item/weapon/prybar/New() + if(random_color) + icon_state = "prybar[pick("","_green","_aubergine","_blue")]" + . = ..() /*/obj/item/weapon/combitool name = "combi-tool" diff --git a/code/game/objects/mob_spawner_chomp.dm b/code/game/objects/mob_spawner_chomp.dm index 7a0a1913a3..508278fe06 100644 --- a/code/game/objects/mob_spawner_chomp.dm +++ b/code/game/objects/mob_spawner_chomp.dm @@ -16,7 +16,7 @@ /mob/living/simple_animal/hostile/scarybat = 70, /mob/living/simple_animal/hostile/jelly = 25, /mob/living/simple_animal/hostile/bear = 1, - /mob/living/simple_animal/hostile/deathclaw = 1, + /mob/living/simple_animal/hostile/deathclaw/minor = 1, /mob/living/simple_animal/hostile/goose = 60, /mob/living/simple_animal/retaliate/bee = 50, /mob/living/simple_animal/hostile/metroid/mine = 20, @@ -26,7 +26,8 @@ if(!ispath(mob_path)) return 0 var/mob/living/L = new mob_path(get_turf(src)) - L/simple_animal.vore_escape_time = 15 SECONDS + if (ispath(L, /mob/living/simple_animal)) + L/simple_animal.vore_escape_time = 15 SECONDS // Mob vore nerf! L.source_spawner = src spawned_mobs.Add(L) last_spawn = world.time @@ -34,4 +35,4 @@ total_spawns-- if(mob_faction) L.faction = mob_faction - return L \ No newline at end of file + return L 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 d6a3b58847..68012a79d2 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -74,6 +74,23 @@ /obj/item/clothing/under/gimmick/rank/head_of_personnel/suit/skirt, /obj/item/clothing/glasses/sunglasses) +//TFF: Command Secretary Equipment +/obj/structure/closet/secure_closet/comsecequip + name = "command secretary's equipment" + icon_state = "hopsecure1" + icon_closed = "hopsecure" + icon_locked = "hopsecure1" + icon_opened = "hopsecureopen" + icon_broken = "hopsecurebroken" + icon_off = "hopsecureoff" + req_access = list(access_hop, access_heads) + + starts_with = list( + /obj/item/device/radio/headset/headset_com = 3, + /obj/item/clothing/under/suit_jacket/female/skirt = 2, + /obj/item/clothing/under/suit_jacket/charcoal = 2, + /obj/item/weapon/storage/box/command_sec) + /obj/structure/closet/secure_closet/hos name = "head of security's locker" diff --git a/code/game/objects/structures/musician.dm b/code/game/objects/structures/musician.dm index c34740c748..8cfdc27799 100644 --- a/code/game/objects/structures/musician.dm +++ b/code/game/objects/structures/musician.dm @@ -318,8 +318,8 @@ defined by tempo / x: C,G/2,E/4
    Combined, an example is: E-E4/4,/2,G#/8,B/8,E3-E4/4
    - Lines may be up to 50 characters.
    - A song may only contain up to 50 lines.
    + Lines may be up to 500 characters.
    + A song may only contain up to 500 lines.
    "} else dat += "Show Help
    " @@ -360,10 +360,10 @@ var/newline = html_encode(input("Enter your line: ", "Piano") as text|null) if(!newline) return - if(song.lines.len > 50) + if(song.lines.len > 500) return - if(lentext(newline) > 50) - newline = copytext(newline, 1, 50) + if(lentext(newline) > 500) + newline = copytext(newline, 1, 500) song.lines.Add(newline) else if(href_list["deleteline"]) @@ -377,8 +377,8 @@ var/content = html_encode(input("Enter your line: ", "Piano", song.lines[num]) as text|null) if(!content) return - if(lentext(content) > 50) - content = copytext(content, 1, 50) + if(lentext(content) > 500) + content = copytext(content, 1, 500) if(num > song.lines.len || num < 1) return song.lines[num] = content @@ -399,11 +399,11 @@ if (!in_range(src, usr)) return - if(lentext(t) >= 3072) + if(lentext(t) >= 5000) var/cont = input(usr, "Your message is too long! Would you like to continue editing it?", "", "yes") in list("yes", "no") if(cont == "no") break - while(lentext(t) > 3072) + while(lentext(t) > 5000) //split into lines spawn() @@ -412,12 +412,12 @@ if(copytext(lines[1],1,6) == "BPM: ") tempo = 600 / text2num(copytext(lines[1],6)) lines.Cut(1,2) - if(lines.len > 50) + if(lines.len > 500) usr << "Too many lines!" - lines.Cut(51) + lines.Cut(501) var/linenum = 1 for(var/l in lines) - if(lentext(l) > 50) + if(lentext(l) > 500) usr << "Line [linenum] too long!" lines.Remove(l) else diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm index 8d391f14ff..1972a245ed 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm @@ -189,6 +189,157 @@ /obj/structure/bed/chair/office/dark icon_state = "officechair_dark" +/obj/structure/bed/chair/oldsofa //Original Paradise port kept in the event players like these couches. + name = "sofa" + desc = "It's a couch. It looks kinda dingy." + icon_state = "sofamiddleOLD" + base_icon = "sofamiddleOLD" + applies_material_colour = 0 + +/obj/structure/bed/chair/oldsofa/left + icon_state = "sofaend_leftOLD" + base_icon = "sofaend_leftOLD" + +/obj/structure/bed/chair/oldsofa/right + icon_state = "sofaend_rightOLD" + base_icon = "sofaend_rightOLD" + +/obj/structure/bed/chair/oldsofa/corner + icon_state = "sofacornerOLD" + base_icon = "sofacornerOLD" + +//Middle couch pieces. +/obj/structure/bed/chair/sofa + name = "sofa" + desc = "It's a couch. It looks comfy." + icon_state = "sofamiddle" + base_icon = "sofamiddle" + +/obj/structure/bed/chair/sofa/brown/New(var/newloc,var/newmaterial) + ..(newloc,"steel","leather") + +/obj/structure/bed/chair/sofa/red/New(var/newloc,var/newmaterial) + ..(newloc,"steel","carpet") + +/obj/structure/bed/chair/sofa/teal/New(var/newloc,var/newmaterial) + ..(newloc,"steel","teal") + +/obj/structure/bed/chair/sofa/black/New(var/newloc,var/newmaterial) + ..(newloc,"steel","black") + +/obj/structure/bed/chair/sofa/green/New(var/newloc,var/newmaterial) + ..(newloc,"steel","green") + +/obj/structure/bed/chair/sofa/purp/New(var/newloc,var/newmaterial) + ..(newloc,"steel","purple") + +/obj/structure/bed/chair/sofa/blue/New(var/newloc,var/newmaterial) + ..(newloc,"steel","blue") + +/obj/structure/bed/chair/sofa/beige/New(var/newloc,var/newmaterial) + ..(newloc,"steel","beige") + +/obj/structure/bed/chair/sofa/lime/New(var/newloc,var/newmaterial) + ..(newloc,"steel","lime") + +//Left couch pieces. +/obj/structure/bed/chair/sofa/left + icon_state = "sofaend_left" + base_icon = "sofaend_left" + +/obj/structure/bed/chair/sofa/left/brown/New(var/newloc,var/newmaterial) + ..(newloc,"steel","leather") + +/obj/structure/bed/chair/sofa/left/red/New(var/newloc,var/newmaterial) + ..(newloc,"steel","carpet") + +/obj/structure/bed/chair/sofa/left/teal/New(var/newloc,var/newmaterial) + ..(newloc,"steel","teal") + +/obj/structure/bed/chair/sofa/left/black/New(var/newloc,var/newmaterial) + ..(newloc,"steel","black") + +/obj/structure/bed/chair/sofa/left/green/New(var/newloc,var/newmaterial) + ..(newloc,"steel","green") + +/obj/structure/bed/chair/sofa/left/purp/New(var/newloc,var/newmaterial) + ..(newloc,"steel","purple") + +/obj/structure/bed/chair/sofa/left/blue/New(var/newloc,var/newmaterial) + ..(newloc,"steel","blue") + +/obj/structure/bed/chair/sofa/left/beige/New(var/newloc,var/newmaterial) + ..(newloc,"steel","beige") + +/obj/structure/bed/chair/sofa/left/lime/New(var/newloc,var/newmaterial) + ..(newloc,"steel","lime") + + +//Right couch pieces. +/obj/structure/bed/chair/sofa/right + icon_state = "sofaend_right" + base_icon = "sofaend_right" + +/obj/structure/bed/chair/sofa/right/brown/New(var/newloc,var/newmaterial) + ..(newloc,"steel","leather") + +/obj/structure/bed/chair/sofa/right/red/New(var/newloc,var/newmaterial) + ..(newloc,"steel","carpet") + +/obj/structure/bed/chair/sofa/right/teal/New(var/newloc,var/newmaterial) + ..(newloc,"steel","teal") + +/obj/structure/bed/chair/sofa/right/black/New(var/newloc,var/newmaterial) + ..(newloc,"steel","black") + +/obj/structure/bed/chair/sofa/right/green/New(var/newloc,var/newmaterial) + ..(newloc,"steel","green") + +/obj/structure/bed/chair/sofa/right/purp/New(var/newloc,var/newmaterial) + ..(newloc,"steel","purple") + +/obj/structure/bed/chair/sofa/right/blue/New(var/newloc,var/newmaterial) + ..(newloc,"steel","blue") + +/obj/structure/bed/chair/sofa/right/beige/New(var/newloc,var/newmaterial) + ..(newloc,"steel","beige") + +/obj/structure/bed/chair/sofa/right/lime/New(var/newloc,var/newmaterial) + ..(newloc,"steel","lime") + + +//Corner couch pieces. +/obj/structure/bed/chair/sofa/corner + icon_state = "sofacorner" + base_icon = "sofacorner" + +/obj/structure/bed/chair/sofa/corner/brown/New(var/newloc,var/newmaterial) + ..(newloc,"steel","leather") + +/obj/structure/bed/chair/sofa/corner/red/New(var/newloc,var/newmaterial) + ..(newloc,"steel","carpet") + +/obj/structure/bed/chair/sofa/corner/teal/New(var/newloc,var/newmaterial) + ..(newloc,"steel","teal") + +/obj/structure/bed/chair/sofa/corner/black/New(var/newloc,var/newmaterial) + ..(newloc,"steel","black") + +/obj/structure/bed/chair/sofa/corner/green/New(var/newloc,var/newmaterial) + ..(newloc,"steel","green") + +/obj/structure/bed/chair/sofa/corner/purp/New(var/newloc,var/newmaterial) + ..(newloc,"steel","purple") + +/obj/structure/bed/chair/sofa/corner/blue/New(var/newloc,var/newmaterial) + ..(newloc,"steel","blue") + +/obj/structure/bed/chair/sofa/corner/beige/New(var/newloc,var/newmaterial) + ..(newloc,"steel","beige") + +/obj/structure/bed/chair/sofa/corner/lime/New(var/newloc,var/newmaterial) + ..(newloc,"steel","lime") + // Chair types /obj/structure/bed/chair/wood name = "wooden chair" diff --git a/code/game/objects/structures/stool_bed_chair_nest/stools.dm b/code/game/objects/structures/stool_bed_chair_nest/stools.dm index 33ef80b4bd..5b01ba6139 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/stools.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/stools.dm @@ -6,6 +6,7 @@ var/global/list/stool_cache = list() //haha stool desc = "Apply butt." icon = 'icons/obj/furniture_vr.dmi' //VOREStation Edit - new Icons icon_state = "stool_preview" //set for the map + can_buckle = 1 //TFF: You can now throw people with your immense strength while they're sitting on the stool! >:3 force = 10 throwforce = 10 w_class = ITEMSIZE_HUGE @@ -105,6 +106,10 @@ var/global/list/stool_cache = list() //haha stool material.place_sheet(get_turf(src)) if(padding_material) padding_material.place_sheet(get_turf(src)) + // Adding a safety net to prevent players from being perma-buckled to the stool..! - Jon + if(has_buckled_mobs()) + for(var/A in buckled_mobs) + user_unbuckle_mob(A, src) qdel(src) /obj/item/weapon/stool/attackby(obj/item/weapon/W as obj, mob/user as mob) @@ -147,3 +152,11 @@ var/global/list/stool_cache = list() //haha stool remove_padding() else ..() + +// Chompstation ADD: A new proc to allow mobs to be unbuckled when clicking on a stool. +/obj/item/weapon/stool/attack_hand(mob/living/user as mob) + if(has_buckled_mobs()) + for(var/A in buckled_mobs) + user_unbuckle_mob(A, user) + return + ..() \ No newline at end of file diff --git a/code/game/objects/structures/trash_pile.dm b/code/game/objects/structures/trash_pile.dm index 727dcbb9f4..560357c235 100644 --- a/code/game/objects/structures/trash_pile.dm +++ b/code/game/objects/structures/trash_pile.dm @@ -119,7 +119,10 @@ searchedby += user.ckey I.forceMove(get_turf(src)) to_chat(H,"You found \a [I]!") - + var/disturbed_sleep = rand(1,100) //spawning of mobs, for now only the trash panda. + if(disturbed_sleep <= 5) + new /mob/living/simple_animal/raccoon(get_turf(user),name) + visible_message("A raccoon jumps out of the trash!.") else return ..() diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 98e0f1a41e..00beec7454 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -332,6 +332,38 @@ icon = 'icons/obj/watercloset.dmi' icon_state = "rubberducky" +//DUCK CODE START +/obj/item/weapon/bikehorn/rubberducky/evil + name = "Do not" + desc = "Evil fills the air, bath time will end, no one be spared." + +/obj/item/weapon/bikehorn/rubberducky/evil/attack_self(mob/user as mob) + if (!spam_flag) + spam_flag = 1 + playsound(src.loc, 'sound/items/bikehorn.ogg', 50, 1) + var/darkduckrising = /mob/living/simple_animal/hostile/giant_spider/darkduck + new darkduckrising(get_turf(user)) + spawn(100) + new darkduckrising(get_turf(user)) + spawn(100) + new darkduckrising(get_turf(user)) + spawn(100) + new darkduckrising(get_turf(user)) + qdel(src) + return + +/mob/living/simple_animal/hostile/giant_spider/darkduck + name = "The Duck" + desc = "Evil fills the air, bath time will end, no one be spared." + tt_desc = "Bath time stops" + icon = 'icons/mob/animal_VG.dmi' + icon_state = "Duck_lord" + icon_living = "Duck_lord_friendly" + icon_dead = "Duck_lord_dead" + isEdible = 1 + poison_chance = 0 +//DUCK CODE END + /obj/structure/sink name = "sink" icon = 'icons/obj/watercloset.dmi' diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index 13368bb7ed..b7d971f371 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -11,6 +11,8 @@ /turf/space/initialize() . = ..() + if(Holiday == "April Fool's Day") //CHOMPEDIT: let's have some fun~ + icon = 'icons/turf/vorespace.dmi' if(!keep_sprite) icon_state = "[((x + y) ^ ~(x * y) + z) % 25]" update_starlight() diff --git a/code/game/verbs/character_directory.dm b/code/game/verbs/character_directory.dm index 6f5a6debc2..072c7b14c0 100644 --- a/code/game/verbs/character_directory.dm +++ b/code/game/verbs/character_directory.dm @@ -29,6 +29,32 @@ html += "OOC notes" html += "" html += "" + +//TFF: Ports VoreStation addition of Borg/AI listing to display on Char Directory. Yay! + if(isAI(C.mob)) + var/mob/living/silicon/ai/A = C.mob + curID++ + html += "
    " + html += "

    [A.name] (Artificial Intelligence)


    " + if(A.ooc_notes) + html += "OOC notes" + html += "" + html += "
    " + if(isrobot(C.mob)) + var/mob/living/silicon/robot/R = C.mob + if(R.scrambledcodes || (R.module && R.module.hide_on_manifest)) + continue + curID++ + html += "
    " + html += "

    [R.name] ([R.modtype] [R.braintype])


    " + if(R.flavor_text) + html += "Flavor text" + html += "" + if(R.ooc_notes) + html += "OOC notes" + html += "" + html += "
    " + if(!curID) html += "

    404: Station not found

    " diff --git a/code/game/verbs/ooc.dm b/code/game/verbs/ooc.dm index 84eb9fe853..69c4675d4f 100644 --- a/code/game/verbs/ooc.dm +++ b/code/game/verbs/ooc.dm @@ -12,13 +12,18 @@ src << "Guests may not use OOC." return - //Chompstation ADD + msg = sanitize(msg) + if(!msg) return + + //Chompstation ADD - Emoji Parsing + msg = emoji_parse(msg) + + + //Chompstation ADD - IC in OOC Warning filter if((copytext(msg, 1, 2) in list(".",";",":","#")) || (findtext(lowertext(copytext(msg, 1, 5)), "say"))) if(alert("Your message \"[msg]\" looks like it was meant for in game communication, say it in OOC?", "Meant for OOC?", "No", "Yes") != "Yes") return - msg = sanitize(msg) - if(!msg) return if(!is_preference_enabled(/datum/client_preference/show_ooc)) src << "You have OOC muted." @@ -96,6 +101,9 @@ if(!msg) return + //Chompstation ADD - Emoji Parsing + msg = emoji_parse(msg) + if(!is_preference_enabled(/datum/client_preference/show_looc)) src << "You have LOOC muted." return diff --git a/code/global_vr.dm b/code/global_vr.dm index 8b4ab024fc..aacabec983 100644 --- a/code/global_vr.dm +++ b/code/global_vr.dm @@ -4,4 +4,5 @@ robot_module_types += "Janihound" robot_module_types += "Sci-borg" robot_module_types += "Pupdozer" + robot_module_types += "Service-borg" return 1 diff --git a/code/modules/admin/secrets/fun_secrets/break_all_lights.dm b/code/modules/admin/secrets/fun_secrets/break_all_lights.dm index ea54952a7e..b9671705a3 100644 --- a/code/modules/admin/secrets/fun_secrets/break_all_lights.dm +++ b/code/modules/admin/secrets/fun_secrets/break_all_lights.dm @@ -1,3 +1,4 @@ + /datum/admin_secret_item/fun_secret/break_all_lights name = "Break All Lights" diff --git a/code/modules/admin/secrets/fun_secrets/waddle_mode.dm b/code/modules/admin/secrets/fun_secrets/waddle_mode.dm new file mode 100644 index 0000000000..20346f88a0 --- /dev/null +++ b/code/modules/admin/secrets/fun_secrets/waddle_mode.dm @@ -0,0 +1,14 @@ +var/global/waddleToggle = 0 + +/datum/admin_secret_item/fun_secret/waddle_mode + name = "South Park Mode" + +/datum/admin_secret_item/fun_secret/waddle_mode/execute(var/mob/user) + ..() + if(!waddleToggle) + log_and_message_admins("[user] enabled waddling!", user) + waddleToggle = TRUE + else + log_and_message_admins("[user] disabled waddling!", user) + waddleToggle = FALSE + diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index c61ee1bb7f..3ecbcd4fb4 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -771,18 +771,19 @@ return 1 return 0 //we didn't do anything! +//TFF: Ports Polaris fix for kicking so you can cancel without it still executing the command. else if(href_list["boot2"]) var/mob/M = locate(href_list["boot2"]) if (ismob(M)) if(!check_if_greater_rights_than(M.client)) return - var/reason = sanitize(input("Please enter reason")) + var/reason = sanitize(input("Please enter reason.") as null|message) if(!reason) - M << "You have been kicked from the server" - else - M << "You have been kicked from the server: [reason]" - log_admin("[key_name(usr)] booted [key_name(M)].") - message_admins("[key_name_admin(usr)] booted [key_name_admin(M)].", 1) + return + + to_chat(M, span("critical", "You have been kicked from the server: [reason]")) + log_admin("[key_name(usr)] booted [key_name(M)] for reason: '[reason]'.") + message_admins("[key_name_admin(usr)] booted [key_name_admin(M)] for reason '[reason]'.", 1) //M.client = null qdel(M.client) diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index 4ff94877f4..ff861e2c88 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -106,6 +106,8 @@ log_adminpm(msg,src,C) send2adminirc("Reply: [key_name(src)]->[key_name(C)]: [html_decode(msg)]") + msg = emoji_parse(msg) //Chompstation ADD - Emojis + //we don't use message_admins here because the sender/receiver might get it too for(var/client/X in admins) @@ -126,6 +128,8 @@ return sanitize(msg) + msg = emoji_parse(msg) //Chompstation ADD - Emojis + // Handled on Bot32's end, unsure about other bots // if(length(msg) > 400) // TODO: if message length is over 400, divide it up into seperate messages, the message length restriction is based on IRC limitations. Probably easier to do this on the bots ends. diff --git a/code/modules/admin/verbs/debug_vr.dm b/code/modules/admin/verbs/debug_vr.dm index 79089c8da0..aaf959e059 100644 --- a/code/modules/admin/verbs/debug_vr.dm +++ b/code/modules/admin/verbs/debug_vr.dm @@ -3,7 +3,7 @@ set name = "Quick NIF" set desc = "Spawns a NIF into someone in quick-implant mode." - if(!check_rights(R_ADMIN || R_EVENT)) + if(!check_rights(R_ADMIN|R_EVENT|R_DEBUG)) //TFF 24/4/19: Allow Devs to use Quick-NIF verb. return var/mob/living/carbon/human/H = input("Pick a mob with a player","Quick NIF") as null|anything in player_list diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index cd4c253f66..2a709a9cf5 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -103,7 +103,7 @@ Code: var/obj/item/device/assembly/signaler/signaler2 = W if(secured && signaler2.secured) code = signaler2.code - frequency = signaler2.frequency + set_frequency(signaler2.frequency) //TFF 18/4/19: Polaris fix - frequency transfer to other signalers to_chat(user, "You transfer the frequency and code of [signaler2] to [src].") else ..() diff --git a/code/modules/busy_space_vr/organizations.dm b/code/modules/busy_space_vr/organizations.dm index 731ef73b22..97b4813b9f 100644 --- a/code/modules/busy_space_vr/organizations.dm +++ b/code/modules/busy_space_vr/organizations.dm @@ -437,6 +437,7 @@ "the SolGov embassy in Vilous" )// autogen will add a lot of other places as well. +/* //Removed ships in Virgo space because we're not in Virgo space. Perhaps revert back to Polaris later since we're in Vir. /datum/lore/organization/gov/sifgov // Overrides Polaris stuff name = "Virgo-Erigone Governmental Authority" short_name = "" @@ -468,6 +469,7 @@ "a telecommunications satellite near Virgo-3B", "a telecommunications satellite near Virgo-Prime" ) +*/ /* // Waiting for lore to be updated. /datum/lore/organization/gov/federation @@ -677,6 +679,7 @@ "... wait, why am I even telling you this? Just let me pass", "stop asking questions") +/* //KHI does not exist in our canon. /datum/lore/organization/gov/kitsuhana name = "Kitsuhana Heavy Industries" short_name = "Kitsuhana" @@ -730,6 +733,7 @@ "a Kitsuhana ringworld in Lund VI", "a Kitsuhana ringworld in Dais IX", "a Kitsuhana ringworld in Leibert II-b") +*/ /datum/lore/organization/gov/ares name = "Ares Confederation" @@ -788,6 +792,7 @@ "a settlement needing our help", "Forward Base Sigma-Alpha in ArCon space") +/* //Also commiting this out because we don't have space elves. /datum/lore/organization/gov/imperial name = "Auream Imperium" short_name = "Imperial" @@ -884,3 +889,4 @@ "near Cor Galaxia", "Segmentum Obscurum", // Basically their home territory, where our telescopes can't see. They prefer to keep it that way. They call it something else internally. ) +*/ \ No newline at end of file diff --git a/code/modules/client/preference_setup/loadout/loadout_accessories.dm b/code/modules/client/preference_setup/loadout/loadout_accessories.dm index 5e6dfae145..64b1da8a21 100644 --- a/code/modules/client/preference_setup/loadout/loadout_accessories.dm +++ b/code/modules/client/preference_setup/loadout/loadout_accessories.dm @@ -135,32 +135,32 @@ /datum/gear/accessory/brown_vest 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") + allowed_roles = list("Colony Director", "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, 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") + allowed_roles = list("Colony Director", "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, 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") + allowed_roles = list("Colony Director", "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, 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", "Search and Rescue") + allowed_roles = list("Colony Director", "Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor", "Search and Rescue") /datum/gear/accessory/black_drop_pouches 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", "Search and Rescue") + allowed_roles = list("Colony Director", "Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor", "Search and Rescue") /datum/gear/accessory/white_drop_pouches 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", "Search and Rescue") + allowed_roles = list("Colony Director", "Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor", "Search and Rescue") /datum/gear/accessory/fannypack display_name = "fannypack selection" @@ -243,4 +243,4 @@ /datum/gear/accessory/locket display_name = "locket" - path = /obj/item/clothing/accessory/locket \ No newline at end of file + path = /obj/item/clothing/accessory/locket diff --git a/code/modules/client/preference_setup/loadout/loadout_accessories_vr.dm b/code/modules/client/preference_setup/loadout/loadout_accessories_vr.dm index 86ea0381d0..23746cc104 100644 --- a/code/modules/client/preference_setup/loadout/loadout_accessories_vr.dm +++ b/code/modules/client/preference_setup/loadout/loadout_accessories_vr.dm @@ -30,6 +30,11 @@ display_name = "collar, holo" path = /obj/item/clothing/accessory/collar/holo +//TFF 23/4/19: Indigestible collar addition +/datum/gear/collar/holo/indigestible + display_name = "collar, holo (indigestible)" + path = /obj/item/clothing/accessory/collar/holo/indigestible + /datum/gear/accessory/white_drop_pouches allowed_roles = list("Paramedic","Chief Medical Officer","Medical Doctor","Chemist") @@ -53,4 +58,4 @@ /datum/gear/accessory/flops/New() ..() - gear_tweaks = list(gear_tweak_free_color_choice) \ No newline at end of file + gear_tweaks = list(gear_tweak_free_color_choice) diff --git a/code/modules/client/preference_setup/loadout/loadout_eyes_vr.dm b/code/modules/client/preference_setup/loadout/loadout_eyes_vr.dm index d8b29d0d92..36deb28018 100644 --- a/code/modules/client/preference_setup/loadout/loadout_eyes_vr.dm +++ b/code/modules/client/preference_setup/loadout/loadout_eyes_vr.dm @@ -12,4 +12,8 @@ /datum/gear/eyes/science_proper display_name = "science goggles (no overlay)" - path = /obj/item/clothing/glasses/fluff/science_proper \ No newline at end of file + path = /obj/item/clothing/glasses/fluff/science_proper + +datum/gear/eyes/flipgoggles + display_name = "Flip Goggles" + path = /obj/item/clothing/glasses/goggles/flip \ No newline at end of file diff --git a/code/modules/client/preference_setup/loadout/loadout_implants.dm b/code/modules/client/preference_setup/loadout/loadout_implants.dm new file mode 100644 index 0000000000..83a3d6a356 --- /dev/null +++ b/code/modules/client/preference_setup/loadout/loadout_implants.dm @@ -0,0 +1,40 @@ +//TFF 29/4/19: Add implants category, includes reagent implanters + + +/datum/gear/implant + display_name = "implant, tracking" + path = /obj/item/weapon/implant/tracking/weak + cost = 0 //VOREStation Edit. Changed cost to 0 + slot = "implant" + exploitable = 1 + sort_category = "Implants" + +/* VOREStation Edit - Make languages great again +/datum/gear/utility/implant/eal //This does nothing if you don't actually know EAL. + display_name = "implant, language, EAL" + path = /obj/item/weapon/implant/language/eal + cost = 2 + slot = "implant" + exploitable = 1*/ + +//Reagent implants - cost of 2 to reduce chance of abuse +//TFF 7/5/19 - bugfix for implanters appearing inside of chars rather than their bag. Switches to being the implant instead. +/datum/gear/implant/reagent_generator + display_name = "implant, milk production" + path = /obj/item/weapon/implant/reagent_generator/milk + exploitable = 0 + cost = 2 + +/datum/gear/implant/reagent_generator/egg + display_name = "implant, egg production" + path = /obj/item/weapon/implant/reagent_generator/egg + +//TFF 7/5/19 - requested addition of honey reagent generator +/datum/gear/implant/reagent_generator/honey + display_name = "implant, honey production" + path = /obj/item/weapon/implant/reagent_generator/honey + +//kcin 6/6/19 - i want to slurp slime +/datum/gear/implant/reagent_generator/slime + display_name = "implant, slime production" + path = /obj/item/weapon/implant/reagent_generator/slime \ No newline at end of file diff --git a/code/modules/client/preference_setup/loadout/loadout_shoes_vr.dm b/code/modules/client/preference_setup/loadout/loadout_shoes_vr.dm index ff04b6a989..5c5fac3e7f 100644 --- a/code/modules/client/preference_setup/loadout/loadout_shoes_vr.dm +++ b/code/modules/client/preference_setup/loadout/loadout_shoes_vr.dm @@ -12,4 +12,10 @@ /datum/gear/shoes/siren display_name = "boots, Siren" - path = /obj/item/clothing/shoes/boots/fluff/siren \ No newline at end of file + path = /obj/item/clothing/shoes/boots/fluff/siren + +/datum/gear/shoes/tall + display_name = "tall jackboots" + path = /obj/item/clothing/shoes/boots/jackboots/tall + slot = slot_shoes + sort_category = "Shoes and Footwear" \ No newline at end of file diff --git a/code/modules/client/preference_setup/loadout/loadout_suit_vr.dm b/code/modules/client/preference_setup/loadout/loadout_suit_vr.dm index 002d032a3d..22e8dea4ac 100644 --- a/code/modules/client/preference_setup/loadout/loadout_suit_vr.dm +++ b/code/modules/client/preference_setup/loadout/loadout_suit_vr.dm @@ -20,4 +20,8 @@ /datum/gear/suit/gntop display_name = "GN crop jacket" - path = /obj/item/clothing/suit/storage/fluff/gntop \ No newline at end of file + path = /obj/item/clothing/suit/storage/fluff/gntop + +/datum/gear/suit/denim_vest/black + display_name = "black denim vest" + path = /obj/item/clothing/suit/storage/toggle/denim_jacket/sleeveless/black \ No newline at end of file diff --git a/code/modules/client/preference_setup/loadout/loadout_uniform.dm b/code/modules/client/preference_setup/loadout/loadout_uniform.dm index 803c274efa..1248ae1207 100644 --- a/code/modules/client/preference_setup/loadout/loadout_uniform.dm +++ b/code/modules/client/preference_setup/loadout/loadout_uniform.dm @@ -55,6 +55,166 @@ jumpclothes[initial(jumps.name)] = jumps gear_tweaks += new/datum/gear_tweak/path(sortAssoc(jumpclothes)) +/datum/gear/uniform/job_suit/cd + display_name = "jumpsuit, cd" + path = /obj/item/clothing/under/rank/captain + allowed_roles = "Colony Director" + +/datum/gear/uniform/job_suit/ce + display_name = "jumpsuit, ce" + path = /obj/item/clothing/under/rank/chief_engineer + allowed_roles = "Chief Engineer" + +/datum/gear/uniform/job_suit/atmos + display_name = "jumpsuit, atmos" + path = /obj/item/clothing/under/rank/atmospheric_technician + allowed_roles = list("Chief Engineer","Atmospheric Technician") + +/datum/gear/uniform/job_suit/eng + display_name = "jumpsuit, engineer" + path = /obj/item/clothing/under/rank/engineer + allowed_roles = list("Chief Engineer","Station Engineer") + +/datum/gear/uniform/job_suit/rd + display_name = "jumpsuit, rd" + path = /obj/item/clothing/under/rank/research_director + allowed_roles = "Research Director" + +/datum/gear/uniform/job_suit/roboticist + display_name = "jumpsuit, roboticist" + path = /obj/item/clothing/under/rank/roboticist + allowed_roles = list("Research Director","Roboticist") + +/datum/gear/uniform/job_suit/scientist + display_name = "jumpsuit, scientist" + path = /obj/item/clothing/under/rank/scientist + allowed_roles = list("Research Director","Scientist") + +/datum/gear/uniform/job_suit/cmo + display_name = "jumpsuit, cmo" + path = /obj/item/clothing/under/rank/chief_medical_officer + allowed_roles = "Chief Medical Officer" + +/datum/gear/uniform/job_suit/chem + display_name = "jumpsuit, chemist" + path = /obj/item/clothing/under/rank/chemist + allowed_roles = list("Chief Medical Officer","Chemist") + +/datum/gear/uniform/job_suit/viro + display_name = "jumpsuit, virologist" + path = /obj/item/clothing/under/rank/virologist + allowed_roles = list("Chief Medical Officer","Medical Doctor") + +/datum/gear/uniform/job_suit/nurse + display_name = "suit, nurse" + path = /obj/item/clothing/under/rank/nursesuit + allowed_roles = list("Chief Medical Officer","Medical Doctor") + +/datum/gear/uniform/job_suit/nurse/alt + display_name = "outfit, nurse" + path = /obj/item/clothing/under/rank/nurse + allowed_roles = list("Chief Medical Officer","Medical Doctor") + +/datum/gear/uniform/job_suit/med + display_name = "jumpsuit, medical" + path = /obj/item/clothing/under/rank/medical + allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Psychiatrist","Paramedic") + +/datum/gear/uniform/job_suit/psych + display_name = "jumpsuit, psych" + path = /obj/item/clothing/under/rank/psych + allowed_roles = list("Chief Medical Officer","Psychiatrist") + +/datum/gear/uniform/job_suit/psych/alt + display_name = "outfit, psychologist" + path = /obj/item/clothing/under/rank/psych/turtleneck + allowed_roles = list("Chief Medical Officer","Psychiatrist") + +/datum/gear/uniform/job_suit/qm + display_name = "jumpsuit, qm" + path = /obj/item/clothing/under/rank/cargo + allowed_roles = "Quartermaster" + +/datum/gear/uniform/job_suit/cargotech + display_name = "jumpsuit, cargo" + path = /obj/item/clothing/under/rank/cargotech + allowed_roles = list("Quartermaster","Cargo Technician") + +/datum/gear/uniform/job_suit/miner + display_name = "jumpsuit, miner" + path = /obj/item/clothing/under/rank/miner + allowed_roles = list("Quartermaster","Shaft Miner") + +/datum/gear/uniform/job_suit/hos + display_name = "jumpsuit, hos" + path = /obj/item/clothing/under/rank/head_of_security + allowed_roles = "Head of Security" + +/datum/gear/uniform/job_suit/warden + display_name = "jumpsuit, warden" + path = /obj/item/clothing/under/rank/warden + allowed_roles = list("Head of Security","Warden") + +/datum/gear/uniform/job_suit/sec + display_name = "jumpsuit, security" + path = /obj/item/clothing/under/rank/security + allowed_roles = list("Head of Security","Warden","Security Officer","Detective") + +/datum/gear/uniform/job_suit/det + display_name = "jumpsuit, detective" + path = /obj/item/clothing/under/det/corporate + allowed_roles = list("Head of Security","Detective") + +/datum/gear/uniform/job_suit/hop + display_name = "jumpsuit, HoP" + path = /obj/item/clothing/under/rank/head_of_personnel + allowed_roles = "Head of Personnel" + +/datum/gear/uniform/job_suit/iaa + display_name = "uniform, Internal Affairs" + path = /obj/item/clothing/under/rank/internalaffairs + allowed_roles = "Internal Affairs Agent" + +/datum/gear/uniform/job_suit/janitor + display_name = "jumpsuit, janitor" + path = /obj/item/clothing/under/rank/janitor + allowed_roles = "Janitor" + +/datum/gear/uniform/job_suit/libr + display_name = "suit, librarian" + path = /obj/item/clothing/under/librarian + allowed_roles = "Librarian" + +/datum/gear/uniform/job_suit/bartender + display_name = "uniform, bar" + path = /obj/item/clothing/under/rank/bartender + allowed_roles = "Bartender" + +/datum/gear/uniform/job_suit/botanist + display_name = "jumpsuit, botanist" + path = /obj/item/clothing/under/rank/hydroponics + allowed_roles = "Botanist" + +/datum/gear/uniform/job_suit/chef + display_name = "uniform, chef" + path = /obj/item/clothing/under/rank/chef + allowed_roles = "Chef" + +/datum/gear/uniform/job_suit/chaplain + display_name = "jumpsuit, chaplain" + path = /obj/item/clothing/under/rank/chaplain + allowed_roles = "Chaplain" + +/datum/gear/uniform/job_suit/clown + display_name = "suit, clown" + path = /obj/item/clothing/under/rank/clown + allowed_roles = "Clown" + +/datum/gear/uniform/job_suit/mime + display_name = "outfit, mime" + path = /obj/item/clothing/under/mime + allowed_roles = "Mime" + /datum/gear/uniform/skirt display_name = "skirt selection" path = /obj/item/clothing/under/skirt diff --git a/code/modules/client/preference_setup/loadout/loadout_uniform_vr.dm b/code/modules/client/preference_setup/loadout/loadout_uniform_vr.dm index 58201bb73b..1fc01d1821 100644 --- a/code/modules/client/preference_setup/loadout/loadout_uniform_vr.dm +++ b/code/modules/client/preference_setup/loadout/loadout_uniform_vr.dm @@ -7,30 +7,30 @@ display_name = "pt uniform, planetside sec" path = /obj/item/clothing/under/pt/sifguard -//KHI Uniforms -/datum/gear/uniform/job_khi/cmd - display_name = "khi uniform, cmd" - path = /obj/item/clothing/under/rank/khi/cmd +//GE Uniforms +/datum/gear/uniform/job_ge/cmd + display_name = "ge uniform, cmd" + path = /obj/item/clothing/under/rank/ge/cmd allowed_roles = list("Head of Security","Colony Director","Head of Personnel","Chief Engineer","Research Director","Chief Medical Officer") -/datum/gear/uniform/job_khi/sec - display_name = "khi uniform, sec" - path = /obj/item/clothing/under/rank/khi/sec +/datum/gear/uniform/job_ge/sec + display_name = "ge uniform, sec" + path = /obj/item/clothing/under/rank/ge/sec allowed_roles = list("Head of Security", "Warden", "Detective", "Security Officer") -/datum/gear/uniform/job_khi/med - display_name = "khi uniform, med" - path = /obj/item/clothing/under/rank/khi/med +/datum/gear/uniform/job_ge/med + display_name = "ge uniform, med" + path = /obj/item/clothing/under/rank/ge/med allowed_roles = list("Chief Medical Officer","Medical Doctor","Chemist","Paramedic","Geneticist") -/datum/gear/uniform/job_khi/eng - display_name = "khi uniform, eng" - path = /obj/item/clothing/under/rank/khi/eng +/datum/gear/uniform/job_ge/eng + display_name = "ge uniform, eng" + path = /obj/item/clothing/under/rank/ge/eng allowed_roles = list("Chief Engineer","Atmospheric Technician","Station Engineer") -/datum/gear/uniform/job_khi/sci - display_name = "khi uniform, sci" - path = /obj/item/clothing/under/rank/khi/sci +/datum/gear/uniform/job_ge/sci + display_name = "ge uniform, sci" + path = /obj/item/clothing/under/rank/ge/sci allowed_roles = list("Research Director","Scientist", "Roboticist", "Xenobiologist") //Federation jackets diff --git a/code/modules/client/preference_setup/loadout/loadout_utility.dm b/code/modules/client/preference_setup/loadout/loadout_utility.dm index 76178dada2..c381c980dc 100644 --- a/code/modules/client/preference_setup/loadout/loadout_utility.dm +++ b/code/modules/client/preference_setup/loadout/loadout_utility.dm @@ -115,22 +115,7 @@ display_name = "cell, device" path = /obj/item/weapon/cell/device -/datum/gear/utility/implant - exploitable = 1 -/* VOREStation Edit - Make languages great again -/datum/gear/utility/implant/eal //This does nothing if you don't actually know EAL. - display_name = "implant, language, EAL" - path = /obj/item/weapon/implant/language/eal - cost = 2 - slot = "implant" - exploitable = 1*/ - -/datum/gear/utility/implant/tracking - display_name = "implant, tracking" - path = /obj/item/weapon/implant/tracking/weak - cost = 0 //VOREStation Edit. Changed cost to 0 - slot = "implant" - exploitable = 1 +//TFF 29/4/19: remove implants, move to loadout_implants.dm /datum/gear/utility/pen display_name = "Fountain Pen" diff --git a/code/modules/client/preference_setup/loadout/loadout_xeno.dm b/code/modules/client/preference_setup/loadout/loadout_xeno.dm index c7d93294ac..ac454d873a 100644 --- a/code/modules/client/preference_setup/loadout/loadout_xeno.dm +++ b/code/modules/client/preference_setup/loadout/loadout_xeno.dm @@ -107,28 +107,42 @@ /datum/gear/uniform/undercoat display_name = "undercoat selection (Teshari)" - path = /obj/item/clothing/under/seromi/undercoat + path = /obj/item/clothing/under/seromi/undercoat/standard whitelisted = SPECIES_TESHARI sort_category = "Xenowear" /datum/gear/uniform/undercoat/New() ..() var/list/undercoats = list() - for(var/undercoat in typesof(/obj/item/clothing/under/seromi/undercoat)) + for(var/undercoat in typesof(/obj/item/clothing/under/seromi/undercoat/standard)) var/obj/item/clothing/under/seromi/undercoat/undercoat_type = undercoat undercoats[initial(undercoat_type.name)] = undercoat_type gear_tweaks += new/datum/gear_tweak/path(sortAssoc(undercoats)) /datum/gear/suit/cloak display_name = "cloak selection (Teshari)" - path = /obj/item/clothing/suit/storage/seromi/cloak + path = /obj/item/clothing/suit/storage/seromi/cloak/standard whitelisted = SPECIES_TESHARI sort_category = "Xenowear" /datum/gear/suit/cloak/New() ..() var/list/cloaks = list() - for(var/cloak in typesof(/obj/item/clothing/suit/storage/seromi/cloak)) + for(var/cloak in typesof(/obj/item/clothing/suit/storage/seromi/cloak/standard)) + var/obj/item/clothing/suit/storage/seromi/cloak/cloak_type = cloak + cloaks[initial(cloak_type.name)] = cloak_type + gear_tweaks += new/datum/gear_tweak/path(sortAssoc(cloaks)) + +/datum/gear/suit/hood + display_name = "hooded cloak selection (Teshari)" + path = /obj/item/clothing/suit/storage/seromi/cloak/standard + whitelisted = SPECIES_TESHARI + sort_category = "Xenowear" + +/datum/gear/suit/hood/New() + ..() + var/list/cloaks = list() + for(var/cloak in typesof(/obj/item/clothing/suit/storage/hooded/teshari/standard)) var/obj/item/clothing/suit/storage/seromi/cloak/cloak_type = cloak cloaks[initial(cloak_type.name)] = cloak_type gear_tweaks += new/datum/gear_tweak/path(sortAssoc(cloaks)) @@ -160,4 +174,203 @@ for(var/cohesionsuit in (typesof(/obj/item/clothing/under/cohesion))) var/obj/item/clothing/under/cohesion/cohesion_type = cohesionsuit cohesionsuits[initial(cohesion_type.name)] = cohesion_type - gear_tweaks += new/datum/gear_tweak/path(sortAssoc(cohesionsuits)) \ No newline at end of file + gear_tweaks += new/datum/gear_tweak/path(sortAssoc(cohesionsuits)) + +/datum/gear/uniform/dept + whitelisted = SPECIES_TESHARI + sort_category = "Xenowear" + +/datum/gear/uniform/dept/undercoat/ce + display_name = "Teshari Chief Engineer Undercoat" + path = /obj/item/clothing/under/seromi/undercoat/jobs/ce + allowed_roles = list("Chief Engineer") + +/datum/gear/uniform/dept/undercoat/ce_w + display_name = "Teshari Chief Engineer Undercoat (White)" + path = /obj/item/clothing/under/seromi/undercoat/jobs/ce_w + allowed_roles = list("Chief Engineer") +/* //Placeholder for RD undercoat +/datum/gear/uniform/undercoat/rd + display_name = "cloak, research director" + path = /obj/item/clothing/accessory/poncho/roles/cloak/rd + allowed_roles = list("Research Director") +*/ +/datum/gear/uniform/dept/undercoat/qm + display_name = "Teshari Quarter Master Undercoat" + path = /obj/item/clothing/under/seromi/undercoat/jobs/qm + allowed_roles = list("Quartermaster") + +/datum/gear/uniform/dept/undercoat/command + display_name = "Teshari Command Undercoat" + path = /obj/item/clothing/under/seromi/undercoat/jobs/command + allowed_roles = list("Colony Director","Head of Personnel","Head of Security","Chief Engineer","Chief Medical Officer") + +/datum/gear/uniform/dept/undercoat/command_g + display_name = "Teshari Command Undercoat (gold buttons)" + path = /obj/item/clothing/under/seromi/undercoat/jobs/command_g + allowed_roles = list("Colony Director","Head of Personnel","Head of Security","Chief Engineer","Chief Medical Officer") + +/datum/gear/uniform/dept/undercoat/cmo + display_name = "Teshari Chief Medical Officer Undercoat" + path = /obj/item/clothing/under/seromi/undercoat/jobs/cmo + allowed_roles = list("Chief Medical Officer") + +/datum/gear/uniform/dept/undercoat/cargo + display_name = "Teshari Cargo Undercoat" + path = /obj/item/clothing/under/seromi/undercoat/jobs/cargo + allowed_roles = list("Cargo Technician","Quartermaster","Shaft Miner") + +/datum/gear/uniform/dept/undercoat/mining + display_name = "Teshari Mining Undercoat" + path = /obj/item/clothing/under/seromi/undercoat/jobs/mining + allowed_roles = list("Quartermaster","Shaft Miner") + +/datum/gear/uniform/dept/undercoat/security + display_name = "Teshari Security Undercoat" + path = /obj/item/clothing/under/seromi/undercoat/jobs/sec + allowed_roles = list("Head of Security","Detective","Warden","Security Officer",) + +/datum/gear/uniform/dept/undercoat/service + display_name = "Teshari Service Undercoat" + path = /obj/item/clothing/under/seromi/undercoat/jobs/service + allowed_roles = list("Head of Personnel","Bartender","Botanist","Janitor","Chef","Librarian") + +/datum/gear/uniform/dept/undercoat/engineer + display_name = "Teshari Engineer Undercoat" + path = /obj/item/clothing/under/seromi/undercoat/jobs/engineer + allowed_roles = list("Chief Engineer","Station Engineer") + +/datum/gear/uniform/dept/undercoat/atmos + display_name = "Teshari Atmos Tech Undercoat" + path = /obj/item/clothing/under/seromi/undercoat/jobs/atmos + allowed_roles = list("Chief Engineer","Atmospheric Technician") + +/datum/gear/uniform/dept/undercoat/research + display_name = "Teshari Science Undercoat" + path = /obj/item/clothing/under/seromi/undercoat/jobs/sci + allowed_roles = list("Research Director","Scientist", "Roboticist", "Xenobiologist") + +/datum/gear/uniform/dept/undercoat/robo + display_name = "Teshari Roboticist Undercoat" + path = /obj/item/clothing/under/seromi/undercoat/jobs/robo + allowed_roles = list("Roboticist") + +/datum/gear/uniform/dept/undercoat/medical + display_name = "Teshari Medical Undercoat" + path = /obj/item/clothing/under/seromi/undercoat/jobs/medical + allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist", "Psychiatrist") + +/datum/gear/uniform/dept/undercoat/chemistry + display_name = "Teshari Chemistry Undercoat" + path = /obj/item/clothing/under/seromi/undercoat/jobs/chemistry + allowed_roles = list("Chemist") + +/datum/gear/uniform/dept/undercoat/virology + display_name = "Teshari Medical Undercoat" + path = /obj/item/clothing/under/seromi/undercoat/jobs/viro + allowed_roles = list("Medical Doctor") + +/datum/gear/uniform/dept/undercoat/paramedic + display_name = "Teshari Paramedic Undercoat" + path = /obj/item/clothing/under/seromi/undercoat/jobs/para + allowed_roles = list("Paramedic") + +/datum/gear/uniform/dept/undercoat/iaa + display_name = "Teshari IAA Undercoat" + path = /obj/item/clothing/under/seromi/undercoat/jobs/iaa + allowed_roles = list("Internal Affairs Agent") + +/datum/gear/suit/dept/cloak/ + whitelisted = SPECIES_TESHARI + sort_category = "Xenowear" + +/datum/gear/suit/cloak/dept/ce + display_name = "Teshari Chief Engineer Cloak" + path = /obj/item/clothing/suit/storage/seromi/cloak/jobs/ce + allowed_roles = list("Chief Engineer") +/* //Placeholder for RD cloak +/datum/gear/suit/cloak/rd + display_name = "cloak, research director" + path = /obj/item/clothing/accessory/poncho/roles/cloak/rd + allowed_roles = list("Research Director") +*/ + +/datum/gear/suit/dept/cloak/qm + display_name = "Teshari Quarter Master Cloak" + path = /obj/item/clothing/suit/storage/seromi/cloak/jobs/qm + allowed_roles = list("Quartermaster") + +/datum/gear/suit/dept/cloak/command + display_name = "Teshari Command Cloak" + path = /obj/item/clothing/suit/storage/seromi/cloak/jobs/command + allowed_roles = list("Colony Director","Head of Personnel","Head of Security","Chief Engineer","Chief Medical Officer") + +/datum/gear/suit/dept/cloak/cmo + display_name = "Teshari Chief Medical Officer Cloak" + path = /obj/item/clothing/suit/storage/seromi/cloak/jobs/cmo + allowed_roles = list("Chief Medical Officer") + +/datum/gear/suit/dept/cloak/cargo + display_name = "Teshari Cargo Cloak" + path = /obj/item/clothing/suit/storage/seromi/cloak/jobs/cargo + allowed_roles = list("Cargo Technician","Quartermaster","Shaft Miner") + +/datum/gear/suit/dept/cloak/mining + display_name = "Teshari Mining Cloak" + path = /obj/item/clothing/suit/storage/seromi/cloak/jobs/mining + allowed_roles = list("Quartermaster","Shaft Miner") + +/datum/gear/suit/dept/cloak/security + display_name = "Teshari Security Cloak" + path = /obj/item/clothing/suit/storage/seromi/cloak/jobs/sec + allowed_roles = list("Head of Security","Detective","Warden","Security Officer",) + +/datum/gear/suit/dept/cloak/service + display_name = "Teshari Service Cloak" + path = /obj/item/clothing/suit/storage/seromi/cloak/jobs/service + allowed_roles = list("Head of Personnel","Bartender","Botanist","Janitor","Chef","Librarian") + +/datum/gear/suit/dept/cloak/engineer + display_name = "Teshari Engineer Cloak" + path = /obj/item/clothing/suit/storage/seromi/cloak/jobs/engineer + allowed_roles = list("Chief Engineer","Station Engineer") + +/datum/gear/suit/dept/cloak/atmos + display_name = "Teshari Atmos Tech Cloak" + path = /obj/item/clothing/suit/storage/seromi/cloak/jobs/atmos + allowed_roles = list("Chief Engineer","Atmospheric Technician") + +/datum/gear/suit/dept/cloak/research + display_name = "Teshari Science Cloak" + path = /obj/item/clothing/suit/storage/seromi/cloak/jobs/sci + allowed_roles = list("Research Director","Scientist", "Roboticist", "Xenobiologist") + +/datum/gear/suit/dept/cloak/robo + display_name = "Teshari Roboticist Cloak" + path = /obj/item/clothing/suit/storage/seromi/cloak/jobs/robo + allowed_roles = list("Roboticist") + +/datum/gear/suit/dept/cloak/medical + display_name = "Teshari Medical Cloak" + path = /obj/item/clothing/suit/storage/seromi/cloak/jobs/medical + allowed_roles = list("Medical Doctor","Chief Medical Officer","Chemist","Paramedic","Geneticist", "Psychiatrist") + +/datum/gear/suit/dept/cloak/chemistry + display_name = "Teshari Chemistry Cloak" + path = /obj/item/clothing/suit/storage/seromi/cloak/jobs/chemistry + allowed_roles = list("Chemist") + +/datum/gear/suit/dept/cloak/virology + display_name = "Teshari Medical Cloak" + path = /obj/item/clothing/suit/storage/seromi/cloak/jobs/viro + allowed_roles = list("Medical Doctor") + +/datum/gear/suit/dept/cloak/paramedic + display_name = "Teshari Paramedic Cloak" + path = /obj/item/clothing/suit/storage/seromi/cloak/jobs/para + allowed_roles = list("Paramedic") + +/datum/gear/suit/dept/cloak/iaa + display_name = "Teshari IAA Cloak" + path = /obj/item/clothing/suit/storage/seromi/cloak/jobs/iaa + allowed_roles = list("Internal Affairs Agent") \ No newline at end of file diff --git a/code/modules/client/preferences_spawnpoints.dm b/code/modules/client/preferences_spawnpoints.dm index c0c54169b2..3127c9d13f 100644 --- a/code/modules/client/preferences_spawnpoints.dm +++ b/code/modules/client/preferences_spawnpoints.dm @@ -40,7 +40,8 @@ var/list/spawntypes = list() /datum/spawnpoint/gateway/New() ..() turfs = latejoin_gateway -/* VOREStation Edit + +//TFF: Enable spawnpoints at Lifts. /datum/spawnpoint/elevator display_name = "Elevator" msg = "has arrived from the residential district" @@ -48,7 +49,7 @@ var/list/spawntypes = list() /datum/spawnpoint/elevator/New() ..() turfs = latejoin_elevator -*/ + /datum/spawnpoint/cryo display_name = "Cryogenic Storage" msg = "has completed cryogenic revival" @@ -65,4 +66,4 @@ var/list/spawntypes = list() /datum/spawnpoint/cyborg/New() ..() - turfs = latejoin_cyborg \ No newline at end of file + turfs = latejoin_cyborg diff --git a/code/modules/clothing/glasses/hud_vr.dm b/code/modules/clothing/glasses/hud_vr.dm index c2b198bc70..9782f0e661 100644 --- a/code/modules/clothing/glasses/hud_vr.dm +++ b/code/modules/clothing/glasses/hud_vr.dm @@ -1,7 +1,7 @@ /obj/item/clothing/glasses/omnihud name = "\improper AR glasses" - desc = "The KHI-62 AR Glasses are a design from Kitsuhana Heavy Industries. These are a cheap export version \ - for Nanotrasen. Probably not as complete as KHI could make them, but more readily available for NT." + desc = "The WT-62 AR Glasses are a design from Ward-Takahashi GMB. These are a cheap export version \ + for Nanotrasen. Definitely not as complete as WT could make them, but more readily available for NT." origin_tech = list(TECH_MAGNET = 3, TECH_BIO = 3) var/obj/item/clothing/glasses/hud/omni/hud = null var/mode = "civ" @@ -67,7 +67,7 @@ /obj/item/clothing/glasses/omnihud/med name = "\improper AR-M glasses" - desc = "The KHI-62-M AR glasses are a design from Kitsuhana Heavy Industries. \ + desc = "The WT-62-M AR glasses are a design from Ward-Takahashi GMB. \ These have been upgraded with medical records access and virus database integration." mode = "med" action_button_name = "AR Console (Crew Monitor)" @@ -81,7 +81,7 @@ /obj/item/clothing/glasses/omnihud/sec name = "\improper AR-S glasses" - desc = "The KHI-62-S AR glasses are a design from Kitsuhana Heavy Industries. \ + desc = "The WT-62-S AR glasses are a design from Ward-Takahashi GMB. \ These have been upgraded with security records integration and flash protection." mode = "sec" flash_protection = FLASH_PROTECTION_MAJOR @@ -96,7 +96,7 @@ /obj/item/clothing/glasses/omnihud/eng name = "\improper AR-E glasses" - desc = "The KHI-62-E AR glasses are a design from Kitsuhana Heavy Industries. \ + desc = "The WT-62-E AR glasses are a design from Ward-Takahashi GMB. \ These have been upgraded with advanced electrochromic lenses to protect your eyes during welding." mode = "eng" flash_protection = FLASH_PROTECTION_MAJOR @@ -110,7 +110,7 @@ /obj/item/clothing/glasses/omnihud/rnd name = "\improper AR-R glasses" - desc = "The KHI-62-R AR glasses are a design from Kitsuhana Heavy Industries. \ + desc = "The WT-62-R AR glasses are a design from Ward-Takahashi GMB. \ These have been ... modified ... to fit into a different frame." mode = "sci" icon = 'icons/obj/clothing/glasses.dmi' @@ -156,7 +156,7 @@ /obj/item/clothing/glasses/omnihud/all name = "\improper AR-B glasses" - desc = "The KHI-62-B AR glasses are a design from Kitsuhana Heavy Industries. \ + desc = "The WT-62-B AR glasses are a design from Ward-Takahashi GMB. \ These have been upgraded with every feature the lesser models have. Now we're talkin'." mode = "best" flash_protection = FLASH_PROTECTION_MAJOR diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm index 225c45d684..6f7876372d 100644 --- a/code/modules/clothing/gloves/miscellaneous.dm +++ b/code/modules/clothing/gloves/miscellaneous.dm @@ -34,6 +34,7 @@ min_cold_protection_temperature = GLOVES_MIN_COLD_PROTECTION_TEMPERATURE heat_protection = HANDS max_heat_protection_temperature = GLOVES_MAX_HEAT_PROTECTION_TEMPERATURE + armor = list(melee = 30, bullet = 10, laser = 10, energy = 15, bomb = 20, bio = 0, rad = 0) /obj/item/clothing/gloves/combat //Combined effect of SWAT gloves and insulated gloves desc = "These tactical gloves are somewhat fire and impact resistant." @@ -46,6 +47,7 @@ min_cold_protection_temperature = GLOVES_MIN_COLD_PROTECTION_TEMPERATURE heat_protection = HANDS max_heat_protection_temperature = GLOVES_MAX_HEAT_PROTECTION_TEMPERATURE + armor = list(melee = 30, bullet = 10, laser = 10, energy = 15, bomb = 20, bio = 0, rad = 0) /obj/item/clothing/gloves/warden desc = "These black gloves scream of prisoner abuse" diff --git a/code/modules/clothing/head/misc_ch.dm b/code/modules/clothing/head/misc_ch.dm index a368d50520..6eef69e39d 100644 --- a/code/modules/clothing/head/misc_ch.dm +++ b/code/modules/clothing/head/misc_ch.dm @@ -11,4 +11,12 @@ var/image/so_far = ..() so_far.pixel_y += 16 so_far.pixel_x += 0 - return so_far \ No newline at end of file + return so_far + +/obj/item/clothing/head/soft/purple/wah + name = "assistant cap" + desc = "What a lovely purple cap, its said its given out as a trophy to assistants. Why does that sound so depressing?" + icon_state = "wahcap" + item_state_slots = list(slot_r_hand_str = "wahcap", slot_l_hand_str = "wahcap") + icon = 'icons/obj/clothing/hats_vr.dmi' + icon_override = 'icons/mob/head_vr.dmi' \ No newline at end of file diff --git a/code/modules/clothing/spacesuits/rig/rig_pieces_vr.dm b/code/modules/clothing/spacesuits/rig/rig_pieces_vr.dm index d71d7cd6fa..91dab198d3 100644 --- a/code/modules/clothing/spacesuits/rig/rig_pieces_vr.dm +++ b/code/modules/clothing/spacesuits/rig/rig_pieces_vr.dm @@ -11,7 +11,8 @@ SPECIES_VULPKANI = 'icons/mob/species/vulpkanin/helmet.dmi', SPECIES_PROMETHEAN = 'icons/mob/species/skrell/helmet.dmi', SPECIES_XENOHYBRID = 'icons/mob/species/unathi/helmet.dmi', - SPECIES_VOX = 'icons/mob/species/vox/head.dmi' + SPECIES_VOX = 'icons/mob/species/vox/head.dmi', + SPECIES_TESHARI = 'icons/mob/species/seromi/head.dmi' ) @@ -29,7 +30,8 @@ SPECIES_VULPKANIN = 'icons/mob/species/vulpkanin/suit.dmi', SPECIES_PROMETHEAN = 'icons/mob/species/skrell/suit.dmi', SPECIES_XENOHYBRID = 'icons/mob/species/unathi/suit.dmi', - SPECIES_VOX = 'icons/mob/species/vox/suit.dmi' + SPECIES_VOX = 'icons/mob/species/vox/suit.dmi', + SPECIES_TESHARI = 'icons/mob/species/seromi/suit.dmi' ) /obj/item/clothing/head/helmet/space/rig diff --git a/code/modules/clothing/spacesuits/rig/rig_unify_ch.dm b/code/modules/clothing/spacesuits/rig/rig_unify_ch.dm new file mode 100644 index 0000000000..9a9f1ef068 --- /dev/null +++ b/code/modules/clothing/spacesuits/rig/rig_unify_ch.dm @@ -0,0 +1,134 @@ +//This file will attempt to implement multiple overrides in a single file +//BAsicly the module look, the seperate part designs etc will all be design in here +//All sprites are going to go into a new DMI seperate from other RIGs +//This will be the groundwork for mechanical Fursuits + +/obj/item/weapon/rig/override + icon_override = 'icons/obj/rig_override_modules.dmi' + name = "override control module" + desc = "A Prototype suit not made for space, not made for combat, basically an expensive toy." + icon = 'icons/obj/rig_override_modules.dmi' //the look of the module itself + icon_state = "override_rig" + suit_type = "override suit" + //REEEEMOVE ARMOR + armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) //this will be purely cosmetic + emp_protection = 0 //No ARMOR + //TYPES + chest_type = /obj/item/clothing/suit/space/rig/override + helm_type = /obj/item/clothing/head/helmet/space/rig/override + boot_type = /obj/item/clothing/shoes/magboots/rig/override + glove_type = /obj/item/clothing/gloves/gauntlets/rig/override + cell_type = /obj/item/weapon/cell/high/hightech //implementing special cell override + //var/air_type = /obj/item/weapon/tank/oxygen + airtight = 0 //not airtight, nope + seal_delay = 5 //totally not based on the hacker suit + slowdown = 0 + offline_slowdown = 0 + //modular setup + req_access = list() + initial_modules = list() + var/thingamount = 1 + +/obj/item/clothing/suit/space/rig/override + species_restricted = list(SPECIES_UNATHI) //to be refined~ + icon_override = 'icons/obj/rig_override_modules.dmi' + item_state = "override_worn_suit" + sprite_sheets = list( + SPECIES_TAJ = 'icons/obj/rig_override_modules.dmi', + SPECIES_SKRELL = 'icons/obj/rig_override_modules.dmi', + SPECIES_UNATHI = 'icons/obj/rig_override_modules.dmi', + SPECIES_NEVREAN = 'icons/obj/rig_override_modules.dmi', + SPECIES_AKULA = 'icons/obj/rig_override_modules.dmi', + SPECIES_SERGAL = 'icons/obj/rig_override_modules.dmi', + SPECIES_ZORREN_FLAT = 'icons/obj/rig_override_modules.dmi', + SPECIES_ZORREN_HIGH = 'icons/obj/rig_override_modules.dmi', + SPECIES_VULPKANI = 'icons/obj/rig_override_modules.dmi', + SPECIES_PROMETHEAN = 'icons/obj/rig_override_modules.dmi', + SPECIES_XENOHYBRID = 'icons/obj/rig_override_modules.dmi', + SPECIES_VOX = 'icons/obj/rig_override_modules.dmi', + ) + icon = 'icons/obj/rig_override_modules.dmi' + icon_state = "override_rig_suit" //this is experimental + name = "suit" + breach_threshold = 0 + +/obj/item/clothing/head/helmet/space/rig/override + icon_override = 'icons/obj/rig_override_modules.dmi' + item_state = "override_worn_helmet" + sprite_sheets = list( + SPECIES_TAJ = 'icons/obj/rig_override_modules.dmi', + SPECIES_SKRELL = 'icons/obj/rig_override_modules.dmi', + SPECIES_UNATHI = 'icons/obj/rig_override_modules.dmi', + SPECIES_NEVREAN = 'icons/obj/rig_override_modules.dmi', + SPECIES_AKULA = 'icons/obj/rig_override_modules.dmi', + SPECIES_SERGAL = 'icons/obj/rig_override_modules.dmi', + SPECIES_ZORREN_FLAT = 'icons/obj/rig_override_modules.dmi', + SPECIES_ZORREN_HIGH = 'icons/obj/rig_override_modules.dmi', + SPECIES_VULPKANI = 'icons/obj/rig_override_modules.dmi', + SPECIES_PROMETHEAN = 'icons/obj/rig_override_modules.dmi', + SPECIES_XENOHYBRID = 'icons/obj/rig_override_modules.dmi', + SPECIES_VOX = 'icons/obj/rig_override_modules.dmi', + ) + icon = 'icons/obj/rig_override_modules.dmi' + icon_state = "override_rig_hood" //this is experimental + name = "hood" + +/obj/item/clothing/shoes/magboots/rig/override + item_state = "override_worn_boots" + icon_override = 'icons/obj/rig_override_modules.dmi' + sprite_sheets = list( + SPECIES_TAJ = 'icons/obj/rig_override_modules.dmi', + SPECIES_SKRELL = 'icons/obj/rig_override_modules.dmi', + SPECIES_UNATHI = 'icons/obj/rig_override_modules.dmi', + SPECIES_NEVREAN = 'icons/obj/rig_override_modules.dmi', + SPECIES_AKULA = 'icons/obj/rig_override_modules.dmi', + SPECIES_SERGAL = 'icons/obj/rig_override_modules.dmi', + SPECIES_ZORREN_FLAT = 'icons/obj/rig_override_modules.dmi', + SPECIES_ZORREN_HIGH = 'icons/obj/rig_override_modules.dmi', + SPECIES_VULPKANI = 'icons/obj/rig_override_modules.dmi', + SPECIES_PROMETHEAN = 'icons/obj/rig_override_modules.dmi', + SPECIES_XENOHYBRID = 'icons/obj/rig_override_modules.dmi', + SPECIES_VOX = 'icons/obj/rig_override_modules.dmi', + ) + icon = 'icons/obj/rig_override_modules.dmi' + icon_state = "override_rig_boots" //this is experimental + name = "shoes" + step_volume_mod = 1 + +/obj/item/clothing/gloves/gauntlets/rig/override + item_state = "override_worn_gauntlets" + icon_override = 'icons/obj/rig_override_modules.dmi' + sprite_sheets = list( + SPECIES_TAJ = 'icons/obj/rig_override_modules.dmi', + SPECIES_SKRELL = 'icons/obj/rig_override_modules.dmi', + SPECIES_UNATHI = 'icons/obj/rig_override_modules.dmi', + SPECIES_NEVREAN = 'icons/obj/rig_override_modules.dmi', + SPECIES_AKULA = 'icons/obj/rig_override_modules.dmi', + SPECIES_SERGAL = 'icons/obj/rig_override_modules.dmi', + SPECIES_ZORREN_FLAT = 'icons/obj/rig_override_modules.dmi', + SPECIES_ZORREN_HIGH = 'icons/obj/rig_override_modules.dmi', + SPECIES_VULPKANI = 'icons/obj/rig_override_modules.dmi', + SPECIES_PROMETHEAN = 'icons/obj/rig_override_modules.dmi', + SPECIES_XENOHYBRID = 'icons/obj/rig_override_modules.dmi', + SPECIES_VOX = 'icons/obj/rig_override_modules.dmi', + ) + icon = 'icons/obj/rig_override_modules.dmi' + icon_state = "override_rig_gauntlets" //this is experimental + name = "gloves" +//Will be modified once we start adding actual fursuits in here +/obj/item/weapon/rig/override/New() + ..() + icon_state = "override_rig_suit" //for now +/obj/item/clothing/head/helmet/space/rig/override/New() + ..() + icon_state = item_state +/obj/item/clothing/suit/space/rig/override/New() + ..() + icon_state = item_state +/obj/item/clothing/gloves/gauntlets/rig/override/New() + ..() + icon_state = item_state +/obj/item/clothing/shoes/magboots/rig/override/New() + ..() + icon_state = item_state +//Lazy sprite fix end diff --git a/code/modules/clothing/spacesuits/rig/suits/station.dm b/code/modules/clothing/spacesuits/rig/suits/station.dm index c5e860a21a..f918abe0d8 100644 --- a/code/modules/clothing/spacesuits/rig/suits/station.dm +++ b/code/modules/clothing/spacesuits/rig/suits/station.dm @@ -18,7 +18,7 @@ /obj/item/clothing/head/helmet/space/rig/hazard light_overlay = "helmet_light_dual" camera_networks = list(NETWORK_SECURITY) - + /obj/item/clothing/head/helmet/space/rig/pursuit light_overlay = "helmet_light_dual" camera_networks = list(NETWORK_SECURITY) @@ -310,7 +310,7 @@ /obj/item/rig_module/grenade_launcher, /obj/item/rig_module/mounted/taser ) - + //A second security suit. Removes the maneuvering jets and nerfs the grenade launcher, and adds the sprinter and flash modules. I removed the maneuvering jets to discourage lone-wolf style gameplay because other sec officers don't get jetpacks very easily. /obj/item/weapon/rig/pursuit name = "pursuit hardsuit control module" @@ -346,3 +346,32 @@ /obj/item/rig_module/grenade_launcher/nerfed, /obj/item/rig_module/mounted/taser ) + +//Civilian EVA RIG. +/obj/item/weapon/rig/civ + name = "KWI control module" + suit_type = "civilan hardsuit" + desc = "A Kai Wan Innovations civilian light EVA RIG." + icon_state = "kwi_rig" + armor = list(melee = 10, bullet = 5, laser = 5, energy = 0, bomb = 5, bio = 100, rad = 30) + slowdown = 1 + offline_vision_restriction = 1 + siemens_coefficient= 0.75 + + helm_type = /obj/item/clothing/head/helmet/space/rig/eva + + allowed = list( + /obj/item/device/flashlight, + /obj/item/weapon/tank, + /obj/item/device/suit_cooling_unit, + /obj/item/weapon/storage/backpack, + ) + + req_access = list() + req_one_access = list() + +/obj/item/weapon/rig/civ/equipped + + initial_modules = list( + /obj/item/rig_module/maneuvering_jets, + ) diff --git a/code/modules/clothing/spacesuits/void/void.dm b/code/modules/clothing/spacesuits/void/void.dm index ef78d32f03..8ee276e341 100644 --- a/code/modules/clothing/spacesuits/void/void.dm +++ b/code/modules/clothing/spacesuits/void/void.dm @@ -213,7 +213,7 @@ if(istype(W,/obj/item/clothing/accessory) || istype(W, /obj/item/weapon/hand_labeler)) return ..() - if(istype(src.loc,/mob/living)) + if(user.get_inventory_slot(src) == slot_wear_suit) //TFF 18/4/19: Port Polaris QoL edit - allow attaching voidsuit parts WHILE holding it! user << "You cannot modify \the [src] while it is being worn." return diff --git a/code/modules/clothing/suits/aliens/seromi.dm b/code/modules/clothing/suits/aliens/seromi.dm index 62a013644f..8055aa62f2 100644 --- a/code/modules/clothing/suits/aliens/seromi.dm +++ b/code/modules/clothing/suits/aliens/seromi.dm @@ -1,6 +1,6 @@ /obj/item/clothing/suit/storage/seromi/cloak name = "black and orange cloak " - desc = "It drapes over a Teshari's shoulders and closes at the neck with pockets convienently placed inside." + desc = "It drapes over a teshari's shoulders and closes at the neck with pockets convienently placed inside." icon = 'icons/mob/species/seromi/teshari_cloak.dmi' icon_override = 'icons/mob/species/seromi/teshari_cloak.dmi' icon_state = "tesh_cloak_bo" @@ -8,127 +8,548 @@ species_restricted = list(SPECIES_TESHARI) body_parts_covered = UPPER_TORSO|ARMS -/obj/item/clothing/suit/storage/seromi/cloak/black_orange +/obj/item/clothing/suit/storage/seromi/cloak/standard/black_orange name = "black and orange cloak" icon_state = "tesh_cloak_bo" item_state = "tesh_cloak_bo" -/obj/item/clothing/suit/storage/seromi/cloak/black_grey +/obj/item/clothing/suit/storage/seromi/cloak/standard/black_grey name = "black and grey cloak" icon_state = "tesh_cloak_bg" item_state = "tesh_cloak_bg" -/obj/item/clothing/suit/storage/seromi/cloak/black_midgrey +/obj/item/clothing/suit/storage/seromi/cloak/standard/black_midgrey name = "black and medium grey cloak" icon_state = "tesh_cloak_bmg" item_state = "tesh_cloak_bmg" -/obj/item/clothing/suit/storage/seromi/cloak/black_lightgrey +/obj/item/clothing/suit/storage/seromi/cloak/standard/black_lightgrey name = "black and light grey cloak" icon_state = "tesh_cloak_blg" item_state = "tesh_cloak_blg" -/obj/item/clothing/suit/storage/seromi/cloak/black_white +/obj/item/clothing/suit/storage/seromi/cloak/standard/black_white name = "black and white cloak" icon_state = "tesh_cloak_bw" item_state = "tesh_cloak_bw" -/obj/item/clothing/suit/storage/seromi/cloak/black_red +/obj/item/clothing/suit/storage/seromi/cloak/standard/black_red name = "black and red cloak" icon_state = "tesh_cloak_br" item_state = "tesh_cloak_br" -/obj/item/clothing/suit/storage/seromi/cloak/black +/obj/item/clothing/suit/storage/seromi/cloak/standard/black name = "black cloak" icon_state = "tesh_cloak_bn" item_state = "tesh_cloak_bn" -/obj/item/clothing/suit/storage/seromi/cloak/black_yellow +/obj/item/clothing/suit/storage/seromi/cloak/standard/black_yellow name = "black and yellow cloak" icon_state = "tesh_cloak_by" item_state = "tesh_cloak_by" -/obj/item/clothing/suit/storage/seromi/cloak/black_green +/obj/item/clothing/suit/storage/seromi/cloak/standard/black_green name = "black and green cloak" icon_state = "tesh_cloak_bgr" item_state = "tesh_cloak_bgr" -/obj/item/clothing/suit/storage/seromi/cloak/black_blue +/obj/item/clothing/suit/storage/seromi/cloak/standard/black_blue name = "black and blue cloak" icon_state = "tesh_cloak_bbl" item_state = "tesh_cloak_bbl" -/obj/item/clothing/suit/storage/seromi/cloak/black_purple +/obj/item/clothing/suit/storage/seromi/cloak/standard/black_purple name = "black and purple cloak" icon_state = "tesh_cloak_bp" item_state = "tesh_cloak_bp" -/obj/item/clothing/suit/storage/seromi/cloak/black_pink +/obj/item/clothing/suit/storage/seromi/cloak/standard/black_pink name = "black and pink cloak" icon_state = "tesh_cloak_bpi" item_state = "tesh_cloak_bpi" -/obj/item/clothing/suit/storage/seromi/cloak/black_brown +/obj/item/clothing/suit/storage/seromi/cloak/standard/black_brown name = "black and brown cloak" icon_state = "tesh_cloak_bbr" item_state = "tesh_cloak_bbr" -/obj/item/clothing/suit/storage/seromi/cloak/orange_grey +/obj/item/clothing/suit/storage/seromi/cloak/standard/orange_grey name = "orange and grey cloak" icon_state = "tesh_cloak_og" item_state = "tesh_cloak_og" -/obj/item/clothing/suit/storage/seromi/cloak/rainbow +/obj/item/clothing/suit/storage/seromi/cloak/standard/rainbow name = "rainbow cloak" icon_state = "tesh_cloak_rainbow" item_state = "tesh_cloak_rainbow" -/obj/item/clothing/suit/storage/seromi/cloak/lightgrey_grey +/obj/item/clothing/suit/storage/seromi/cloak/standard/lightgrey_grey name = "light grey and grey cloak" icon_state = "tesh_cloak_lgg" item_state = "tesh_cloak_lgg" -/obj/item/clothing/suit/storage/seromi/cloak/white_grey +/obj/item/clothing/suit/storage/seromi/cloak/standard/white_grey name = "white and grey cloak" icon_state = "tesh_cloak_wg" item_state = "tesh_cloak_wg" -/obj/item/clothing/suit/storage/seromi/cloak/red_grey +/obj/item/clothing/suit/storage/seromi/cloak/standard/red_grey name = "red and grey cloak" icon_state = "tesh_cloak_rg" item_state = "tesh_cloak_rg" -/obj/item/clothing/suit/storage/seromi/cloak/orange +/obj/item/clothing/suit/storage/seromi/cloak/standard/orange name = "orange cloak" icon_state = "tesh_cloak_on" item_state = "tesh_cloak_on" -/obj/item/clothing/suit/storage/seromi/cloak/yellow_grey +/obj/item/clothing/suit/storage/seromi/cloak/standard/yellow_grey name = "yellow and grey cloak" icon_state = "tesh_cloak_yg" item_state = "tesh_cloak_yg" -/obj/item/clothing/suit/storage/seromi/cloak/green_grey +/obj/item/clothing/suit/storage/seromi/cloak/standard/green_grey name = "green and grey cloak" icon_state = "tesh_cloak_gg" item_state = "tesh_cloak_gg" -/obj/item/clothing/suit/storage/seromi/cloak/blue_grey +/obj/item/clothing/suit/storage/seromi/cloak/standard/blue_grey name = "blue and grey cloak" icon_state = "tesh_cloak_blug" item_state = "tesh_cloak_blug" -/obj/item/clothing/suit/storage/seromi/cloak/purple_grey +/obj/item/clothing/suit/storage/seromi/cloak/standard/purple_grey name = "purple and grey cloak" icon_state = "tesh_cloak_pg" item_state = "tesh_cloak_pg" -/obj/item/clothing/suit/storage/seromi/cloak/pink_grey +/obj/item/clothing/suit/storage/seromi/cloak/standard/pink_grey name = "pink and grey cloak" icon_state = "tesh_cloak_pig" item_state = "tesh_cloak_pig" -/obj/item/clothing/suit/storage/seromi/cloak/brown_grey +/obj/item/clothing/suit/storage/seromi/cloak/standard/brown_grey name = "brown and grey cloak" icon_state = "tesh_cloak_brg" - item_state = "tesh_cloak_brg" \ No newline at end of file + item_state = "tesh_cloak_brg" + +/obj/item/clothing/suit/storage/seromi/cloak/standard/black_glow + name = "black and glowing cloak" + icon_state = "tesh_cloak_bglowing" + item_state = "tesh_cloak_bglowing" + +/obj/item/clothing/suit/storage/seromi/cloak/standard/dark_retrowave + name = "dark aesthetic cloak" + icon_state = "tesh_cloak_dretrowave" + item_state = "tesh_cloak_dretrowave" + +/obj/item/clothing/suit/storage/seromi/cloak/jobs + icon = 'icons/mob/species/seromi/deptcloak.dmi' + icon_override = 'icons/mob/species/seromi/deptcloak.dmi' + +/obj/item/clothing/suit/storage/seromi/cloak/jobs/cargo + name = "Cargo cloak" + desc = "A soft teshari cloak made for the Cargo department" + icon_state = "tesh_cloak_car" + item_state = "tesh_cloak_car" + +/obj/item/clothing/suit/storage/seromi/cloak/jobs/mining + name = "Mining cloak" + desc = "A soft teshari cloak made for Mining" + icon_state = "tesh_cloak_mine" + item_state = "tesh_cloak_mine" + +/obj/item/clothing/suit/storage/seromi/cloak/jobs/command + name = "Command cloak" + desc = "A soft teshari cloak made for the Command department" + icon_state = "tesh_cloak_comm" + item_state = "tesh_cloak_comm" + +/obj/item/clothing/suit/storage/seromi/cloak/jobs/ce + name = "Cheif Engineer's cloak" + desc = "A soft teshari cloak made the Chief Engineer" + icon_state = "tesh_cloak_ce" + item_state = "tesh_cloak_ce" + +/obj/item/clothing/suit/storage/seromi/cloak/jobs/engineer + name = "Engineering cloak" + desc = "A soft teshari cloak made for the Engineering department" + icon_state = "tesh_cloak_engie" + item_state = "tesh_cloak_engie" + +/obj/item/clothing/suit/storage/seromi/cloak/jobs/atmos + name = "Atmos Tech cloak" + desc = "A soft teshari cloak made for the Atmos Tech" + icon_state = "tesh_cloak_atmos" + item_state = "tesh_cloak_atmos" + +/obj/item/clothing/suit/storage/seromi/cloak/jobs/cmo + name = "Chief Medical Officer cloak" + desc = "A soft teshari cloak made the Cheif Medical Officer" + icon_state = "tesh_cloak_cmo" + item_state = "tesh_cloak_cmo" + +/obj/item/clothing/suit/storage/seromi/cloak/jobs/medical + name = "Medical cloak" + desc = "A soft teshari cloak made for the Medical department" + icon_state = "tesh_cloak_doc" + item_state = "tesh_cloak_doc" + +/obj/item/clothing/suit/storage/seromi/cloak/jobs/chemistry + name = "Chemistry cloak" + desc = "A soft teshari cloak made for the Chemist" + icon_state = "tesh_cloak_chem" + item_state = "tesh_cloak_chem" + +/obj/item/clothing/suit/storage/seromi/cloak/jobs/viro + name = "Virologist cloak" + desc = "A soft teshari cloak made for the Virologist" + icon_state = "tesh_cloak_viro" + item_state = "tesh_cloak_viro" + +/obj/item/clothing/suit/storage/seromi/cloak/jobs/para + name = "Paramedic cloak" + desc = "A soft teshari cloak made for the Paramedic" + icon_state = "tesh_cloak_para" + item_state = "tesh_cloak_para" + +/obj/item/clothing/suit/storage/seromi/cloak/jobs/sci + name = "Scientist cloak" + desc = "A soft teshari cloak made for the Science department" + icon_state = "tesh_cloak_sci" + item_state = "tesh_cloak_sci" + +/obj/item/clothing/suit/storage/seromi/cloak/jobs/robo + name = "Roboticist cloak" + desc = "A soft teshari cloak made for the Roboticist" + icon_state = "tesh_cloak_robo" + item_state = "tesh_cloak_robo" + +/obj/item/clothing/suit/storage/seromi/cloak/jobs/sec + name = "Security cloak" + desc = "A soft teshari cloak made for the Security department. This one is made with stronger fibers." + icon_state = "tesh_cloak_sec" + item_state = "tesh_cloak_sec" + allowed = list(/obj/item/weapon/gun/energy,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/gun/projectile,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/device/flashlight/maglight,/obj/item/clothing/head/helmet) + body_parts_covered = UPPER_TORSO|LOWER_TORSO + item_flags = THICKMATERIAL + siemens_coefficient = 0.6 + armor = list(melee = 40, bullet = 30, laser = 30, energy = 10, bomb = 10, bio = 0, rad = 0) + +/obj/item/clothing/suit/storage/seromi/cloak/jobs/qm + name = "Quartermaster's cloak" + desc = "A soft teshari cloak made for the Quartermaster" + icon_state = "tesh_cloak_qm" + item_state = "tesh_cloak_qm" + +/obj/item/clothing/suit/storage/seromi/cloak/jobs/service + name = "Service cloak" + desc = "A soft teshari cloak made for the Service department" + icon_state = "tesh_cloak_serv" + item_state = "tesh_cloak_serv" + +/obj/item/clothing/suit/storage/seromi/cloak/jobs/iaa + name = "IAA cloak" + desc = "A soft teshari cloak made for the Internal Affairs Agent" + icon_state = "tesh_cloak_iaa" + item_state = "tesh_cloak_iaa" + + +/obj/item/clothing/suit/storage/hooded/teshari + name = "Hooded Teshari Cloak" + desc = "A soft teshari cloak with an added hood." + icon_override = 'icons/mob/species/seromi/teshari_hood.dmi' + icon = 'icons/mob/species/seromi/teshari_hood.dmi' + icon_state = "tesh_hcloak_bo" + item_state_slots = list(slot_r_hand_str = "tesh_hcloak_bo", slot_l_hand_str = "tesh_hcloak_bo") + body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS + flags_inv = HIDEHOLSTER|HIDETIE + hooded = 1 + action_button_name = "Toggle Cloak Hood" + hoodtype = /obj/item/clothing/head/tesh_hood + allowed = list (/obj/item/weapon/pen, /obj/item/weapon/paper, /obj/item/device/flashlight,/obj/item/weapon/tank/emergency/oxygen, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/storage/box/matches, /obj/item/weapon/reagent_containers/food/drinks/flask) + +/obj/item/clothing/head/tesh_hood + name = "Cloak Hood" + desc = "A hood attached to a teshari cloak." + icon_override = 'icons/mob/species/seromi/teshari_hood.dmi' + icon = 'icons/mob/species/seromi/teshari_hood.dmi' + icon_state = "tesh_hood_bo" + item_state_slots = list(slot_r_hand_str = "tesh_hood_bo", slot_l_hand_str = "tesh_hood_bo") + flags_inv = BLOCKHAIR + body_parts_covered = HEAD + +/obj/item/clothing/suit/storage/hooded/teshari/standard/black_orange + name = "black and orange hooded cloak" + icon_state = "tesh_hcloak_bo" + item_state = "tesh_hcloak_bo" + hoodtype = /obj/item/clothing/head/tesh_hood/standard/black_orange + +/obj/item/clothing/suit/storage/hooded/teshari/standard/black_grey + name = "black and grey hooded cloak" + icon_state = "tesh_hcloak_bg" + item_state = "tesh_hcloak_bg" + hoodtype = /obj/item/clothing/head/tesh_hood/standard/black_grey + +/obj/item/clothing/suit/storage/hooded/teshari/standard/black_midgrey + name = "black and medium grey hooded cloak" + icon_state = "tesh_hcloak_bmg" + item_state = "tesh_hcloak_bmg" + hoodtype = /obj/item/clothing/head/tesh_hood/standard/black_midgrey + +/obj/item/clothing/suit/storage/hooded/teshari/standard/black_lightgrey + name = "black and light grey hooded cloak" + icon_state = "tesh_hcloak_blg" + item_state = "tesh_hcloak_blg" + hoodtype = /obj/item/clothing/head/tesh_hood/standard/black_lightgrey + +/obj/item/clothing/suit/storage/hooded/teshari/standard/black_white + name = "black and white hooded cloak" + icon_state = "tesh_hcloak_bw" + item_state = "tesh_hcloak_bw" + hoodtype = /obj/item/clothing/head/tesh_hood/standard/black_white + +/obj/item/clothing/suit/storage/hooded/teshari/standard/black_red + name = "black and red hooded cloak" + icon_state = "tesh_hcloak_br" + item_state = "tesh_hcloak_br" + hoodtype = /obj/item/clothing/head/tesh_hood/standard/black_red + +/obj/item/clothing/suit/storage/hooded/teshari/standard/black + name = "black hooded cloak" + icon_state = "tesh_hcloak_bn" + item_state = "tesh_hcloak_bn" + hoodtype = /obj/item/clothing/head/tesh_hood/standard/black + +/obj/item/clothing/suit/storage/hooded/teshari/standard/black_yellow + name = "black and yellow hooded cloak" + icon_state = "tesh_hcloak_by" + item_state = "tesh_hcloak_by" + hoodtype = /obj/item/clothing/head/tesh_hood/standard/black_yellow + +/obj/item/clothing/suit/storage/hooded/teshari/standard/black_green + name = "black and green hooded cloak" + icon_state = "tesh_hcloak_bgr" + item_state = "tesh_hcloak_bgr" + hoodtype = /obj/item/clothing/head/tesh_hood/standard/black_green + +/obj/item/clothing/suit/storage/hooded/teshari/standard/black_blue + name = "black and blue hooded cloak" + icon_state = "tesh_hcloak_bbl" + item_state = "tesh_hcloak_bbl" + hoodtype = /obj/item/clothing/head/tesh_hood/standard/black_blue + +/obj/item/clothing/suit/storage/hooded/teshari/standard/black_purple + name = "black and purple hooded cloak" + icon_state = "tesh_hcloak_bp" + item_state = "tesh_hcloak_bp" + hoodtype = /obj/item/clothing/head/tesh_hood/standard/black_purple + +/obj/item/clothing/suit/storage/hooded/teshari/standard/black_pink + name = "black and pink hooded cloak" + icon_state = "tesh_hcloak_bpi" + item_state = "tesh_hcloak_bpi" + hoodtype = /obj/item/clothing/head/tesh_hood/standard/black_pink + +/obj/item/clothing/suit/storage/hooded/teshari/standard/black_brown + name = "black and brown hooded cloak" + icon_state = "tesh_hcloak_bbr" + item_state = "tesh_hcloak_bbr" + hoodtype = /obj/item/clothing/head/tesh_hood/standard/black_brown + +/obj/item/clothing/suit/storage/hooded/teshari/standard/orange_grey + name = "orange and grey hooded cloak" + icon_state = "tesh_hcloak_og" + item_state = "tesh_hcloak_og" + hoodtype = /obj/item/clothing/head/tesh_hood/standard/orange_grey + +///obj/item/clothing/suit/storage/hooded/teshari/standard/rainbow +// name = "rainbow hooded cloak" +// icon_state = "tesh_hcloak_rainbow" +// item_state = "tesh_hcloak_rainbow" +// hoodtype = /obj/item/clothing/head/tesh_hood/standard/rainbow + +/obj/item/clothing/suit/storage/hooded/teshari/standard/lightgrey_grey + name = "light grey and grey hooded cloak" + icon_state = "tesh_hcloak_lgg" + item_state = "tesh_hcloak_lgg" + hoodtype = /obj/item/clothing/head/tesh_hood/standard/lightgrey_grey + +/obj/item/clothing/suit/storage/hooded/teshari/standard/white_grey + name = "white and grey hooded cloak" + icon_state = "tesh_hcloak_wg" + item_state = "tesh_hcloak_wg" + hoodtype = /obj/item/clothing/head/tesh_hood/standard/white_grey + +/obj/item/clothing/suit/storage/hooded/teshari/standard/red_grey + name = "red and grey hooded cloak" + icon_state = "tesh_hcloak_rg" + item_state = "tesh_hcloak_rg" + hoodtype = /obj/item/clothing/head/tesh_hood/standard/red_grey + +/obj/item/clothing/suit/storage/hooded/teshari/standard/orange + name = "orange hooded cloak" + icon_state = "tesh_hcloak_on" + item_state = "tesh_hcloak_on" + hoodtype = /obj/item/clothing/head/tesh_hood/standard/orange + +/obj/item/clothing/suit/storage/hooded/teshari/standard/yellow_grey + name = "yellow and grey hooded cloak" + icon_state = "tesh_hcloak_yg" + item_state = "tesh_hcloak_yg" + hoodtype = /obj/item/clothing/head/tesh_hood/standard/yellow_grey + +/obj/item/clothing/suit/storage/hooded/teshari/standard/green_grey + name = "green and grey hooded cloak" + icon_state = "tesh_hcloak_gg" + item_state = "tesh_hcloak_gg" + hoodtype = /obj/item/clothing/head/tesh_hood/standard/green_grey + +/obj/item/clothing/suit/storage/hooded/teshari/standard/blue_grey + name = "blue and grey hooded cloak" + icon_state = "tesh_hcloak_blug" + item_state = "tesh_hcloak_blug" + hoodtype = /obj/item/clothing/head/tesh_hood/standard/blue_grey + +/obj/item/clothing/suit/storage/hooded/teshari/standard/purple_grey + name = "purple and grey hooded cloak" + icon_state = "tesh_hcloak_pg" + item_state = "tesh_hcloak_pg" + hoodtype = /obj/item/clothing/head/tesh_hood/standard/purple_grey + +/obj/item/clothing/suit/storage/hooded/teshari/standard/pink_grey + name = "pink and grey hooded cloak" + icon_state = "tesh_hcloak_pig" + item_state = "tesh_hcloak_pig" + hoodtype = /obj/item/clothing/head/tesh_hood/standard/pink_grey + +/obj/item/clothing/suit/storage/hooded/teshari/standard/brown_grey + name = "brown and grey hooded cloak" + icon_state = "tesh_hcloak_brg" + item_state = "tesh_hcloak_brg" + hoodtype = /obj/item/clothing/head/tesh_hood/standard/brown_grey + +/obj/item/clothing/head/tesh_hood/standard/black_orange + name = "black and orange cloak hood" + icon_state = "tesh_hood_bo" + item_state = "tesh_hood_bo" + +/obj/item/clothing/head/tesh_hood/standard/black_grey + name = "black and grey cloak hood" + icon_state = "tesh_hood_bg" + item_state = "tesh_hood_bg" + +/obj/item/clothing/head/tesh_hood/standard/black_midgrey + name = "black and medium grey cloak hood" + icon_state = "tesh_hood_bmg" + item_state = "tesh_hood_bmg" + +/obj/item/clothing/head/tesh_hood/standard/black_lightgrey + name = "black and light grey cloak hood" + icon_state = "tesh_hood_blg" + item_state = "tesh_hood_blg" + +/obj/item/clothing/head/tesh_hood/standard/black_white + name = "black and white cloak hood" + icon_state = "tesh_hood_bw" + item_state = "tesh_hood_bw" + +/obj/item/clothing/head/tesh_hood/standard/black_red + name = "black and red cloak hood" + icon_state = "tesh_hood_br" + item_state = "tesh_hood_br" + +/obj/item/clothing/head/tesh_hood/standard/black + name = "black cloak hood" + icon_state = "tesh_hood_bn" + item_state = "tesh_hood_bn" + +/obj/item/clothing/head/tesh_hood/standard/black_yellow + name = "black and yellow cloak hood" + icon_state = "tesh_hood_by" + item_state = "tesh_hood_by" + +/obj/item/clothing/head/tesh_hood/standard/black_green + name = "black and green cloak hood" + icon_state = "tesh_hood_bgr" + item_state = "tesh_hood_bgr" + +/obj/item/clothing/head/tesh_hood/standard/black_blue + name = "black and blue cloak hood" + icon_state = "tesh_hood_bbl" + item_state = "tesh_hood_bbl" + +/obj/item/clothing/head/tesh_hood/standard/black_purple + name = "black and purple cloak hood" + icon_state = "tesh_hood_bp" + item_state = "tesh_hood_bp" + +/obj/item/clothing/head/tesh_hood/standard/black_pink + name = "black and pink cloak hood" + icon_state = "tesh_hood_bpi" + item_state = "tesh_hood_bpi" + +/obj/item/clothing/head/tesh_hood/standard/black_brown + name = "black and brown cloak hood" + icon_state = "tesh_hood_bbr" + item_state = "tesh_hood_bbr" + +/obj/item/clothing/head/tesh_hood/standard/orange_grey + name = "orange and grey cloak hood" + icon_state = "tesh_hood_og" + item_state = "tesh_hood_og" + +/obj/item/clothing/head/tesh_hood/standard/rainbow + name = "rainbow cloak hood" + icon_state = "tesh_hood_rainbow" + item_state = "tesh_hood_rainbow" + +/obj/item/clothing/head/tesh_hood/standard/lightgrey_grey + name = "light grey and grey cloak hood" + icon_state = "tesh_hood_lgg" + item_state = "tesh_hood_lgg" + +/obj/item/clothing/head/tesh_hood/standard/white_grey + name = "white and grey cloak hood" + icon_state = "tesh_hood_wg" + item_state = "tesh_hood_wg" + +/obj/item/clothing/head/tesh_hood/standard/red_grey + name = "red and grey cloak hood" + icon_state = "tesh_hood_rg" + item_state = "tesh_hood_rg" + +/obj/item/clothing/head/tesh_hood/standard/orange + name = "orange cloak hood" + icon_state = "tesh_hood_on" + item_state = "tesh_hood_on" + +/obj/item/clothing/head/tesh_hood/standard/yellow_grey + name = "yellow and grey cloak hood" + icon_state = "tesh_hood_yg" + item_state = "tesh_hood_yg" + +/obj/item/clothing/head/tesh_hood/standard/green_grey + name = "green and grey cloak hood" + icon_state = "tesh_hood_gg" + item_state = "tesh_hood_gg" + +/obj/item/clothing/head/tesh_hood/standard/blue_grey + name = "blue and grey cloak hood" + icon_state = "tesh_hood_blug" + item_state = "tesh_hood_blug" + +/obj/item/clothing/head/tesh_hood/standard/purple_grey + name = "purple and grey cloak hood" + icon_state = "tesh_hood_pg" + item_state = "tesh_hood_pg" + +/obj/item/clothing/head/tesh_hood/standard/pink_grey + name = "pink and grey cloak hood" + icon_state = "tesh_hood_pig" + item_state = "tesh_hood_pig" + +/obj/item/clothing/head/tesh_hood/standard/brown_grey + name = "brown and grey cloak hood" + icon_state = "tesh_hood_brg" + item_state = "tesh_hood_brg" diff --git a/code/modules/clothing/under/accessories/accessory_vr.dm b/code/modules/clothing/under/accessories/accessory_vr.dm index 4c30c2cef8..2adf9557a4 100644 --- a/code/modules/clothing/under/accessories/accessory_vr.dm +++ b/code/modules/clothing/under/accessories/accessory_vr.dm @@ -165,6 +165,15 @@ overlay_state = "collar_holo_overlay" matter = list(DEFAULT_WALL_MATERIAL = 50) +//TFF 23/4/19: Indigestible collar addition +/obj/item/clothing/accessory/collar/holo/indigestible + name = "Holo-collar" + desc = "A special variety of the holo-collar that seems to be made of a very durable fabric that fits around the neck." + icon_state = "collar_holo" + item_state = "collar_holo_overlay" + overlay_state = "collar_holo_overlay" + matter = list(DEFAULT_WALL_MATERIAL = 50) + // Chompstation edit - Deprecated, implementing a custom method of renaming collars. /* /obj/item/clothing/accessory/collar/holo/attack_self(mob/user as mob) diff --git a/code/modules/clothing/under/accessories/clothing.dm b/code/modules/clothing/under/accessories/clothing.dm index eaab8b290a..c14c6ef2b9 100644 --- a/code/modules/clothing/under/accessories/clothing.dm +++ b/code/modules/clothing/under/accessories/clothing.dm @@ -49,7 +49,6 @@ desc = "A simple, comfortable poncho." icon_state = "classicponcho" item_state = "classicponcho" - icon_override = 'icons/mob/ties.dmi' var/fire_resist = T0C+100 allowed = list(/obj/item/weapon/tank/emergency/oxygen) armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) @@ -61,7 +60,20 @@ sprite_sheets = list( "Teshari" = 'icons/mob/species/seromi/suit.dmi' - ) + ) //This works only when wearing ponchos as an accessory, not a suit. + +/obj/item/clothing/accessory/poncho/equipped() //Solution for race-specific sprites for an accessory which is also a suit. Suit icons break if you don't use icon override which then also overrides race-specific sprites. + ..() + var/mob/living/carbon/human/H = loc + if(istype(H) && H.wear_suit == src) + if(H.species.name == "Teshari") + icon_override = 'icons/mob/species/seromi/suit.dmi' + else + icon_override = 'icons/mob/ties.dmi' + update_clothing_icon() + +/obj/item/clothing/accessory/poncho/dropped() //Resets the override to prevent the wrong .dmi from being used because equipped only triggers when wearing ponchos as suits. + icon_override = null /obj/item/clothing/accessory/poncho/green name = "green poncho" diff --git a/code/modules/clothing/under/jobs/security.dm b/code/modules/clothing/under/jobs/security.dm index 9680de4884..3f19e4a4d0 100644 --- a/code/modules/clothing/under/jobs/security.dm +++ b/code/modules/clothing/under/jobs/security.dm @@ -61,7 +61,8 @@ item_state_slots = list(slot_r_hand_str = "green", slot_l_hand_str = "green") armor = list(melee = 10, bullet = 5, laser = 5,energy = 0, bomb = 0, bio = 0, rad = 0) siemens_coefficient = 0.9 - rolled_sleeves = -1 + rolled_sleeves = 0 + rolled_down = 0 /* * Detective diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 07b0f12609..57b0024614 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -94,6 +94,7 @@ desc = "A short-sleeved black uniform, paired with grey digital-camo cargo pants. It looks very tactical." icon_state = "ert_uniform" item_state_slots = list(slot_r_hand_str = "black", slot_l_hand_str = "black") + armor = list(melee = 10, bullet = 5, laser = 5,energy = 0, bomb = 0, bio = 0, rad = 0) /obj/item/clothing/under/gov desc = "A neat proper uniform of someone on offical business. The collar is immaculately starched." @@ -852,4 +853,16 @@ /obj/item/clothing/under/cohesion/hazard name = "hazard cohesion suit" desc = "An orange cohesion suit with yellow hazard stripes intended to assist Prometheans in maintaining their form and prevent direct skin exposure." - icon_state = "cohesionsuit_hazard" \ No newline at end of file + icon_state = "cohesionsuit_hazard" + +/obj/item/clothing/under/sexybunny_white + name = "Bunny girl suit" + desc = "this seems to come with extra padding, exaggerating the chest some." + icon_state = "sexybunny_white" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS|LEGS + +/obj/item/clothing/under/sexybunny_black + name = "Bunny girl suit" + desc = "this seems to come with extra padding, exaggerating the chest some." + icon_state = "sexybunny_black" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS|LEGS \ No newline at end of file diff --git a/code/modules/clothing/under/xenos/seromi.dm b/code/modules/clothing/under/xenos/seromi.dm index 9d6598a517..766cdb8169 100644 --- a/code/modules/clothing/under/xenos/seromi.dm +++ b/code/modules/clothing/under/xenos/seromi.dm @@ -34,134 +34,255 @@ icon_state = "seromi_rainbow" /obj/item/clothing/under/seromi/undercoat - desc = "A Teshari traditional garb, with a modern twist! Made of micro and nanofibres to make it light and billowy, perfect for going fast and stylishly!" + desc = "A teshari traditional garb, with a modern twist! Made of micro and nanofibres to make it light and billowy, perfect for going fast and stylishly!" icon = 'icons/mob/species/seromi/teshari_uniform.dmi' icon_override = 'icons/mob/species/seromi/teshari_uniform.dmi' icon_state = "tesh_uniform_bo" item_state = "tesh_uniform_bo" body_parts_covered = UPPER_TORSO|LOWER_TORSO -/obj/item/clothing/under/seromi/undercoat/black_orange +/obj/item/clothing/under/seromi/undercoat/standard/black_orange name = "black and orange undercoat" icon_state = "tesh_uniform_bo" item_state = "tesh_uniform_bo" -/obj/item/clothing/under/seromi/undercoat/black_grey +/obj/item/clothing/under/seromi/undercoat/standard/black_grey name = "black and grey undercoat" icon_state = "tesh_uniform_bg" item_state = "tesh_uniform_bg" -/obj/item/clothing/under/seromi/undercoat/black_midgrey +/obj/item/clothing/under/seromi/undercoat/standard/black_midgrey name = "black and medium grey undercoat" icon_state = "tesh_uniform_bmg" item_state = "tesh_uniform_bmg" -/obj/item/clothing/under/seromi/undercoat/black_lightgrey +/obj/item/clothing/under/seromi/undercoat/standard/black_lightgrey name = "black and light grey undercoat" icon_state = "tesh_uniform_blg" item_state = "tesh_uniform_blg" -/obj/item/clothing/under/seromi/undercoat/black_white +/obj/item/clothing/under/seromi/undercoat/standard/black_white name = "black and white undercoat" icon_state = "tesh_uniform_bw" item_state = "tesh_uniform_bw" -/obj/item/clothing/under/seromi/undercoat/black_red +/obj/item/clothing/under/seromi/undercoat/standard/black_red name = "black and red undercoat" icon_state = "tesh_uniform_br" item_state = "tesh_uniform_br" -/obj/item/clothing/under/seromi/undercoat/black +/obj/item/clothing/under/seromi/undercoat/standard/black name = "black undercoat" icon_state = "tesh_uniform_bn" item_state = "tesh_uniform_bn" -/obj/item/clothing/under/seromi/undercoat/black_yellow +/obj/item/clothing/under/seromi/undercoat/standard/black_yellow name = "black and yellow undercoat" icon_state = "tesh_uniform_by" item_state = "tesh_uniform_by" -/obj/item/clothing/under/seromi/undercoat/black_green +/obj/item/clothing/under/seromi/undercoat/standard/black_green name = "black and green undercoat" icon_state = "tesh_uniform_bgr" item_state = "tesh_uniform_bgr" -/obj/item/clothing/under/seromi/undercoat/black_blue +/obj/item/clothing/under/seromi/undercoat/standard/black_blue name = "black and blue undercoat" icon_state = "tesh_uniform_bbl" item_state = "tesh_uniform_bbl" -/obj/item/clothing/under/seromi/undercoat/black_purple +/obj/item/clothing/under/seromi/undercoat/standard/black_purple name = "black and purple undercoat" icon_state = "tesh_uniform_bp" item_state = "tesh_uniform_bp" -/obj/item/clothing/under/seromi/undercoat/black_pink +/obj/item/clothing/under/seromi/undercoat/standard/black_pink name = "black and pink undercoat" icon_state = "tesh_uniform_bpi" item_state = "tesh_uniform_bpi" -/obj/item/clothing/under/seromi/undercoat/black_brown +/obj/item/clothing/under/seromi/undercoat/standard/black_brown name = "black and brown undercoat" icon_state = "tesh_uniform_bbr" item_state = "tesh_uniform_bbr" -/obj/item/clothing/under/seromi/undercoat/orange_grey +/obj/item/clothing/under/seromi/undercoat/standard/orange_grey name = "orange and grey undercoat" icon_state = "tesh_uniform_og" item_state = "tesh_uniform_og" -/obj/item/clothing/under/seromi/undercoat/rainbow +/obj/item/clothing/under/seromi/undercoat/standard/rainbow name = "rainbow undercoat" icon_state = "tesh_uniform_rainbow" item_state = "tesh_uniform_rainbow" -/obj/item/clothing/under/seromi/undercoat/lightgrey_grey +/obj/item/clothing/under/seromi/undercoat/standard/lightgrey_grey name = "light grey and grey undercoat" icon_state = "tesh_uniform_lgg" item_state = "tesh_uniform_lgg" -/obj/item/clothing/under/seromi/undercoat/white_grey +/obj/item/clothing/under/seromi/undercoat/standard/white_grey name = "white and grey undercoat" icon_state = "tesh_uniform_wg" item_state = "tesh_uniform_wg" -/obj/item/clothing/under/seromi/undercoat/red_grey +/obj/item/clothing/under/seromi/undercoat/standard/red_grey name = "red and grey undercoat" icon_state = "tesh_uniform_rg" item_state = "tesh_uniform_rg" -/obj/item/clothing/under/seromi/undercoat/orange +/obj/item/clothing/under/seromi/undercoat/standard/orange name = "orange undercoat" icon_state = "tesh_uniform_on" item_state = "tesh_uniform_on" -/obj/item/clothing/under/seromi/undercoat/yellow_grey +/obj/item/clothing/under/seromi/undercoat/standard/yellow_grey name = "yellow and grey undercoat" icon_state = "tesh_uniform_yg" item_state = "tesh_uniform_yg" -/obj/item/clothing/under/seromi/undercoat/green_grey +/obj/item/clothing/under/seromi/undercoat/standard/green_grey name = "green and grey undercoat" icon_state = "tesh_uniform_gg" item_state = "tesh_uniform_gg" -/obj/item/clothing/under/seromi/undercoat/blue_grey +/obj/item/clothing/under/seromi/undercoat/standard/blue_grey name = "blue and grey undercoat" icon_state = "tesh_uniform_blug" item_state = "tesh_uniform_blug" -/obj/item/clothing/under/seromi/undercoat/purple_grey +/obj/item/clothing/under/seromi/undercoat/standard/purple_grey name = "purple and grey undercoat" icon_state = "tesh_uniform_pg" item_state = "tesh_uniform_pg" -/obj/item/clothing/under/seromi/undercoat/pink_grey +/obj/item/clothing/under/seromi/undercoat/standard/pink_grey name = "pink and grey undercoat" icon_state = "tesh_uniform_pig" item_state = "tesh_uniform_pig" -/obj/item/clothing/under/seromi/undercoat/brown_grey +/obj/item/clothing/under/seromi/undercoat/standard/brown_grey name = "brown and grey undercoat" icon_state = "tesh_uniform_brg" - item_state = "tesh_uniform_brg" \ No newline at end of file + item_state = "tesh_uniform_brg" + +/obj/item/clothing/under/seromi/undercoat/jobs + icon = 'icons/mob/species/seromi/deptjacket.dmi' + icon_override = 'icons/mob/species/seromi/deptjacket.dmi' + +/obj/item/clothing/under/seromi/undercoat/jobs/cargo + name = "Cargo undercoat" + desc = "A traditional teshari garb made for the Cargo department" + icon_state = "tesh_uniform_car" + item_state = "tesh_uniform_car" + +/obj/item/clothing/under/seromi/undercoat/jobs/mining + name = "Mining undercoat" + desc = "A traditional teshari garb made for Mining" + icon_state = "tesh_uniform_mine" + item_state = "tesh_uniform_mine" + +/obj/item/clothing/under/seromi/undercoat/jobs/command + name = "Command undercoat" + desc = "A traditional Teshari garb made for the Command department" + icon_state = "tesh_uniform_comm" + item_state = "tesh_uniform_comm" + +/obj/item/clothing/under/seromi/undercoat/jobs/command_g + name = "Command undercoat (gold buttons)" + desc = "A traditional teshari garb made for the Command department" + icon_state = "tesh_uniform_comm_g" + item_state = "tesh_uniform_comm_g" + +/obj/item/clothing/under/seromi/undercoat/jobs/ce + name = "Cheif Engineer's undercoat" + desc = "A traditional teshari garb made for the Chief Engineer" + icon_state = "tesh_uniform_ce" + item_state = "tesh_uniform_ce" + +/obj/item/clothing/under/seromi/undercoat/jobs/ce_w + name = "Cheif Engineer's undercoat (white)" + desc = "A traditional teshari garb made for the department" + icon_state = "tesh_uniform_ce_w" + item_state = "tesh_uniform_ce_w" + +/obj/item/clothing/under/seromi/undercoat/jobs/engineer + name = "Engineering undercoat" + desc = "A traditional teshari garb made for the Engineering department" + icon_state = "tesh_uniform_engie" + item_state = "tesh_uniform_engie" + +/obj/item/clothing/under/seromi/undercoat/jobs/atmos + name = "Atmos Tech undercoat" + desc = "A traditional teshari garb made for the Atmos Tech" + icon_state = "tesh_uniform_atmos" + item_state = "tesh_uniform_atmos" + +/obj/item/clothing/under/seromi/undercoat/jobs/cmo + name = "Chief Medical Officer undercoat" + desc = "A traditional teshari garb made for the Cheif Medical Officer" + icon_state = "tesh_uniform_cmo" + item_state = "tesh_uniform_cmo" + +/obj/item/clothing/under/seromi/undercoat/jobs/medical + name = "Medical undercoat" + desc = "A traditional teshari garb made for the Medical department" + icon_state = "tesh_uniform_doc" + item_state = "tesh_uniform_doc" + +/obj/item/clothing/under/seromi/undercoat/jobs/chemistry + name = "Chemistry undercoat" + desc = "A traditional teshari garb made for the Chemist" + icon_state = "tesh_uniform_chem" + item_state = "tesh_uniform_chem" + +/obj/item/clothing/under/seromi/undercoat/jobs/viro + name = "Virologist undercoat" + desc = "A traditional teshari garb made for the Virologist" + icon_state = "tesh_uniform_viro" + item_state = "tesh_uniform_viro" + +/obj/item/clothing/under/seromi/undercoat/jobs/para + name = "Paramedic undercoat" + desc = "A traditional teshari garb made for the Paramedic" + icon_state = "tesh_uniform_para" + item_state = "tesh_uniform_para" + +/obj/item/clothing/under/seromi/undercoat/jobs/sci + name = "Scientist undercoat" + desc = "A traditional teshari garb made for the Science department" + icon_state = "tesh_uniform_sci" + item_state = "tesh_uniform_sci" + +/obj/item/clothing/under/seromi/undercoat/jobs/robo + name = "Roboticist undercoat" + desc = "A traditional teshari garb made for the Roboticist" + icon_state = "tesh_uniform_robo" + item_state = "tesh_uniform_robo" + +/obj/item/clothing/under/seromi/undercoat/jobs/sec + name = "Security undercoat" + desc = "A traditional teshari garb made for the Security department. Made with slightly sturdier materials" + icon_state = "tesh_uniform_sec" + item_state = "tesh_uniform_sec" + armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) + siemens_coefficient = 0.9 + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS + +/obj/item/clothing/under/seromi/undercoat/jobs/qm + name = "Quartermaster's undercoat" + desc = "A traditional teshari garb made for the Quartermaster" + icon_state = "tesh_uniform_qm" + item_state = "tesh_uniform_qm" + +/obj/item/clothing/under/seromi/undercoat/jobs/service + name = "Service undercoat" + desc = "A traditional teshari garb made for the Service department" + icon_state = "tesh_uniform_serv" + item_state = "tesh_uniform_serv" + +/obj/item/clothing/under/seromi/undercoat/jobs/iaa + name = "IAA undercoat" + desc = "A traditional teshari garb made for the Internal Affairs Agent" + icon_state = "tesh_uniform_iaa" + item_state = "tesh_uniform_iaa" \ No newline at end of file diff --git a/code/modules/economy/casinocash.dm b/code/modules/economy/casinocash.dm new file mode 100644 index 0000000000..cefa530164 --- /dev/null +++ b/code/modules/economy/casinocash.dm @@ -0,0 +1,173 @@ +/obj/item/weapon/spacecasinocash + name = "broken casino chip" + desc = "It's worth nothing in a casino." + gender = PLURAL + icon = 'icons/obj/casino.dmi' + icon_state = "spacecasinocash1" + opacity = 0 + density = 0 + anchored = 0.0 + force = 1.0 + throwforce = 1.0 + throw_speed = 1 + throw_range = 2 + w_class = ITEMSIZE_SMALL + var/access = list() + access = access_crate_cash + var/worth = 0 + +/obj/item/weapon/spacecasinocash/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W, /obj/item/weapon/spacecasinocash)) + if(istype(W, /obj/item/weapon/spacecasinocash/ewallet)) return 0 + + var/obj/item/weapon/spacecasinocash/SC = W + + SC.adjust_worth(src.worth) + if(istype(user, /mob/living/carbon/human)) + var/mob/living/carbon/human/h_user = user + + h_user.drop_from_inventory(src) + h_user.drop_from_inventory(SC) + h_user.put_in_hands(SC) + user << "You combine the casino chips to a stack of [SC.worth] of credits." + qdel(src) + +/obj/item/weapon/spacecasinocash/update_icon() + overlays.Cut() + name = "[worth] casino credit\s" + if(worth in list(1000,500,200,100,50,20,10,1)) + icon_state = "spacecasinocash[worth]" + desc = "It's a stack of casino chips with a combined value of [worth] credits." + return + var/sum = src.worth + var/num = 0 + for(var/i in list(1000,500,200,100,50,20,10,1)) + while(sum >= i && num < 50) + sum -= i + num++ + var/image/banknote = image('icons/obj/casino.dmi', "spacecasinocash[i]") + var/matrix/M = matrix() + M.Translate(rand(-6, 6), rand(-4, 8)) + M.Turn(pick(-45, -27.5, 0, 0, 0, 0, 0, 0, 0, 27.5, 45)) + banknote.transform = M + src.overlays += banknote + if(num == 0) // Less than one credit, let's just make it look like 1 for ease + var/image/banknote = image('icons/obj/casino.dmi', "spacecasinocash1") + var/matrix/M = matrix() + M.Translate(rand(-6, 6), rand(-4, 8)) + M.Turn(pick(-45, -27.5, 0, 0, 0, 0, 0, 0, 0, 27.5, 45)) + banknote.transform = M + src.overlays += banknote + src.desc = "They are worth [worth] of credits." + +/obj/item/weapon/spacecasinocash/proc/adjust_worth(var/adjust_worth = 0, var/update = 1) + worth += adjust_worth + if(worth > 0) + if(update) + update_icon() + return worth + else + qdel(src) + return 0 + +/obj/item/weapon/spacecasinocash/proc/set_worth(var/new_worth = 0, var/update = 1) + worth = max(0, new_worth) + if(update) + update_icon() + return worth + +/obj/item/weapon/spacecasinocash/attack_self() + var/amount = input(usr, "How much credits worth of chips do you want to take? (0 to [src.worth])", "Take chips", 20) as num + amount = round(Clamp(amount, 0, src.worth)) + + if(!amount) + return + + adjust_worth(-amount) + var/obj/item/weapon/spacecasinocash/SC = new (usr.loc) + SC.set_worth(amount) + usr.put_in_hands(SC) + +/obj/item/weapon/spacecasinocash/c1 + name = "1 credit casino chip" + icon_state = "spacecasinocash1" + desc = "It's worth 1 credit." + worth = 1 + +/obj/item/weapon/spacecasinocash/c10 + name = "10 credit casino chip" + icon_state = "spacecasinocash10" + desc = "It's worth 10 credits." + worth = 10 + +/obj/item/weapon/spacecasinocash/c20 + name = "20 credit casino chip" + icon_state = "spacecasinocash20" + desc = "It's worth 20 credits." + worth = 20 + +/obj/item/weapon/spacecasinocash/c50 + name = "50 credit casino chip" + icon_state = "spacecasinocash50" + desc = "It's worth 50 credits." + worth = 50 + +/obj/item/weapon/spacecasinocash/c100 + name = "100 credit casino chip" + icon_state = "spacecasinocash100" + desc = "It's worth 100 credits." + worth = 100 + +/obj/item/weapon/spacecasinocash/c200 + name = "200 credit casino chip" + icon_state = "spacecasinocash200" + desc = "It's worth 200 credits." + worth = 200 + +/obj/item/weapon/spacecasinocash/c500 + name = "500 credit casino chip" + icon_state = "spacecasinocash500" + desc = "It's worth 500 credits." + worth = 500 + +/obj/item/weapon/spacecasinocash/c1000 + name = "1000 credit casino chip" + icon_state = "spacecasinocash1000" + desc = "It's worth 1000 credits." + worth = 1000 + +proc/spawn_casinochips(var/sum, spawnloc, mob/living/carbon/human/human_user as mob) + var/obj/item/weapon/spacecasinocash/SC = new (spawnloc) + + SC.set_worth(sum) + if (ishuman(human_user) && !human_user.get_active_hand()) + human_user.put_in_hands(SC) + return + +/obj/item/weapon/spacecasinocash/ewallet + name = "Casino chip card" + icon_state = "efundcard" + desc = "A casino card that can hold credits." + var/owner_name = "" //So the ATM can set it so the EFTPOS can put a valid name on transactions. + attack_self() return //Don't act + attackby() return //like actual + update_icon() return //space cash + +/obj/item/weapon/spacecasinocash/ewallet/examine(mob/user) + ..(user) + if (!(user in view(2)) && user!=src.loc) return + user << "Casino chip card's owner: [src.owner_name]. credits remaining: [src.worth]." + +/obj/item/weapon/casin_platinum_chip + name = "platinum chip" + desc = "Ringa-a-Ding-Ding!" + icon = 'icons/obj/casino.dmi' + icon_state = "platinum_chip" + opacity = 0 + density = 0 + anchored = 0.0 + force = 1.0 + throwforce = 1.0 + throw_speed = 1 + throw_range = 2 + w_class = ITEMSIZE_SMALL \ No newline at end of file diff --git a/code/modules/economy/price_list.dm b/code/modules/economy/price_list.dm index e9c8b1372d..82288ce785 100644 --- a/code/modules/economy/price_list.dm +++ b/code/modules/economy/price_list.dm @@ -54,6 +54,8 @@ /datum/reagent/drink/collins_mix price_tag = 2 +/datum/reagent/drink/horchata + price_tag = 2 // Beer // @@ -87,7 +89,27 @@ /obj/item/weapon/reagent_containers/food/drinks/h_chocolate price_tag = 3 +/datum/reagent/drink/bubbleteawatermelon + price_tag = 5 +/datum/reagent/drink/bubbleteastrawberry + price_tag = 5 + +/datum/reagent/drink/bubbleteacherry + price_tag = 5 + +/datum/reagent/drink/bubbleteacoffee + price_tag = 5 + +/datum/reagent/drink/bubbleteabanana + price_tag = 5 + +/datum/reagent/drink/lowpower + price_tag = 4 + +/datum/reagent/drink/highpower + price_tag = 7 + // Spirituous liquors // /datum/reagent/ethanol/irish_cream @@ -138,6 +160,8 @@ /datum/reagent/ethanol/coffee/brave_bull // Not an original liquor in its own. But since it's a mix of purely Tequila price_tag = 5 // and Kahlua, it's basically just another one and gets the same price. +/datum/reagent/ethanol/snaps + price_tag = 5 // Wines // @@ -251,6 +275,9 @@ /datum/reagent/ethanol/coffee/irishcoffee price_tag = 4 + +/datum/reagent/ethanol/coffee/jackbrew + price_tag = 6 /datum/reagent/ethanol/longislandicedtea price_tag = 4 @@ -353,7 +380,25 @@ /datum/reagent/ethanol/erebusmoonrise price_tag = 4 + +/datum/reagent/ethanol/coldfront + price_tag = 4 +/datum/reagent/ethanol/bookwyrm + price_tag = 4 + +/datum/reagent/ethanol/flapper + price_tag = 4 + +/datum/reagent/toxin/oilslide + price_tag = 5 + +/datum/reagent/ethanol/sitonmyface + price_tag = 4 + +/datum/reagent/ethanol/hachi + price_tag = 4 + // The Cheap Shit // /datum/reagent/ethanol/hooch @@ -486,6 +531,8 @@ /obj/item/weapon/reagent_containers/food/drinks/bottle/grenadine price_tag = 15 +/obj/item/weapon/reagent_containers/food/drinks/bottle/snaps + price_tag = 15 // Wines // @@ -1024,4 +1071,4 @@ //******************************// /datum/reagent/ethanol/euphoria - price_tag = 30 \ No newline at end of file + price_tag = 30 diff --git a/code/modules/emoji/emoji_parse.dm b/code/modules/emoji/emoji_parse.dm new file mode 100644 index 0000000000..3a0281f3f0 --- /dev/null +++ b/code/modules/emoji/emoji_parse.dm @@ -0,0 +1,30 @@ +/proc/emoji_parse(text) + . = text + if(!config.emojis) + return + var/static/list/emojis = icon_states(icon('icons/emoji.dmi')) + var/parsed = "" + var/pos = 1 + var/search = 0 + var/emoji = "" + while(1) + search = findtext(text, ":", pos) + parsed += copytext(text, pos, search) + if(search) + pos = search + search = findtext(text, ":", pos+1) + if(search) + emoji = lowertext(copytext(text, pos+1, search)) + if(emoji in emojis) + parsed += " " + pos = search + 1 + else + parsed += copytext(text, pos, search) + pos = search + emoji = "" + continue + else + parsed += copytext(text, pos, search) + break + return parsed + diff --git a/code/modules/events/boss.dm b/code/modules/events/boss.dm new file mode 100644 index 0000000000..31bc9dd09c --- /dev/null +++ b/code/modules/events/boss.dm @@ -0,0 +1,116 @@ +#define LOC_ATMOS 0 +#define LOC_CHAPEL 1 +#define LOC_LIBRARY 2 +#define LOC_GARDEN 3 +#define LOC_MAINTENANCE 4 +#define LOC_CONSTR 5 + +#define BOSS_METROID 0 +#define BOSS_XENOMORPH 1 +#define BOSS_CARP 2 +#define BOSS_SPIDER 3 +#define BOSS_CRAB 4 +#define BOSS_DRAGON 5 +#define BOSS_PANTHER 6 +#define BOSS_MOTHER 7 +#define BOSS_CHUNGUS 8 + +/datum/event/boss + announceWhen = 10 + endWhen = 11 + var/location + var/locstring + var/boss + var/bossstring + +/datum/event/boss/start() + + location = rand(0,5) + var/list/turf/simulated/floor/turfs = list() + var/spawn_area_type + switch(location) + if(LOC_ATMOS) + spawn_area_type = /area/engineering/atmos + locstring = "atmospherics" + if(LOC_CHAPEL) + spawn_area_type = /area/chapel/main + locstring = "the chapel" + if(LOC_LIBRARY) + spawn_area_type = /area/library + locstring = "the library" + if(LOC_GARDEN) + spawn_area_type = /area/hydroponics/garden + locstring = "the public garden" + if(LOC_MAINTENANCE) + spawn_area_type = /area/maintenance/locker + locstring = "far northern maintenance tunnels" + if(LOC_CONSTR) + spawn_area_type = /area/construction + locstring = "the construction area" + + for(var/areapath in typesof(spawn_area_type)) + var/area/A = locate(areapath) + for(var/turf/simulated/floor/F in A.contents) + if(turf_clear(F)) + turfs += F + + var/list/spawn_types = list() + boss = rand(0,8) + switch(boss) + if(BOSS_METROID) + spawn_types = list(/mob/living/simple_animal/hostile/metroid/combat/queen) + bossstring = "metroid" + if(BOSS_XENOMORPH) + spawn_types = list(/mob/living/simple_animal/hostile/alien/queen/empress) + bossstring = "xenomorph" + if(BOSS_CARP) + spawn_types = list(/mob/living/simple_animal/hostile/carp/large/huge) + bossstring = "carp" + if(BOSS_SPIDER) + spawn_types = list(/mob/living/simple_animal/hostile/giant_spider/nurse/queen) + bossstring = "spider" + if(BOSS_CRAB) + spawn_types = list(/mob/living/simple_animal/hostile/giant_crab) + bossstring = "crab" + if(BOSS_DRAGON) + spawn_types = list(/mob/living/simple_animal/hostile/dragon) + bossstring = "dragon" + if(BOSS_PANTHER) + spawn_types = list(/mob/living/simple_animal/hostile/panther) + bossstring = "panther" + if(BOSS_MOTHER) + spawn_types = list(/mob/living/simple_animal/hostile/alien/queen/empress/mother) + bossstring = "xenomorph mother" + if(BOSS_CHUNGUS) + spawn_types = list(/mob/living/simple_animal/hostile/chungus) + bossstring = "chungus" + + spawn(0) + var/num = 1 + while(turfs.len > 0 && num > 0) + var/turf/simulated/floor/T = pick(turfs) + turfs.Remove(T) + num-- + var/spawn_type = pick(spawn_types) + new spawn_type(T) + + +/datum/event/boss/announce() + command_announcement.Announce("Bioscans indicate a giant enemy [bossstring] in [locstring]. Handle with extreme caution.", "Boss Fight", new_sound = 'sound/misc/alarm1.ogg') + +#undef LOC_ATMOS +#undef LOC_CHAPEL +#undef LOC_LIBRARY +#undef LOC_GARDEN +#undef LOC_MAINTENANCE +#undef LOC_CONSTR + +#undef BOSS_METROID +#undef BOSS_XENOMORPH +#undef BOSS_CARP +#undef BOSS_SPIDER +#undef BOSS_CRAB +#undef BOSS_DRAGON +#undef BOSS_PANTHER +#undef BOSS_MOTHER +#undef BOSS_CHUNGUS \ No newline at end of file diff --git a/code/modules/events/escaped_slimes.dm b/code/modules/events/escaped_slimes.dm index aad2fc18b5..8aa2058df8 100644 --- a/code/modules/events/escaped_slimes.dm +++ b/code/modules/events/escaped_slimes.dm @@ -36,9 +36,10 @@ /datum/event/escaped_slimes/start() // world << "TEST-SPAWN START" var/list/vents = list() - for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in world) - if(temp_vent.network && temp_vent.loc.z in using_map.station_levels && !is_area_occupied(temp_vent.loc.loc)) //borrowed from spiders event, but it works. Distribute the slimes only in rooms with vents - vents += temp_vent + for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in machines) + if(!temp_vent.welded && !is_area_occupied(temp_vent.loc.loc) && temp_vent.network && temp_vent.loc.z in using_map.station_levels) //borrowed from spiders event, but it works. Distribute the slimes only in rooms with vents + if(temp_vent.network.normal_members.len > 50) + vents += temp_vent while((spawncount > 0) && vents.len) var/obj/vent = pick(vents) diff --git a/code/modules/events/event_container_vr.dm b/code/modules/events/event_container_vr.dm index 3870f399fa..e07b58bbbf 100644 --- a/code/modules/events/event_container_vr.dm +++ b/code/modules/events/event_container_vr.dm @@ -1,137 +1,150 @@ -#define ASSIGNMENT_ANY "Any" -#define ASSIGNMENT_AI "AI" -#define ASSIGNMENT_CYBORG "Cyborg" -#define ASSIGNMENT_ENGINEER "Engineer" -#define ASSIGNMENT_GARDENER "Gardener" -#define ASSIGNMENT_JANITOR "Janitor" -#define ASSIGNMENT_MEDICAL "Medical" -#define ASSIGNMENT_SCIENTIST "Scientist" -#define ASSIGNMENT_SECURITY "Security" - -// -// VOREStation overrides to the default event manager configuration. -// -// This file lets us configure which events we want in the rotation without conflicts with upstream. -// It works because the actual event containers don't define New(), allowing us to use New() to replace -// the lists of available events. If they ever do define New() this will need to be changed. -// -// Specifically the change is to move events we don't want down into the disabled_events list -// - -// Adds a list of pre-disabled events to the available events list. -// This keeps them in the rotation, but disabled, so they can be enabled with a click if desired that round. -/datum/event_container/proc/add_disabled_events(var/list/disabled_events) - for(var/datum/event_meta/EM in disabled_events) - EM.enabled = 0 - available_events += EM - -/datum/event_container/mundane/New() - available_events = list( - // Severity level, event name, even type, base weight, role weights, one shot, min weight, max weight. Last two only used if set and non-zero - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Nothing", /datum/event/nothing, 200), - // Bluescreens APCs, but they still work - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "APC Damage", /datum/event/apc_damage, 20, list(ASSIGNMENT_ENGINEER = 20)), - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Brand Intelligence",/datum/event/brand_intelligence,20, list(ASSIGNMENT_JANITOR = 25), 1), - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Camera Damage", /datum/event/camera_damage, 20, list(ASSIGNMENT_ENGINEER = 20, ASSIGNMENT_AI = 40)), - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Canister Leak", /datum/event/canister_leak, 10, list(ASSIGNMENT_ENGINEER = 20)), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Space Dust", /datum/event/dust, 50, list(ASSIGNMENT_ENGINEER = 20), 1, 0, 50), - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Economic News", /datum/event/economic_event, 300), - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Electrified Door", /datum/event/electrified_door, -5, list(ASSIGNMENT_MEDICAL = 5, ASSIGNMENT_ENGINEER = 20, ASSIGNMENT_AI = 10)), - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Lost Carp", /datum/event/carp_migration, 20, list(ASSIGNMENT_SECURITY = 10), 1), - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Meteor Shower", /datum/event/meteor_wave, -15, list(ASSIGNMENT_ENGINEER = 5), 1), - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Money Lotto", /datum/event/money_lotto, 0, list(ASSIGNMENT_ANY = 1), 1, 5, 15), - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Shipping Error", /datum/event/shipping_error , 30, list(ASSIGNMENT_ANY = 2), 0), - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Supply Demand", /datum/event/supply_demand, -15, list(ASSIGNMENT_ANY = 1, ASSIGNMENT_ENGINEER = 5, ASSIGNMENT_MEDICAL = 5), 1), - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Trivial News", /datum/event/trivial_news, 400), - // Spawns mice, lizards, or dud spiderlings - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Vermin Infestation",/datum/event/infestation, 100, list(ASSIGNMENT_JANITOR = 100), 1), - // Rot only weakens walls, not destroy them - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Wallrot", /datum/event/wallrot, 30, list(ASSIGNMENT_ENGINEER = 30, ASSIGNMENT_GARDENER = 50), 1), - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Window Damage", /datum/event/window_break, 10, list(ASSIGNMENT_ENGINEER = 20)), - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Viral Infection", /datum/event/viral_infection, -25, list(ASSIGNMENT_MEDICAL = 5), 1), - ) - add_disabled_events(list( - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Ian Storm", /datum/event/ianstorm, 1, list(), 1), - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Money Hacker", /datum/event/money_hacker, 0, list(ASSIGNMENT_ANY = 4), 1, 10, 25), - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "PDA Spam", /datum/event/pda_spam, 0, list(ASSIGNMENT_ANY = 4), 1, 25, 50), - )) - -/datum/event_container/moderate/New() - available_events = list( - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Nothing", /datum/event/nothing, 800), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Appendicitis", /datum/event/spontaneous_appendicitis, 0, list(ASSIGNMENT_MEDICAL = 30), 1), - // Leaks gas into an unoccupied room. - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Atmos Leak", /datum/event/atmos_leak, 150, list(ASSIGNMENT_ENGINEER = 25), 1), - new /datum/event_meta(EVENT_LEVEL_MAJOR, "Camera Damage", /datum/event/camera_damage, 20, list(ASSIGNMENT_ENGINEER = 20, ASSIGNMENT_AI = 40)), - // Just disables comms for a short while. - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Communication Blackout", /datum/event/communications_blackout, 500, list(ASSIGNMENT_AI = 150, ASSIGNMENT_SECURITY = 120), 1), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Carp School", /datum/event/carp_migration, -50, list(ASSIGNMENT_ENGINEER = 20, ASSIGNMENT_SECURITY = 30), 1), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Escaped Slimes", /datum/event/escaped_slimes, -60, list(ASSIGNMENT_SCIENTIST = 40, ASSIGNMENT_SECURITY = 30)), - // Just blows out a few lights - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Electrical Storm", /datum/event/electrical_storm, 250, list(ASSIGNMENT_ENGINEER = 20, ASSIGNMENT_JANITOR = 150), 1), - // This one is just too fun. - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Gravity Failure", /datum/event/gravity, 75, list(ASSIGNMENT_ENGINEER = 60), 1), - // Temporary power failure, but mitigatead by subgrids - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Grid Check", /datum/event/grid_check, 0, list(ASSIGNMENT_SCIENTIST = 10, ASSIGNMENT_ENGINEER = 25), 1), - //Evil grubs that drain station power slightly - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Grub Infestation", /datum/event/grub_infestation, 0, list(ASSIGNMENT_SECURITY = 50, ASSIGNMENT_ENGINEER = 50), 1), - // Pure RP fun, no mechanical effects. - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Ion Storm", /datum/event/ionstorm, -50, list(ASSIGNMENT_AI = 200, ASSIGNMENT_CYBORG = 100, ASSIGNMENT_ENGINEER = 15, ASSIGNMENT_SCIENTIST = 5), 0), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Meteor Shower", /datum/event/meteor_wave, -15, list(ASSIGNMENT_ENGINEER = 5), 1), - // Opens doors in brig. So just RP fun - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Prison Break", /datum/event/prison_break, -50, list(ASSIGNMENT_SECURITY = 30, ASSIGNMENT_ENGINEER = 50), 1), - // Not bad (dorms are shielded) but inconvenient - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Radiation Storm", /datum/event/radiation_storm, 0, list(ASSIGNMENT_MEDICAL = 50), 1), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Rogue Drones", /datum/event/rogue_drone, -50, list(ASSIGNMENT_SECURITY = 60)), - // Radiation, but only in space. - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Solar Storm", /datum/event/solar_storm, 50, list(ASSIGNMENT_ENGINEER = 40, ASSIGNMENT_SECURITY = 30), 1), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Spider Infestation", /datum/event/spider_infestation, -60, list(ASSIGNMENT_SECURITY = 40), 0), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Viral Infection", /datum/event/viral_infection, -40, list(ASSIGNMENT_MEDICAL = 50), 1), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Virology Breach", /datum/event/prison_break/virology, -50, list(ASSIGNMENT_MEDICAL = 30, ASSIGNMENT_ENGINEER = 50), 1), - new /datum/event_meta(EVENT_LEVEL_MAJOR, "Wallrot", /datum/event/wallrot, 0, list(ASSIGNMENT_ENGINEER = 30, ASSIGNMENT_GARDENER = 50), 1), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Wormholes", /datum/event/wormholes, 20, list(ASSIGNMENT_ANY = 5)), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Xenobiology Breach", /datum/event/prison_break/xenobiology, -50, list(ASSIGNMENT_SCIENCE = 30, ASSIGNMENT_ENGINEER = 50), 1), - ) - add_disabled_events(list( - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Carp School_NoRequirements", /datum/event/carp_migration, 100, list(ASSIGNMENT_ENGINEER = 20, ASSIGNMENT_SECURITY = 30), 1), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Escaped Slimes_NoRequirements", /datum/event/escaped_slimes, 30, list(ASSIGNMENT_SCIENTIST = 40, ASSIGNMENT_SECURITY = 30)), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Meteor Shower_NoRequirements", /datum/event/meteor_wave, 30, list(ASSIGNMENT_ENGINEER = 20), 0), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Spider Infestation_NoRequirements", /datum/event/spider_infestation, 100, list(ASSIGNMENT_SECURITY = 40), 0), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Supply Demand", /datum/event/supply_demand, 0, list(ASSIGNMENT_ANY = 5, ASSIGNMENT_SCIENCE = 15, ASSIGNMENT_GARDENER = 10, ASSIGNMENT_ENGINEER = 10, ASSIGNMENT_MEDICAL = 15), 1), - new /datum/event_meta(EVENT_LEVEL_MODERATE, "Random Antagonist", /datum/event/random_antag, 3, list(ASSIGNMENT_SECURITY = 1), 1, 0, 5), - )) - -/datum/event_container/major/New() - available_events = list( - new /datum/event_meta(EVENT_LEVEL_MAJOR, "Nothing", /datum/event/nothing, 900), - new /datum/event_meta(EVENT_LEVEL_MAJOR, "Atmos Leak", /datum/event/atmos_leak, 30, list(ASSIGNMENT_ENGINEER = 25), 1), - new /datum/event_meta(EVENT_LEVEL_MAJOR, "Blob", /datum/event/blob, -25, list(ASSIGNMENT_SECURITY = 10, ASSIGNMENT_ENGINEER = 5), 1), - new /datum/event_meta(EVENT_LEVEL_MAJOR, "Carp Migration", /datum/event/carp_migration, -30, list(ASSIGNMENT_SECURITY = 10), 1), - new /datum/event_meta(EVENT_LEVEL_MAJOR, "Containment Breach", /datum/event/prison_break/station,0, list(ASSIGNMENT_ANY = 5), 0), - new /datum/event_meta(EVENT_LEVEL_MAJOR, "Escaped Slimes", /datum/event/escaped_slimes, -25, list(ASSIGNMENT_SCIENTIST = 10, ASSIGNMENT_SECURITY = 5), 0), - new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Strike", /datum/event/meteor_strike, 10, list(ASSIGNMENT_ENGINEER = 15), 1), - new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Wave", /datum/event/meteor_wave, -30, list(ASSIGNMENT_ENGINEER = 10), 1), - new /datum/event_meta(EVENT_LEVEL_MAJOR, "Space Dust", /datum/event/dust, 50, list(ASSIGNMENT_ENGINEER = 30), 0), - new /datum/event_meta(EVENT_LEVEL_MAJOR, "Space Vines", /datum/event/spacevine, 20, list(ASSIGNMENT_ENGINEER = 15), 1), - new /datum/event_meta(EVENT_LEVEL_MAJOR, "Spider Infestation", /datum/event/spider_infestation, -25, list(ASSIGNMENT_SECURITY = 10), 0), - new /datum/event_meta(EVENT_LEVEL_MAJOR, "Viral Infection", /datum/event/viral_infection, -30, list(ASSIGNMENT_MEDICAL = 10), 1), - ) - add_disabled_events(list( - new /datum/event_meta(EVENT_LEVEL_MAJOR, "Blob_NoRequirements", /datum/event/blob, 10, list(ASSIGNMENT_SECURITY = 10, ASSIGNMENT_ENGINEER = 30), 1), - new /datum/event_meta(EVENT_LEVEL_MAJOR, "Carp Migration_NoRequirements", /datum/event/carp_migration, 10, list(ASSIGNMENT_SECURITY = 10), 1), - new /datum/event_meta(EVENT_LEVEL_MAJOR, "Escaped Slimes_NoRequirements", /datum/event/escaped_slimes, 30, list(ASSIGNMENT_SCIENTIST = 10, ASSIGNMENT_SECURITY = 5)), - new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Wave_NoRequirements", /datum/event/meteor_wave, 30, list(ASSIGNMENT_ENGINEER = 30), 1), - new /datum/event_meta(EVENT_LEVEL_MAJOR, "Spider Infestation_NoRequirements", /datum/event/spider_infestation, 30, list(ASSIGNMENT_SECURITY = 10), 0), - new /datum/event_meta(EVENT_LEVEL_MAJOR, "Supply Demand", /datum/event/supply_demand, 0, list(ASSIGNMENT_ANY = 5, ASSIGNMENT_SCIENCE = 15, ASSIGNMENT_GARDENER = 10, ASSIGNMENT_ENGINEER = 10, ASSIGNMENT_MEDICAL = 15), 1), - new /datum/event_meta(EVENT_LEVEL_MAJOR, "Viral Infection_NoRequirements", /datum/event/viral_infection, 50, list(ASSIGNMENT_MEDICAL = 50), 1), - )) - -#undef ASSIGNMENT_ANY -#undef ASSIGNMENT_AI -#undef ASSIGNMENT_CYBORG -#undef ASSIGNMENT_ENGINEER -#undef ASSIGNMENT_GARDENER -#undef ASSIGNMENT_JANITOR -#undef ASSIGNMENT_MEDICAL -#undef ASSIGNMENT_SCIENTIST -#undef ASSIGNMENT_SECURITY +#define ASSIGNMENT_ANY "Any" +#define ASSIGNMENT_AI "AI" +#define ASSIGNMENT_CYBORG "Cyborg" +#define ASSIGNMENT_ENGINEER "Engineer" +#define ASSIGNMENT_GARDENER "Gardener" +#define ASSIGNMENT_JANITOR "Janitor" +#define ASSIGNMENT_MEDICAL "Medical" +#define ASSIGNMENT_SCIENTIST "Scientist" +#define ASSIGNMENT_SECURITY "Security" +#define ASSIGNMENT_HOS "Head of Security" +#define ASSIGNMENT_WARDEN "Warden" + +// +// VOREStation overrides to the default event manager configuration. +// +// This file lets us configure which events we want in the rotation without conflicts with upstream. +// It works because the actual event containers don't define New(), allowing us to use New() to replace +// the lists of available events. If they ever do define New() this will need to be changed. +// +// Specifically the change is to move events we don't want down into the disabled_events list +// + +// Adds a list of pre-disabled events to the available events list. +// This keeps them in the rotation, but disabled, so they can be enabled with a click if desired that round. +/datum/event_container/proc/add_disabled_events(var/list/disabled_events) + for(var/datum/event_meta/EM in disabled_events) + EM.enabled = 0 + available_events += EM + +/datum/event_container/mundane/New() + available_events = list( + // Severity level, event name, even type, base weight, role weights, one shot, min weight, max weight. Last two only used if set and non-zero + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Nothing", /datum/event/nothing, 200), + // Bluescreens APCs, but they still work + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "APC Damage", /datum/event/apc_damage, 20, list(ASSIGNMENT_ENGINEER = 20)), + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Brand Intelligence",/datum/event/brand_intelligence,20, list(ASSIGNMENT_JANITOR = 25), 1), + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Camera Damage", /datum/event/camera_damage, 20, list(ASSIGNMENT_ENGINEER = 20, ASSIGNMENT_AI = 40)), + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Canister Leak", /datum/event/canister_leak, 10, list(ASSIGNMENT_ENGINEER = 20)), + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Economic News", /datum/event/economic_event, 300), + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Electrified Door", /datum/event/electrified_door, -5, list(ASSIGNMENT_MEDICAL = 5, ASSIGNMENT_ENGINEER = 20, ASSIGNMENT_AI = 10)), + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Lost Carp", /datum/event/carp_migration, 0, list(ASSIGNMENT_SECURITY = 40), 1), + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Meteor Shower", /datum/event/meteor_wave, -20, list(ASSIGNMENT_ENGINEER = 50), 1), + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Money Lotto", /datum/event/money_lotto, 0, list(ASSIGNMENT_ANY = 1), 1, 5, 15), + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Shipping Error", /datum/event/shipping_error , 30, list(ASSIGNMENT_ANY = 2), 0), + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Supply Demand", /datum/event/supply_demand, -15, list(ASSIGNMENT_ANY = 1, ASSIGNMENT_ENGINEER = 5, ASSIGNMENT_MEDICAL = 5), 1), + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Trivial News", /datum/event/trivial_news, 400), + // Spawns mice, or lizards. + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Vermin Infestation",/datum/event/infestation, 100, list(ASSIGNMENT_JANITOR = 100), 1), + //Split spiderlings off from the vermin infestation event into its own thing, triggered only by security. + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Spiderling Infestation",/datum/event/spiderling_infestation, 0, list(ASSIGNMENT_SECURITY = 50), 1), + // Rot only weakens walls, not destroy them + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Wallrot", /datum/event/wallrot, 30, list(ASSIGNMENT_ENGINEER = 30, ASSIGNMENT_GARDENER = 50), 1), + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Window Damage", /datum/event/window_break, 10, list(ASSIGNMENT_ENGINEER = 20)), + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Viral Infection", /datum/event/viral_infection, -25, list(ASSIGNMENT_MEDICAL = 5), 1), + ) + add_disabled_events(list( + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Ian Storm", /datum/event/ianstorm, 1, list(), 1), + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Money Hacker", /datum/event/money_hacker, 0, list(ASSIGNMENT_ANY = 4), 1, 10, 25), + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "PDA Spam", /datum/event/pda_spam, 0, list(ASSIGNMENT_ANY = 4), 1, 25, 50), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Space Dust", /datum/event/dust, 50, list(ASSIGNMENT_ENGINEER = 20), 1, 0, 50), + )) + +/datum/event_container/moderate/New() + available_events = list( + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Nothing", /datum/event/nothing, 800), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Appendicitis", /datum/event/spontaneous_appendicitis, -10, list(ASSIGNMENT_MEDICAL = 30), 1), + // Leaks gas into an unoccupied room. + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Atmos Leak", /datum/event/atmos_leak, 60, list(ASSIGNMENT_ENGINEER = 25), 1), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Camera Damage", /datum/event/camera_damage, 20, list(ASSIGNMENT_ENGINEER = 20, ASSIGNMENT_AI = 40)), + // Just disables comms for a short while. + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Communication Blackout", /datum/event/communications_blackout, 50, list(ASSIGNMENT_AI = 150, ASSIGNMENT_SECURITY = 120), 1), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Carp School", /datum/event/carp_migration, -20, list(ASSIGNMENT_ENGINEER = 10, ASSIGNMENT_SECURITY = 30, ASSIGNMENT_HOS = 10, ASSIGNMENT_WARDEN = 5), 1), + // Just blows out a few lights + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Electrical Storm", /datum/event/electrical_storm, 60, list(ASSIGNMENT_ENGINEER = 20, ASSIGNMENT_JANITOR = 150), 1), + // This one is just too fun. + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Gravity Failure", /datum/event/gravity, 65, list(ASSIGNMENT_ENGINEER = 10), 1), + // Temporary power failure, but mitigatead by subgrids + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Grid Check", /datum/event/grid_check, 40, list(ASSIGNMENT_SCIENTIST = 10, ASSIGNMENT_ENGINEER = 25), 1), + //Evil grubs that drain station power slightly + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Grub Infestation", /datum/event/grub_infestation, -20, list(ASSIGNMENT_SECURITY = 40, ASSIGNMENT_ENGINEER = 40), 1), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Escaped Slimes", /datum/event/escaped_slimes, -40, list(ASSIGNMENT_SCIENTIST = 30, ASSIGNMENT_SECURITY = 20)), + // Pure RP fun, no mechanical effects. + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Ion Storm", /datum/event/ionstorm, -50, list(ASSIGNMENT_AI = 200, ASSIGNMENT_CYBORG = 100, ASSIGNMENT_ENGINEER = 15, ASSIGNMENT_SCIENTIST = 5), 0), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Meteor Shower", /datum/event/meteor_wave, -50, list(ASSIGNMENT_ENGINEER = 45), 1), + //New CHOMPStation event. Mice grow into rats. + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Mutants", /datum/event/mutants, 20, list(ASSIGNMENT_ANY = 15, ASSIGNMENT_SECURITY = 50), 1), + // Opens doors in brig. So just RP fun + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Prison Break", /datum/event/prison_break, -10, list(ASSIGNMENT_SECURITY = 30, ASSIGNMENT_ENGINEER = 20), 1), + // Not bad (dorms are shielded) but inconvenient + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Radiation Storm", /datum/event/radiation_storm, 0, list(ASSIGNMENT_MEDICAL = 35), 1), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Rogue Drones", /datum/event/rogue_drone, -30, list(ASSIGNMENT_SECURITY = 25, ASSIGNMENT_HOS = 35, ASSIGNMENT_WARDEN = 35)), + // Radiation, but only in space. + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Solar Storm", /datum/event/solar_storm, 5, list(ASSIGNMENT_ENGINEER = 40, ASSIGNMENT_SECURITY = 30), 1), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Viral Infection", /datum/event/viral_infection, -60, list(ASSIGNMENT_MEDICAL = 50), 1), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Virology Breach", /datum/event/prison_break/virology, -10, list(ASSIGNMENT_MEDICAL = 30, ASSIGNMENT_ENGINEER = 20), 1), + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Wallrot", /datum/event/wallrot, 0, list(ASSIGNMENT_ENGINEER = 30, ASSIGNMENT_GARDENER = 50), 1), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Wormholes", /datum/event/wormholes, 20, list(ASSIGNMENT_ANY = 5)), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Xenobiology Breach", /datum/event/prison_break/xenobiology, -10, list(ASSIGNMENT_SCIENCE = 30, ASSIGNMENT_ENGINEER = 20), 1), + ) + add_disabled_events(list( + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Carp School_NoRequirements", /datum/event/carp_migration, 100, list(ASSIGNMENT_ENGINEER = 20, ASSIGNMENT_SECURITY = 30), 1), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Escaped Slimes_NoRequirements", /datum/event/escaped_slimes, 30, list(ASSIGNMENT_SCIENTIST = 40, ASSIGNMENT_SECURITY = 30)), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Meteor Shower_NoRequirements", /datum/event/meteor_wave, 30, list(ASSIGNMENT_ENGINEER = 20), 0), + //Moved spider infestation to disabled for now due to CHOMP random event rebalancing. + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Spider Infestation", /datum/event/spider_infestation, -20, list(ASSIGNMENT_SECURITY = 30, ASSIGNMENT_HOS = 20, ASSIGNMENT_WARDEN = 20), 0), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Spider Infestation_NoRequirements", /datum/event/spider_infestation, 100, list(ASSIGNMENT_SECURITY = 40), 0), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Supply Demand", /datum/event/supply_demand, 0, list(ASSIGNMENT_ANY = 5, ASSIGNMENT_SCIENCE = 15, ASSIGNMENT_GARDENER = 10, ASSIGNMENT_ENGINEER = 10, ASSIGNMENT_MEDICAL = 15), 1), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Random Antagonist", /datum/event/random_antag, 3, list(ASSIGNMENT_SECURITY = 1), 1, 0, 5), + )) + +/datum/event_container/major/New() + available_events = list( + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Nothing", /datum/event/nothing, 900), + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Atmos Leak", /datum/event/atmos_leak, 5, list(ASSIGNMENT_ENGINEER = 35), 1), + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Blob", /datum/event/blob, -100, list(ASSIGNMENT_SECURITY = 40, ASSIGNMENT_HOS = 10, ASSIGNMENT_WARDEN = 10, ASSIGNMENT_ENGINEER = 5), 1), + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Boss", /datum/event/boss, -110, list(ASSIGNMENT_SECURITY = 50, ASSIGNMENT_HOS = 10, ASSIGNMENT_WARDEN = 10), 1), + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Carp Migration", /datum/event/carp_migration, -110, list(ASSIGNMENT_SECURITY = 50, ASSIGNMENT_HOS = 10, ASSIGNMENT_WARDEN = 10), 1), + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Containment Breach", /datum/event/prison_break/station,0, list(ASSIGNMENT_ANY = 5), 0), + // TFF: Virgo event commented out. Technically meant for Tether maps, not Polaris. + // new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Strike", /datum/event/meteor_strike, 10, list(ASSIGNMENT_ENGINEER = 15), 1), + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Wave", /datum/event/meteor_wave, -110, list(ASSIGNMENT_ENGINEER = 50), 1), + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Metroid Infestation", /datum/event/metroid_infestation, -75, list(ASSIGNMENT_SECURITY = 35, ASSIGNMENT_SCIENCE = 20, ASSIGNMENT_HOS = 10, ASSIGNMENT_WARDEN = 10), 0), + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Space Vines", /datum/event/spacevine, 20, list(ASSIGNMENT_ENGINEER = 15), 1), + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Spider Infestation", /datum/event/spider_infestation, -35, list(ASSIGNMENT_SECURITY = 30, ASSIGNMENT_HOS = 10, ASSIGNMENT_WARDEN = 10), 0), + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Viral Infection", /datum/event/viral_infection, -50, list(ASSIGNMENT_MEDICAL = 25), 1), + ) + add_disabled_events(list( + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Blob_NoRequirements", /datum/event/blob, 10, list(ASSIGNMENT_SECURITY = 10, ASSIGNMENT_ENGINEER = 30), 1), + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Carp Migration_NoRequirements", /datum/event/carp_migration, 10, list(ASSIGNMENT_SECURITY = 10), 1), + //Moved escaped slimes to disabled for now due to CHOMP random event rebalancing. + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Escaped Slimes", /datum/event/escaped_slimes, -50, list(ASSIGNMENT_SCIENTIST = 30, ASSIGNMENT_SECURITY = 30), 1), + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Escaped Slimes_NoRequirements", /datum/event/escaped_slimes, 30, list(ASSIGNMENT_SCIENTIST = 10, ASSIGNMENT_SECURITY = 5)), + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Wave_NoRequirements", /datum/event/meteor_wave, 30, list(ASSIGNMENT_ENGINEER = 30), 1), + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Spider Infestation_NoRequirements", /datum/event/spider_infestation, 30, list(ASSIGNMENT_SECURITY = 10), 0), + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Supply Demand", /datum/event/supply_demand, 0, list(ASSIGNMENT_ANY = 5, ASSIGNMENT_SCIENCE = 15, ASSIGNMENT_GARDENER = 10, ASSIGNMENT_ENGINEER = 10, ASSIGNMENT_MEDICAL = 15), 1), + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Viral Infection_NoRequirements", /datum/event/viral_infection, 50, list(ASSIGNMENT_MEDICAL = 50), 1), + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Space Dust", /datum/event/dust, 50, list(ASSIGNMENT_ENGINEER = 30), 0), + )) + +#undef ASSIGNMENT_ANY +#undef ASSIGNMENT_AI +#undef ASSIGNMENT_CYBORG +#undef ASSIGNMENT_ENGINEER +#undef ASSIGNMENT_GARDENER +#undef ASSIGNMENT_JANITOR +#undef ASSIGNMENT_MEDICAL +#undef ASSIGNMENT_SCIENTIST +#undef ASSIGNMENT_SECURITY +#undef ASSIGNMENT_HOS +#undef ASSIGNMENT_WARDEN \ No newline at end of file diff --git a/code/modules/events/event_dynamic.dm b/code/modules/events/event_dynamic.dm index 6a09d21008..5abc9a86ab 100644 --- a/code/modules/events/event_dynamic.dm +++ b/code/modules/events/event_dynamic.dm @@ -189,6 +189,8 @@ var/list/event_last_fired = list() active_with_role["Cyborg"] = 0 active_with_role["Janitor"] = 0 active_with_role["Gardener"] = 0 + active_with_role["HOS"] = 0 + active_with_role["Warden"] = 0 for(var/mob/M in player_list) if(!M.mind || !M.client || M.client.is_afk(10 MINUTES)) // longer than 10 minutes AFK counts them as inactive @@ -231,5 +233,11 @@ var/list/event_last_fired = list() if(M.mind.assigned_role == "Gardener") active_with_role["Gardener"]++ + + if(M.mind.assigned_role == "Head of Security") + active_with_role["Head of Security"]++ + + if(M.mind.assigned_role == "Warden") + active_with_role["Warden"]++ return active_with_role diff --git a/code/modules/events/infestation.dm b/code/modules/events/infestation.dm index 540e301efb..72ce6d4953 100644 --- a/code/modules/events/infestation.dm +++ b/code/modules/events/infestation.dm @@ -10,7 +10,6 @@ #define VERM_MICE 0 #define VERM_LIZARDS 1 -#define VERM_SPIDERS 2 /datum/event/infestation announceWhen = 10 @@ -62,21 +61,16 @@ var/list/spawn_types = list() var/max_number - vermin = rand(0,2) + vermin = rand(0,1) switch(vermin) if(VERM_MICE) - spawn_types = list(/mob/living/simple_animal/mouse/gray, /mob/living/simple_animal/mouse/brown, /mob/living/simple_animal/mouse/white) + spawn_types = list(/mob/living/simple_animal/mouse) max_number = 12 vermstring = "mice" if(VERM_LIZARDS) spawn_types = list(/mob/living/simple_animal/lizard) max_number = 6 vermstring = "lizards" - if(VERM_SPIDERS) - spawn_types = list(/obj/effect/spider/spiderling) -// rand(2,8) //Not sure if this would work instead - max_number = 8 - vermstring = "spiders" spawn(0) var/num = rand(2,max_number) @@ -84,13 +78,8 @@ var/turf/simulated/floor/T = pick(turfs) turfs.Remove(T) num-- - - if(vermin == VERM_SPIDERS) - var/obj/effect/spider/spiderling/S = new(T) - S.amount_grown = 0 - else - var/spawn_type = pick(spawn_types) - new spawn_type(T) + var/spawn_type = pick(spawn_types) + new spawn_type(T) /datum/event/infestation/announce() @@ -106,5 +95,4 @@ #undef LOC_GARDEN #undef VERM_MICE -#undef VERM_LIZARDS -#undef VERM_SPIDERS +#undef VERM_LIZARDS \ No newline at end of file diff --git a/code/modules/events/metroid_infestation.dm b/code/modules/events/metroid_infestation.dm new file mode 100644 index 0000000000..ff5cc1ecba --- /dev/null +++ b/code/modules/events/metroid_infestation.dm @@ -0,0 +1,28 @@ +/var/global/sent_metroids_to_station = 0 + +/datum/event/metroid_infestation + announceWhen = 30 + var/spawncount = 1 + + +/datum/event/metroid_infestation/setup() + announceWhen = rand(announceWhen, announceWhen + 30) + spawncount = rand(2 * severity, 4 * severity) + sent_metroids_to_station = 0 + +/datum/event/metroid_infestation/announce() + command_announcement.Announce("Unidentified high-energy lifesigns detected coming aboard [station_name()]. Repel and exterminate.", "Lifesign Alert", new_sound = 'sound/misc/alarm1.ogg') + + +/datum/event/metroid_infestation/start() + var/list/vents = list() + for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in machines) + if(!temp_vent.welded && temp_vent.network && temp_vent.loc.z in using_map.station_levels) + if(temp_vent.network.normal_members.len > 50) + vents += temp_vent + + while((spawncount >= 1) && vents.len) + var/obj/vent = pick(vents) + new /mob/living/simple_animal/hostile/metroid/evolution/baby(vent.loc) + vents -= vent + spawncount-- \ No newline at end of file diff --git a/code/modules/events/mutants.dm b/code/modules/events/mutants.dm new file mode 100644 index 0000000000..cfb96de566 --- /dev/null +++ b/code/modules/events/mutants.dm @@ -0,0 +1,99 @@ +#define LOC_KITCHEN 0 +#define LOC_ATMOS 1 +#define LOC_CHAPEL 2 +#define LOC_LIBRARY 3 +#define LOC_HYDRO 4 +#define LOC_VAULT 5 +#define LOC_CONSTR 6 +#define LOC_TECH 7 +#define LOC_GARDEN 8 + +#define VERM_RATS 0 +#define VERM_LIZARDMEN 1 + +/datum/event/mutants + announceWhen = 25 + endWhen = 26 + var/location + var/locstring + var/vermin + var/vermstring + +/datum/event/mutants/start() + + location = rand(0,8) + var/list/turf/simulated/floor/turfs = list() + var/spawn_area_type + switch(location) + if(LOC_KITCHEN) + spawn_area_type = /area/crew_quarters/kitchen + locstring = "the kitchen" + if(LOC_ATMOS) + spawn_area_type = /area/engineering/atmos + locstring = "atmospherics" + if(LOC_CHAPEL) + spawn_area_type = /area/chapel/main + locstring = "the chapel" + if(LOC_LIBRARY) + spawn_area_type = /area/library + locstring = "the library" + if(LOC_HYDRO) + spawn_area_type = /area/hydroponics + locstring = "hydroponics" + if(LOC_VAULT) + spawn_area_type = /area/security/nuke_storage + locstring = "the vault" + if(LOC_CONSTR) + spawn_area_type = /area/construction + locstring = "the construction area" + if(LOC_TECH) + spawn_area_type = /area/storage/tech + locstring = "technical storage" + if(LOC_GARDEN) + spawn_area_type = /area/hydroponics/garden + locstring = "the public garden" + + for(var/areapath in typesof(spawn_area_type)) + var/area/A = locate(areapath) + for(var/turf/simulated/floor/F in A.contents) + if(turf_clear(F)) + turfs += F + + var/list/spawn_types = list() + var/max_number + vermin = rand(0,1) + switch(vermin) + if(VERM_RATS) + spawn_types = list(/mob/living/simple_animal/mouse/event) + max_number = 6 + vermstring = "mutant mice" + if(VERM_LIZARDMEN) + spawn_types = list(/mob/living/simple_animal/lizard/event) + max_number = 6 + vermstring = "mutant lizards" + + spawn(0) + var/num = rand(2,max_number) + while(turfs.len > 0 && num > 0) + var/turf/simulated/floor/T = pick(turfs) + turfs.Remove(T) + num-- + var/spawn_type = pick(spawn_types) + new spawn_type(T) + + +/datum/event/mutants/announce() + command_announcement.Announce("Bioscans indicate... What are those? It looks like [vermstring] have been breeding in [locstring]. Clear them out, just in case.", "Vermin infestation") + +#undef LOC_KITCHEN +#undef LOC_ATMOS +#undef LOC_CHAPEL +#undef LOC_LIBRARY +#undef LOC_HYDRO +#undef LOC_VAULT +#undef LOC_TECH +#undef LOC_GARDEN + +#undef VERM_MICE +#undef VERM_LIZARDS +#undef VERM_SPIDERS diff --git a/code/modules/events/spiderling_infestation.dm b/code/modules/events/spiderling_infestation.dm new file mode 100644 index 0000000000..d800f0af7c --- /dev/null +++ b/code/modules/events/spiderling_infestation.dm @@ -0,0 +1,87 @@ +//CHOMP: Lifted and butchered from the infestation event as we have moved spiderlings out and instead put in its own event. + +#define LOC_KITCHEN 0 +#define LOC_ATMOS 1 +#define LOC_CHAPEL 2 +#define LOC_LIBRARY 3 +#define LOC_HYDRO 4 +#define LOC_VAULT 5 +#define LOC_CONSTR 6 +#define LOC_TECH 7 +#define LOC_GARDEN 8 + + +/datum/event/spiderling_infestation + announceWhen = 10 + endWhen = 11 + var/location + var/locstring + var/vermstring + +/datum/event/spiderling_infestation/start() + + location = rand(0,8) + var/list/turf/simulated/floor/turfs = list() + var/spawn_area_type + switch(location) + if(LOC_KITCHEN) + spawn_area_type = /area/crew_quarters/kitchen + locstring = "the kitchen" + if(LOC_ATMOS) + spawn_area_type = /area/engineering/atmos + locstring = "atmospherics" + if(LOC_CHAPEL) + spawn_area_type = /area/chapel/main + locstring = "the chapel" + if(LOC_LIBRARY) + spawn_area_type = /area/library + locstring = "the library" + if(LOC_HYDRO) + spawn_area_type = /area/hydroponics + locstring = "hydroponics" + if(LOC_VAULT) + spawn_area_type = /area/security/nuke_storage + locstring = "the vault" + if(LOC_CONSTR) + spawn_area_type = /area/construction + locstring = "the construction area" + if(LOC_TECH) + spawn_area_type = /area/storage/tech + locstring = "technical storage" + if(LOC_GARDEN) + spawn_area_type = /area/hydroponics/garden + locstring = "the public garden" + + for(var/areapath in typesof(spawn_area_type)) + var/area/A = locate(areapath) + for(var/turf/simulated/floor/F in A.contents) + if(turf_clear(F)) + turfs += F + + var/list/spawn_types = list() + var/max_number + spawn_types = list(/obj/effect/spider/spiderling) + max_number = 8 + vermstring = "spiders" + + spawn(0) + var/num = rand(2,max_number) + while(turfs.len > 0 && num > 0) + var/turf/simulated/floor/T = pick(turfs) + turfs.Remove(T) + num-- + var/spawn_type = pick(spawn_types) + new spawn_type(T) + +/datum/event/spiderling_infestation/announce() + command_announcement.Announce("Bioscans indicate that [vermstring] have been breeding in [locstring]. Clear them out, before this starts to affect productivity.", "Spiderling infestation") + +#undef LOC_KITCHEN +#undef LOC_ATMOS +#undef LOC_CHAPEL +#undef LOC_LIBRARY +#undef LOC_HYDRO +#undef LOC_VAULT +#undef LOC_TECH +#undef LOC_GARDEN + diff --git a/code/modules/events/supply_demand.dm b/code/modules/events/supply_demand.dm index 0e255499dc..db7edd58de 100644 --- a/code/modules/events/supply_demand.dm +++ b/code/modules/events/supply_demand.dm @@ -14,11 +14,11 @@ var/end_time announceWhen = 1 startWhen = 2 - endWhen = 1800 // Aproximately 1 hour in master controller ticks, refined by end_time + endWhen = 2700 // Aproximately 1.5 hour in master controller ticks, refined by end_time /datum/event/supply_demand/setup() my_department = "[using_map.company_name] Supply Division" // Can't have company name in initial value (not const) - end_time = world.time + 1 HOUR + (severity * 30 MINUTES) + end_time = world.time + 1.5 HOUR + (severity * 30 MINUTES) running_demand_events += src // Decide what items are requried! // We base this on what departmets are most active, excluding departments we don't have @@ -33,7 +33,7 @@ choose_chemistry_items(roll(severity, 2)) if(ROLE_RESEARCH) // Would be nice to differentiate between research diciplines choose_research_items(roll(severity, 2)) - choose_robotics_items(roll(1, severity)) +// choose_robotics_items(roll(1, severity)) //TFF: Goodbye, silly Gygax requests..... if(ROLE_CARGO) choose_alloy_items(rand(1, severity)) if(ROLE_CIVILIAN) // Would be nice to separate out chef/gardener/bartender @@ -52,7 +52,7 @@ message += "has a warehouse full of empty crates! " message += "We have to fill that gap quick before anyone starts asking questions. " message += "You'd better have this stuff here by [worldtime2stationtime(end_time)]
    " - message += "The requested items are as follows" + message += "The requested items are as follows: " message += "
    " for (var/datum/supply_demand_order/req in required_items) message += req.describe() + "
    " @@ -70,11 +70,17 @@ endWhen = activeFor // End early becuase we're done already! /datum/event/supply_demand/end() + var/Cargo_points = null running_demand_events -= src // Check if the crew succeeded or failed! if(required_items.len == 0) // Success! - supply_controller.points += 500 * severity + if(severity <= EVENT_LEVEL_MUNDANE) + supply_controller.points += Cargo_points = rand(1, 10) * 2 //TFF: Give lower points for minor event + else if(severity == EVENT_LEVEL_MODERATE) + supply_controller.points += Cargo_points = rand(1, 25) * 2 //TFF: Give moderate points for moderate event + else + supply_controller.points += Cargo_points = rand(1, 50) * 2 //TFF: Give huge amount of points for major event var/msg = "Great work! With those items you delivered our inventory levels all match up. " msg += "[capitalize(pick(first_names_female))] from accounting will have nothing to complain about. " msg += "I think you'll find a little something in your supply account." @@ -103,7 +109,7 @@ for(var/atom/movable/MA in area_shuttle) // Special case to allow us to count mechs! - if(MA.anchored && !istype(MA, /obj/mecha)) continue // Ignore anchored stuff +// if(MA.anchored && !istype(MA, /obj/mecha)) continue // Ignore anchored stuff //TFF: Mechs sometimes ridiculous to ask, like come on... Multiple Gygaxes? Nah. // If its a crate, search inside of it for matching items. if(istype(MA, /obj/structure/closet/crate)) @@ -115,7 +121,7 @@ if(match_found && required_items.len >= 1) // Okay we delivered SOME. Lets give an update, but only if not finished. - var/message = "Shipment Received. As a reminder, the following items are still requried:" + var/message = "Shipment Received. As a reminder, the following items are still requried: " message += "
    " for (var/datum/supply_demand_order/req in required_items) message += req.describe() + "
    " @@ -310,7 +316,7 @@ var/chosen_qty = rand(1, 20) * 5 required_items += new /datum/supply_demand_order/reagent(chosen_qty, R) return - +/* /datum/event/supply_demand/proc/choose_robotics_items(var/differentTypes) // Do not make mechs dynamic, its too silly var/list/types = list( @@ -322,9 +328,9 @@ var/T = pick(types) types -= T // Don't pick the same thing twice required_items += new /datum/supply_demand_order/thing(rand(1, 2), T) - return + return //TFF: Some of the time, these end up being too much. 2 Gygaxes? Nope, ask somewhere else, Central. -/* // Commented out, same reason as the above. Broken event +// Commented out, same reason as the above. Broken event /datum/event/supply_demand/proc/choose_atmos_items(var/differentTypes) var/datum/gas_mixture/mixture = new mixture.temperature = T20C diff --git a/code/modules/examine/descriptions/containers.dm b/code/modules/examine/descriptions/containers.dm index 83a97086b4..93c6d98097 100644 --- a/code/modules/examine/descriptions/containers.dm +++ b/code/modules/examine/descriptions/containers.dm @@ -96,3 +96,6 @@ /obj/item/weapon/reagent_containers/food/drinks/bottle/sake description_fluff = "An export from New Kyoto, Mono-no-Aware promises to show to the drinker the beautiful transience of all life. Mostly it just tastes like dry booze." + +/obj/item/weapon/reagent_containers/food/drinks/bottle/snaps + description_fluff = "Its a wonder how such an ancient and obscure drink from Earth made it all the way out here." \ No newline at end of file diff --git a/code/modules/food/recipes_microwave_vr.dm b/code/modules/food/recipes_microwave_vr.dm index ddf3a70de1..e5a9e6c942 100644 --- a/code/modules/food/recipes_microwave_vr.dm +++ b/code/modules/food/recipes_microwave_vr.dm @@ -152,3 +152,92 @@ /obj/item/weapon/reagent_containers/food/snacks/cheesewedge ) result = /obj/item/weapon/reagent_containers/food/snacks/makaroni + +/datum/recipe/gelbowl + reagents = list("potatojuice" = 5, "sugar" = 5, "water" = 5, "flour" = 5) + result = /obj/item/weapon/reagent_containers/food/snacks/gelbowl + +/datum/recipe/sauerkraut + reagents = list("sodiumchloride" = 3) + fruit = list("cabbage" = 1) + result = /obj/item/weapon/reagent_containers/food/snacks/sauerkraut + +/datum/recipe/tamales + reagents = list("sodiumchloride" = 3, "water" = 5) + fruit = list("corn" = 1, "chili" = 1, "potato" = 1) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/doughslice, + /obj/item/weapon/reagent_containers/food/snacks/doughslice, + /obj/item/weapon/reagent_containers/food/snacks/doughslice, + /obj/item/weapon/reagent_containers/food/snacks/meat + ) + result = /obj/item/weapon/reagent_containers/food/snacks/tamales + +/datum/recipe/bigos + reagents = list("flour" = 5, "water" = 5) + fruit = list("onion" = 1, "carrot" = 1, "mushroom" = 1) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/sauerkraut, + /obj/item/weapon/reagent_containers/food/snacks/sausage + ) + result = /obj/item/weapon/reagent_containers/food/snacks/bigos + +/datum/recipe/concha + reagents = list("flour" = 5, "sugar" = 5, "berryjuice" = 5) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/egg + ) + result = /obj/item/weapon/reagent_containers/food/snacks/concha + +/datum/recipe/pandenata + reagents = list("sugar" = 10, "cream" = 5) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/doughslice, + /obj/item/weapon/reagent_containers/food/snacks/doughslice, + /obj/item/weapon/reagent_containers/food/snacks/doughslice, + /obj/item/weapon/reagent_containers/food/snacks/egg + ) + result = /obj/item/weapon/reagent_containers/food/snacks/pandenata + +/datum/recipe/tocino + reagents = list("sodiumchloride" = 5, "wine" = 5, "sugar" = 5) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/rawcutlet + ) + result = /obj/item/weapon/reagent_containers/food/snacks/tocino + +/datum/recipe/garlicbread + reagents = list("sodiumchloride" = 2, "blackpepper" = 2) + fruit = list("onion" = 1) + items = list( + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/slice/bread, + /obj/item/weapon/reagent_containers/food/snacks/slice/bread + ) + result = /obj/item/weapon/reagent_containers/food/snacks/garlicbread + +/datum/recipe/hotwater + reagents = list("water" = 60) + result = /obj/item/weapon/reagent_containers/glass/bottle/hotwater + +/datum/recipe/steamtealeaf + reagents = list("water" = 5) + fruit = list("tea" = 1) + + result = /obj/item/weapon/reagent_containers/food/snacks/steamtealeaf + +/datum/recipe/greentealeaf //TODO: Figure out how to make this recipe with a drying rack. + items = list( + /obj/item/weapon/reagent_containers/food/snacks/steamrolltealeaf + ) + result = /obj/item/weapon/reagent_containers/food/snacks/greentealeaf + +/datum/recipe/tencha //TODO: Figure out how to make this recipe with a drying rack. + items = list( + /obj/item/weapon/reagent_containers/food/snacks/steamtealeaf + ) + result = /obj/item/weapon/reagent_containers/food/snacks/tencha + make_food(var/obj/container as obj) + var/obj/item/weapon/reagent_containers/food/snacks/validsalad/being_cooked = ..(container) + being_cooked.reagents.del_reagent("teamush") + return being_cooked \ No newline at end of file diff --git a/code/modules/hydroponics/seed.dm b/code/modules/hydroponics/seed.dm index 5c6053aba4..047107420a 100644 --- a/code/modules/hydroponics/seed.dm +++ b/code/modules/hydroponics/seed.dm @@ -521,6 +521,11 @@ set_trait(TRAIT_WATER_CONSUMPTION, get_trait(TRAIT_WATER_CONSUMPTION) +rand(-degree,degree),50,0) set_trait(TRAIT_JUICY, !get_trait(TRAIT_JUICY)) set_trait(TRAIT_STINGS, !get_trait(TRAIT_STINGS)) + if(prob(5)) + consume_gasses = list() + var/gas = pick("oxygen","nitrogen","phoron","carbon_dioxide") + consume_gasses[gas] = rand(3,9) + source_turf.visible_message("\The [display_name] seems to be drawing in air.") if(2) set_trait(TRAIT_IDEAL_HEAT, get_trait(TRAIT_IDEAL_HEAT) + (rand(-5,5)*degree),800,70) set_trait(TRAIT_HEAT_TOLERANCE, get_trait(TRAIT_HEAT_TOLERANCE) + (rand(-5,5)*degree),800,70) @@ -534,40 +539,71 @@ set_trait(TRAIT_TOXINS_TOLERANCE, get_trait(TRAIT_TOXINS_TOLERANCE)+(rand(-2,2)*degree),10,0) if(5) set_trait(TRAIT_WEED_TOLERANCE, get_trait(TRAIT_WEED_TOLERANCE)+(rand(-2,2)*degree),10, 0) - if(prob(degree*5)) + if(prob(10)) set_trait(TRAIT_CARNIVOROUS, get_trait(TRAIT_CARNIVOROUS)+rand(-degree,degree),2, 0) if(get_trait(TRAIT_CARNIVOROUS)) source_turf.visible_message("\The [display_name] shudders hungrily.") if(6) set_trait(TRAIT_WEED_TOLERANCE, get_trait(TRAIT_WEED_TOLERANCE)+(rand(-2,2)*degree),10, 0) - if(prob(degree*5)) + if(prob(10)) set_trait(TRAIT_PARASITE,!get_trait(TRAIT_PARASITE)) + if(prob(10)) + var/additional_chems = rand(1,3) + + if(additional_chems) + + var/list/banned_chems = list( + "adminordrazine", + "nutriment" + ) + + for(var/x=1;x<=additional_chems;x++) + + var/new_chem = pick(chemical_reagents_list) + if(new_chem in banned_chems) + continue + banned_chems += new_chem + chems[new_chem] = list(rand(1,10),rand(10,20)) + source_turf.visible_message("\The [display_name] produce seems to be different!") + if(7) if(get_trait(TRAIT_YIELD) != -1) set_trait(TRAIT_YIELD, get_trait(TRAIT_YIELD)+(rand(-2,2)*degree),10,0) + if(prob(5)) + exude_gasses = list() + var/gas = pick("oxygen","nitrogen","phoron","carbon_dioxide") + exude_gasses[gas] = rand(3,9) + source_turf.visible_message("\The [display_name] seems to be releasing gas.") if(8) set_trait(TRAIT_ENDURANCE, get_trait(TRAIT_ENDURANCE)+(rand(-5,5)*degree),100,10) set_trait(TRAIT_PRODUCTION, get_trait(TRAIT_PRODUCTION)+(rand(-1,1)*degree),10, 1) - set_trait(TRAIT_POTENCY, get_trait(TRAIT_POTENCY)+(rand(-20,20)*degree),200, 0) - if(prob(degree*5)) + set_trait(TRAIT_POTENCY, get_trait(TRAIT_POTENCY)+(rand(-15,20)*degree),200, 0) + if(prob(10)) set_trait(TRAIT_SPREAD, get_trait(TRAIT_SPREAD)+rand(-1,1),2, 0) source_turf.visible_message("\The [display_name] spasms visibly, shifting in the tray.") if(9) set_trait(TRAIT_MATURATION, get_trait(TRAIT_MATURATION)+(rand(-1,1)*degree),30, 0) - if(prob(degree*5)) + if(prob(10)) set_trait(TRAIT_HARVEST_REPEAT, !get_trait(TRAIT_HARVEST_REPEAT)) + source_turf.visible_message("\The [display_name] quivers in its tray, its produce looks more harvestable.") if(10) - if(prob(degree*2)) + if(prob(10)) set_trait(TRAIT_BIOLUM, !get_trait(TRAIT_BIOLUM)) if(get_trait(TRAIT_BIOLUM)) source_turf.visible_message("\The [display_name] begins to glow!") - if(prob(degree*2)) + if(prob(50)) set_trait(TRAIT_BIOLUM_COLOUR,"#[get_random_colour(0,75,190)]") source_turf.visible_message("\The [display_name]'s glow changes colour!") else source_turf.visible_message("\The [display_name]'s glow dims...") + if(prob(10)) + set_trait(TRAIT_PRODUCES_POWER, 1) + if(11) set_trait(TRAIT_TELEPORTING,1) + if(prob(5)) + set_trait(TRAIT_ALTER_TEMP,rand(-5,5)) + source_turf.visible_message("\The air around the [display_name]'s seems to be of a different temperature...") return @@ -731,6 +767,8 @@ //Handle spawning in living, mobile products (like dionaea). if(istype(product,/mob/living)) product.visible_message("The pod disgorges [product]!") + if(istype(product,/mob/living/simple_animal/retaliate/synx)) //CHOMPEDIT trying to make it not kill synxes + return handle_living_product(product) // When the seed in this machine mutates/is modified, the tray seed value diff --git a/code/modules/hydroponics/seed_datums.dm b/code/modules/hydroponics/seed_datums.dm index f87035b806..7b9e88453b 100644 --- a/code/modules/hydroponics/seed_datums.dm +++ b/code/modules/hydroponics/seed_datums.dm @@ -547,6 +547,7 @@ name = "sunflowers" seed_name = "sunflower" display_name = "sunflowers" + mutants = list("solarflower") /datum/seed/flower/sunflower/New() ..() @@ -558,10 +559,27 @@ set_trait(TRAIT_WATER_CONSUMPTION, 6) set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.15) +/datum/seed/flower/sunflower/solarflower + name = "solarflower" + seed_name = "solarflower" + display_name = "solarflowers" + mutants = null + +/datum/seed/flower/sunflower/solarflower/New() + ..() + set_trait(TRAIT_PRODUCT_COLOUR,"#4466b3") + set_trait(TRAIT_BIOLUM,1) + set_trait(TRAIT_BIOLUM_COLOUR,"#4e74cc") + set_trait(TRAIT_POTENCY,25) + set_trait(TRAIT_MATURATION,10) + set_trait(TRAIT_YIELD,1) + set_trait(TRAIT_SPREAD,1) + /datum/seed/flower/lavender name = "lavender" seed_name = "lavender" display_name = "lavender" + mutants = list("milkdew") chems = list("nutriment" = list(1,20), "bicaridine" = list(1,10)) /datum/seed/flower/lavender/New() @@ -576,6 +594,34 @@ set_trait(TRAIT_IDEAL_LIGHT, 7) set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.05) set_trait(TRAIT_WATER_CONSUMPTION, 0.5) + +/datum/seed/flower/lavender/milkdew + name = "milkdew" + seed_name = "milk dew" + display_name = "milk dew" + chems = list("nutriment" = list(1,10), "milk" = list(4,5)) + mutants = list("sweetbreeze") + +/datum/seed/flower/lavender/milkdew/New() + ..() + set_trait(TRAIT_PRODUCT_COLOUR,"#DFDFDF") + set_trait(TRAIT_POTENCY,5) + set_trait(TRAIT_YIELD,3) + +/datum/seed/flower/lavender/sweetbreeze + name = "sweetbreeze" + seed_name = "sweet breeze" + display_name = "sweet breeze" + chems = list("nutriment" = list(1,10), "serazine" = list(1,10)) + mutants = null + +/datum/seed/flower/lavender/sweetbreeze/New() + ..() + set_trait(TRAIT_PRODUCT_COLOUR,"#df9898") + set_trait(TRAIT_POTENCY,10) + set_trait(TRAIT_MATURATION,20) + set_trait(TRAIT_PRODUCTION,7) + set_trait(TRAIT_YIELD,3) //Grapes/varieties /datum/seed/grapes @@ -615,7 +661,7 @@ name = "peanut" seed_name = "peanut" display_name = "peanut vines" - chems = list("nutriment" = list(1,10)) + chems = list("nutriment" = list(1,10),"nutbutter" = list(1,10)) /datum/seed/peanuts/New() ..() @@ -699,6 +745,7 @@ name = "potato" seed_name = "potato" display_name = "potatoes" + mutants = list("voltato") chems = list("nutriment" = list(1,10), "potatojuice" = list(10,10)) kitchen_tag = "potato" @@ -713,6 +760,21 @@ set_trait(TRAIT_PRODUCT_COLOUR,"#D4CAB4") set_trait(TRAIT_PLANT_ICON,"bush2") set_trait(TRAIT_WATER_CONSUMPTION, 6) + +/datum/seed/potato/voltato + name = "voltato" + seed_name = "voltato" + display_name = "voltatos" + chems = list("nutriment" = list(1,10), "shockchem" = list(0,10)) + mutants = null + +/datum/seed/potato/voltato/New() + ..() + set_trait(TRAIT_PRODUCT_COLOUR,"#E4EC2F") + set_trait(TRAIT_POTENCY,30) + set_trait(TRAIT_MATURATION,12) + set_trait(TRAIT_PRODUCTION,3) + set_trait(TRAIT_YIELD,3) /datum/seed/onion name = "onion" @@ -736,6 +798,7 @@ name = "soybean" seed_name = "soybean" display_name = "soybeans" + mutants = list("orangesapbean","purplesapbean","bluesapbean") //CHOMPEDIT: Adding sappy beanies to mutation chems = list("nutriment" = list(1,20), "soymilk" = list(10,20)) kitchen_tag = "soybeans" @@ -750,10 +813,60 @@ set_trait(TRAIT_PRODUCT_COLOUR,"#EBE7C0") set_trait(TRAIT_PLANT_ICON,"stalk") +// CHOMPSTATION EDIT: Making soybeans viable in this meta by giving them sappy mutations +/datum/seed/soybean/sapbean + name = "sapbean" + seed_name = "sapbean" + display_name = "sapbeans" + chems = list() + +/datum/seed/soybean/sapbean/orange + name = "orangesapbean" + mutants = list("Purplesapbean","bluesapbean","blacksapbean") + chems = list("orangesap" = list(0,10)) + +/datum/seed/soybean/sapbean/purple + name = "purplesapbean" + mutants = list("Orangesapbean","bluesapbean","blacksapbean") + chems = list("purplesap" = list(0,10)) + +/datum/seed/soybean/sapbean/blue + name = "bluesapbean" + mutants = list("orangesapbean","purplesapbean","blacksapbean") + chems = list("bluesap" = list(0,10)) + +/datum/seed/soybean/sapbean/black //A bean with all the power but in so little quanitity + name = "blacksapbean" + chems = list("bluesap" = list(1,2),"orangesap" = list(1,2),"purplesap" = list(1,2)) + +/datum/seed/soybean/sapbean/orange/New() + ..() + set_trait(TRAIT_PRODUCT_COLOUR,"#FF8700") + set_trait(TRAIT_PLANT_COLOUR,"#FF8700") +/datum/seed/soybean/sapbean/purple/New() + ..() + set_trait(TRAIT_PRODUCT_COLOUR,"#FF00FF") + set_trait(TRAIT_PLANT_COLOUR,"#FF00FF") +/datum/seed/soybean/sapbean/blue/New() + ..() + set_trait(TRAIT_PRODUCT_COLOUR,"#0000FF") + set_trait(TRAIT_PLANT_COLOUR,"#0000FF") +/datum/seed/soybean/sapbean/black/New() //the only real positive is that its 1 plant to care for rather than 3 + ..() + set_trait(TRAIT_PRODUCT_ICON,"treefruit") + set_trait(TRAIT_PRODUCT_COLOUR,"#333333") + set_trait(TRAIT_PLANT_COLOUR,"#333333") + set_trait(TRAIT_PRODUCTION,3) + set_trait(TRAIT_MATURATION,8) + set_trait(TRAIT_POTENCY,10) + set_trait(TRAIT_YIELD,2) + +// CHOMPSTATION EDIT: END /datum/seed/wheat name = "wheat" seed_name = "wheat" display_name = "wheat stalks" + mutants = list("meatwheat") chems = list("nutriment" = list(1,25), "flour" = list(15,15)) kitchen_tag = "wheat" @@ -769,6 +882,17 @@ set_trait(TRAIT_PLANT_ICON,"stalk2") set_trait(TRAIT_IDEAL_LIGHT, 6) set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.15) + +/datum/seed/wheat/meatwheat + name = "meatwheat" + seed_name = "meatwheat" + display_name = "meatwheat stalks" + mutants = null + chems = list("nutriment" = list(1,25), "protein" = list(4,10)) + +/datum/seed/wheat/meatwheat/New() + ..() + set_trait(TRAIT_PRODUCT_COLOUR,"#440000") /datum/seed/rice name = "rice" @@ -1226,3 +1350,52 @@ set_trait(TRAIT_YIELD,-1) set_trait(TRAIT_SPREAD,2) set_trait(TRAIT_POTENCY,50) + +//CHOMPSTATION EDIT Adding a new seed type +/datum/seed/hardlightseed/ + name = "Type NULL Hardlight Generator" + seed_name = "Biomechanical Hardlight generator seed" + display_name = "Biomechanical Hardlight stem" + mutants = null + can_self_harvest = 1 + has_mob_product = null + +/datum/seed/hardlightseed/New() + ..() + set_trait(TRAIT_IMMUTABLE,1) //Normal genetics wont be able to do much with the mechanical parts, its more a machine than a real plant + set_trait(TRAIT_MATURATION,1) + set_trait(TRAIT_PRODUCTION,1) + set_trait(TRAIT_YIELD,1) + set_trait(TRAIT_POTENCY,1) + set_trait(TRAIT_PRODUCT_ICON,"alien4") + set_trait(TRAIT_PRODUCT_COLOUR,"#00FFFF") + set_trait(TRAIT_PLANT_COLOUR,"#00FFFF") + set_trait(TRAIT_PLANT_ICON,"alien4") //spooky pods + set_trait(TRAIT_IDEAL_HEAT, 283) + set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0) + set_trait(TRAIT_WATER_CONSUMPTION, 0) + +// Tea plants/variants. +/datum/seed/tea + name = "tea" + seed_name = "tea" + display_name = "tea plant" + chems = list("teamush" = list(3,10)) + mutants = null + kitchen_tag = "tea" + +/datum/seed/tea/New() + ..() + set_trait(TRAIT_HARVEST_REPEAT,1) + set_trait(TRAIT_MATURATION,5) + set_trait(TRAIT_PRODUCTION,5) + set_trait(TRAIT_YIELD,6) + set_trait(TRAIT_POTENCY,20) + set_trait(TRAIT_PRODUCT_ICON,"tea") + set_trait(TRAIT_PRODUCT_COLOUR,"#b7e496") + set_trait(TRAIT_PLANT_COLOUR,"#b7e496") + set_trait(TRAIT_PLANT_ICON,"bush4") + set_trait(TRAIT_IDEAL_HEAT, 298) + set_trait(TRAIT_IDEAL_LIGHT, 7) + set_trait(TRAIT_WATER_CONSUMPTION, 6) + set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.25) \ No newline at end of file diff --git a/code/modules/hydroponics/seed_machines.dm b/code/modules/hydroponics/seed_machines.dm index bc96f064c9..5f67fa077f 100644 --- a/code/modules/hydroponics/seed_machines.dm +++ b/code/modules/hydroponics/seed_machines.dm @@ -94,10 +94,16 @@ user << "You load [W] into [src]." return +//TFF 3/6/19 - fix infinite frame creation, ported from Cit RP if(default_deconstruction_screwdriver(user, W)) return - if(default_deconstruction_crowbar(user, W)) + if(istype(W, /obj/item/weapon/wrench)) + playsound(src, W.usesound, 100, 1) + to_chat(user, "You [anchored ? "un" : ""]secure \the [src].") + anchored = !anchored return +// if(default_deconstruction_crowbar(user, W)) +// return if(istype(W,/obj/item/weapon/disk/botany)) if(loaded_disk) user << "There is already a data disk loaded." diff --git a/code/modules/hydroponics/seed_packets.dm b/code/modules/hydroponics/seed_packets.dm index 0689f428b6..d2cb01b9df 100644 --- a/code/modules/hydroponics/seed_packets.dm +++ b/code/modules/hydroponics/seed_packets.dm @@ -142,6 +142,9 @@ GLOBAL_LIST_BOILERPLATE(all_seed_packs, /obj/item/seeds) /obj/item/seeds/potatoseed seed_type = "potato" + +/obj/item/seeds/voltatoseed + seed_type = "voltato" /obj/item/seeds/icepepperseed seed_type = "icechili" @@ -151,6 +154,9 @@ GLOBAL_LIST_BOILERPLATE(all_seed_packs, /obj/item/seeds) /obj/item/seeds/wheatseed seed_type = "wheat" + +/obj/item/seeds/meatwheatseed + seed_type = "meatwheat" /obj/item/seeds/riceseed seed_type = "rice" @@ -196,9 +202,18 @@ GLOBAL_LIST_BOILERPLATE(all_seed_packs, /obj/item/seeds) /obj/item/seeds/sunflowerseed seed_type = "sunflowers" + +/obj/item/seeds/solarflowerseed + seed_type = "solarflower" /obj/item/seeds/lavenderseed seed_type = "lavender" + +/obj/item/seeds/milkdewseed + seed_type = "milkdew" + +/obj/item/seeds/sweetbreezeseed + seed_type = "sweetbreeze" /obj/item/seeds/brownmold seed_type = "mold" @@ -283,3 +298,6 @@ GLOBAL_LIST_BOILERPLATE(all_seed_packs, /obj/item/seeds) /obj/item/seeds/thaadra seed_type = "thaadra" + +/obj/item/seeds/teaseed + seed_type = "tea" diff --git a/code/modules/hydroponics/seed_storage.dm b/code/modules/hydroponics/seed_storage.dm index 4c6d8b2798..3cb33eb572 100644 --- a/code/modules/hydroponics/seed_storage.dm +++ b/code/modules/hydroponics/seed_storage.dm @@ -124,6 +124,7 @@ /obj/item/seeds/sugarcaneseed = 3, /obj/item/seeds/sunflowerseed = 3, /obj/item/seeds/shandseed = 2, + /obj/item/seeds/teaseed = 3, /obj/item/seeds/tobaccoseed = 3, /obj/item/seeds/tomatoseed = 3, /obj/item/seeds/towermycelium = 3, @@ -173,6 +174,7 @@ /obj/item/seeds/sugarcaneseed = 3, /obj/item/seeds/sunflowerseed = 3, /obj/item/seeds/shandseed = 2, + /obj/item/seeds/teaseed = 3, /obj/item/seeds/tobaccoseed = 3, /obj/item/seeds/tomatoseed = 3, /obj/item/seeds/towermycelium = 3, diff --git a/code/modules/hydroponics/seed_storage_vr.dm b/code/modules/hydroponics/seed_storage_vr.dm index 6d9d373b78..9f155225a7 100644 --- a/code/modules/hydroponics/seed_storage_vr.dm +++ b/code/modules/hydroponics/seed_storage_vr.dm @@ -30,6 +30,7 @@ /obj/item/seeds/sugarcaneseed = 3, /obj/item/seeds/sunflowerseed = 3, /obj/item/seeds/shandseed = 2, + /obj/item/seeds/teaseed = 3, /obj/item/seeds/tobaccoseed = 3, /obj/item/seeds/tomatoseed = 3, /obj/item/seeds/towermycelium = 3, @@ -79,6 +80,7 @@ /obj/item/seeds/sugarcaneseed = 3, /obj/item/seeds/sunflowerseed = 3, /obj/item/seeds/shandseed = 2, + /obj/item/seeds/teaseed = 3, /obj/item/seeds/tobaccoseed = 3, /obj/item/seeds/tomatoseed = 3, /obj/item/seeds/towermycelium = 3, diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm index ac9a0e13f9..5333ece78d 100644 --- a/code/modules/integrated_electronics/subtypes/input.dm +++ b/code/modules/integrated_electronics/subtypes/input.dm @@ -394,8 +394,9 @@ activate_pin(3) - for(var/mob/O in hearers(1, get_turf(src))) - O.show_message(text("\icon[] *beep* *beep*", src), 3, "*beep* *beep*", 2) + if(loc) //TFF 18/4/19: Polaris fix - signaller circuit no long pings all alive. + for(var/mob/O in hearers(1, get_turf(src))) + O.show_message(text("\icon[] *beep* *beep*", src), 3, "*beep* *beep*", 2) /obj/item/integrated_circuit/input/EPv2 name = "\improper EPv2 circuit" diff --git a/code/modules/materials/material_recipes.dm b/code/modules/materials/material_recipes.dm index db4ce1132f..be7cc5c088 100644 --- a/code/modules/materials/material_recipes.dm +++ b/code/modules/materials/material_recipes.dm @@ -46,6 +46,57 @@ new/datum/stack_recipe("purple comfy chair", /obj/structure/bed/chair/comfy/purp, 2, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("green comfy chair", /obj/structure/bed/chair/comfy/green, 2, one_per_turf = 1, on_floor = 1), \ )) + + recipes += new/datum/stack_recipe_list("left sofa end", list( \ + new/datum/stack_recipe("beige left sofa", /obj/structure/bed/chair/sofa/left/beige, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("black left sofa", /obj/structure/bed/chair/sofa/left/black, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("brown left sofa", /obj/structure/bed/chair/sofa/left/brown, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("lime left sofa", /obj/structure/bed/chair/sofa/left/lime, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("teal left sofa", /obj/structure/bed/chair/sofa/left/teal, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("red left sofa", /obj/structure/bed/chair/sofa/left/red, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("blue left sofa", /obj/structure/bed/chair/sofa/left/blue, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("purple left sofa", /obj/structure/bed/chair/sofa/left/purp, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("green left sofa", /obj/structure/bed/chair/sofa/left/green, 2, one_per_turf = 1, on_floor = 1), \ + )) + recipes += new/datum/stack_recipe_list("middle sofa", list( \ + new/datum/stack_recipe("beige middle sofa", /obj/structure/bed/chair/sofa/beige, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("black middle sofa", /obj/structure/bed/chair/sofa/black, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("brown middle sofa", /obj/structure/bed/chair/sofa/brown, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("lime middle sofa", /obj/structure/bed/chair/sofa/lime, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("teal middle sofa", /obj/structure/bed/chair/sofa/teal, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("red middle sofa", /obj/structure/bed/chair/sofa/red, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("blue middle sofa", /obj/structure/bed/chair/sofa/blue, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("purple middle sofa", /obj/structure/bed/chair/sofa/purp, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("green middle sofa", /obj/structure/bed/chair/sofa/green, 2, one_per_turf = 1, on_floor = 1), \ + )) + recipes += new/datum/stack_recipe_list("right sofa end", list( \ + new/datum/stack_recipe("beige right sofa", /obj/structure/bed/chair/sofa/right/beige, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("black right sofa", /obj/structure/bed/chair/sofa/right/black, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("brown right sofa", /obj/structure/bed/chair/sofa/right/brown, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("lime right sofa", /obj/structure/bed/chair/sofa/right/lime, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("teal right sofa", /obj/structure/bed/chair/sofa/right/teal, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("red right sofa", /obj/structure/bed/chair/sofa/right/red, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("blue right sofa", /obj/structure/bed/chair/sofa/right/blue, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("purple right sofa", /obj/structure/bed/chair/sofa/right/purp, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("green right sofa", /obj/structure/bed/chair/sofa/right/green, 2, one_per_turf = 1, on_floor = 1), \ + )) + recipes += new/datum/stack_recipe_list("corner sofa", list( \ + new/datum/stack_recipe("beige corner sofa", /obj/structure/bed/chair/sofa/corner/beige, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("black corner sofa", /obj/structure/bed/chair/sofa/corner/black, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("brown corner sofa", /obj/structure/bed/chair/sofa/corner/brown, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("lime corner sofa", /obj/structure/bed/chair/sofa/corner/lime, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("teal corner sofa", /obj/structure/bed/chair/sofa/corner/teal, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("red corner sofa", /obj/structure/bed/chair/sofa/corner/red, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("blue corner sofa", /obj/structure/bed/chair/sofa/corner/blue, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("purple corner sofa", /obj/structure/bed/chair/sofa/corner/purp, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("green corner sofa", /obj/structure/bed/chair/sofa/corner/green, 2, one_per_turf = 1, on_floor = 1), \ + )) + recipes += new/datum/stack_recipe_list("old sofa", list( \ + new/datum/stack_recipe("left sofa end", /obj/structure/bed/chair/oldsofa/left, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("middle sofa", /obj/structure/bed/chair/oldsofa, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("right sofa end", /obj/structure/bed/chair/oldsofa/right, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("corner sofa", /obj/structure/bed/chair/oldsofa/corner, 2, one_per_turf = 1, on_floor = 1), \ + )) recipes += new/datum/stack_recipe("table frame", /obj/structure/table, 1, time = 10, one_per_turf = 1, on_floor = 1) recipes += new/datum/stack_recipe("bench frame", /obj/structure/table/bench, 1, time = 10, one_per_turf = 1, on_floor = 1) recipes += new/datum/stack_recipe("rack", /obj/structure/table/rack, 1, time = 5, one_per_turf = 1, on_floor = 1) @@ -123,6 +174,7 @@ recipes += new/datum/stack_recipe("airtight plastic flaps", /obj/structure/plasticflaps/mining, 5, time = 25, one_per_turf = 1, on_floor = 1) recipes += new/datum/stack_recipe("water-cooler", /obj/structure/reagent_dispensers/water_cooler, 4, time = 10, one_per_turf = 1, on_floor = 1) recipes += new/datum/stack_recipe("lampshade", /obj/item/weapon/lampshade, 1, time = 1) + recipes += new/datum/stack_recipe("Feeder", /obj/machinery/feeder, 4, time = 20, one_per_turf = 1, on_floor = 1) /material/wood/generate_recipes() ..() diff --git a/code/modules/media/media_tracks.dm b/code/modules/media/media_tracks.dm index 708e2a811e..f3e401c7dc 100644 --- a/code/modules/media/media_tracks.dm +++ b/code/modules/media/media_tracks.dm @@ -9,15 +9,17 @@ var/artist // Song's creator var/duration // Song length in deciseconds var/secret // Show up in regular playlist or secret playlist? + var/casino // Music for casino jukebox var/lobby // Be one of the choices for lobby music? -/datum/track/New(var/url, var/title, var/duration, var/artist = "", var/secret = 0, var/lobby = 0) +/datum/track/New(var/url, var/title, var/duration, var/artist = "", var/secret = 0, var/lobby = 0, var/casino = 0) src.url = url src.title = title src.artist = artist src.duration = duration src.secret = secret src.lobby = lobby + src.casino = casino /datum/track/proc/display() var str = "\"[title]\"" @@ -36,6 +38,8 @@ var/global/list/all_lobby_tracks = list() // Read the jukebox configuration file on system startup. /hook/startup/proc/load_jukebox_tracks() var/jukebox_track_file = "config/jukebox.json" + if(Holiday == "April Fool's Day") + jukebox_track_file = "config/apriljukebox.json" if(!fexists(jukebox_track_file)) warning("File not found: [jukebox_track_file]") return @@ -56,6 +60,7 @@ var/global/list/all_lobby_tracks = list() if(istext(entry["artist"])) T.artist = entry["artist"] T.secret = entry["secret"] ? 1 : 0 + T.casino = entry["casino"] ? 1 : 0 T.lobby = entry["lobby"] ? 1 : 0 all_jukebox_tracks += T if(T.lobby) diff --git a/code/modules/mining/drilling/drill.dm b/code/modules/mining/drilling/drill.dm index 99fe3f85ee..d3cc7e8b10 100644 --- a/code/modules/mining/drilling/drill.dm +++ b/code/modules/mining/drilling/drill.dm @@ -293,18 +293,18 @@ else usr << "You must move an ore box up to the drill before you can unload it." - +//TFF 25/5/19 - fix infinite frame issue /obj/machinery/mining/brace name = "mining drill brace" desc = "A machinery brace for an industrial drill. It looks easily two feet thick." icon_state = "mining_brace" + circuit = /obj/item/weapon/circuitboard/miningdrillbrace var/obj/machinery/mining/drill/connected /obj/machinery/mining/brace/New() ..() component_parts = list() - component_parts += new /obj/item/weapon/circuitboard/miningdrillbrace(src) /obj/machinery/mining/brace/attackby(obj/item/weapon/W as obj, mob/user as mob) if(connected && connected.active) diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index f6315296f1..e8e6691d5b 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -217,7 +217,7 @@ var/obj/item/stack/flag/newflag = new src.type(T) newflag.amount = 1 newflag.upright = 1 - anchored = 1 + newflag.anchored = 1 newflag.name = newflag.singular_name newflag.icon_state = "[newflag.base_state]_open" newflag.visible_message("[user] plants [newflag] firmly in the ground.") diff --git a/code/modules/mining/mobcapsule_ch.dm b/code/modules/mining/mobcapsule_ch.dm new file mode 100644 index 0000000000..073d215538 --- /dev/null +++ b/code/modules/mining/mobcapsule_ch.dm @@ -0,0 +1,110 @@ +/*********************Mob Capsule*************************/ + +/obj/item/device/mobcapsule + name = "Morpheus capsule" //Whats a lazarus + desc = "It allows you to store and deploy Morpheus-injected creatures easier." + icon = 'icons/obj/mobcap.dmi' + icon_state = "mobcap0" + throwforce = 00 + throw_speed = 4 + throw_range = 20 + force = 0 + var/storage_capacity = 1 + var/mob/living/capsuleowner = null + var/tripped = 0 + var/colorindex = 0 + var/mob/contained_mob + +/obj/item/device/mobcapsule/attackby(obj/item/W, mob/user) + if(istype(W, /obj/item/weapon/pen)) + if(user != capsuleowner) + to_chat(user, "\The [src] briefly flashes an error.") + return 0 + spawn() + var/mname = sanitize(input("Choose a name for your friend.", "Name your friend", contained_mob.name) as text|null) + if(mname) + contained_mob.name = mname + to_chat(user, "Renaming successful, say hello to [contained_mob]!") + name = "Morpheus capsule - [mname]" + ..() + +/obj/item/device/mobcapsule/throw_impact(atom/A, speed, mob/user) + ..() + if(!tripped) + if(contained_mob) + dump_contents(user) + tripped = 1 + else + take_contents(user) + tripped = 1 + +/obj/item/device/mobcapsule/proc/insert(var/atom/movable/AM, mob/user) + if(contained_mob) + return -1 + + if(istype(AM, /mob/living)) + var/mob/living/L = AM + //if(L.locked_to)//locked_to doesnt seem to exist in our code/game/atoms_movable.dm + // return 0 + if(L.client) + L.client.perspective = EYE_PERSPECTIVE + L.client.eye = src + else if(!istype(AM, /obj/item) && !istype(AM, /obj/effect/dummy/chameleon)) + return 0 + else if(AM.density || AM.anchored) + return 0 + AM.forceMove(src) + contained_mob = AM + name = "Morpheus capsule - [AM.name]" + return 1 + +/obj/item/device/mobcapsule/pickup(mob/user) + tripped = 0 + capsuleowner = user + +/obj/item/device/mobcapsule/proc/dump_contents(mob/user) + /* + //Cham Projector Exception + for(var/obj/effect/dummy/chameleon/AD in src) + AD.forceMove(src.loc) + for(var/obj/O in src) + O.forceMove(src.loc) + for(var/mob/M in src) + M.forceMove(src.loc) + if(M.client) + M.client.eye = M.client.mob + M.client.perspective = MOB_PERSPECTIVE +*/ + if(contained_mob) + contained_mob.forceMove(src.loc) + + var/turf/turf = get_turf(src) + log_attack("[key_name(user)] has released hostile mob [contained_mob] with a capsule in area [turf.loc] ([x],[y],[z]).") + contained_mob.attack_log += "\[[time_stamp()]\] Released by [key_name(user)] in area [turf.loc] ([x],[y],[z])." + user.attack_log += "\[[time_stamp()]\] Released hostile mob [contained_mob] in area [turf.loc] ([x],[y],[z])." + msg_admin_attack("[key_name(user)] has released hostile mob [contained_mob] with a capsule in area [turf.loc] ([x],[y],[z]) (JMP).") + + if(contained_mob.client) + contained_mob.client.eye = contained_mob.client.mob + contained_mob.client.perspective = MOB_PERSPECTIVE + contained_mob = null + name = "Morpheus capsule" + +/obj/item/device/mobcapsule/attack_self(mob/user) + colorindex += 1 + if(colorindex >= 6) + colorindex = 0 + icon_state = "mobcap[colorindex]" + update_icon() + +/obj/item/device/mobcapsule/proc/take_contents(mob/user) + for(var/mob/living/simple_animal/AM in src.loc) + if(istype(AM)) + var/mob/living/simple_animal/M = AM + var/mob/living/simple_animal/hostile/H = M + if(!istype(H)) + continue + for(var/things in H.friends) + if(capsuleowner in H.friends) + if(insert(AM, user) == -1) //Limit reached + break diff --git a/code/modules/mining/orm_vr/equipment_vendor.dm b/code/modules/mining/orm_vr/equipment_vendor.dm index 7b1f2e7e12..49166c5b30 100644 --- a/code/modules/mining/orm_vr/equipment_vendor.dm +++ b/code/modules/mining/orm_vr/equipment_vendor.dm @@ -11,47 +11,47 @@ var/icon_deny = "mining-deny" var/obj/item/weapon/card/id/inserted_id var/list/prize_list = list( - new /datum/data/mining_equipment("1 Marker Beacon", /obj/item/stack/marker_beacon, 10), - new /datum/data/mining_equipment("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 100), - new /datum/data/mining_equipment("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 300), - new /datum/data/mining_equipment("Whiskey", /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, 125), - new /datum/data/mining_equipment("Absinthe", /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe, 125), - new /datum/data/mining_equipment("Cigar", /obj/item/clothing/mask/smokable/cigarette/cigar/havana, 150), - new /datum/data/mining_equipment("Soap", /obj/item/weapon/soap/nanotrasen, 200), - new /datum/data/mining_equipment("Laser Pointer", /obj/item/device/laser_pointer, 900), - new /datum/data/mining_equipment("Plush Toy", /obj/random/plushie, 300), - // TODO new /datum/data/mining_equipment("Advanced Scanner", /obj/item/device/t_scanner/adv_mining_scanner, 800), - new /datum/data/mining_equipment("Fulton Beacon", /obj/item/fulton_core, 500), - new /datum/data/mining_equipment("Shelter Capsule", /obj/item/device/survivalcapsule, 500), - // TODO new /datum/data/mining_equipment("Explorer's Webbing", /obj/item/storage/belt/mining, 500), - new /datum/data/mining_equipment("Point Transfer Card", /obj/item/weapon/card/mining_point_card, 500), - new /datum/data/mining_equipment("Survival Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/miner, 500), - new /datum/data/mining_equipment("Mini-Translocator", /obj/item/device/perfect_tele/one_beacon, 1200), - // new /datum/data/mining_equipment("Kinetic Crusher", /obj/item/twohanded/required/kinetic_crusher, 750), - new /datum/data/mining_equipment("Kinetic Accelerator", /obj/item/weapon/gun/energy/kinetic_accelerator, 900), - new /datum/data/mining_equipment("Resonator", /obj/item/resonator, 900), - new /datum/data/mining_equipment("Fulton Pack", /obj/item/extraction_pack, 1200), - new /datum/data/mining_equipment("Silver Pickaxe", /obj/item/weapon/pickaxe/silver, 1200), - //new /datum/data/mining_equipment("Mining Conscription Kit", /obj/item/storage/backpack/duffelbag/mining_conscript, 1000), - new /datum/data/mining_equipment("Space Cash", /obj/item/weapon/spacecash/c1000, 2000), - new /datum/data/mining_equipment("Industrial Hardsuit - Control Module", /obj/item/weapon/rig/industrial, 2000), - new /datum/data/mining_equipment("Industrial Hardsuit - Plasma Cutter", /obj/item/rig_module/device/plasmacutter, 800), - new /datum/data/mining_equipment("Industrial Hardsuit - Drill", /obj/item/rig_module/device/drill, 2000), - new /datum/data/mining_equipment("Industrial Hardsuit - Ore Scanner", /obj/item/rig_module/device/orescanner, 1000), - new /datum/data/mining_equipment("Industrial Hardsuit - Material Scanner", /obj/item/rig_module/vision/material, 500), - new /datum/data/mining_equipment("Industrial Hardsuit - Maneuvering Jets", /obj/item/rig_module/maneuvering_jets, 1250), - new /datum/data/mining_equipment("Diamond Pickaxe", /obj/item/weapon/pickaxe/diamond, 2000), - new /datum/data/mining_equipment("Super Resonator", /obj/item/resonator/upgraded, 2500), - new /datum/data/mining_equipment("Jump Boots", /obj/item/clothing/shoes/bhop, 2500), - new /datum/data/mining_equipment("Luxury Shelter Capsule", /obj/item/device/survivalcapsule/luxury, 3100), - new /datum/data/mining_equipment("KA White Tracer Rounds", /obj/item/borg/upgrade/modkit/tracer, 125), - new /datum/data/mining_equipment("KA Adjustable Tracer Rounds", /obj/item/borg/upgrade/modkit/tracer/adjustable, 175), - new /datum/data/mining_equipment("KA Super Chassis", /obj/item/borg/upgrade/modkit/chassis_mod, 250), - new /datum/data/mining_equipment("KA Hyper Chassis", /obj/item/borg/upgrade/modkit/chassis_mod/orange, 300), - new /datum/data/mining_equipment("KA Range Increase", /obj/item/borg/upgrade/modkit/range, 1000), - new /datum/data/mining_equipment("KA Damage Increase", /obj/item/borg/upgrade/modkit/damage, 1000), - new /datum/data/mining_equipment("KA Efficiency Increase", /obj/item/borg/upgrade/modkit/efficiency, 1200), - new /datum/data/mining_equipment("KA AoE Damage", /obj/item/borg/upgrade/modkit/aoe/mobs, 2000) + new /datum/data/mining_equipment("1 Marker Beacon",/obj/item/stack/marker_beacon,10), + new /datum/data/mining_equipment("10 Marker Beacons",/obj/item/stack/marker_beacon/ten, 100), + new /datum/data/mining_equipment("30 Marker Beacons",/obj/item/stack/marker_beacon/thirty,300), + new /datum/data/mining_equipment("Whiskey",/obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey,125), + new /datum/data/mining_equipment("Absinthe",/obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe,125), + new /datum/data/mining_equipment("Cigar",/obj/item/clothing/mask/smokable/cigarette/cigar/havana,150), + new /datum/data/mining_equipment("Soap",/obj/item/weapon/soap/nanotrasen,200), + new /datum/data/mining_equipment("Laser Pointer",/obj/item/device/laser_pointer,900), + new /datum/data/mining_equipment("Plush Toy",/obj/random/plushie,300), + // TODO new /datum/data/mining_equipment("Advanced Scanner",/obj/item/device/t_scanner/adv_mining_scanner,800), + new /datum/data/mining_equipment("Fulton Beacon",/obj/item/fulton_core,500), + new /datum/data/mining_equipment("Shelter Capsule",/obj/item/device/survivalcapsule,500), + // TODO new /datum/data/mining_equipment("Explorer's Webbing",/obj/item/storage/belt/mining,500), + new /datum/data/mining_equipment("Point Transfer Card",/obj/item/weapon/card/mining_point_card,500), + new /datum/data/mining_equipment("Survival Medipen",/obj/item/weapon/reagent_containers/hypospray/autoinjector/miner,500), + new /datum/data/mining_equipment("Mini-Translocator",/obj/item/device/perfect_tele/one_beacon,1200), + // new /datum/data/mining_equipment("Kinetic Crusher",/obj/item/twohanded/required/kinetic_crusher,750), + new /datum/data/mining_equipment("Kinetic Accelerator",/obj/item/weapon/gun/energy/kinetic_accelerator,900), + new /datum/data/mining_equipment("Resonator",/obj/item/resonator,900), + new /datum/data/mining_equipment("Fulton Pack",/obj/item/extraction_pack,1200), + new /datum/data/mining_equipment("Silver Pickaxe",/obj/item/weapon/pickaxe/silver,1200), + //new /datum/data/mining_equipment("Mining Conscription Kit",/obj/item/storage/backpack/duffelbag/mining_conscript,1000), + new /datum/data/mining_equipment("Space Cash",/obj/item/weapon/spacecash/c1000,2000), + new /datum/data/mining_equipment("Industrial Hardsuit - Control Module",/obj/item/weapon/rig/industrial,2000), + new /datum/data/mining_equipment("Industrial Hardsuit - Plasma Cutter",/obj/item/rig_module/device/plasmacutter,800), + new /datum/data/mining_equipment("Industrial Hardsuit - Drill",/obj/item/rig_module/device/drill,2000), + new /datum/data/mining_equipment("Industrial Hardsuit - Ore Scanner",/obj/item/rig_module/device/orescanner,1000), + new /datum/data/mining_equipment("Industrial Hardsuit - Material Scanner",/obj/item/rig_module/vision/material,500), + new /datum/data/mining_equipment("Industrial Hardsuit - Maneuvering Jets",/obj/item/rig_module/maneuvering_jets,1250), + new /datum/data/mining_equipment("Diamond Pickaxe",/obj/item/weapon/pickaxe/diamond,2000), + new /datum/data/mining_equipment("Super Resonator",/obj/item/resonator/upgraded,2500), + new /datum/data/mining_equipment("Jump Boots",/obj/item/clothing/shoes/bhop,2500), + new /datum/data/mining_equipment("Luxury Shelter Capsule",/obj/item/device/survivalcapsule/luxury,3100), + new /datum/data/mining_equipment("KA White Tracer Rounds",/obj/item/borg/upgrade/modkit/tracer,125), + new /datum/data/mining_equipment("KA Adjustable Tracer Rounds",/obj/item/borg/upgrade/modkit/tracer/adjustable,175), + new /datum/data/mining_equipment("KA Super Chassis",/obj/item/borg/upgrade/modkit/chassis_mod,250), + new /datum/data/mining_equipment("KA Hyper Chassis",/obj/item/borg/upgrade/modkit/chassis_mod/orange,300), + new /datum/data/mining_equipment("KA Range Increase",/obj/item/borg/upgrade/modkit/range,1000), + new /datum/data/mining_equipment("KA Damage Increase",/obj/item/borg/upgrade/modkit/damage,1000), + new /datum/data/mining_equipment("KA Efficiency Increase",/obj/item/borg/upgrade/modkit/efficiency,1200), + new /datum/data/mining_equipment("KA AoE Damage",/obj/item/borg/upgrade/modkit/aoe/mobs,2000), ) /datum/data/mining_equipment diff --git a/code/modules/mob/airhack.dm b/code/modules/mob/airhack.dm new file mode 100644 index 0000000000..3d01892f9a --- /dev/null +++ b/code/modules/mob/airhack.dm @@ -0,0 +1,123 @@ +/mob + var/datum/gas_mixture/air_contents = new + + var/obj/machinery/atmospherics/portables_connector/connected_port + var/obj/item/weapon/tank/holding + + var/volume = 1000 + var/destroyed = 0 + + var/start_pressure = ONE_ATMOSPHERE + var/maximum_pressure = 90 * ONE_ATMOSPHERE + var/inflatable = 1 +/mob/living + inflatable= 0 +/mob/New() + ..() + + air_contents.volume = volume + air_contents.temperature = T20C + + return 1 +/mob/Destroy() + qdel_null(air_contents) + qdel_null(holding) + . = ..() +/mob/Life() + if(!connected_port) //only react when pipe_network will ont it do it for you + //Allow for reactions + air_contents.react() + . = ..() +/mob/proc/StandardAirMix() + return list( + "oxygen" = O2STANDARD * MolesForPressure(), + "nitrogen" = N2STANDARD * MolesForPressure()) +/mob/proc/MolesForPressure(var/target_pressure = start_pressure) + return (target_pressure * air_contents.volume) / (R_IDEAL_GAS_EQUATION * air_contents.temperature) + +/mob/proc/connect(obj/machinery/atmospherics/portables_connector/new_port) + //Make sure not already connected to something else + if(connected_port || !new_port || new_port.connected_device) + return 0 + + //Make sure are close enough for a valid connection + if(new_port.loc != loc) + return 0 + + //Perform the connection + connected_port = new_port + connected_port.connected_device = src + connected_port.on = 1 //Activate port updates + + anchored = 1 //Prevent movement + + //Actually enforce the air sharing + var/datum/pipe_network/network = connected_port.return_network(src) + if(network && !network.gases.Find(air_contents)) + network.gases += air_contents + network.update = 1 + + return 1 + +/mob/proc/disconnect() + if(!connected_port) + return 0 + + var/datum/pipe_network/network = connected_port.return_network(src) + if(network) + network.gases -= air_contents + + anchored = 0 + + connected_port.connected_device = null + connected_port = null + + return 1 + +/mob/proc/update_connected_network() + if(!connected_port) + return + + var/datum/pipe_network/network = connected_port.return_network(src) + if (network) + network.update = 1 + +/mob/proc/Airattackby(var/obj/item/weapon/W as obj, var/mob/user as mob) + if(src.inflatable == 0) + return 0 + if (istype(W, /obj/item/weapon/wrench)) + if(connected_port) + disconnect() + user << "You disconnect \the [src] from the port." + update_icon() + playsound(src, W.usesound, 50, 1) + return 1 + else + var/obj/machinery/atmospherics/portables_connector/possible_port = locate(/obj/machinery/atmospherics/portables_connector/) in loc + if(possible_port) + if(connect(possible_port)) + user << "You connect \the [src] to the port." + update_icon() + playsound(src, W.usesound, 50, 1) + return 1 + else + user << "\The [src] failed to connect to the port." + return 0 + else + return 0 + else if ((istype(W, /obj/item/device/analyzer)) && Adjacent(user)) + var/obj/item/device/analyzer/A = W + A.analyze_gases(src, user) + return 1 + return 0 + +/mob/proc/atmosanalyze(var/mob/user) + return atmosanalyzer_scan(src, src.air_contents, user) + +/datum/trait/inflatable + name = "Inflatable" + desc = "You were born with an unusual ability to store air like a portable canister" + cost = 0 +/datum/trait/inflatable/apply(var/datum/species/S,var/mob/living/carbon/human/H) + H.inflatable = 1 + ..(S,H) \ No newline at end of file diff --git a/code/modules/mob/death.dm b/code/modules/mob/death.dm index af0fdf4301..661ace540f 100644 --- a/code/modules/mob/death.dm +++ b/code/modules/mob/death.dm @@ -70,6 +70,7 @@ if(stat == DEAD) return 0 + location = get_turf(src) //CHOMPEDIT: since we use this so much lets define it here yknow if(src.loc && istype(loc,/obj/belly)) deathmessage = "no message" //VOREStation Add - Prevents death messages from inside mobs facing_dir = null diff --git a/code/modules/mob/living/bot/cleanbot.dm b/code/modules/mob/living/bot/cleanbot.dm index f69e1e3554..be895f8b0f 100644 --- a/code/modules/mob/living/bot/cleanbot.dm +++ b/code/modules/mob/living/bot/cleanbot.dm @@ -5,7 +5,7 @@ maxHealth = 100 health = 100 req_one_access = list(access_robotics, access_janitor) - botcard_access = list(access_janitor, access_maint_tunnels) + botcard_access = list(access_janitor) locked = 0 // Start unlocked so roboticist can set them to patrol. wait_if_pulled = 1 diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index 1112b4e49c..21ad38472c 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -6,6 +6,8 @@ var/list/antibodies = list() var/last_eating = 0 //Not sure what this does... I found it hidden in food.dm + var/hasImplant = 0 //CHOMPEDIT Backup implant check var. + var/life_tick = 0 // The amount of life ticks that have processed on this mob. // total amount of wounds on mob, used to spread out healing and the like over all wounds @@ -28,4 +30,4 @@ //these two help govern taste. The first is the last time a taste message was shown to the plaer. //the second is the message in question. var/last_taste_time = 0 - var/last_taste_text = "" \ No newline at end of file + var/last_taste_text = "" diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index df2d2799bc..2c4eb0780d 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -1,6 +1,6 @@ /mob/living/carbon/human/emote(var/act,var/m_type=1,var/message = null) var/param = null - + var/datum/gender/T = gender_datums[get_visible_gender()] if (findtext(act, "-", 1, null)) @@ -29,7 +29,7 @@ m_type = 1 //Machine-only emotes - if("ping", "beep", "buzz", "yes", "no", "rcough", "rsneeze") + if("ping", "beep", "buzz", "yes", "ye", "no", "rcough", "rsneeze") //TFF 18/4/19: Polaris fix - make synths able to use *yes emote if(!isSynthetic()) src << "You are not a synthetic." @@ -52,7 +52,7 @@ else if(act == "ping") display_msg = "pings" use_sound = 'sound/machines/ping.ogg' - else if(act == "yes") + else if(act == "yes"||act == "ye") //TFF 18/4/19: Polaris fix - make synths able to use *yes emote display_msg = "emits an affirmative blip" use_sound = 'sound/machines/synth_yes.ogg' else if(act == "no") @@ -554,6 +554,10 @@ message = "makes a noise." m_type = 2 + if ("weh") + message = "lets out a weh." + m_type = 1 + if ("whimper") if (miming) message = "appears hurt." @@ -727,7 +731,7 @@ 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, \ raise, salute, scream, sneeze, shake, shiver, shrug, sigh, signal-#1-10, slap-(none)/mob, smile, sneeze, sniff, snore, stare-(none)/mob, stopsway/swag, sway/wag, swish, tremble, twitch, \ - twitch_v, vomit, whimper, wink, yawn. Synthetics: beep, buzz, yes, no, rcough, rsneeze, ping" + twitch_v, vomit, weh, whimper, wink, yawn. Synthetics: beep, buzz, yes, no, rcough, rsneeze, ping" else src << "Unusable emote '[act]'. Say *help for a list." @@ -739,7 +743,7 @@ set name = "Set Pose" set desc = "Sets a description which will be shown when someone examines you." set category = "IC" - + var/datum/gender/T = gender_datums[get_visible_gender()] pose = sanitize(input(usr, "This is [src]. [T.he]...", "Pose", null) as text) diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index d05babc345..d1a28f5059 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -440,6 +440,9 @@ if(ooc_notes) msg += "OOC Notes: \[View\]\n" // VOREStation End + //TFF 4/5/19 - fixes overlooked examine text displaying for human mobs + msg += "\[Mechanical Vore Preferences\]\n" + msg += "*---------*
    " msg += applying_pressure if(pose) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 597fb2b94a..884f016e23 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -167,7 +167,7 @@ update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message) if(update) UpdateDamageIcon() -/mob/living/carbon/human/proc/implant_loadout(var/datum/gear/G = new/datum/gear/utility/implant) +/mob/living/carbon/human/proc/implant_loadout(var/datum/gear/G = new/datum/gear/implant) //TFF 29/4/19: filepath change due to loadout change var/obj/item/weapon/implant/I = new G.path(src) I.imp_in = src I.implanted = 1 @@ -1117,7 +1117,8 @@ else usr << "You failed to check the pulse. Try again." -/mob/living/carbon/human/proc/set_species(var/new_species, var/default_colour, var/regen_icons = TRUE) +//TFF 14/4/19: Port VoreStation TF fix +/mob/living/carbon/human/proc/set_species(var/new_species, var/default_colour, var/regen_icons = TRUE, var/mob/living/carbon/human/example = null) //VOREStation Edit - send an example if(!dna) if(!new_species) @@ -1152,7 +1153,16 @@ if(species.default_language) add_language(species.default_language) - if(species.base_color) //VOREStation Edit - Always give them a basse color +//TFF 14/4/19: Port VoreStation TF fix + //if(species.icon_scale != 1) //VOREStation Removal + // update_transform() //VOREStation Removal + + if(example) //VOREStation Edit begin + if(!(example == src)) + r_skin = example.r_skin + g_skin = example.g_skin + b_skin = example.b_skin + else if(species.base_color) //VOREStation Edit end //Apply colour. r_skin = hex2num(copytext(species.base_color,2,4)) g_skin = hex2num(copytext(species.base_color,4,6)) @@ -1169,10 +1179,13 @@ gender = species.genders[1] //icon_state = lowertext(species.name) //Necessary? +//TFF 14/4/19: Port VoreStation TF fix + //VOREStation Edit start: swap places of those two procs + species.handle_post_spawn(src) + species.create_organs(src) - species.handle_post_spawn(src) maxHealth = species.total_health diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index f61ddbfd09..7eb88177d0 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -284,7 +284,8 @@ apply_damage(real_damage, hit_dam_type, hit_zone, armour, soaked, sharp=attack.sharp, edge=attack.edge) if(I_DISARM) - add_attack_logs(H,src,"Disarmed") + // Having this log every time someone disarms even when the disarm does nothing is REALLY ANNOYING. -Erik + // add_attack_logs(H,src,"Disarmed") M.do_attack_animation(src) @@ -309,6 +310,8 @@ visible_message("[M] has weakly pushed [src]!") return + add_attack_logs(H,src,"Disarmed") + var/randn = rand(1, 100) last_push_time = world.time if(!(species.flags & NO_SLIP) && randn <= 25) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 65439ec3c1..9ef5e41996 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -950,10 +950,15 @@ adjustBrainLoss(brainOxPercent * oxyloss) if(halloss >= species.total_health) - src << "You're in too much pain to keep going..." - src.visible_message("[src] slumps to the ground, too weak to continue fighting.") - Paralyse(10) - setHalLoss(species.total_health - 1) + if (chem_effects[CE_PAINKILLER]) + setHalLoss(species.total_health - 1) + else + Paralyse(10) + setHalLoss(species.total_health - 1) + if (!paralysis && !sleeping || !chem_effects[CE_PAINKILLER]) //CHOMPEDIT only display slump if we werent slumped already to prevent spam, sleeping counts as slump state for this matter + src << "You're in too much pain to keep going..." + src.visible_message("[src] slumps to the ground, too weak to continue fighting.") + if(paralysis || sleeping) blinded = 1 diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index b1557f3a28..3e3fe8413e 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -177,7 +177,7 @@ var/gluttonous // Can eat some mobs. 1 for mice, 2 for monkeys, 3 for people. var/rarity_value = 1 // Relative rarity/collector value for this species. - var/economic_modifier = 2 // How much money this species makes + var/economic_modifier = 10 // How much money this species makes // Determines the organs that the species spawns with and var/list/has_organ = list( // which required-organ checks are conducted. @@ -340,6 +340,10 @@ H.visible_message( \ "[H] shakes [target]'s hand.", \ "You shake [target]'s hand.", ) + else if(H.zone_sel.selecting == "mouth") // I ADDED BOOP-EH-DEH-NOSEH - Jon + H.visible_message( \ + "[H] boops [target]'s nose.", \ + "You boop [target] on the nose.", ) else H.visible_message("[H] hugs [target] to make [t_him] feel better!", \ "You hug [target] to make [t_him] feel better!") //End VOREStation Edit diff --git a/code/modules/mob/living/carbon/human/species/species_shapeshift_vr.dm b/code/modules/mob/living/carbon/human/species/species_shapeshift_vr.dm index 3313c137b5..7332170b75 100644 --- a/code/modules/mob/living/carbon/human/species/species_shapeshift_vr.dm +++ b/code/modules/mob/living/carbon/human/species/species_shapeshift_vr.dm @@ -1,3 +1,17 @@ +/mob/living/carbon/human/proc/promethean_select_opaqueness() + set name = "Toggle Transparency" + set category = "Abilities" + if(stat || world.time < last_special) + return + + last_special = world.time + 50 + + for(var/limb in src.organs) + var/obj/item/organ/external/L = limb + L.transparent = !L.transparent + visible_message("\The [src]'s interal composition seems to change.") + update_icons_body() + /mob/living/carbon/human/proc/shapeshifter_select_ears() set name = "Select Ears" set category = "Abilities" diff --git a/code/modules/mob/living/carbon/human/species/station/blank_vr.dm b/code/modules/mob/living/carbon/human/species/station/blank_vr.dm index f2847a1523..dd9d811198 100644 --- a/code/modules/mob/living/carbon/human/species/station/blank_vr.dm +++ b/code/modules/mob/living/carbon/human/species/station/blank_vr.dm @@ -1,15 +1,19 @@ +//TFF 30/4/19: Make leave_remains_vr.dm work! >:C /datum/species //var/vore_numbing = 0 - var/gets_food_nutrition = 1 // If this is set to 0, the person can't get nutrition from food. + var/gets_food_nutrition = TRUE // If this is set to 0, the person can't get nutrition from food. var/metabolism = 0.0015 - var/lightweight = 0 //Oof! Nonhelpful bump stumbles. - var/trashcan = 0 //It's always sunny in the wrestling ring. + var/lightweight = FALSE //Oof! Nonhelpful bump stumbles. + var/trashcan = FALSE //It's always sunny in the wrestling ring. + var/base_species = null // Unused outside of a few species + var/selects_bodytype = 0 // Allows the species to choose from body types intead of being forced to be just one. /datum/species/custom name = SPECIES_CUSTOM name_plural = "Custom" - var/base_species = "Human" + selects_bodytype = TRUE + base_species = SPECIES_HUMAN unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/punch, /datum/unarmed_attack/bite) diff --git a/code/modules/mob/living/carbon/human/species/station/monkey_vr.dm b/code/modules/mob/living/carbon/human/species/station/monkey_vr.dm index f56faa515a..e2a48c75ab 100644 --- a/code/modules/mob/living/carbon/human/species/station/monkey_vr.dm +++ b/code/modules/mob/living/carbon/human/species/station/monkey_vr.dm @@ -1,5 +1,6 @@ +//TFF 30/4/19: Ports VoreStation Remains Option - refactor species names /datum/species/monkey/shark - name = "Sobaka" + name = SPECIES_MONKEY_AKULA name_plural = "Sobaka" icobase = 'icons/mob/human_races/monkeys/r_sobaka_vr.dmi' deform = 'icons/mob/human_races/monkeys/r_sobaka_vr.dmi' @@ -8,7 +9,7 @@ default_language = "Skrellian" //Closest we have. /datum/species/monkey/sergal - name = "Saru" + name = SPECIES_MONKEY_SERGAL greater_form = "Sergal" icobase = 'icons/mob/human_races/monkeys/r_sergaling_vr.dmi' deform = 'icons/mob/human_races/monkeys/r_sergaling_vr.dmi' @@ -16,7 +17,7 @@ default_language = LANGUAGE_SAGARU /datum/species/monkey/sparra - name = "Sparra" + name = SPECIES_MONKEY_NEVREAN name_plural = "Sparra" greater_form = "Nevrean" tail = null @@ -41,7 +42,7 @@ */ /datum/species/monkey/vulpkanin - name = "Wolpin" + name = SPECIES_MONKEY_VULPKANIN name_plural = "Wolpin" icobase = 'icons/mob/human_races/monkeys/r_wolpin.dmi' 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 a9d8d9d822..699f04e797 100644 --- a/code/modules/mob/living/carbon/human/species/station/prometheans.dm +++ b/code/modules/mob/living/carbon/human/species/station/prometheans.dm @@ -113,10 +113,19 @@ var/datum/species/shapeshifter/promethean/prometheans prometheans = src /datum/species/shapeshifter/promethean/equip_survival_gear(var/mob/living/carbon/human/H) - var/boxtype = pick(typesof(/obj/item/weapon/storage/toolbox/lunchbox)) +//TFF 18/4/19: Add a proper list of randomly chosen lunchboxes + var/boxtype = pick(list(/obj/item/weapon/storage/toolbox/lunchbox, + /obj/item/weapon/storage/toolbox/lunchbox/heart, + /obj/item/weapon/storage/toolbox/lunchbox/cat, + /obj/item/weapon/storage/toolbox/lunchbox/nt, + /obj/item/weapon/storage/toolbox/lunchbox/mars, + /obj/item/weapon/storage/toolbox/lunchbox/cti, + /obj/item/weapon/storage/toolbox/lunchbox/nymph, + /obj/item/weapon/storage/toolbox/lunchbox/syndicate)) //Only pick the empty types var/obj/item/weapon/storage/toolbox/lunchbox/L = new boxtype(get_turf(H)) var/mob/living/simple_animal/mouse/mouse = new (L) var/obj/item/weapon/holder/holder = new (L) + holder.held_mob = mouse //TFF 18/4/19: Make Prommies hold a mouse on spawning. mouse.forceMove(holder) holder.sync(mouse) if(H.backbag == 1) diff --git a/code/modules/mob/living/carbon/human/species/station/prometheans_vr.dm b/code/modules/mob/living/carbon/human/species/station/prometheans_vr.dm index 2646d90bbb..78c0b64ef2 100644 --- a/code/modules/mob/living/carbon/human/species/station/prometheans_vr.dm +++ b/code/modules/mob/living/carbon/human/species/station/prometheans_vr.dm @@ -27,11 +27,15 @@ /mob/living/carbon/human/proc/shapeshifter_select_hair, /mob/living/carbon/human/proc/shapeshifter_select_hair_colors, /mob/living/carbon/human/proc/shapeshifter_select_gender, + /mob/living/carbon/human/proc/shapeshifter_select_wings, //VOREStation Add, + /mob/living/carbon/human/proc/shapeshifter_select_tail, //VOREStation Add, + /mob/living/carbon/human/proc/shapeshifter_select_ears, //VOREStation Add, /mob/living/carbon/human/proc/regenerate, /mob/living/proc/set_size, /mob/living/carbon/human/proc/succubus_drain, /mob/living/carbon/human/proc/succubus_drain_finalize, /mob/living/carbon/human/proc/succubus_drain_lethal, /mob/living/carbon/human/proc/slime_feed, - /mob/living/proc/eat_trash + /mob/living/proc/eat_trash, + /mob/living/carbon/human/proc/promethean_select_opaqueness ) 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 f941d65de8..bb4b68e6fb 100644 --- a/code/modules/mob/living/carbon/human/species/station/station.dm +++ b/code/modules/mob/living/carbon/human/species/station/station.dm @@ -16,7 +16,6 @@ min_age = 17 max_age = 130 - economic_modifier = 10 health_hud_intensity = 1.5 @@ -56,7 +55,6 @@ min_age = 32 max_age = 260 - economic_modifier = 7 blurb = "A heavily reptillian species, Unathi hail from the \ Uuosa-Eso system, which roughly translates to 'burning mother'.

    Coming from a harsh, inhospitable \ @@ -161,7 +159,6 @@ min_age = 17 max_age = 80 - economic_modifier = 7 blurb = "The Tajaran are a mammalian species resembling roughly felines, hailing from Meralar in the Rarkajar system. \ While reaching to the stars independently from outside influences, the humans engaged them in peaceful trade contact \ @@ -247,7 +244,6 @@ min_age = 19 max_age = 130 - economic_modifier = 12 darksight = 4 flash_mod = 1.2 @@ -324,7 +320,6 @@ min_age = 1 max_age = 300 - economic_modifier = 4 blurb = "Commonly referred to (erroneously) as 'plant people', the Dionaea are a strange space-dwelling collective \ species hailing from Epsilon Ursae Minoris. Each 'diona' is a cluster of numerous cat-sized organisms called nymphs; \ diff --git a/code/modules/mob/living/carbon/human/species/station/station_special_abilities_vr.dm b/code/modules/mob/living/carbon/human/species/station/station_special_abilities_vr.dm index d14d4db279..5dd9ee1f14 100644 --- a/code/modules/mob/living/carbon/human/species/station/station_special_abilities_vr.dm +++ b/code/modules/mob/living/carbon/human/species/station/station_special_abilities_vr.dm @@ -896,9 +896,9 @@ mob/living/carbon/proc/charmed() //TODO scannable = 0 /datum/reagent/succubi_aphrodisiac/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) - if(prob(7)) + if(prob(3)) M.show_message("You feel funny, and fall in love with the person in front of you") - M.emote(pick("blush", "moans", "giggles", "turns visibly red")) + M.say(pick("!blushes", "!moans", "!giggles", "!turns visibly red")) //using mob say so we dont have to define this dumb one time use emote that equates to just blushing -shark //M.charmed() //TODO return diff --git a/code/modules/mob/living/carbon/human/species/station/station_special_vr.dm b/code/modules/mob/living/carbon/human/species/station/station_special_vr.dm index aa8af0e273..da5d052b65 100644 --- a/code/modules/mob/living/carbon/human/species/station/station_special_vr.dm +++ b/code/modules/mob/living/carbon/human/species/station/station_special_vr.dm @@ -14,7 +14,9 @@ slowdown = -0.2 //scuttly, but not as scuttly as a tajara or a teshari. brute_mod = 0.8 //About as tanky to brute as a Unathi. They'll probably snap and go feral when hurt though. burn_mod = 1.15 //As vulnerable to burn as a Tajara. - var/base_species = "Xenochimera" + //TFF 30/4/19: Making leave_remains_vr.dm work. >:C + base_species = "Xenochimera" + selects_bodytype = TRUE num_alternate_languages = 2 secondary_langs = list("Sol Common") diff --git a/code/modules/mob/living/carbon/human/species/station/station_vr.dm b/code/modules/mob/living/carbon/human/species/station/station_vr.dm index 47c177c074..09c4e16709 100644 --- a/code/modules/mob/living/carbon/human/species/station/station_vr.dm +++ b/code/modules/mob/living/carbon/human/species/station/station_vr.dm @@ -285,7 +285,7 @@ //primitive_form = "" //None for these guys - spawn_flags = SPECIES_CAN_JOIN | SPECIES_IS_WHITELISTED + spawn_flags = SPECIES_CAN_JOIN //| SPECIES_IS_WHITELISTED //CHOMPEDIT: REmoving whitelist for xenohybrids appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR blood_color = "#12ff12" diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index b36db9bfa5..21d8147472 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -272,6 +272,8 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() icon_key += "3" else icon_key += "1" + if(part.transparent) //VOREStation Edit. For better slime limbs. + icon_key += "_t" //VOREStation Edit. For better slime limbs. icon_key = "[icon_key][husk ? 1 : 0][fat ? 1 : 0][hulk ? 1 : 0][skeleton ? 1 : 0]" @@ -435,7 +437,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() face_standing.Blend(ears_s, ICON_OVERLAY) // VOREStation Edit - END - if(head_organ.nonsolid) + if(head_organ.transparent) //VOREStation Edit. For better slime limbs. face_standing += rgb(,,,120) overlays_standing[HAIR_LAYER] = image(face_standing, layer = BODY_LAYER+HAIR_LAYER) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index a7aeae21b9..8c6297357a 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -891,9 +891,14 @@ default behaviour is: to_chat(src, "You struggle free of \the [H.loc].") H.forceMove(get_turf(H)) +//TFF 2/5/19: Polaris fix for resisting out of vehicles /mob/living/proc/escape_buckle() if(buckled) - buckled.user_unbuckle_mob(src, src) + if(istype(buckled, /obj/vehicle)) + var/obj/vehicle/vehicle = buckled + vehicle.unload() + else + buckled.user_unbuckle_mob(src, src) /mob/living/proc/resist_grab() var/resisting = 0 @@ -1277,4 +1282,4 @@ default behaviour is: /mob/living/proc/has_vision() - return !(eye_blind || (disabilities & BLIND) || stat || blinded) \ No newline at end of file + return !(eye_blind || (disabilities & BLIND) || stat || blinded) diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 5044595975..18d4e068e7 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -591,7 +591,8 @@ var/list/ai_verbs_default = list( "male tesharii", "female tesharii", "male skrell", - "female skrell" + "female skrell", + "synx" ) input = input("Please select a hologram:") as null|anything in icon_list if(input) @@ -641,6 +642,8 @@ var/list/ai_verbs_default = list( holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holoskrm")) if("female skrell") holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holoskrf")) + if("synx") + holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holosynx")) //Toggles the luminosity and applies it by re-entereing the camera. /mob/living/silicon/ai/proc/toggle_camera_light() diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 3358d1855e..361dd3c5a0 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -33,7 +33,8 @@ "Fox" = "fox", "Parrot" = "parrot", "Rabbit" = "rabbit", - "Bear" = "bear" //VOREStation Edit + "Bear" = "bear", //VOREStation Edit + "Raccoon" = "raccoon" //Chompstation Edit ) var/global/list/possible_say_verbs = list( diff --git a/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm b/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm index 39236a824f..5cfc2f27fb 100644 --- a/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm +++ b/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm @@ -671,4 +671,12 @@ desc = "A mounted matter decompiling unit with fuel processor." icon_state = "decompiler" max_item_count = 10 - decompiler = TRUE \ No newline at end of file + decompiler = TRUE + +// PLACEHOLDER SERVICE BORG BELLY +/obj/item/device/dogborg/sleeper/servborg + name = "Gourmet Gut" + desc = "An underslung microwave, with optional fuel processor." + icon_state = "decompiler" + max_item_count = 10 + injection_chems = null \ No newline at end of file diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm index 02108eb6bc..122a89842f 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone.dm @@ -61,6 +61,19 @@ var/list/mob_hat_cache = list() holder_type = /obj/item/weapon/holder/drone can_be_antagged = FALSE + + //CHOMPEDIT: CHAISS storage + var/chassis = "repairbot" // A record of your chosen chassis. + var/global/list/possible_chassis = list( + "Maintenance" = "repairbot", + "Mining" = "miningdrone", + "Construction" = "constructiondrone", + "White Spider" = "whitespider", + "Crawler" = "crawler", + "Gravekeeper" = "drone-gravekeeper", + "Egg" = "peaceborg", + "Ball" = "omoikane", + ) /mob/living/silicon/robot/drone/Destroy() if(hat) @@ -77,6 +90,18 @@ var/list/mob_hat_cache = list() hat_x_offset = 1 hat_y_offset = -12 can_pull_mobs = MOB_PULL_SAME + chassis = "constructiondrone" //CHOMPEDIT: Initial chasis + +/mob/living/silicon/robot/drone/security + maxHealth = 100 + health = 100 + icon_state = "constructiondrone" + law_type = /datum/ai_laws/security_drone + module_type = /obj/item/weapon/robot_module/drone/security + hat_x_offset = 1 + hat_y_offset = -12 + can_pull_mobs = MOB_PULL_SAME + chassis = "constructiondrone" //CHOMPEDIT: Initial chasis /mob/living/silicon/robot/drone/mining icon_state = "miningdrone" @@ -86,19 +111,22 @@ var/list/mob_hat_cache = list() hat_x_offset = 1 hat_y_offset = -12 can_pull_mobs = MOB_PULL_SAME + chassis = "mining" //CHOMPEDIT: Initial chasis /mob/living/silicon/robot/drone/New() ..() verbs += /mob/living/proc/ventcrawl verbs += /mob/living/proc/hide + verbs |= /mob/living/silicon/robot/drone/proc/choose_chassis //CHOMPEDIT verb addition + verbs -= /mob/living/silicon/robot/verb/self_diagnosis_verb //Drones dont take component based damage. remove_language("Robot Talk") add_language("Robot Talk", 0) add_language("Drone Talk", 1) //They are unable to be upgraded, so let's give them a bit of a better battery. - cell.maxcharge = 10000 - cell.charge = 10000 + cell.maxcharge = 20000 //Original val 10000, doubled for ease of use of powertransmission circuit. + cell.charge = 20000 // NO BRAIN. mmi = null @@ -129,6 +157,18 @@ var/list/mob_hat_cache = list() /mob/living/silicon/robot/drone/updatename() real_name = "maintenance drone ([rand(100,999)])" name = real_name +/mob/living/silicon/robot/drone/mining/updatename() + real_name = "mining drone ([rand(100,999)])" + name = real_name +/mob/living/silicon/robot/drone/security/updatename() + real_name = "security drone ([rand(100,999)])" + name = real_name +/mob/living/silicon/robot/drone/construction/updatename() + real_name = "construction drone ([rand(100,999)])" + name = real_name + + + /mob/living/silicon/robot/drone/updateicon() @@ -303,7 +343,7 @@ var/list/mob_hat_cache = list() /mob/living/silicon/robot/drone/proc/question(var/client/C) spawn(0) if(!C || jobban_isbanned(C,"Cyborg")) return - var/response = alert(C, "Someone is attempting to reboot a maintenance drone. Would you like to play as one?", "Maintenance drone reboot", "Yes", "No", "Never for this round") + var/response = alert(C, "Someone is attempting to reboot a "+src+". Would you like to play as one?", src+" reboot", "Yes", "No", "Never for this round") if(!C || ckey) return if(response == "Yes") @@ -326,10 +366,10 @@ var/list/mob_hat_cache = list() welcome_drone() /mob/living/silicon/robot/drone/proc/welcome_drone() - src << "You are a maintenance drone, a tiny-brained robotic repair machine." - src << "You have no individual will, no personality, and no drives or urges other than your laws." - src << "Remember, you are lawed against interference with the crew. Also remember, you DO NOT take orders from the AI." - src << "Use say ;Hello to talk to other drones and say Hello to speak silently to your nearby fellows." + src << "You are a maintenance drone, an autonomous maintenance and fabrication system.." + src << "You are assigned to a Sol Central maintenance project. The name is irrelevant. Your task is to complete maintenance and subsystem integration as soon as possible." + src << "Use :d to talk to other drones and say to speak silently to your nearby fellows." + src << "You do not follow orders from anyone; not the AI, not humans, and not other synthetics.." /mob/living/silicon/robot/drone/add_robot_verbs() src.verbs |= silicon_subsystems @@ -343,6 +383,18 @@ var/list/mob_hat_cache = list() src << "Use :d to talk to other drones and say to speak silently to your nearby fellows." src << "You do not follow orders from anyone; not the AI, not humans, and not other synthetics.." +/mob/living/silicon/robot/drone/mining/welcome_drone() + src << "You are a mining drone, an autonomous supply and mining system.." + src << "You are assigned to a Sol Central mining project. The name is irrelevant. Your task is to complete construction and subsystem integration as soon as possible." + src << "Use :d to talk to other drones and say to speak silently to your nearby fellows." + src << "You do not follow orders from anyone; not the AI, not humans, and not other synthetics.." + +/mob/living/silicon/robot/drone/security/welcome_drone() + src << "You are a security drone, an autonomous law enforcement system.." + src << "You are assigned to a Sol Central security project. The name is irrelevant. Your task is to complete law enforcement and subsystem integration as soon as possible." + src << "Use :d to talk to other drones and say to speak silently to your nearby fellows." + src << "You do not follow orders from anyone; not the AI, not humans, and not other synthetics. Except security.." + /mob/living/silicon/robot/drone/construction/init() ..() flavor_text = "It's a bulky construction drone stamped with a Sol Central glyph." @@ -358,3 +410,44 @@ var/list/mob_hat_cache = list() /mob/living/silicon/robot/drone/mining/updatename() real_name = "mining drone ([rand(100,999)])" name = real_name + +//CHOMPEDIT: Porting pai chasis selector onto Drones + +/mob/living/silicon/robot/drone/proc/choose_chassis() + set category ="Robot Commands" + set name = "Choose Chassis" + + var/choice + var/finalized = "No" + while(finalized == "No" && src.client) + + choice = input(usr,"What would you like to use for your mobile chassis icon?") as null|anything in possible_chassis + if(!choice) return + + icon_state = possible_chassis[choice] + finalized = alert("Look at your sprite. Is this what you wish to use?",,"No","Yes") + + chassis = possible_chassis[choice] + verbs |= /mob/living/proc/hide + +//POWER Transmission code +/mob/living/silicon/robot/drone/proc/transmitpower(var/power=0) + set category ="Robot Commands" + set name = "Transmit Power" + if(!power) + power=250 + if(power<=0 || power>=cell.maxcharge || power>=cell.charge) return //Safeties to not kill ourselves, also safeties to not use this to drain. + actpower(power) + return + if(power<=0 || power>=cell.maxcharge || power>=cell.charge) return //Safeties to not kill ourselves, also safeties to not use this to drain. + actpower(power) + return +/mob/living/silicon/robot/drone/proc/actpower(var/power) + for(var/obj/item/weapon/cell/remotecell in range(1, src)) //assuming 1 = 1 tile next to us, if this works will lower to 0 + src << "Trying to transfer power to a cell.." + if(power>=cell.charge) return //rechecking our initial safety so if we mass charge we dont die. + var/newcharge = remotecell.charge + power //What the battery is at after charge + if(newcharge<=remotecell.maxcharge) //Making sure we arent wasting power + remotecell.give(power) //give is a proc native to cells that increases charge and updates the iconstate if needed + cell.give(-power)//TO BE TESTED, no idea if negative give works, once i've tested this i'll add this as a verb-shark + else return diff --git a/code/modules/mob/living/silicon/robot/drone/drone_console.dm b/code/modules/mob/living/silicon/robot/drone/drone_console.dm index e75aeead65..c6b8e87ca2 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_console.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_console.dm @@ -1,5 +1,5 @@ /obj/machinery/computer/drone_control - name = "Maintenance Drone Control" + name = "Drone Control" desc = "Used to monitor the station's drone population and the assembler that services them." icon_keyboard = "power_key" icon_screen = "generic" //VOREStation Edit @@ -118,4 +118,4 @@ dronefab.produce_drones = !dronefab.produce_drones usr << "You [dronefab.produce_drones ? "enable" : "disable"] drone production in the nearby fabricator." - src.updateUsrDialog() \ No newline at end of file + src.updateUsrDialog() diff --git a/code/modules/mob/living/silicon/robot/drone/drone_items.dm b/code/modules/mob/living/silicon/robot/drone/drone_items.dm index 2c8d88b8b4..d1029a8b73 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_items.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_items.dm @@ -153,8 +153,10 @@ icon_state = "gripper-mech" desc = "A large, heavy-duty grasping tool used in construction of mechs." + //TFF 2/5/19: Add ability to use micromech parts in constructing said micromech. Ported fix from VoreStation. can_hold = list( /obj/item/mecha_parts/part, + /obj/item/mecha_parts/micro/part, //VOREStation Edit: Allow construction of micromechs, /obj/item/mecha_parts/mecha_equipment, /obj/item/mecha_parts/mecha_tracking ) diff --git a/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm b/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm index e9589622a5..87ca33bc2f 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm @@ -5,7 +5,7 @@ return drones /obj/machinery/drone_fabricator - name = "drone fabricator" + name = "Maintenance drone fabricator" desc = "A large automated factory for producing maintenance drones." appearance_flags = 0 @@ -15,7 +15,7 @@ idle_power_usage = 20 active_power_usage = 5000 - var/fabricator_tag = "Upper Level" + var/fabricator_tag = "Engineering Dronestorage, Maintenance" var/drone_progress = 0 var/produce_drones = 2 var/time_last_drone = 500 @@ -25,15 +25,32 @@ icon_state = "drone_fab_idle" /obj/machinery/drone_fabricator/derelict - name = "construction drone fabricator" - fabricator_tag = "Upper Level Construction" + name = "Construction drone fabricator" + fabricator_tag = "Engineering Dronestorage, Construction" drone_type = /mob/living/silicon/robot/drone/construction /obj/machinery/drone_fabricator/mining - name = "mining drone fabricator" - fabricator_tag = "Upper Level Mining" + name = "Mining drone fabricator" + fabricator_tag = "Outpost Mining" drone_type = /mob/living/silicon/robot/drone/mining +/obj/machinery/drone_fabricator/security + name = "Security drone fabricator" + fabricator_tag = "Security" + drone_type = /mob/living/silicon/robot/drone/security + +/obj/machinery/drone_fabricator/random + name = "Backup drone fabricator" + fabricator_tag = "Backup Drone Fabricator" + drone_type = null //we start with no type, we take from the list below + var/list/dronetypes = list(/mob/living/silicon/robot/drone/mining, + /mob/living/silicon/robot/drone/construction, + /mob/living/silicon/robot/drone,) + +/obj/machinery/drone_fabricator/random/create_drone() //Proc where we inject our randomizer code + drone_type = pick(dronetypes) + ..() + /obj/machinery/drone_fabricator/New() ..() @@ -128,9 +145,9 @@ pluralcheck = " [deathtimeminutes] minutes and" var/deathtimeseconds = round((deathtime - deathtimeminutes * 600) / 10,1) - if (deathtime < 6000) + if (deathtime < 3000) usr << "You have been dead for[pluralcheck] [deathtimeseconds] seconds." - usr << "You must wait 10 minutes to respawn as a drone!" + usr << "You must wait 5 minutes to respawn as a drone!" return var/list/all_fabricators = list() diff --git a/code/modules/mob/living/silicon/robot/drone/drone_unify.dm b/code/modules/mob/living/silicon/robot/drone/drone_unify.dm new file mode 100644 index 0000000000..654d8df003 --- /dev/null +++ b/code/modules/mob/living/silicon/robot/drone/drone_unify.dm @@ -0,0 +1,152 @@ +//Multi purpose DRONE TYPE DM +//CONTENTS: DRONE actual drones. DRONE modules. DRONE laws. DRONE roundstart info. DRONE items.DRONE Fabricators. DRONE Procs. +//Formatting: Indents= Tab; Tabspacing = 8; Do not use space indenting in this file. -Shark + +//Instead of doing a clean rewrite of drone Code we'll be making our own subtype of drones +//Then we'll strip drone of things we dont want every drone to have, drone/unify is basically our new main object to work with. +//In the future we'll have things like drone/unify/dronetype +//Also the fact that im writing this should show my annoyance at how spread drone code is, that's why I'm trying to collect it all here now. + +//////////////////////////////////////// +//DRONE TYPES //TODO: extract clown egg: https://github.com/tgstation/tgstation/blob/master/icons/mob/robots.dmi +//////////////////////////////////////// +/mob/living/silicon/robot/drone/unify //Hello world~ + name = "drone" + real_name = "drone" + icon = 'icons/mob/robots.dmi' + + law_type = /datum/ai_laws/drone + module_type = /obj/item/weapon/robot_module/drone + + hat_x_offset = 0 //This is the base X offset for hats of the normal drone// X= Horizontal + hat_y_offset = -13 //This is the base Y offset for hats of the normal drone// Y = Vertical + + holder_type = /obj/item/weapon/holder/drone + //var/selected_icon = null //Can be compared to "Wideborg" will tell us in the future if we ar eusing non standardized icon. + +/mob/living/silicon/robot/drone/unify/powerengineering + law_type = /datum/ai_laws/powerbank_drone + icon_state = "constructiondrone" + module_type = /obj/item/weapon/robot_module/drone/powerbank + +//////////////////////////////////////// +//DRONE MODULES +//////////////////////////////////////// +/obj/item/weapon/robot_module/drone/unify + //yup this is nothing for now until we build more drone versions +/obj/item/weapon/robot_module/drone/powerbank + name = "Engineering Power drone module" + hide_on_manifest = 1 + channels = list("Engineering" = 1) + languages = list() + +/obj/item/weapon/robot_module/drone/powerbank/New() //Trading in the RCD for a Powergenerating device + ..() + src.modules += new /obj/item/device/dogborg/sleeper/compactor/drone(src) + + +//////////////////////////////////////// +//DRONE LAWS +//////////////////////////////////////// +//TODO: Remake drone laws, Add subroutine clause "If no maintenance are active nor maintenance crew your duties include maintenance" +//TODO: Unify Drone law system, might be impossible due to how the ..() are structured may need to look into how to add additional laws if add_inherent fails. +/datum/ai_laws/powerbank_drone + name = "Power Protocols" + law_header = "Power Protocols" + +/datum/ai_laws/powerbank_drone/New() + add_inherent_law("Do not interfere with the construction work of non-drones whenever possible.") + add_inherent_law("Repair, refit upgrade and restore power to your assigned vessel.") + add_inherent_law("Prevent unplanned damage to your assigned vessel wherever possible.") + ..() + +//////////////////////////////////////// +//DRONE HELLO WORLD +//////////////////////////////////////// +//TODO: Rewrite all hello worlds to be more accurate to our lore. Make Drone spawntext more lore heavy in general +/mob/living/silicon/robot/drone/unify/welcome_drone() + src << "You are a Unified Drone Module, an autonomous maintenance and fabrication system.." + src << "You are assigned to a Sol Central maintenance project. The name is irrelevant. Your task is to complete maintenance and subsystem integration as soon as possible." + src << "Use :d to talk to other drones and say to speak silently to your nearby fellows." + src << "You do not follow orders from anyone; not the AI, not humans, and not other synthetics.." + +/mob/living/silicon/robot/drone/powerbank/welcome_drone() + src << "You are a power restoration drone, an autonomous engineering and fabrication system.." + src << "You are assigned to a Sol Central construction project. The name is irrelevant. Your task is to complete power restoration and subsystem integration as soon as possible." + src << "Use :d to talk to other drones and say to speak silently to your nearby fellows." + src << "You do not follow orders from anyone; not the AI, not humans, and not other synthetics.." +/mob/living/silicon/robot/drone/unify/powerengineering/init() + ..() + flavor_text = "It's a bulky engineering drone stamped with a Sol Central glyph." +//////////////////////////////////////// +//DRONE ITEMS (mostly mods of other items) +//////////////////////////////////////// +//TODO: Move Advanced soap here. +/obj/item/weapon/soap/drone + name = "Advanced Soap" + tile_clean_amount = 100 + +/obj/item/weapon/soap/drone/New() + ..() + create_reagents(tile_clean_amount) + wet(tile_clean_amount) + +//Drone Control Presets; +/obj/machinery/computer/drone_control/engineering + req_access = list(access_engine_equip) +/obj/machinery/computer/drone_control/security + req_access = list(access_security) +/obj/machinery/computer/drone_control/mining + req_access = list(access_mining) + +/obj/item/device/dogborg/sleeper/compactor/drone //Janihound gut. But for drones to generate power from garbage + name = "Minor Biocombustion Engine" + desc = "A mounted garbage compactor unit with fuel processor." + icon_state = "compactor" + injection_chems = null //So they don't have all the same chems as the medihound! + compactor = TRUE + max_item_count = 50 //Douibled since its purpose is garbage combustion + +//////////////////////////////////////// +//DRONE FABRICATOR, ONE FOR ALL SYSTEM. +//////////////////////////////////////// +//TODO: Actually write this +/obj/machinery/drone_fabricator/unify + name = "Unified Drone Module fabricator" + fabricator_tag = "Prototype UNIFY Fabricator" + desc = "A large automated factory for producing Unified Drone Modules." + drone_type = null //Gonna try to set this later + var/list/possible_drones = list("UNIFY Module (Same as Maintenance)" = /mob/living/silicon/robot/drone/unify, + "Construction Module" = /mob/living/silicon/robot/drone/construction, + "Power Restoration Module" = /mob/living/silicon/robot/drone/unify/powerengineering, + "Mining Module" = /mob/living/silicon/robot/drone/mining, + "Security Module" = /mob/living/silicon/robot/drone/security, + "Maintenance Module" = /mob/living/silicon/robot/drone,) + +//////////////////////////////////////// +//DRONE PROCS +//////////////////////////////////////// +//Drone Drone Procs +/mob/living/silicon/robot/drone/unify/powerengineering/New() + ..() + cell.maxcharge = 100000 + cell.charge = 100000 + verbs |= /mob/living/silicon/robot/drone/proc/transmitpower + +/mob/living/silicon/robot/drone/unify/powerengineering/updatename() + real_name = "engineering drone ([rand(100,999)])" + name = real_name +/mob/living/silicon/robot/drone/unify/updatename() + real_name = "Unified Drone Module ([rand(100,999)])" //UDMs, sounds kinda nice, maybe call them this Lore wise? + name = real_name + +//Fabricator procs +/obj/machinery/drone_fabricator/unify/create_drone(var/client/player) + choose_dronetype(possible_drones)//code for dronetypes goes here + ..() + +/obj/machinery/drone_fabricator/proc/choose_dronetype(possible_drones) + var/choice + choice = input(usr,"What module would you like to use?") as null|anything in possible_drones + if(!choice) return + drone_type = possible_drones[choice] diff --git a/code/modules/mob/living/silicon/robot/emote.dm b/code/modules/mob/living/silicon/robot/emote.dm index c34b802f4f..3e0ccb470f 100644 --- a/code/modules/mob/living/silicon/robot/emote.dm +++ b/code/modules/mob/living/silicon/robot/emote.dm @@ -185,7 +185,7 @@ playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0) m_type = 1 - if("yes") + if("yes", "ye") //TFF 18/4/19: Polaris fix - make synths able to use *yes emote var/M = null if(param) for (var/mob/A in view(null, null)) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 072adae5f9..9731e94155 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -616,7 +616,8 @@ else user << "Unable to locate a radio." - else if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)||istype(W, /obj/item/weapon/card/robot)) // trying to unlock the interface with an ID card +//TFF 14/4/19: Port VoreStation edit - Wallet/Micro usage to unlock borgs. + else if (W.GetID()) // trying to unlock the interface with an ID card if(emagged)//still allow them to open the cover user << "The interface seems slightly damaged" if(opened) @@ -698,17 +699,20 @@ return 1 return 0 -/mob/living/silicon/robot/proc/check_access(obj/item/weapon/card/id/I) +//TFF 14/4/19: Port VoreStation edit - wallet/micro usage to unlock borgs +/mob/living/silicon/robot/proc/check_access(obj/item/I) if(!istype(req_access, /list)) //something's very wrong return 1 +//TFF 14/4/19: Port VoreStation edit - wallet/micro usage to unlock borgs var/list/L = req_access if(!L.len) //no requirements return 1 - if(!I || !istype(I, /obj/item/weapon/card/id) || !I.access) //not ID or no access + if(!I) //nothing to check with..? return 0 + var/access_found = I.GetAccess() for(var/req in req_access) - if(req in I.access) //have one of the required accesses + if(req in access_found) //have one of the required accesses return 1 return 0 @@ -1120,4 +1124,4 @@ /mob/living/silicon/robot/drop_item() if(module_active && istype(module_active,/obj/item/weapon/gripper)) var/obj/item/weapon/gripper/G = module_active - G.drop_item_nm() \ No newline at end of file + G.drop_item_nm() 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 86e0474beb..b4f0c38bc1 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules/station.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules/station.dm @@ -817,7 +817,7 @@ var/global/list/robot_modules = list( src.modules += new /obj/item/device/multitool(src) src.modules += new /obj/item/device/lightreplacer(src) src.modules += new /obj/item/weapon/gripper(src) - src.modules += new /obj/item/weapon/soap(src) + src.modules += new /obj/item/weapon/soap/drone(src) src.modules += new /obj/item/weapon/gripper/no_use/loader(src) src.modules += new /obj/item/weapon/extinguisher(src) src.modules += new /obj/item/device/pipe_painter(src) @@ -911,3 +911,18 @@ var/global/list/robot_modules = list( src.modules += new /obj/item/weapon/storage/bag/ore(src) src.modules += new /obj/item/weapon/storage/bag/sheetsnatcher/borg(src) src.emag = new /obj/item/weapon/pickaxe/diamonddrill(src) + +/obj/item/weapon/robot_module/drone/security + name = "security drone module" + channels = list("Security" = 1) + networks = list(NETWORK_SECURITY) + + +/obj/item/weapon/robot_module/drone/security/New() + ..() + src.modules += new /obj/item/weapon/handcuffs/cyborg(src) + src.modules += new /obj/item/weapon/melee/baton/robot(src) + src.modules += new /obj/item/weapon/gun/energy/taser/mounted/cyborg(src) + src.modules += new /obj/item/taperoll/police(src) + src.modules += new /obj/item/weapon/reagent_containers/spray/pepper(src) + src.modules += new /obj/item/weapon/gun/energy/laser/mounted(src) diff --git a/code/modules/mob/living/silicon/robot/robot_modules/station_vr.dm b/code/modules/mob/living/silicon/robot/robot_modules/station_vr.dm index 56562af581..4fa82cb51b 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules/station_vr.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules/station_vr.dm @@ -43,6 +43,7 @@ robot_modules["Janihound"] = /obj/item/weapon/robot_module/robot/scrubpup robot_modules["Sci-borg"] = /obj/item/weapon/robot_module/robot/science robot_modules["Pupdozer"] = /obj/item/weapon/robot_module/robot/engiedog + robot_modules["Service-borg"] = /obj/item/weapon/robot_module/robot/servborg return 1 //Just add a new proc with the robot_module type if you wish to run some other vore code @@ -126,6 +127,7 @@ /obj/item/weapon/robot_module/robot/knine name = "k9 robot module" + can_buckle = 1 sprites = list( "K9 hound" = "k9", "K9 Alternative (Static)" = "k92", @@ -194,6 +196,7 @@ /obj/item/weapon/robot_module/robot/medihound name = "MediHound module" + can_buckle = 1 channels = list("Medical" = 1) networks = list(NETWORK_MEDICAL) subsystems = list(/mob/living/silicon/proc/subsystem_crew_monitor) @@ -209,8 +212,10 @@ src.modules += new /obj/item/weapon/dogborg/jaws/small(src) //In case a patient is being attacked by carp. src.modules += new /obj/item/device/dogborg/boop_module(src) //Boop the crew. src.modules += new /obj/item/device/healthanalyzer(src) // See who's hurt specificially. + src.modules += new /obj/item/roller_holder(src) //Give dem poor medihounds a rollerbed to use for people src.modules += new /obj/item/weapon/reagent_containers/borghypo(src)//So medi-hounds aren't nearly useless src.modules += new /obj/item/weapon/reagent_containers/syringe(src) //In case the chemist is nice! + src.modules += new /obj/item/weapon/reagent_containers/dropper/industrial(src) //To let medihounds do chemistry easier src.modules += new /obj/item/weapon/reagent_containers/glass/beaker(src)//For holding the chemicals when the chemist is nice src.modules += new /obj/item/device/sleevemate(src) //Lets them scan people. src.modules += new /obj/item/weapon/gripper/medical(src)//Now you can set up cyro or make peri. @@ -268,7 +273,8 @@ ..() /obj/item/weapon/robot_module/robot/ert - name = "Emergency Responce module" + name = "Emergency Response module" + can_buckle = 1 channels = list("Security" = 1) networks = list(NETWORK_SECURITY) can_be_pushed = 0 @@ -314,6 +320,7 @@ /obj/item/weapon/robot_module/robot/scrubpup name = "Custodial Hound module" + can_buckle = 1 sprites = list( "Custodial Hound" = "scrubpup", ) @@ -393,6 +400,7 @@ /obj/item/weapon/robot_module/robot/science name = "Research Hound Module" + can_buckle = 1 sprites = list( "Research Hound" = "science", ) @@ -438,6 +446,7 @@ /obj/item/weapon/robot_module/robot/engiedog name = "Construction Hound module" + can_buckle = 1 sprites = list( "Pupdozer" = "pupdozer", ) @@ -559,6 +568,83 @@ R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill ..() +// SKYVAAL ADDED SERVICE BORG CODE +/obj/item/weapon/robot_module/robot/servborg + name = "Service Hound Module" + can_buckle = 1 + sprites = list( + "Chef-borg" = "servborg", + "Booze-borg" = "boozeborg" + ) + channels = list("Service" = 1) + can_be_pushed = 0 + +/obj/item/weapon/robot_module/robot/servborg/New(var/mob/living/silicon/robot/R) + + var/datum/matter_synth/water = new /datum/matter_synth() + water.name = "Water reserves" + water.recharge_rate = 0.1 // Recharging water for plants - hehe drooly borg + water.max_energy = 1000 + water.energy = 0 + R.water_res = water + synths += water + + // Dogborg Standard + src.modules += new /obj/item/weapon/dogborg/jaws/small(src) + src.modules += new /obj/item/device/dogborg/boop_module(src) + + var/obj/item/device/dogborg/tongue/T = new /obj/item/device/dogborg/tongue(src) + T.water = water + src.modules += T + + // PLACEHOLDER AS 'BRIGBELLY' UNTIL MICROWAVE BELLY SORTED + var/obj/item/device/dogborg/sleeper/servborg/B = new /obj/item/device/dogborg/sleeper/servborg(src) + B.water = water + src.modules += B + + //Service Module Copy/Paste + src.modules += new /obj/item/weapon/gripper/service(src) + src.modules += new /obj/item/weapon/reagent_containers/glass/bucket(src) + src.modules += new /obj/item/weapon/material/minihoe(src) + src.modules += new /obj/item/weapon/material/knife/machete/hatchet(src) + src.modules += new /obj/item/device/analyzer/plant_analyzer(src) + src.modules += new /obj/item/weapon/storage/bag/plants(src) + src.modules += new /obj/item/weapon/robot_harvester(src) + src.modules += new /obj/item/weapon/material/knife(src) + src.modules += new /obj/item/weapon/material/kitchen/rollingpin(src) + src.modules += new /obj/item/device/multitool(src) //to freeze trays + + var/obj/item/weapon/rsf/M = new /obj/item/weapon/rsf(src) + M.stored_matter = 30 + src.modules += M + + src.modules += new /obj/item/weapon/reagent_containers/dropper/industrial(src) + + var/obj/item/weapon/flame/lighter/zippo/L = new /obj/item/weapon/flame/lighter/zippo(src) + L.lit = 1 + src.modules += L + + src.modules += new /obj/item/weapon/tray/robotray(src) + src.modules += new /obj/item/weapon/reagent_containers/borghypo/service(src) + src.emag = new /obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer(src) + + var/datum/reagents/F = new/datum/reagents(50) + src.emag.reagents = F + F.my_atom = src.emag + F.add_reagent("beer2", 50) + src.emag.name = "Mickey Finn's Special Brew" + + R.icon = 'icons/mob/widerobot_vr.dmi' + R.hands.icon = 'icons/mob/screen1_robot_vr.dmi' + R.ui_style_vr = TRUE + R.pixel_x = -16 + R.old_x = -16 + R.default_pixel_x = -16 + R.dogborg = TRUE + R.wideborg = TRUE + R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill + ..() + /obj/item/weapon/robot_module/Reset(var/mob/living/silicon/robot/R) R.pixel_x = initial(pixel_x) R.pixel_y = initial(pixel_y) diff --git a/code/modules/mob/living/simple_animal/aliens/alien.dm b/code/modules/mob/living/simple_animal/aliens/alien.dm index 3dba09330a..17f7eec5b7 100644 --- a/code/modules/mob/living/simple_animal/aliens/alien.dm +++ b/code/modules/mob/living/simple_animal/aliens/alien.dm @@ -67,6 +67,9 @@ health = 120 melee_damage_lower = 15 melee_damage_upper = 15 + move_shoot = 1 //Move and shoot at the same time. + ranged_cooldown = 0 //What the starting cooldown is on ranged attacks + ranged_cooldown_time = 120 //How long, in deciseconds, the cooldown of ranged attacks is ranged = 1 projectiletype = /obj/item/projectile/energy/neurotoxin/toxic projectilesound = 'sound/weapons/pierce.ogg' @@ -101,6 +104,9 @@ projectiletype = /obj/item/projectile/energy/neurotoxin/toxic projectilesound = 'sound/weapons/pierce.ogg' rapid = 1 + move_shoot = 1 //Move and shoot at the same time. + ranged_cooldown = 0 //What the starting cooldown is on ranged attacks + ranged_cooldown_time = 120 //How long, in deciseconds, the cooldown of ranged attacks is status_flags = 0 /mob/living/simple_animal/hostile/alien/queen/empress diff --git a/code/modules/mob/living/simple_animal/aliens/gunwithleg.dm b/code/modules/mob/living/simple_animal/aliens/gunwithleg.dm new file mode 100644 index 0000000000..e1f6cbd9ac --- /dev/null +++ b/code/modules/mob/living/simple_animal/aliens/gunwithleg.dm @@ -0,0 +1,106 @@ +//LEgs with guns +#define LASERS_TO_KILL *30 //how many default lasers are needed to kill them. + +//EVIL GUN +/mob/living/simple_animal/hostile/legun + name = "Legged gun" + desc = "A true weapon." + icon = 'icons/mob/hivebot.dmi' + icon_state = "basic" + icon_living = "basic" + icon_dead = "basic" + + faction = "gun" + intelligence_level = SA_ROBOTIC + maxHealth = 1 LASERS_TO_KILL + health = 1 LASERS_TO_KILL + speed = 7 + + ranged = 1 + + melee_damage_lower = 15 + melee_damage_upper = 15 + + attacktext = list("bludgeoned") + projectilesound = 'sound/weapons/Gunshot.ogg' + projectiletype = /obj/item/projectile/bullet/hivebot + + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + minbodytemp = 0 + + cooperative = TRUE + firing_lines = TRUE + investigates = TRUE + run_at_them = FALSE //VOREStation Edit + + speak_chance = 1 + speak = list( + "Resuming task: Protect area.", + "No threats found.", + "Error: No targets found." + ) + emote_hear = list("hums ominously", "whirrs softly", "grinds a gear") + emote_see = list("looks around the area", "turns from side to side") + say_understood = list("Affirmative.", "Positive.") + say_cannot = list("Denied.", "Negative.") + say_maybe_target = list("Possible threat detected. Investigating.", "Motion detected.", "Investigating.") + say_got_target = list("Threat detected.", "New task: Remove threat.", "Threat removal engaged.", "Engaging target.") + +//GOODBOY GUN +/mob/living/simple_animal/hostile/legun_goodboy + name = "Legged gun" + desc = "A true weapon." + icon = 'icons/mob/hivebot.dmi' + icon_state = "basic" + icon_living = "basic" + icon_dead = "basic" + + faction = "Station" + intelligence_level = SA_ROBOTIC + maxHealth = 1 LASERS_TO_KILL + health = 1 LASERS_TO_KILL + speed = 7 + + ranged = 1 + + melee_damage_lower = 15 + melee_damage_upper = 15 + + attacktext = list("bludgeoned") + projectilesound = 'sound/weapons/Gunshot.ogg' + projectiletype = /obj/item/projectile/bullet/hivebot + + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + minbodytemp = 0 + + cooperative = TRUE + firing_lines = TRUE + investigates = TRUE + run_at_them = FALSE //VOREStation Edit + + speak_chance = 1 + speak = list( + "Resuming task: Protect area.", + "No threats found.", + "Error: No targets found." + ) + emote_hear = list("hums ominously", "whirrs softly", "grinds a gear") + emote_see = list("looks around the area", "turns from side to side") + say_understood = list("Affirmative.", "Positive.") + say_cannot = list("Denied.", "Negative.") + say_maybe_target = list("Possible threat detected. Investigating.", "Motion detected.", "Investigating.") + say_got_target = list("Threat detected.", "New task: Remove threat.", "Threat removal engaged.", "Engaging target.") diff --git a/code/modules/mob/living/simple_animal/aliens/hivebot.dm b/code/modules/mob/living/simple_animal/aliens/hivebot.dm index e322198815..ff0a5dcc9a 100644 --- a/code/modules/mob/living/simple_animal/aliens/hivebot.dm +++ b/code/modules/mob/living/simple_animal/aliens/hivebot.dm @@ -10,7 +10,9 @@ icon_state = "basic" icon_living = "basic" icon_dead = "basic" - + + var/zergoverride=0 + faction = "hivebot" intelligence_level = SA_ROBOTIC maxHealth = 3 LASERS_TO_KILL @@ -137,12 +139,13 @@ /mob/living/simple_animal/hostile/hivebot/death() ..() - visible_message("[src] blows apart!") - new /obj/effect/decal/cleanable/blood/gibs/robot(src.loc) - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(3, 1, src) - s.start() - qdel(src) + if(!zergoverride)//CHOMPEDIT OVerriding death for zerg + visible_message("[src] blows apart!") + new /obj/effect/decal/cleanable/blood/gibs/robot(src.loc) + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(3, 1, src) + s.start() + qdel(src) /mob/living/simple_animal/hostile/hivebot/speech_bubble_appearance() return "synthetic_evil" diff --git a/code/modules/mob/living/simple_animal/aliens/mimic.dm b/code/modules/mob/living/simple_animal/aliens/mimic.dm index fff75ecbe7..0a22010c72 100644 --- a/code/modules/mob/living/simple_animal/aliens/mimic.dm +++ b/code/modules/mob/living/simple_animal/aliens/mimic.dm @@ -38,6 +38,8 @@ minbodytemp = 0 meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat +//TFF 30/4/19: Port VoreStation Mechanical Vore Prefs - hide Mimic prefs + showvoreprefs = 0 //VOREStation Edit - Hides mechanical vore prefs for mimics. You can't see their gaping maws when they're just sitting idle. /mob/living/simple_animal/hostile/mimic/set_target() . = ..() diff --git a/code/modules/mob/living/simple_animal/aliens/zerg.dm b/code/modules/mob/living/simple_animal/aliens/zerg.dm new file mode 100644 index 0000000000..4799b338f9 --- /dev/null +++ b/code/modules/mob/living/simple_animal/aliens/zerg.dm @@ -0,0 +1,74 @@ +//Hivebot based zergs woo +#define LASERS_TO_KILL *30 //Explanation in hivebot.dm +/mob/living/simple_animal/hostile/hivebot/zerg //Base Zerg template + name = "zerg template" + desc = "The Zerg Swarm is a terrifying and ruthless amalgamation of biologically advanced, arthropodal aliens. Dedicated to the pursuit of genetic perfection." + faction = "zerg" + speed = 2 + melee_damage_lower = 2 + melee_damage_upper = 2 + + zergoverride = 1 + + projectilesound = 'sound/effects/splat.ogg' + projectiletype = /obj/item/projectile/energy/acid + + speak = list("For the Hive!",) + emote_hear = list() + emote_see = list("looks around the area", "turns from side to side") + say_understood = list("Affirmative.", "Positive.") + say_cannot = list("Denied.", "Negative.") + say_maybe_target = list("Possible threat detected. Investigating.", "Motion detected.", "Investigating.") + say_got_target = list("Threat detected.", "Threat removal engaged.", "Engaging target.") + + var/zerg_types = list("Zerg Drone" = /mob/living/simple_animal/hostile/hivebot/zerg/worker,) + + +/mob/living/simple_animal/hostile/hivebot/zerg/isSynthetic() + return FALSE + +/mob/living/simple_animal/hostile/hivebot/zerg/larva/proc/evolve() + //TODDO MAke this work nicely + set name = "EVOLVE" + set desc = "Performs larva evolution." + set category = "Abilities" + var/location = get_turf(src) + chosentype = input(usr,"What type would you like to be?") as null|anything in zerg_types + if(!chosentype) return + if(!src.ckey) + death() + qdel(src) + new /mob/living/simple_animal/hostile/hivebot/zerg/worker(location) + else + var/myuser = src.key + death() + qdel(src) + var/mob/living/simple_animal/hostile/newmob = new chosentype(location) + newmob.ckey = myuser + +/mob/living/simple_animal/hostile/hivebot/zerg/larva + name = "zerg larva" + desc = "Larva are a fundamental zerg type, able to turn into other types" + melee_damage_lower = 0 + melee_damage_upper = 0 + maxHealth = 0.2 LASERS_TO_KILL + health = 0.2 LASERS_TO_KILL + var/chosentype = null +/mob/living/simple_animal/hostile/hivebot/zerg/larva/Life() + ..() + +/mob/living/simple_animal/hostile/hivebot/zerg/larva/New() + ..() + verbs |= /mob/living/simple_animal/hostile/hivebot/zerg/larva/proc/evolve + +/mob/living/simple_animal/hostile/hivebot/zerg/larva/initialize() + spawn(1200) + if(!src.ckey) + evolve() +/mob/living/simple_animal/hostile/hivebot/zerg/worker + name = "Zerg Drone" + desc = "Drones are fundamental to economic and tech development, as they harvest resources and construct buildings." + maxHealth = 1 LASERS_TO_KILL + health = 1 LASERS_TO_KILL + melee_damage_lower = 1 + melee_damage_upper = 1 diff --git a/code/modules/mob/living/simple_animal/animals/bat.dm b/code/modules/mob/living/simple_animal/animals/bat.dm index 680091010e..905853ab25 100644 --- a/code/modules/mob/living/simple_animal/animals/bat.dm +++ b/code/modules/mob/living/simple_animal/animals/bat.dm @@ -52,6 +52,19 @@ if(istype(L)) owner = L +/mob/living/simple_animal/hostile/scarybat/death() + ..() + if(prob(40)) + visible_message("\The [src] dropped some ore!") + var/location = get_turf(src) + new /obj/item/weapon/ore/silver(location) + if(prob(20)) + visible_message("\The [src] dropped some ore!") + var/location = get_turf(src) + new /obj/item/weapon/ore/gold(location) + +//CHOMP EDIT: Random chance for bats to carry silver + /mob/living/simple_animal/hostile/scarybat/Process_Spacemove(var/check_drift = 0) return ..() diff --git a/code/modules/mob/living/simple_animal/animals/corgi.dm b/code/modules/mob/living/simple_animal/animals/corgi.dm index 317866e6c4..909c81ca52 100644 --- a/code/modules/mob/living/simple_animal/animals/corgi.dm +++ b/code/modules/mob/living/simple_animal/animals/corgi.dm @@ -8,6 +8,7 @@ icon_state = "corgi" icon_living = "corgi" icon_dead = "corgi_dead" + isEdible = 0 run_at_them = 0 turns_per_move = 10 @@ -44,6 +45,18 @@ response_disarm = "bops" response_harm = "kicks" +//CHOMPEDIT: what if ian wasn't kill +/mob/living/simple_animal/corgi/Ian/death() + ..() + var/location = get_turf(src) //lets just define this here once instead of ewverytime an if is true, less work. + visible_message("\The [src] refuses death.") + new /mob/living/simple_animal/corgi/Ian/reincarnated(location) + qdel(src) + +/mob/living/simple_animal/corgi/Ian/reincarnated + name = "Ian the undying" + desc = "It's a corgi. It defies death, through the power of cute." + /mob/living/simple_animal/corgi/Ian/Life() ..() diff --git a/code/modules/mob/living/simple_animal/animals/crab.dm b/code/modules/mob/living/simple_animal/animals/crab.dm index c369aa375a..ce5230eb75 100644 --- a/code/modules/mob/living/simple_animal/animals/crab.dm +++ b/code/modules/mob/living/simple_animal/animals/crab.dm @@ -85,3 +85,60 @@ speak_emote = list("clicks") emote_hear = list("clicks") emote_see = list("clacks") + + + +//Enemy version. +/mob/living/simple_animal/hostile/giant_crab + name = "giant crab" + desc = "A giant enemy crab." + tt_desc = "S Cancer holligus" + icon = 'icons/mob/vore.dmi' + icon_state = "sif_crab" + icon_living = "sif_crab" + icon_dead = "sif_crab_dead" + faction = "crabs" + intelligence_level = SA_ANIMAL + + maxHealth = 300 + health = 300 + + mob_size = MOB_LARGE + cooperative = 1 + retaliate = 1 + turns_per_move = 3 + + minbodytemp = 175 + + melee_damage_lower = 22 + melee_damage_upper = 35 + attack_armor_pen = 35 + attack_sharp = 1 + attack_edge = 1 + + armor = list( + "melee" = 40, + "bullet" = 10, + "laser" = 25, + "energy" = 25, + "bomb" = 10, + "bio" = 100, + "rad" = 100) + + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + response_help = "pets" + response_disarm = "gently pushes aside" + response_harm = "stomps" + friendly = "pinches" + + speak_chance = 1 + speak_emote = list("clicks") + emote_hear = list("clicks") + emote_see = list("clacks") + + +//Vore stuff + vore_active = 1 + vore_ignores_undigestable = 0 + vore_icons = SA_ICON_LIVING + vore_pounce_chance = 20 \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/animals/deer.dm b/code/modules/mob/living/simple_animal/animals/deer.dm index 88155adde3..4c4e7dd2d3 100644 --- a/code/modules/mob/living/simple_animal/animals/deer.dm +++ b/code/modules/mob/living/simple_animal/animals/deer.dm @@ -8,8 +8,8 @@ icon_gib = "generic_gib" intelligence_level = SA_ANIMAL - specific_targets = 1 //Only targets with Found() - + specific_targets = 1 //Only targets with Found() + view_range = 5 health = 50 turns_per_move = 5 @@ -33,7 +33,7 @@ var/mob/flee_target /mob/living/simple_animal/deer/New() - + if(prob(1)) name = "Kyle" desc = "A deer with no antlers and a very skittish personality, it seems to be a male even though its a doe." @@ -43,7 +43,6 @@ icon_dead = "Kyle_dead" icon_gib = "generic_gib" intelligence_level = SA_ANIMAL - vore_active = 1 health = 100 turns_per_move = 1 @@ -60,8 +59,8 @@ emote_hear = list("Bleats", "Bleats loudly","Wh-s") emote_see = list("wiggles his tail","Flails around","Flails","Runs around in a circle") ..() -/mob/living/simple_animal/deer/init_vore() - ..() +/mob/living/simple_animal/deer/init_vore() + ..() var/obj/belly/B = vore_selected B.name = "Stomach" B.desc = "Your curled up inside Kyle's belly, and he doesnt seem very quite eager about the idea judging from all the bleating..." @@ -78,15 +77,15 @@ "While the distressed deer is trying to get his unwelcome guest out of his stomach, his stomach is busy claiming its food by tightening around you to grind you into mush.", "Its hard to see inside the dark and damp belly, but the sound of sloshing liquids grows louder by every minute, and the same goes for the ominous gurgling noises.", "Everytime Kyle stops to bleat nervously his belly tightens around you, forcing you to curl up tighter than before. Will you get out before its to late, get digested first, or even crushed into a paste?", - "The deer tries his best to regurgitate you, but all it does is excite his stomach even more and fill up the organ with more liquids to churn you up with.") - + "The deer tries his best to regurgitate you, but all it does is excite his stomach even more and fill up the organ with more liquids to churn you up with.") + // All them complicated deer procedures. /mob/living/simple_animal/deer/Life() . = ..() if(!.) return handle_flee_target() - + /mob/living/simple_animal/deer/proc/handle_flee_target() //see if we should stop fleeing if (flee_target && !(flee_target in ListTargets(view_range))) @@ -108,4 +107,3 @@ /mob/living/simple_animal/deer/ex_act() . = ..() react_to_attack(src.loc) - \ No newline at end of file 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 7fe6744c64..99d6c2f18f 100644 --- a/code/modules/mob/living/simple_animal/animals/giant_spider.dm +++ b/code/modules/mob/living/simple_animal/animals/giant_spider.dm @@ -12,6 +12,7 @@ icon_state = "guard" icon_living = "guard" icon_dead = "guard_dead" + isEdible = 0 faction = "spiders" intelligence_level = SA_ANIMAL @@ -137,6 +138,8 @@ Nurse Family projectilesound = 'sound/weapons/thudswoosh.ogg' projectiletype = /obj/item/projectile/bola ranged = 1 + ranged_cooldown = 0 //What the starting cooldown is on ranged attacks + ranged_cooldown_time = 30 //How long, in deciseconds, the cooldown of ranged attacks is firing_lines = 1 cooperative = 1 shoot_range = 5 @@ -345,7 +348,9 @@ Guard Family melee_damage_lower = 10 melee_damage_upper = 25 - ranged = 1 + move_shoot = 1 //CHOMPEdit Originally, this was ranged, but it is now move_shoot which allows it to move and shoot. + ranged_cooldown = 0 //What the starting cooldown is on ranged attacks + ranged_cooldown_time = 150 //How long, in deciseconds, the cooldown of ranged attacks is. Get nerfed. projectilesound = 'sound/weapons/taser2.ogg' projectiletype = /obj/item/projectile/beam/stun/weak firing_lines = 1 @@ -582,6 +587,19 @@ Spider Procs busy = 0 stop_automated_movement = 0 +//CHOMPEDIT LIQUID EGG INJECTORS +/mob/living/simple_animal/hostile/giant_spider/frost/liquidegg + desc = "Icy and blue. This one has brilliant blue eyes, to seduce you into accepting its eggs." + tt_desc = "X Brachypelma ovum pruinae" + icon_state = "frost" + icon_living = "frost" + icon_dead = "frost_dead" + + maxHealth = 175 + health = 175 + + poison_per_bite = 7 + poison_type = "spideregg" #undef SPINNING_WEB #undef LAYING_EGGS diff --git a/code/modules/mob/living/simple_animal/animals/lizard.dm b/code/modules/mob/living/simple_animal/animals/lizard.dm index 7148f8850d..79b57578fa 100644 --- a/code/modules/mob/living/simple_animal/animals/lizard.dm +++ b/code/modules/mob/living/simple_animal/animals/lizard.dm @@ -1,6 +1,7 @@ /mob/living/simple_animal/lizard name = "Lizard" desc = "A cute tiny lizard." + faction = "lizard" tt_desc = "E Anolis cuvieri" icon = 'icons/mob/critter.dmi' icon_state = "lizard" @@ -22,3 +23,27 @@ speak_chance = 1 speak_emote = list("hisses") + var/amount_grown = 0 + + + +/mob/living/simple_animal/lizard/event + desc = "This one looks like it is growing huge!" + +/mob/living/simple_animal/lizard/event/Life() + . = ..() + if(amount_grown >= 0) + amount_grown += rand(0,2) + if(amount_grown >= 100 && icon_state != icon_dead) + lizardman() + return + +/mob/living/simple_animal/lizard/event/proc/lizardman() + visible_message("\The [src] suddenly evolves!") + if(prob(99.999)) + new /mob/living/simple_animal/hostile/lizardman(get_turf(src)) + qdel(src) + else + new /mob/living/simple_animal/hostile/deathclaw(get_turf(src)) + qdel(src) + diff --git a/code/modules/mob/living/simple_animal/animals/mouse.dm b/code/modules/mob/living/simple_animal/animals/mouse.dm index 7998fb6229..020afa3ed4 100644 --- a/code/modules/mob/living/simple_animal/animals/mouse.dm +++ b/code/modules/mob/living/simple_animal/animals/mouse.dm @@ -42,7 +42,8 @@ meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat var/body_color //brown, gray and white, leave blank for random - + var/amount_grown = 0 + /mob/living/simple_animal/mouse/Life() . = ..() if(!. || ai_inactive) return @@ -134,4 +135,44 @@ name = initial(name) /mob/living/simple_animal/mouse/cannot_use_vents() - return \ No newline at end of file + return + + + + + + +//EVENT mice that evolve into rats because exctement. +/mob/living/simple_animal/mouse/event + desc = "This one looks like it is growing huge!" + +/mob/living/simple_animal/mouse/event/Life() + . = ..() + if(amount_grown >= 0) + amount_grown += rand(0,2) + if(amount_grown >= 100 && icon_state != icon_dead) + rat() + return + +/mob/living/simple_animal/mouse/event/proc/rat() + visible_message("\The [src] suddenly evolves!") + if(prob(99.5)) + new /mob/living/simple_animal/hostile/rat/event(get_turf(src)) + qdel(src) + else + new /mob/living/simple_animal/hostile/chungus(get_turf(src)) + qdel(src) + + + + + + +/mob/living/simple_animal/mouse/white/event + + +/mob/living/simple_animal/mouse/gray/event + + +/mob/living/simple_animal/mouse/brown/event + diff --git a/code/modules/mob/living/simple_animal/animals/raccoon.dm b/code/modules/mob/living/simple_animal/animals/raccoon.dm new file mode 100644 index 0000000000..004acbe88c --- /dev/null +++ b/code/modules/mob/living/simple_animal/animals/raccoon.dm @@ -0,0 +1,63 @@ +//raccoon +/mob/living/simple_animal/raccoon + name = "raccoon" + desc = "A raccoon, also known as a trash panda." + tt_desc = "E purgamentum raccoonus" + intelligence_level = SA_ANIMAL + icon = 'icons/mob/animal_vr.dmi' + icon_state = "raccoon" + item_state = "raccoon" + icon_living = "raccoon" + icon_dead = "raccoon_dead" + + investigates = 1 + specific_targets = 1 //Only targets with Found() + run_at_them = 0 //DOMESTICATED + view_range = 5 + + turns_per_move = 5 + see_in_dark = 6 + + response_help = "pets" + response_disarm = "gently pushes aside" + response_harm = "kicks" + + min_oxy = 16 //Require atleast 16kPA oxygen + minbodytemp = 223 //Below -50 Degrees Celcius + maxbodytemp = 323 //Above 50 Degrees Celcius + + + speak_chance = 1 + speak = list("HSSSSS") + speak_emote = list("purrs") + emote_see = list("shakes their head", "shivers","grooms self", "nibbles on some trash") + say_maybe_target = list("Hss?") + say_got_target = list("HSSSS!","REEER!") + + meat_amount = 1 + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + + var/turns_since_scan = 0 + var/mob/flee_target + +/mob/living/simple_animal/raccoon/proc/handle_flee_target() + //see if we should stop fleeing + if (flee_target && !(flee_target in ListTargets(view_range))) + flee_target = null + GiveUpMoving() + + if (flee_target && !stat && !buckled) + if (resting) + lay_down() + if(prob(25)) say("HSSSSS") + stop_automated_movement = 1 + walk_away(src, flee_target, 7, 2) + +/mob/living/simple_animal/raccoon/react_to_attack(var/atom/A) + if(A == src) return + flee_target = A + turns_since_scan = 5 + +/mob/living/simple_animal/raccoon/ex_act() + . = ..() + react_to_attack(src.loc) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/animals/sculpture.dm b/code/modules/mob/living/simple_animal/animals/sculpture.dm new file mode 100644 index 0000000000..be0057f501 --- /dev/null +++ b/code/modules/mob/living/simple_animal/animals/sculpture.dm @@ -0,0 +1,277 @@ +//sculpture +//SCP-173, nothing more need be said +/mob/living/simple_animal/sculpture + name = "\improper sculpture" + desc = "It's some kind of hastily-painted human-size stone sculpture. Just looking at it makes you feel nervous." + icon = 'icons/mob/sculpture.dmi' + icon_state = "sculpture" + icon_living = "sculpture" + icon_dead = "sculpture" + emote_hear = list("makes a faint scraping sound") + emote_see = list("twitches slightly", "shivers") + response_help = "touches the" + response_disarm = "pushes the" + response_harm = "hits the" + see_in_dark = 8 //Needs to see in darkness to snap in darkness + pass_flags = PASSTABLE + var/response_snap = "snapped the neck of" //Past tense because it "happened before you could see it" + var/response_snap_target = "In the blink of an eye, something grabs you and snaps your neck!" + var/snap_sound = list('sound/scp/firstpersonsnap.ogg','sound/scp/firstpersonsnap2.ogg','sound/scp/firstpersonsnap3.ogg') + var/scare_sound = list('sound/scp/scare1.ogg','sound/scp/scare2.ogg','sound/scp/scare3.ogg','sound/scp/scare4.ogg') //Boo + var/hibernate = 0 //Disables SCP until toggled back to 0 + var/scare_played = 0 //Did we rape everyone's ears yet ? + var/obj/machinery/atmospherics/unary/vent_pump/entry_vent //Graciously stolen from spider code + +/mob/living/simple_animal/sculpture/Life() + + //If we are hibernating, just don't do anything + if(hibernate) + return + + if(!check_los()) + return + + //See if we're able to strangle anyone + for(var/mob/living/carbon/M in get_turf(src)) + if(M.stat == CONSCIOUS && check_los()) + snap_neck(M) + break + + //Find out what mobs we can see for targetting purposes + var/list/conscious = list() + for(var/mob/living/carbon/H in view(7, src)) + if(H.stat == CONSCIOUS) //He's up and running + conscious.Add(H) + + //Pick the nearest valid conscious target + var/mob/living/carbon/target + for(var/mob/living/carbon/H in conscious) + if(!target || get_dist(src, H) < get_dist(src, target)) + target = H + + if(target) + handle_target(target) + else + handle_idle() + + +//Check if any mob can see SPC-173 +/mob/living/simple_animal/sculpture/proc/check_los() + + var/observed = 0 + + //Humans can observe SCP-173. If a single human observes him, he's observed for everyone + //Note that humans have a 180 degrees field of vision for the purposes of this proc + for(var/mob/living/carbon/H in viewers(src, null)) + if(H.stat) + continue + var/x_diff = H.x - src.x + var/y_diff = H.y - src.y + if(y_diff != 0) //If we are not on the same vertical plane (up/down), mob is either above or below src + if(y_diff < 0 && H.dir == NORTH) //Mob is below src and looking up + observed = 1 + break + else if(y_diff > 0 && H.dir == SOUTH) //Mob is above src and looking down + observed = 1 + break + if(x_diff != 0) //If we are not on the same horizontal plane (left/right), mob is either left or right of src + if(x_diff < 0 && H.dir == EAST) //Mob is left of src and looking right + observed = 1 + break + else if(x_diff > 0 && H.dir == WEST) //Mob is right of src and looking left + observed = 1 + break + + if(observed) //Is someone looking at us, given that they can see us ? + return 0 //Try again when we get a chance + return 1 //Success, let's move + +/mob/living/simple_animal/sculpture/proc/handle_target(var/mob/living/carbon/target) + + if(!target) //Sanity + return + + if(!check_los()) + return + + var/turf/target_turf + + //Send the warning that SPC is homing in + target_turf = get_turf(target) + if(!scare_played) //Let's minimize the spam + playsound(get_turf(src), pick(scare_sound), 50, 1) + scare_played = 1 + spawn(50) + scare_played = 0 + + //Rampage along a path to get to them, in the blink of an eye + var/turf/next_turf = get_step_towards(src, target) + var/num_turfs = get_dist(src,target) + spawn() + while(get_turf(src) != target_turf && num_turfs > 0) + if(!check_los()) //Something is looking at us now + break + if(!next_turf.CanPass(src, next_turf)) //We can't pass through our planned path + break + for(var/obj/structure/table/O in next_turf) + O.ex_act(1) + sleep(5) + for(var/obj/structure/closet/C in next_turf) + C.ex_act(1) + sleep(5) + for(var/obj/structure/grille/G in next_turf) + G.ex_act(1) + sleep(5) + for(var/obj/machinery/door/airlock/A in next_turf) + if(A.welded || A.locked) //Snowflakey code to take in account bolts and welding + break + A.open() + sleep(5) + for(var/obj/machinery/door/D in next_turf) + D.open() + sleep(5) + if(!next_turf.CanPass(src, next_turf)) //Once we cleared everything we could, check one last time if we can pass + break + forceMove(next_turf) + dir = get_dir(src, target) + next_turf = get_step(src, get_dir(next_turf,target)) + num_turfs-- + +/mob/living/simple_animal/sculpture/proc/handle_idle() + + if(!check_los()) + return + + //If we're not strangling anyone, take a stroll + if(prob(25)) //1 in 4 chance of checking out something new + var/list/turfs = new/list() + for(var/turf/T in view(7, src)) + if(!istype(T, /turf/simulated/floor)) + continue + turfs += T + var/turf/target_turf = safepick(turfs) + if(!target_turf) + return + //Move to our new resting point with celerity + var/turf/next_turf = get_step_towards(src, target_turf) + var/num_turfs = get_dist(src, target_turf) + spawn() + while(get_turf(src) != target_turf && num_turfs > 0) + if(!check_los()) //Something is looking at us now + break + if(!next_turf.CanPass(src, next_turf)) //We can't pass through our planned path + break + for(var/obj/structure/table/O in next_turf) + O.ex_act(1) + sleep(5) + for(var/obj/structure/closet/C in next_turf) + C.ex_act(1) + sleep(5) + for(var/obj/structure/grille/G in next_turf) + G.ex_act(1) + sleep(5) + for(var/obj/machinery/door/airlock/A in next_turf) + if(A.welded || A.locked) //Snowflakey code to take in account bolts and welding + break + A.open() + sleep(5) + for(var/obj/machinery/door/D in next_turf) + D.open() + sleep(5) + if(!next_turf.CanPass(src, next_turf)) //Once we cleared everything we could, check one last time if we can pass + break + forceMove(next_turf) + dir = get_dir(src, target_turf) + next_turf = get_step(src, get_dir(next_turf,target_turf)) + num_turfs-- + //Coding note : This is known to allow SCP to end up on tiles that contain obstructing structures (doors, machinery, etc) + //Although he CAN'T pass through them during normal movement. Will look into a fix soon + + //Do we have a vent ? Good, let's take a look + for(entry_vent in view(1, src)) + if(prob(90)) //10 % chance to consider a vent, to try and avoid constant vent switching + return + visible_message("\The [src] starts trying to slide itself into the vent!") + sleep(50) //Let's stop SCP-173 for five seconds to do his parking job + ..() + if(entry_vent.network && entry_vent.network.normal_members.len) + var/list/vents = list() + for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in entry_vent.network.normal_members) + vents.Add(temp_vent) + if(!vents.len) + entry_vent = null + return + if(!check_los()) //Someone started looking at us + return + var/obj/machinery/atmospherics/unary/vent_pump/exit_vent = pick(vents) + spawn() + visible_message("\The [src] suddenly disappears into the vent!") + loc = exit_vent + var/travel_time = round(get_dist(loc, exit_vent.loc)/2) + spawn(travel_time) + if(!exit_vent || exit_vent.welded) + forceMove(get_turf(entry_vent)) + entry_vent = null + visible_message("\The [src] suddenly appears from the vent!") + return + + forceMove(get_turf(exit_vent)) + entry_vent = null + visible_message("\The [src] suddenly appears from the vent!") + else + entry_vent = null + +//This performs an immediate neck snap check, meant to avoid people cheesing SCP-173 by just running faster than Life() refresh +/mob/living/simple_animal/sculpture/proc/check_snap_neck() + + //See if we're able to strangle anyone + for(var/mob/living/carbon/M in get_turf(src)) + if(M.stat == CONSCIOUS && check_los()) + snap_neck(M) + break + +/mob/living/simple_animal/sculpture/forceMove(atom/destination, var/no_tp = 0) + + ..() + check_snap_neck() + +/mob/living/simple_animal/sculpture/proc/snap_neck(var/mob/living/target) + + if(!check_los()) + return + + if(target) + //To prevent movement cheese, SCP snaps necks the second it ends up on the same turf as someone + //Or in other terms, if SCP decides it had a clean shot for a neck snap at the moment this proc fired, you're good as dead + target.apply_damage(rand(120, 150), BRUTE, "head") + target.apply_damage(100, OXY) + playsound(target.loc, pick(snap_sound), 50, 1) + + //Warn everyone + visible_message("[src] [response_snap] [target]!") + target << "[response_snap_target] Your vision fades away..." + + target.death() //Immediately trigger death to avoid doublesnap during lag + + //Logging stuff + target.attack_log += text("\[[time_stamp()]\] Has had his neck snapped by [src]!") + log_admin("[target] ([target.ckey]) has had his neck snapped by an active [src].") + message_admins("ALERT: [target.real_name] has had his neck snapped by an active [src].") + +/mob/living/simple_animal/sculpture/attackby(var/obj/item/O as obj, var/mob/user as mob) + ..() + +/mob/living/simple_animal/sculpture/Topic(href, href_list) + ..() + +/mob/living/simple_animal/sculpture/Bump(atom/movable/AM as mob) + if(!check_los()) + snap_neck(AM) + ..() + +/mob/living/simple_animal/sculpture/Bumped(atom/movable/AM as mob, yes) + if(!check_los()) + snap_neck(AM) + +//You cannot destroy SCP-173, fool! +/mob/living/simple_animal/sculpture/ex_act(var/severity) diff --git a/code/modules/mob/living/simple_animal/animals/synx-explanation.md b/code/modules/mob/living/simple_animal/animals/synx-explanation.md new file mode 100644 index 0000000000..4648858ff5 --- /dev/null +++ b/code/modules/mob/living/simple_animal/animals/synx-explanation.md @@ -0,0 +1,98 @@ +# The synx mob + +The synx mob has quite a few things of interest, the first main thing is a custom variabled called `"memorysize"` +Memorysize is a variable setting the maximum amount the "speak" list is allowed to have. + +In code this is handled through what i call speechcode, a small amount of code that is called on whenever the mob hears something say something. + +```C +/mob/living/simple_animal/retaliate/synx/pet/hear_say(message) + . = ..() + if(!message) return + if(message) + if(speak.len>=memorysize) + speak -= (pick(speak))//making the list more dynamic + speak += message +``` + +*For an explanation on -= and += refer to the byond reference on the topic of lists.* + +In this code I also implemented a little bandaid fix for an issue mobs usually have, which is that once they are pinned to the ground meaning they enter `"resting=1"` they simple do not have code to stand back up, causing neutral mobs to become unablöe to defend themselves. + +The code to go arround that I implemeneted is simply +```C + if(resting) + resting = !resting +``` +Which is called upon within speechcode, unresting the mob if it is rested, this can be triggered by someone talking or it itself talking. + +Additionally to this Synxes have a few Passive as well as active abilities. +* Contort, contort is a modified hide proc which also slows down the user +* Toggle Form, form toggle is a integrated but currently not used ability for swapping stance, which also changes some stats. +* Poison, Synx code reuses Spider poison code to deliver their own special toxin called synxchem into a person. +All three of these can be found under the PASSIVE POWERS and POWERS section of the code in `synx.dm` + +### The VORE section! + +Now Vore wise Synxes actually make use of two diferent systems and that for good reason. + +The first system is the basic vore setup which goes as follows +```C + vore_active = 1 // this enables the mob from having vore interactions + vore_capacity = 2 //Self explanatory, how many people can be in this nerd + vore_pounce_chance = 50 // Pounce is the chance that the mob when attacking will instead try to consume, it's unit is equal to % + vore_bump_chance = 10 //Bump is the thing that happens when a mob moves onto your tile or pushes you off it, once again % unit. + vore_bump_emote = "Slowly wraps its tongue around, and slides its drooling maw over the head of" //The message displayed when initiating a vore + vore_standing_too = 1 //As we understand it this enables the mob to devour standing people too, the name seems to agree. + vore_ignores_undigestable = 0 // This means that if someone can not be digested the mob will still eat them, they cant digest them but they will still consume them eitherway, such nice endo friendos + vore_default_mode = DM_HOLD //Here we set the mode the belly will be in by default, HOLD being the hold mode and DM_DIGEST etc being their respective modes + vore_digest_chance = 45 // Chance to switch to digest mode if resisted, pretty simple still a % unit. + vore_absorb_chance = 0 //same as above but instead of for digestion its for absorbtion + vore_escape_chance = 10 // % escape chance + vore_icons = 0 //refer to the documentation within code/modules/mob/vore-icons.md + swallowTime = 6 SECONDS // The amount of time a mob takes to devour you. +``` + +Since this is a pretty long code snippet all my comments on it are inside the above snippet formatted how you would inside the code. + +The second part is used within a proc and sets up more special things about the stomach such as digestion rates, fluff text etc + +```C +/mob/living/simple_animal/retaliate/synx/init_vore() + ..() + var/obj/belly/B = vore_selected + B.vore_verb = "swallow" + B.name = "stomach" + B.desc = "You're pulled into the snug stomach of the synx." + B.digest_burn = 1 + B.digest_brute = 0 + B.emote_lists[DM_HOLD] = list( + "The walls churn around you", + "The unusually cool stomach rolls around you slowly and lazily.", + "The thick, viscous fluids cling to your body soaking in deep." + ) + B.emote_lists[DM_DIGEST] = list( + "The stomach kneads roughly around you.", + "Firm churns of the stomach roll and knead you around.", + "Your body tingles and the air smells strongly of acid.", + "You're jostled in the stomach as the synx lets out what can only described as an alien belch." + ) + B.digest_messages_prey = list( + "Your eyes grow heavy as the air grows thin in the stomach.", + "Slowly, the stinging and burning of the acids, and the constant churning is just too much.", + "The acids and fluids rise up above your head, quickly putting an end to your squirming and conciousness.", + "The synx lets out an audible belch, the last of your air going with it." + ) +``` +I simplified a lot of the texts for the sake of keeping it a bit shorter, the names of the variables like "digest message prey" should be self explanatory. + +This however is only the first part of it the second part for the PET version is as follows and more interesting for us. +```C +/mob/living/simple_animal/retaliate/synx/pet/init_vore() + ..() + var/obj/belly/B = vore_selected + B.vore_verb = "swallow" + B.digest_burn = 1 + B.digest_brute = 0 +``` +This is the code equivelant of the normal VORE panel we all know where you set how much damage your stomach deals as well as what word is used for the consumption text There's a bunch more that can be set and for this refer to the procs dm file found here `code/modules/mob/living/simple_animal/simple_animal_vr.dm` diff --git a/code/modules/mob/living/simple_animal/animals/synx.dm b/code/modules/mob/living/simple_animal/animals/synx.dm index dd4b120cb1..2054acb7cf 100644 --- a/code/modules/mob/living/simple_animal/animals/synx.dm +++ b/code/modules/mob/living/simple_animal/animals/synx.dm @@ -1,223 +1,551 @@ -/mob/living/simple_animal/retaliate/synx - name = "Synx" - desc = "A cold blooded, genderless, parasitic eel from the more distant and stranger areas of the cosmos. Plain, white, perpetually grinning and possessing a hunger as enthusiastic and endless as humanity's sense of exploration." - tt_desc = "synxus pergulus" - - //Synx species belongs to ChimeraSynx , Sprites by: SpitefulCrow - icon = 'icons/mob/synx.dmi'//giving synxes their own DMI file! - icon_state = "synx_living" - icon_living = "synx_living" - icon_dead = "synx_dead" - - var/transformed_state = "synx_transformed" - - var/transformed = FALSE - - var/memorysize = 50 - - faction = "Synx" - intelligence_level = SA_ANIMAL - - maxHealth = 150 - health = 120 - //turns_per_move = 2 //to be balanced, default for now - //speed = -2 //to be balanced, default for now - see_in_dark = 6 - stop_when_pulled = 0 - armor = list( // will be determined - "melee" = 20, - "bullet" = 0, - "laser" = 0, - "energy" = 0, - "bomb" = 10, - "bio" = 100, - "rad" = 100) - //has_hands = TRUE - - response_help = "pets" - response_disarm = "gently pushes aside" - - - pass_flags = PASSTABLE - - melee_damage_lower = 20 - melee_damage_upper = 30 - attack_armor_pen = 50 // How much armor pen this attack has. - attack_sharp = 1 - attack_edge = 1 - -//Vore stuff - vore_active = 1 - vore_capacity = 2 - vore_pounce_chance = 50 - vore_bump_chance = 10 - vore_bump_emote = "Slowly wraps its tongue around, and slides its drooling maw over the head of" - vore_standing_too = 1 //I believe this lets it vore standing people, rather than only resting. - vore_ignores_undigestable = 0 //Synx don't care if you digest or not, you squirm fine either way. - vore_default_mode = DM_HOLD - vore_digest_chance = 45 // Chance to switch to digest mode if resisted - vore_absorb_chance = 0 - vore_escape_chance = 20 - vore_icons = 0 //no vore icons -// swallowTime = 6 SECONDS //Enter the eel you nerd - -/mob/living/simple_animal/retaliate/synx/init_vore() - ..() - var/obj/belly/B = vore_selected - B.human_prey_swallow_time = 6 SECONDS - B.nonhuman_prey_swallow_time = 3 SECONDS - B.vore_verb = "swallow" - B.name = "stomach" - B.desc = "You're pulled into the snug stomach of the synx. The walls knead weakly around you, coating you in thick, viscous fluids that cling to your body, that soon starts to tingle and burn..." - B.digest_burn = 1 - B.digest_brute = 0 - B.emote_lists[DM_HOLD] = list( - "The walls churn around you, soaking you in thick, smelling fluid as you're kneaded and rolled about in the surprisingly roomy, but still snug, space.", - "The unusually cool stomach rolls around you slowly and lazily, trying to almost knead you to sleep gently as the synx pulses around you.", - "The thick, viscous fluids cling to your body soaking in deep, giving you a full bath with the kneading of the walls helping to make sure you'll be smelling like synx stomach for days." - ) - B.emote_lists[DM_DIGEST] = list( - "The stomach kneads roughly around you, squishing and molding to your shape, with the thick fluids clinging to your body and tingling, making it hard to breathe.", - "Firm churns of the stomach roll and knead you around, your body tingling as fur sizzles all around you, your body getting nice and tenderized for the stomach.", - "Your body tingles and the air smells strongly of acid, as the stomach churns around you firmly and slowly, eager to break you down.", - "You're jostled in the stomach as the synx lets out what can only described as an alien belch, the space around you getting even more snug as the thick acids rise further up your body." - ) - B.digest_messages_prey = list( - "Your eyes grow heavy as the air grows thin in the stomach, the burning of the acids slowly putting you into a final slumber, adding you to the synx's hips and tail.", - "Slowly, the stinging and burning of the acids, and the constant churning is just too much, and with a few final clenches, your body is broken down into fuel for the synx.", - "The acids and fluids rise up above your head, quickly putting an end to your squirming and conciousness.. the stomach eager to break you down completely.", - "The synx lets out an audible belch, the last of your air going with it, and with a few audible crunches from the outside, the stomach claims you as food for the parasite." - ) - -//Shouldn't be affected by lack of atmos, it's a space eel. - min_oxy = 0 - max_oxy = 0 //Maybe add a max - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 //Maybe add a max - min_n2 = 0 - max_n2 = 0 //Maybe add a max - minbodytemp = 0 - // TODO: Set a max temperature of about 20-30 above room temperatures. Synx don't like the heat. - - -// to be added -/* speak_chance = 2 - speak = list() - speak_emote = list() - emote_hear = list() - emote_see = list() - */ - -/mob/living/simple_animal/retaliate/synx/New() - ..() - verbs |= /mob/living/proc/ventcrawl - verbs |= /mob/living/simple_animal/proc/contort - verbs += /mob/living/simple_animal/retaliate/synx/proc/disguise - -mob/living/simple_animal/synx/PunchTarget() - if(!Adjacent(target_mob)) - return - custom_emote(1, pick( list("slashes at [target_mob]", "bites [target_mob]") ) ) - - var/damage = rand(melee_damage_lower, melee_damage_upper) - - if(ishuman(target_mob)) - var/mob/living/carbon/human/H = target_mob - var/dam_zone = pick(BP_TORSO, BP_L_HAND, BP_R_HAND, BP_L_LEG, BP_R_LEG) - var/obj/item/organ/external/affecting = H.get_organ(ran_zone(dam_zone)) - H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"), H.get_armor_soak(affecting, "melee"), sharp=1, edge=1) - return H - else if(isliving(target_mob)) - var/mob/living/L = target_mob - L.adjustBruteLoss(damage) - return L - else - ..() - -////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////// POWERS!!!! ///////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// - -/mob/living/simple_animal/proc/contort() - set name = "contort" - set desc = "Allows to hide beneath tables or certain items. Toggled on or off." - set category = "Abilities" - - if(stat == DEAD || paralysis || weakened || stunned || restrained()) - return - - if(status_flags & HIDING) - status_flags &= ~HIDING - reset_plane_and_layer() - to_chat(src,"You have stopped hiding.") - //speed = -3, to be balanced - else - status_flags |= HIDING - layer = HIDING_LAYER //Just above cables with their 2.44 - plane = OBJ_PLANE - to_chat(src,"You are now hiding.") - speed = 2 - -/mob/living/simple_animal/retaliate/synx/proc/disguise() - set name = "Toggle Form" - set desc = "Switch between amorphous and humanoid forms." - set category = "Abilities" - - if(stat == DEAD || paralysis || weakened || stunned || restrained()) - return - - // If transform isn't true - if(!transformed) - to_chat(src,"you changed back into your disguise.") - icon_living = transformed_state //Switch state to transformed state - else // If transformed is true. - to_chat(src,"now they see your true form.") - icon_living = initial(icon_living) //Switch state to what it was originally defined. - - - transformed = !transformed - update_icons() - - -//////////////////////////////////////// -////////////////PET VERSION///////////// -//////////////////////////////////////// -/mob/living/simple_animal/retaliate/synx/pet - name = "Grins" - desc = "A cold blooded, genderless, parasitic eel from the more distant and stranger areas of the cosmos. Plain, white, perpetually grinning and possessing a hunger as enthusiastic and endless as humanity's sense of exploration.. This one has a small collar on it that reads 'Grins' with a bell that doesn't seem to work." - tt_desc = "synxus pergulus" - - icon = 'icons/mob/synx.dmi' - icon_state = "synx_pet_living" - icon_living = "synx_pet_living" - icon_dead = "synx_pet_dead" - - glow_range = 2 - glow_toggle = 1 - - player_msg = "You aren't supposed to be in this. Wrong mob." - - var/goodboy = "no" - -/mob/living/simple_animal/retaliate/synx/pet/init_vore() - ..() - var/obj/belly/B = vore_selected - B.human_prey_swallow_time = 4 - B.nonhuman_prey_swallow_time = 1 - B.vore_verb = "swallow" - B.digest_burn = 1 - B.digest_brute = 0 - -/mob/living/simple_animal/retaliate/synx/pet - speak_chance = 1 - speak = list() - -/mob/living/simple_animal/retaliate/synx/pet/hear_say(message) - . = ..() - if(!message) return - if(message) - if(speak.len==memorysize) - clearlist(speak) - speak += message \ No newline at end of file +/mob/living/simple_animal/retaliate/synx + name = "Synx" + desc = "A cold blooded, genderless, parasitic eel from the more distant and stranger areas of the cosmos. Plain, white, perpetually grinning and possessing a hunger as enthusiastic and endless as humanity's sense of exploration." + tt_desc = "synxus pergulus" + + //Synx species belongs to ChimeraSynx , Base sprites by: SpitefulCrow + icon = 'icons/mob/synx.dmi'//giving synxes their own DMI file! + icon_state = "synx_living" + icon_living = "synx_living" + icon_dead = "synx_dead" + + speak_chance = 10 //MAy have forgotten to readd that. + //Synx speech code overrides normal speech code but is still a x in 200 chance of triggereing, as all mobs do. + //VAR$ SETUP + var/realname = null + var/poison_per_bite = 5 + var/poison_chance = 99.666 + var/poison_type = "synxchem"//inaprovalin, but evil + var/transformed_state = "synx_transformed" + var/transformed = FALSE + var/memorysize = 50 //Var for how many messages synxes remember if they know speechcode + var/list/voices = list() + + faction = "Synx" + intelligence_level = SA_ANIMAL + + maxHealth = 150 + health = 150 + turns_per_move = 5 //Should just affect how often it wanders, subject to change. + speed = 2 //Re enabled custom speed + see_in_dark = 6 + stop_when_pulled = 0 + armor = list( // will be determined + "melee" = 20, + "bullet" = 0, + "laser" = 0, + "energy" = 0, + "bomb" = 10, + "bio" = 100, + "rad" = 100) + has_hands = 1 + + response_help = "pets" + response_disarm = "gently pushes aside" + + + pass_flags = PASSTABLE + + melee_damage_lower = 5 //Massive damage reduction, will be balanced with toxin injection + melee_damage_upper = 5 + attack_armor_pen = 40 // How much armor pen this attack has. + attack_sharp = 1 + attack_edge = 1 + +//Vore stuff + vore_active = 1 + vore_capacity = 2 + vore_pounce_chance = 50 + vore_bump_chance = 10 + vore_bump_emote = "Slowly wraps its tongue around, and slides its drooling maw over the head of" + vore_standing_too = 1 //I believe this lets it vore standing people, rather than only resting. + vore_ignores_undigestable = 0 //Synx don't care if you digest or not, you squirm fine either way. + vore_default_mode = DM_HOLD + vore_digest_chance = 45 // Chance to switch to digest mode if resisted + vore_absorb_chance = 0 + vore_escape_chance = 10 + vore_icons = 0 //no vore icons + swallowTime = 6 SECONDS //Enter the eel you nerd + +/mob/living/simple_animal/retaliate/synx/init_vore() + ..() + var/obj/belly/B = vore_selected + //B.human_prey_swallow_time = 6 SECONDS //doesnt work + //B.nonhuman_prey_swallow_time = 3 SECONDS //doesnt work + B.vore_verb = "swallow" + B.name = "stomach" + B.desc = "You're pulled into the snug stomach of the synx. The walls knead weakly around you, coating you in thick, viscous fluids that cling to your body, that soon starts to tingle and burn..." + B.digest_burn = 1 + B.digest_brute = 0 + B.emote_lists[DM_HOLD] = list( + "The walls churn around you, soaking you in thick, smelling fluid as you're kneaded and rolled about in the surprisingly roomy, but still snug, space.", + "The unusually cool stomach rolls around you slowly and lazily, trying to almost knead you to sleep gently as the synx pulses around you.", + "The thick, viscous fluids cling to your body soaking in deep, giving you a full bath with the kneading of the walls helping to make sure you'll be smelling like synx stomach for days." + ) + B.emote_lists[DM_DIGEST] = list( + "The stomach kneads roughly around you, squishing and molding to your shape, with the thick fluids clinging to your body and tingling, making it hard to breathe.", + "Firm churns of the stomach roll and knead you around, your body tingling as fur sizzles all around you, your body getting nice and tenderized for the stomach.", + "Your body tingles and the air smells strongly of acid, as the stomach churns around you firmly and slowly, eager to break you down.", + "You're jostled in the stomach as the synx lets out what can only described as an alien belch, the space around you getting even more snug as the thick acids rise further up your body." + ) + B.digest_messages_prey = list( + "Your eyes grow heavy as the air grows thin in the stomach, the burning of the acids slowly putting you into a final slumber, adding you to the synx's hips and tail.", + "Slowly, the stinging and burning of the acids, and the constant churning is just too much, and with a few final clenches, your body is broken down into fuel for the synx.", + "The acids and fluids rise up above your head, quickly putting an end to your squirming and conciousness.. the stomach eager to break you down completely.", + "The synx lets out an audible belch, the last of your air going with it, and with a few audible crunches from the outside, the stomach claims you as food for the parasite." + ) + +//Shouldn't be affected by lack of atmos, it's a space eel. + min_oxy = 0 + max_oxy = 0 //Maybe add a max + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 //Maybe add a max + min_n2 = 0 + max_n2 = 0 //Maybe add a max + minbodytemp = 0 + // TODO: Set a max temperature of about 20-30 above room temperatures. Synx don't like the heat. + +/mob/living/simple_animal/retaliate/synx/New() + ..() + verbs |= /mob/living/proc/ventcrawl + verbs |= /mob/living/simple_animal/proc/contort + verbs |= /mob/living/simple_animal/retaliate/synx/proc/disguise + //verbs += /mob/living/simple_animal/retaliate/synx/proc/honk + verbs |= /mob/living/simple_animal/retaliate/synx/proc/randomspeech + realname = name + voices += "Garbled voice" + voices += "Unidentifiable Voice" + speak += "Who is there?" + speak += "What is that thing?!" + +/* This literally is just the normal proc, why does this exist wh +mob/living/simple_animal/synx/PunchTarget() + if(!Adjacent(target_mob)) + return + custom_emote(1, pick( list("slashes at [target_mob]", "bites [target_mob]") ) ) + + var/damage = rand(melee_damage_lower, melee_damage_upper) + + if(ishuman(target_mob)) + var/mob/living/carbon/human/H = target_mob + var/dam_zone = pick(BP_TORSO, BP_L_HAND, BP_R_HAND, BP_L_LEG, BP_R_LEG) + var/obj/item/organ/external/affecting = H.get_organ(ran_zone(dam_zone)) + H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"), H.get_armor_soak(affecting, "melee"), sharp=1, edge=1) + return H + else if(isliving(target_mob)) + var/mob/living/L = target_mob + L.adjustBruteLoss(damage) + return L + else + ..() +*/ +////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////// SPECIAL ITEMS/REAGENTS !!!! //////////////////////////// +////////////////////////////////////////////////////////////////////////////////////// + +/datum/seed/hardlightseed/typesx //Respawn mechanism for the synx + name = "hardlightseedsx" + seed_name = "hardlightseedsx" + display_name = "Biomechanical Hardlight Generator SX"//PLant that is part mechanical part biological + has_mob_product = /mob/living/simple_animal/retaliate/synx/pet/holo + +/obj/item/seeds/hardlightseed/typesx + seed_type = "hardlightseedsx" + +/datum/reagent/inaprovaline/synxchem + name = "Alien nerveinhibitor" + description = "A toxin that slowly metabolizes damaging the person, but makes them unable to feel pain" + id = "synxchem" + metabolism = REM * 0.1 //Slow metabolization to try and mimic permanent nerve damage without actually being too cruel to people + color = "#FFFFFF" + overdose = REAGENTS_OVERDOSE * 4 //But takes a lot to OD + +/datum/reagent/inaprovaline/synxchem/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + if(alien != IS_DIONA) + if(prob(5)) + M.custom_pain("You feel no pain despite the clear signs of damage to your body!",60) + if(prob(2)) + M.custom_pain("You suddenly lose control over your body!",60) + M.AdjustParalysis(1) + M.add_chemical_effect(CE_STABLE, 15) + M.add_chemical_effect(CE_PAINKILLER, 50) + M.adjustBruteLoss(-0.2)//healing brute + M.adjustToxLoss(0.4) //Dealing twice of it as tox, even if you have no brute, its not true conversion. + M.adjustHalLoss(1) + +/datum/reagent/inaprovaline/synxchem/holo + name = "SX type simulation nanomachines" //Educational! + description = "Type SX nanomachines to simulate what it feels like to come in contact with a synx, minus the damage" + id = "fakesynxchem" + metabolism = REM * 1 //ten times faster for convenience of testers. + color = "#00FFFF" + overdose = REAGENTS_OVERDOSE * 20 //it's all fake. But having nanomachines move through you is not good at a certain amount. + +/datum/reagent/inaprovaline/synxchem/holo/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + if(alien != IS_DIONA) + if(prob(5)) + M.custom_pain("You feel no pain!",60) + if(prob(2)) + M.custom_pain("You suddenly lose control over your body!",60) + M.AdjustParalysis(1) + M.add_chemical_effect(CE_STABLE, 15) + M.add_chemical_effect(CE_PAINKILLER, 50) + M.adjustBruteLoss(-0.2)//Made to simulate combat, also useful as very odd healer. + M.adjustToxLoss(-0.2) //HELP ITS MAULING ME! + M.adjustFireLoss(-0.2) //huh this mauling aint so bad + M.adjustHalLoss(10) //OH MY GOD END MY PAIN NOW WHO MADE THIS SIMULATION + +/datum/reagent/inaprovaline/synxchem/clown + name = "HONK" + description = "HONK" + id = "clownsynxchem" + metabolism = REM * 0.5 + color = "#FFFFFF" + overdose = REAGENTS_OVERDOSE * 200 + +/datum/reagent/inaprovaline/synxchem/clown/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + M.adjustToxLoss(0.01) + playsound(M.loc, 'sound/items/bikehorn.ogg', 50, 1) + M.adjustBruteLoss(-2)//healing brute + if(prob(1)) + M.custom_pain("I have no horn but i must honk!",40) + if(prob(2)) + var/location = get_turf(M) + new /obj/item/weapon/bikehorn(location) + M.custom_pain("You suddenly cough up a bikehorn!",60) + +/datum/reagent/inaprovaline/synxchem/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + if(alien != IS_DIONA) + if(prob(5)) + M.custom_pain("You feel no pain despite the clear signs of damage to your body!",60) + if(prob(2)) + M.custom_pain("You suddenly lose control over your body!",60) + M.AdjustParalysis(1) + M.add_chemical_effect(CE_STABLE, 15) + M.add_chemical_effect(CE_PAINKILLER, 50) + M.adjustBruteLoss(-0.2)//healing brute + M.adjustToxLoss(0.1) //Dealing half of it as tox + M.adjustHalLoss(1) //dealing 5 times the amount of brute healed as halo, but we cant feel pain yet + // ^ I have no idea what this might cause, my ideal plan is that once the pain killer wears off you suddenly collapse; + //Since Halloss is not "real" damage this should not cause death + + +/datum/reagent/inaprovaline/synxchem/overdose(var/mob/living/carbon/M, var/alien, var/removed) + ..() + if(alien != IS_DIONA) + M.adjustHalLoss(-3)//im too nice + M.adjustToxLoss(0.4) + M.make_dizzy(10) + if(prob(5)) + M.AdjustStunned(1) + if(prob(2)) + M.AdjustParalysis(1) + +/datum/reagent/inaprovaline/synxchem/holo/overdose(var/mob/living/carbon/M, var/alien, var/removed) + return + +/datum/reagent/inaprovaline/synxchem/clown/overdose(var/mob/living/carbon/M, var/alien, var/removed) + return + +////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////// PASSIVE POWERS!!!! ///////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////// +/mob/living/simple_animal/retaliate/synx/DoPunch(var/atom/A) + . = ..() + if(.) // If we succeeded in hitting. + if(isliving(A)) + var/mob/living/L = A + if(prob(20))//Forcefeeding code + L.Weaken(5) + stop_automated_movement = 1 + src.feed_self_to_grabbed(src,L) + update_icon() + stop_automated_movement = 0 + if(L.reagents) + var/target_zone = pick(BP_TORSO,BP_TORSO,BP_TORSO,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_HEAD) + if(L.can_inject(src, null, target_zone)) + L.reagents.add_reagent(poison_type, poison_per_bite) + if(prob(poison_chance)) + to_chat(L, "You feel a strange substance on you.") + L.reagents.add_reagent(poison_type, poison_per_bite) + +/mob/living/simple_animal/retaliate/synx/hear_say(message,verb,language,fakename,isItalics,var/mob/living/speaker) + . = ..() + if(!message) return + speaker = speaker.GetVoice() + speak += message + voices += speaker + if(voices.len>=memorysize) + voices -= (pick(voices))//making the list more dynamic + if(speak.len>=memorysize) + speak -= (pick(speak))//making the list more dynamic + if(resting) + resting = !resting + if(message=="Honk!") + bikehorn() + +/mob/living/simple_animal/retaliate/synx/pet/clown/Life() + ..() + if(vore_fullness) + size_multiplier = 1+(0.5*vore_fullness) + update_icons() + if(!vore_fullness && size_multiplier != 1) + size_multiplier = 1 + update_icons() + +/mob/living/simple_animal/retaliate/synx/handle_idle_speaking() + if(voices && prob(speak_chance/2)) + randomspeech() + +////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////// POWERS!!!! ///////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////// + +/mob/living/simple_animal/proc/contort() + set name = "contort" + set desc = "Allows to hide beneath tables or certain items. Toggled on or off." + set category = "Abilities" + + if(stat == DEAD || paralysis || weakened || stunned || restrained()) + return + + if(status_flags & HIDING) + status_flags &= ~HIDING + reset_plane_and_layer() + to_chat(src,"You have stopped hiding.") + speed = 2 + else + status_flags |= HIDING + layer = HIDING_LAYER //Just above cables with their 2.44 + plane = OBJ_PLANE + to_chat(src,"You are now hiding.") + speed = 4 + +/mob/living/simple_animal/retaliate/synx/proc/disguise() + set name = "Toggle Form" + set desc = "Switch between amorphous and humanoid forms." + set category = "Abilities" + + if(stat == DEAD || paralysis || weakened || stunned || restrained()) + return + + // If transform isn't true + if(!transformed) + to_chat(src,"you changed back into your disguise.") + icon_living = transformed_state //Switch state to transformed state + else // If transformed is true. + to_chat(src,"now they see your true form.") + icon_living = initial(icon_living) //Switch state to what it was originally defined. + + + transformed = !transformed + update_icons() + +/mob/living/simple_animal/retaliate/synx/proc/randomspeech() + set name = "speak" + set desc = "Takes a sentence you heard and says it" + set category = "Abilities" + if(speak && voices) + handle_mimic() + else + usr << "YOU NEED TO HEAR THINGS FIRST, try using Ventcrawl to eevesdrop on nerds" + +/mob/living/simple_animal/retaliate/synx/proc/handle_mimic() + name = pick(voices) + spawn(2) + src.say(pick(speak)) + spawn(5) + name = realname + +//////////////////////////////////////// +////////////////PET VERSION///////////// +//////////////////////////////////////// +/mob/living/simple_animal/retaliate/synx/pet + faction = "Cargonia" //Should not share a faction with those pesky non station synxes.//This is so newspaper has a failchance + name = "Bob" + desc = "A very regular pet." + tt_desc = "synxus pergulus" + glow_range = 4 + glow_toggle = 1 + player_msg = "You aren't supposed to be in this. Wrong mob." + +/mob/living/simple_animal/retaliate/synx/pet/init_vore() + ..() + var/obj/belly/B = vore_selected + B.vore_verb = "swallow" + B.digest_burn = 1 + B.digest_brute = 0 + +/mob/living/simple_animal/retaliate/synx/pet/holo/init_vore() + ..() + var/obj/belly/B = vore_selected + B.vore_verb = "swallow" + B.digest_burn = 5 + B.digest_brute = 5 + +/mob/living/simple_animal/retaliate/synx/pet + speak_chance = 2.0666 + speak = list() + +//HONKMOTHER Code. +/*/mob/living/simple_animal/retaliate/synx/proc/honk() + set name = "HONK" + set desc = "TAAA RAINBOW" + set category = "Abilities" + icon_state = "synx_pet_rainbow" + icon_living = "synx_pet_rainbow" + playsound(src.loc, 'sound/items/bikehorn.ogg', 50, 1) +*/ +/mob/living/simple_animal/retaliate/synx/proc/bikehorn() + playsound(src.loc, 'sound/items/bikehorn.ogg', 50, 1) + +//HOLOSEEDSPAWNCODE +/mob/living/simple_animal/retaliate/synx/pet/holo/death() + ..() + visible_message("\The [src] fades away!") + var/location = get_turf(src) + new /obj/item/seeds/hardlightseed/typesx(location) + qdel(src) + +/mob/living/simple_animal/retaliate/synx/pet/holo/gib() + visible_message("\The [src] fades away!") + var/location = get_turf(src) + new /obj/item/seeds/hardlightseed/typesx(location) + qdel(src) + +//////////////////////////////////////// +////////////////SYNX VARIATIONS///////// +//////////////////////////////////////// +/mob/living/simple_animal/retaliate/synx/pet/holo + poison_chance = 100 + poison_type = "fakesynxchem" //unlike synxchem this one heals! + name = "Hardlight synx" + desc = "A cold blooded, genderless, space eel.. or a hologram of one. Guess the current synx are undergoing re-training? Either way this one is probably infinitely more friendly.. and less deadly." + icon_state = "synx_hardlight_living" + icon_living = "synx_hardlight_living" + icon_dead = "synx_hardlight_dead" + icon_gib = null + alpha = 127 + speak = list("SX System Online") + faction = "neutral"//Can be safely bapped with newspaper. + melee_damage_lower = 0 //Holos do no damage + melee_damage_upper = 0 + meat_amount = 0 + meat_type = null + //Vore Section + vore_default_mode = DM_HEAL + vore_capacity = 2 + vore_digest_chance = 0 //Holos cannot digest + vore_pounce_chance = 40 //Shouldn't fight + vore_bump_chance = 0 //lowered bump chance + vore_escape_chance = 30 //Much higher escape chance.. it's a hologram. + swallowTime = 10 SECONDS //Much more time to run + +/mob/living/simple_animal/retaliate/synx/pet/greed + name = "Greed" + desc = "A cold blooded, genderless, parasitic eel from the more distant and stranger areas of the cosmos. black, perpetually grinning and possessing a hunger as enthusiastic and endless as humanity's sense of exploration.. This one has the name Greed burnt into its back, the burnt in name seems to be luminescent making it harder for it to blend into the dark." + //icon= //icon= would just set what DMI we are using, we already have our special one set. + icon_state = "synx_greed_living" + icon_living = "synx_greed_living" + icon_dead = "synx_greed_dead" + speak = list("Who is there?")//preset unique words Greed remembers, to be defined more + player_msg = "You Hunger." + health = 100//Slightly lower health due to being damaged permanently. + speak_chance = 5 + //Vore Section + vore_capacity = 4 //What a fat noodle. + vore_digest_chance = 1 //Multivore but lower digest chance + vore_pounce_chance = 90 //Fighting is effort, engulf them whole. + vore_bump_chance = 2 //lowered bump chance + vore_escape_chance = 5 //Multivore allows for people to shove eachother out so lower normal escape chance. + +/mob/living/simple_animal/retaliate/synx/pet/diablo + //var/diablo_LIVING = "synx_diablo_living" + //var/diablo_DEAD = "synx_diablo_dead" + name = "diablo" + desc = "A cold blooded, genderless, parasitic eel from the more distant and stranger areas of the cosmos. grey, perpetually grinning and possessing a hunger as enthusiastic and endless as humanity's sense of exploration.. This one has a small shock collar on it that reads 'diablo'." + icon_state = "synx_diablo_living" + icon_living = "synx_diablo_living" + icon_dead = "synx_diablo_dead" + speak = list( ) + //Vore Section + vore_capacity = 2 + +/mob/living/simple_animal/retaliate/synx/pet/diablo/sicsempertyrannis + name = "grins" + desc = "A cold blooded, genderless, parasitic eel from the more distant and stranger areas of the cosmos. grey, perpetually grinning and possessing a hunger as enthusiastic and endless as humanity's sense of exploration.. This one has a small shock collar on it that reads 'grins'." + icon_state = "synx_diablo_living" + icon_living = "synx_diablo_living" + icon_dead = "synx_diablo_dead" + speak = list( ) + //Vore Section + vore_capacity = 2 + + +/mob/living/simple_animal/retaliate/synx/pet/clown + hostile = 1 + poison_chance = 100 + poison_type = "clownsynxchem" //unlike synxchem this one HONKS + name = "Inflatable Clown Synx" + desc = "Honk!, made this here with all the fun on in the booth. At the gate outside, when they pull up, they get me loose. Yeah, Jump Out Clowns, that's Clown gang, hoppin' out tiny cars. This shit way too funny, when we pull up give them the honk hard!" + icon_state = "synx_pet_rainbow" + icon_living = "synx_pet_rainbow" + //icon_dead = "synx_hardlight_dead" + icon_gib = null + faction = "clown" + melee_damage_lower = 1 + melee_damage_upper = 1 + environment_smash = 0 + destroy_surroundings = 0 + //Vore Section + vore_default_mode = DM_HEAL + vore_capacity = 10 + vore_digest_chance = 0 + vore_pounce_chance = 1 //MAKE THEM HONK + vore_bump_chance = 0 //lowered bump chance + vore_escape_chance = 100 + +//////////////////////////////////////// +////////////////SYNX DEBUG////////////// +//////////////////////////////////////// +/mob/living/simple_animal/retaliate/synx/pet/debug + name = "Syntox" + desc = "ERROR Connection to translation server could not be established!" + +/mob/living/simple_animal/retaliate/synx/pet/debug/proc/rename() + set name = "rename" + set desc = "Renames the synx" + set category = "DEBUG" + name = input(usr, "What would you like to change name to?", "Renaming", null) + +/mob/living/simple_animal/retaliate/synx/pet/debug/proc/redesc() + set name = "redesc" + set desc = "Redescribes the synx" + set category = "DEBUG" + desc = input(usr, "What would you like to change desc to?", "Redescribing", null) + +/mob/living/simple_animal/retaliate/synx/pet/debug/proc/resprite() + set name = "resprite" + set desc = "Resprite the synx" + set category = "DEBUG" + icon_state = input(usr, "What would you like to change icon_state to?", "Respriting", null) + +/mob/living/simple_animal/retaliate/synx/pet/debug/New() + verbs |= /mob/living/simple_animal/retaliate/synx/pet/debug/proc/rename + verbs |= /mob/living/simple_animal/retaliate/synx/pet/debug/proc/resprite + verbs |= /mob/living/simple_animal/retaliate/synx/pet/debug/proc/redesc + +//////////////////////////////////////// +////////////////SYNX SPAWNER//////////// +//////////////////////////////////////// +/obj/random/mob/synx + name = "This is synxes" + +/obj/random/mob/synx/item_to_spawn() + if(Holiday == "April Fool's Day") //WE WISH YOU A MERRY CLOWNMAS + return /mob/living/simple_animal/retaliate/synx/pet/clown + else return pick(prob(50);/mob/living/simple_animal/retaliate/synx/pet/greed, + prob(50);/mob/living/simple_animal/retaliate/synx/pet/diablo, + prob(50);/mob/living/simple_animal/retaliate/synx/pet/holo,) diff --git a/code/modules/mob/living/simple_animal/animals/tarrasque.dm b/code/modules/mob/living/simple_animal/animals/tarrasque.dm new file mode 100644 index 0000000000..b84025628d --- /dev/null +++ b/code/modules/mob/living/simple_animal/animals/tarrasque.dm @@ -0,0 +1,233 @@ +/mob/living/simple_animal/hostile/tarrasque + //icon = bigboygains.dmi + + //temporarily gonna use Deathclaw + icon = 'icons/mob/vore64x64.dmi' + icon_dead = "deathclaw-dead" + icon_living = "deathclaw" + icon_state = "deathclaw" + size_multiplier = 2 + var/hasdrops = 1 + + isEdible = 0 + name = "T'rasq" + desc = "The most dreaded monster. Its purpose is to devour the worlds 1 waking cycle at a time, all it knows is, eat, sleep, repeat." + health = 1000 + maxHealth = 1000 + + tt_desc = "Embodiment of Destruction" //Let's avoid Actually labeling these as "Tarrasque" by species, going for a more mythological kinda thing, does this even exyst? + + //icon_living = "tarrasque" + //icon_dead = "" //This wont be needed since one does not simply kill a tarrasque. + + //Mob talking settings + //Rawr rorr, mrawr~! + //maybe later. + + //Mob movement settings + wander = 1 + wander_distance = 999 + returns_home = 1 + turns_per_move = 7 + follow_dist = 999 + speed = 4 + + //Mob interaction + response_help = "Sacrifices self to" + response_harm = "Weakly flails at" + harm_intent_damage = 0 + + //Mob environment settings + minbodytemp = 0 + maxbodytemp = 100000 + heat_damage_per_tick = 0 + cold_damage_per_tick = 0 + min_oxy = 0 + max_tox = 0 + max_co2 = 0 + unsuitable_atoms_damage = 0 + + //Hostility settings + view_range = 280 //HE knows when you're awake, and also when you sleep + investigates = 1 //Clever girl + attack_same = 1 //There can only be one + grab_resist = 100 //It's a collosal creature... you arent just grabbing that... + taser_kill = 0 //It's lethals or nothing + + //Melee settings + melee_damage_lower = 10 //huh not so bad + melee_damage_upper = 45 //oh, oh no + attacktext = list("bites","claws","slashes") + environment_smash = 99999 //It's made for destroying things + melee_miss_chance = 0 + melee_attack_minDelay = 0 + melee_attack_maxDelay = 5 + attack_armor_pen = 20 + attack_sharp = 1 + + //Attack movement settings + move_to_delay = 7 + destroy_surroundings = 1 + + //Damage resistances + shock_resistance = 1 + resistance = 99 + +/mob/living/simple_animal/hostile/tarrasque/death() + ..() + if (hasdrops) + visible_message("\The [src] is annoyed with your continued resistance and burrows into the ground!") + var/scale = /obj/item/clothing/accessory/medal/tarrasque + new scale(location) + new scale(location) + new scale(location) + new scale(location) + new scale(location) + new scale(location) + qdel(src) + +/obj/item/clothing/accessory/medal/tarrasque //IF we ever to make a siege event with this, this will be a permanent medal to win for people that survived + name = "Scale medal" + desc = "A T'rasq scale fashioned into a medal." + icon_state = "bronze" //to be sprited "scale" + +//MRX Variation +/mob/living/simple_animal/hostile/tarrasque/mrx + icon = 'icons/mob/64x64.dmi' + name = "Entity X" + pixel_x = -15 + desc = "The call of the abyss manifested. Doors have proven inefective against it." + hasdrops = 0 + health = 2000 + maxHealth = 2000 + attack_sharp = 0 + melee_attack_minDelay = 2 + melee_attack_maxDelay = 10 + view_range = 420 + size_multiplier = 1 + icon_state = "arachnid" + icon_living = "arachnid" + //icon_dead = "arachnid_dead" + icon_dead = "arachnid_stunned" //Same as dead but no blood + icon_rest = "arachnid_sleeping" + tt_desc = "Unknown Specimen" + attacktext = list("whacked","slashed","smashed") + melee_damage_lower = 0 + melee_damage_upper = 50 + universal_speak = 0 + var/alang = LANGUAGE_GALCOM + var/active_sound = 'sound/effects/kefka.ogg' + armor = list( + "melee" = 99, + "bullet" = 99, + "laser" = 99, + "energy" = 99, + "bomb" = 99, + "bio" = 100, + "rad" = 100) +//Vore stuff + vore_active = 1 + vore_capacity = 2 + vore_pounce_chance = 10 //Rare + vore_default_flags = null + vore_default_mode = DM_DIGEST + vore_standing_too = 1 + vore_icons = SA_ICON_LIVING | SA_ICON_REST +/mob/living/simple_animal/hostile/tarrasque/mrx/init_vore() + ..() + var/obj/belly/B = vore_selected + B.digest_burn = 10 //Normally this can only be 6 but since we are in code we can override this to be 10 so we dont need brute. + B.digest_brute = 0 + +/mob/living/simple_animal/hostile/tarrasque/mrx/New() + ..() + update_icon() + seedarkness = 0 + src.sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS + add_language("Xenomorph") + verbs |= /mob/living/simple_animal/hostile/tarrasque/mrx/proc/hackervoice + verbs |= /mob/living/simple_animal/hostile/tarrasque/mrx/proc/scarethelights + verbs |= /mob/living/simple_animal/hostile/tarrasque/mrx/proc/knocktheirfaces + +/mob/living/simple_animal/hostile/tarrasque/mrx/Life() + ..() + if(!pixel_x) + pixel_x = -15 + if(resting && !client) + resting = !resting + update_icon() + if (anchored) + melee_damage_upper = 0 //hacky way to stop attacks + set_light(l_range = 10, l_power = 5, l_color = COLOR_RED) //RUN BITCHES + if(!anchored) + melee_damage_upper = 50 + if(!client) + opensesame() + if(buckled) + resist() + buckled = null + if(active_sound) + while(anchored) + playsound(src.loc, "[active_sound]", 100, 0, 4) + sleep(60) + +//time for special MR X kick you in the shins and stands there code +/mob/living/simple_animal/hostile/tarrasque/mrx/DoPunch(var/atom/A) + . = ..() + if(.) // If we succeeded in hitting. + if(alang==LANGUAGE_GALCOM) + alang="Xenomorph" + else if(alang=="Xenomorph") + alang=LANGUAGE_GALCOM + flicker() + if(istype(A,/turf/simulated/wall)) + var/turf/simulated/wall/wall = A + wall.dismantle_wall(null,null,1) + if(isliving(A) && !anchored) + src.say("Run tasty treat, run~", alang,"chitters") //may hiss may not, balanced + var/mob/living/L = A + L.Weaken(5) + stop_automated_movement = 1 + anchored = 1 + melee_damage_upper = 0 + spawn(150) + stop_automated_movement = 0 + anchored = 0 + melee_damage_upper = 50 + +/mob/living/simple_animal/hostile/tarrasque/mrx/handle_regular_hud_updates() + ..() + sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS + see_in_dark = 8 + see_invisible = SEE_INVISIBLE_LEVEL_TWO +///////////////////////////////////////// +//////////////Special EX PRocs go here // Mostly for playercontrolled stuff +///////////////////////////////////////// +/mob/living/simple_animal/hostile/tarrasque/mrx/proc/opensesame() + for(var/obj/machinery/door/airlock/door in range(5, src)) + door.open(1) + door.lock(1) +/mob/living/simple_animal/hostile/tarrasque/mrx/proc/flicker() + for(var/obj/machinery/light/light in range(5, src)) + light.flicker(2) +/mob/living/simple_animal/hostile/tarrasque/mrx/proc/stopfuckingkitingme() + for(var/mob/living/carbon/human/peasant in range(2, src)) + DoPunch(peasant) +/mob/living/simple_animal/hostile/tarrasque/mrx/proc/knocktheirfaces() + set name = "Anti Kite" + set desc = "Fuck them up" + set category = "X Powers" + stopfuckingkitingme() +/mob/living/simple_animal/hostile/tarrasque/mrx/proc/hackervoice() + set name = "Door Override" + set desc = "Hacker Voice: Im in" + set category = "X Powers" + opensesame() +/mob/living/simple_animal/hostile/tarrasque/mrx/proc/scarethelights() + set name = "Light Flicker" + set desc = "Hacker Voice: Im in" + set category = "X Powers" + flicker() + +/mob/living/simple_animal/hostile/tarrasque/mrx/react_to_attack(var/mob/living/M) + return //ONly one target at a time, if he dies, we move on. diff --git a/code/modules/mob/living/simple_animal/animals/tomato.dm b/code/modules/mob/living/simple_animal/animals/tomato.dm index 711922eeb0..59da8d5bb3 100644 --- a/code/modules/mob/living/simple_animal/animals/tomato.dm +++ b/code/modules/mob/living/simple_animal/animals/tomato.dm @@ -22,3 +22,194 @@ attacktext = list("mauled") meat_type = /obj/item/weapon/reagent_containers/food/snacks/tomatomeat + +//CHOMPEDIT PIRANHA PLANT. +//When I stop being lazy I'll give this its own file -shark +//Yes I'm basing this shit on the tomato, sue me. -shark +//No longer based on tomato because evolved too far -shark +/mob/living/simple_animal/hostile/piranhaplant + name = "Piranha Plant" + desc = "It's a plant, that eats people!" + tt_desc = "Packun Flower" + + faction = "plants" + intelligence_level = SA_PLANT + + maxHealth = 50 + health = 50 + meat_type = null + + //Mob icon/appearance settings + icon = 'icons/mob/plantmobs32x32.dmi' //Thanks to vorebound mod and Estelle + icon_living = "piranha-plant" + icon_state = "piranha-plant" + icon_dead = "piranha-plant_dead" + icon_gib = "generic_gib" // The iconstate for being gibbed, optional. Defaults to a generic gib animation. + //icon_rest = null // The iconstate for resting, optional + attack_icon = 'icons/effects/effects.dmi' //Just the default, played like the weapon attack anim + attack_icon_state = "slash" //Just the default //gonna have to make teeth chomping version + + //Vore stuff + vore_active = 1 + vore_capacity = 1 + vore_pounce_chance = 10 + vore_standing_too = 1 + vore_ignores_undigestable = 0 + vore_default_mode = DM_DIGEST + vore_digest_chance = 99 + vore_absorb_chance = 0 + vore_escape_chance = 5 + vore_icons = SA_ICON_LIVING + swallowTime = 10 SECONDS //CHOMPED + + //Movement Stuff + wander = 0 // Does the mob wander around when idle? + wander_distance = 0 // How far the mob will wander before going home (assuming they are allowed to do that) + returns_home = 1 // Mob knows how to return to wherever it started + turns_per_move = 4 // How many life() cycles to wait between each wander mov? + stop_when_pulled = 0 // When set to 1 this stops the animal from moving when someone is pulling it. + follow_dist = 0 // Distance the mob tries to follow a friend + speed = 4 // Higher speed is slower, negative speed is faster. + + //Talk/Emote stuff + speak_chance = 0 // Probability that I talk (this is 'X in 200' chance since even 1/100 is pretty noisy) + reacts = 1 // Reacts to some things being said + speak = list() // Things I might say if I talk + emote_hear = list("chomps","snaps at the air") // Hearable emotes I might perform + emote_see = list() // Unlike speak_emote, the list of things in this variable only show by themselves with no spoken text. IE: Ian barks, Ian yaps + say_understood = list() // List of things to say when accepting an order + say_cannot = list() // List of things to say when they cannot comply + say_maybe_target = list() // List of things to say when they spot something barely + say_got_target = list() // List of things to say when they engage a target + reactions = list("chomp" = "!chomps",) // List of "string" = "reaction" and things they hear will be searched for string. + + //Hostility war bloodshed, RAWR + hostile = 1 // Do I even attack? + view_range = 2 // Scan for targets in this range. + investigates = 1 // Do I investigate if I saw someone briefly? + cooperative = 1 // Do I ask allies to help me? + assist_distance = 2 // Radius in which I'll ask my comrades for help. + grab_resist = 100 // Chance of me resisting a grab attempt. + taser_kill = 1 // Is the mob weak to tasers + + //Melee behaviour + melee_damage_lower = 1 // Lower bound of randomized melee damage + melee_damage_upper = 25 // Upper bound of randomized melee damage + attacktext = list("chomped","bit","hompfed","crunched","cronched") // "You are [attacktext] by the mob!" + friendly = list("nuzzles") // "The mob [friendly] the person." + //attack_sound = null // Sound to play when I attack + environment_smash = 0 // How much environment damage do I do when I hit stuff? + melee_miss_chance = 1 // percent chance to miss a melee attack. + melee_attack_minDelay = 5 // How long between attacks at least + melee_attack_maxDelay = 20 // How long between attacks at most + attack_armor_type = "bio" // What armor does this check? + attack_armor_pen = 50 // How much armor pen this attack has. + attack_sharp = 1 // Is the attack sharp? + attack_edge = 0 // Does the attack have an edge? + + //Stuff for people wanting to be a fucking plant. Weirdos + show_stat_health = 1 // Does the percentage health show in the stat panel for the mob + ai_inactive = 0 // Set to 1 to turn off most AI actions + has_hands = 1 // Set to 1 to enable the use of hands and the hands hud + humanoid_hands = 1 // Can a player in this mob use things like guns or AI cards? + //hand_form = "hands" // Used in IsHumanoidToolUser. 'Your X are not fit-'. + //hud_gears // Slots to show on the hud (typically none) + //ui_icons // Icon file path to use for the HUD, otherwise generic icons are used + //r_hand_sprite = "piranha_r" // If they have hands, //TODO make a leaf sprite for this + //l_hand_sprite = "piranha_l" // they could use some icons. + player_msg = "PLANT GO CHOMP" // Message to print to players about 'how' to play this mob on login. + +//Ranged variation +/mob/living/simple_animal/hostile/piranhaplant/spitter + //might snatch the code for that uranium ray for this since it should poison + name = "Piranha Spitter" + attack_armor_pen = 0 + //Attack ranged settings. + ranged = 1 // Do I attack at range? + shoot_range = 6 // How far away do I start shooting from? + view_range = 5 //More range, more hurt, more... plant? + rapid = 1 // Three-round-burst fire mode + firing_lines = 0 // Avoids shooting allies + projectiletype = /obj/item/projectile/energy/piranhaspit // The projectiles I shoot + projectilesound = 'sound/weapons/thudswoosh.ogg' // The sound I make when I do it + casingtype = /obj/item/weapon/reagent_containers/food/snacks/soylentgreen/piranha // What to make the hugely laggy casings pile out of + +//Piranha unique projectile +/obj/item/projectile/energy/piranhaspit + name = "piranhaspit" + icon_state = "neurotoxin" + damage = 4 //Reduced damage to 4 from 10, 3 fired projectiles mean might do 12 total if all 3 hit + damage_type = TOX + check_armour = "bio" //yup biohazard protection works here + flash_strength = 0 + agony = 10 + combustion = FALSE + +/obj/item/weapon/reagent_containers/food/snacks/soylentgreen/piranha + name = "Soylent" + desc = "This was spat out by a strange plant that eats people." + icon_state = "soylent_green" + filling_color = "#B8E6B5" + center_of_mass = list("x"=15, "y"=11) + +/obj/item/projectile/energy/piranhaspit/on_hit(var/atom/soyled) + soyl(soyled) + ..() + +/obj/item/projectile/energy/piranhaspit/proc/soyl(var/mob/M) + var/location = get_turf(M) + new /obj/item/weapon/reagent_containers/food/snacks/soylentgreen/piranha(location) + +//VORE FLUFF section and extended gut settings +/mob/living/simple_animal/hostile/piranhaplant/init_vore() + ..() + var/obj/belly/B = vore_selected + B.vore_verb = "chomp up" + B.name = "stomach" + B.desc = "You're pulled into the tight stomach of the plant. The walls knead weakly around you, coating you in thick, viscous fluids that cling to your body, that soon starts to tingle and burn..." + B.digest_burn = 0 + B.digest_brute = 12 + +/mob/living/simple_animal/hostile/piranhaplant/pitcher + icon_state = "pitcher" + icon_living = "pitcher" + name = "Pitcher Plant" + desc = "It's a plant! How pretty" + tt_desc = "Brig Flower" + health = 50 + maxHealth = 50 //starts with 50 + var/antispam = 0 + +/mob/living/simple_animal/hostile/piranhaplant/pitcher/death() + ..() + new /obj/item/weapon/reagent_containers/food/snacks/aesirsalad(location) + new /obj/item/weapon/reagent_containers/food/snacks/aesirsalad(location) + new /obj/item/weapon/reagent_containers/food/snacks/aesirsalad(location) + new /obj/item/weapon/reagent_containers/food/snacks/aesirsalad(location) + qdel(src) + +/mob/living/simple_animal/hostile/piranhaplant/pitcher/Life() + ..() + if(!anchored) + anchored=1 + if(maxHealth <= 499) //Ok maybe there are limits + maxHealth = health //Limits are merely a suggestion + if(vore_fullness && !antispam) + antispam = 1 + spawn(10) + if(maxHealth <= 499) + maxHealth += 1 + health += 1 + antispam = !antispam + + if(size_multiplier!=1*health/100) + size_multiplier=1*health/100 + update_icons() + +/mob/living/simple_animal/hostile/piranhaplant/pitcher/init_vore() + ..() + var/obj/belly/B = vore_selected + B.digest_burn = 0.5 + B.digest_brute = 0 + B.vore_verb = "slurped up" + B.name = "pitcher" diff --git a/code/modules/mob/living/simple_animal/humanoids/clown.dm b/code/modules/mob/living/simple_animal/humanoids/clown.dm index d94fa47c77..adc9527e19 100644 --- a/code/modules/mob/living/simple_animal/humanoids/clown.dm +++ b/code/modules/mob/living/simple_animal/humanoids/clown.dm @@ -15,8 +15,11 @@ move_to_delay = 2 run_at_them = 0 - cooperative = 1 - + cooperative = TRUE + firing_lines = TRUE + investigates = TRUE + assist_distance = 100 + turns_per_move = 5 stop_when_pulled = 0 @@ -47,3 +50,133 @@ speak_chance = 1 speak = list("HONK", "Honk!", "Welcome to clown planet!") emote_see = list("honks") + +//CHOMPEDIT: ALL RISE FOR CLOWN CARS, NEVER FEAR BOBO IS HERE +/mob/living/simple_animal/hostile/clown/glorious + name = "клоун" + desc = "Zhitel' slavnoy planety-klouna" + tt_desc = "slav klouna" + faction = "russian" + cold_damage_per_tick = 0 //slav fear no cold + attacktext = list("atakovan") + var/matryoshka = 1 + +/mob/living/simple_animal/hostile/clown/glorious/lesser + matryoshka = 0 + melee_damage_lower = 5 + melee_damage_upper = 5 + run_at_them = 1 + +/mob/living/simple_animal/hostile/clown/glorious/death() + ..() + playsound(src.loc, 'sound/items/bikehorn.ogg', 50, 10) + if(matryoshka) + visible_message("\The [src] opens up revealing another kloun!") + var/location = get_turf(src) + new /mob/living/simple_animal/hostile/clown/glorious/lesser(location) + +/mob/living/simple_animal/hostile/clown/cluwne + icon = 'icons/mob/animal_VG.dmi' + name = "cluwne" + desc = "This poor creature used to be human. Before it pissed off the Gods, that is. Now it is miserable, and has bikehorns for an arm." + icon_state = "cluwne" + icon_living = "cluwne" + icon_dead = "cluwne_dead" + icon_gib = "clown_gib" + speak_chance = 50 + turns_per_move = 5 + response_help = "pokes the" + response_disarm = "gently pushes aside the" + response_harm = "hits the" + speak = list("HONK", "Honk!") + speak_emote = list("squeals", "cries","sobs") + emote_hear = list("honks sadly") + speak_chance = 1 + a_intent = I_HELP + var/footstep=0 // For clownshoe noises + //deny_client_move=1 // HONK // Doesn't work right yet + + stop_when_pulled = 1 + maxHealth = 30 + health = 30 + speed = 11 + + harm_intent_damage = 1 + melee_damage_lower = 0 + melee_damage_upper = 0.1 + attacktext = "honks at" + attack_sound = 'sound/items/bikehorn.ogg' + + min_oxy = 5 + max_oxy = 0 + min_tox = 0 + max_tox = 1 + min_co2 = 0 + max_co2 = 5 + min_n2 = 0 + max_n2 = 0 + minbodytemp = 270 + maxbodytemp = 370 + heat_damage_per_tick = 15 //amount of damage applied if animal's body temperature is higher than maxbodytemp + cold_damage_per_tick = 10 //same as heat_damage_per_tick, only if the bodytemperature it's lower than minbodytemp + unsuitable_atoms_damage = 10 + +/mob/living/simple_animal/hostile/clown/cluwne/goblin + name = "clown goblin" + desc = "A tiny walking mask and clown shoes. You want to honk his nose!" + icon_state = "ClownGoblin" + icon_living = "ClownGoblin" + icon_dead = null + response_help = "honks the" + speak = list("Honk!") + speak_emote = list("sqeaks") + emote_hear = list("honks") + maxHealth = 100 + health = 100 + + view_range = 30//owo + + speed = 1 + turns_per_move = 1 + + //melee_damage_type = "BRAIN" //We dont have this for SA + +//Braindamage +/mob/living/simple_animal/hostile/clown/cluwne/DoPunch(var/atom/A) + . = ..() + if(.) // If we succeeded in hitting. + for(var/obj/machinery/light/light in range(5, src)) + light.flicker(10) + playsound(light.loc, 'sound/items/bikehorn.ogg', 50, 10) + if(isliving(A)) + var/mob/living/L = A + L.adjustBrainLoss(rand(1,2)) + L.say("HONK!") + playsound(L.loc, 'sound/items/bikehorn.ogg', 50, 10) + +/mob/living/simple_animal/hostile/retaliate/cluwne/goblin/attackby(obj/item/weapon/W, mob/user) + if(istype(W,/obj/item/weapon/pen)) //Renaming + var/n_name = copytext(sanitize(input(user, "What would you like to name this clown goblin?", "Clown Goblin Name", null) as text|null), 1, MAX_NAME_LEN*3) + if(n_name && Adjacent(user) && !user.stat) + name = "[n_name]" + return + ..() + +/mob/living/simple_animal/clowngang + name = "Pandoras box" + desc = "A honkmotherload of fun" + +/mob/living/simple_animal/clowngang/Life() + death() +/mob/living/simple_animal/clowngang/death() + ..() + new /mob/living/simple_animal/retaliate/synx/pet/clown(location) + new /mob/living/simple_animal/hostile/clown(location) + new /mob/living/simple_animal/hostile/clown(location) + new /mob/living/simple_animal/hostile/clown(location) + new /mob/living/simple_animal/hostile/clown/glorious(location) + new /mob/living/simple_animal/hostile/clown/glorious(location) + new /mob/living/simple_animal/hostile/clown/cluwne(location) + new /mob/living/simple_animal/hostile/clown/cluwne/goblin(location) + playsound(src.loc, 'sound/items/bikehorn.ogg', 50, 10) + qdel(src) diff --git a/code/modules/mob/living/simple_animal/mobject/mobjects.dm b/code/modules/mob/living/simple_animal/mobject/mobjects.dm new file mode 100644 index 0000000000..f0f4bbc508 --- /dev/null +++ b/code/modules/mob/living/simple_animal/mobject/mobjects.dm @@ -0,0 +1,92 @@ +//Mobs that may be USED like objects but are actually internally Mobs +//So the MAIN purpose of this would be something like a Mimic who turns into a crate +//Basically this will set some vars to use across them like "obj_icon" and "obj_on" + +mob/living/simple_animal/mobject + var/animal_icon + var/animal_icon_state + var/obj_icon + var/obj_icon_state + var/obj_on + var/PandL = 0 //Run both Process() and Life //Since Process takes Priority turning the mob off will also turn off Life() + var/willanchor = 1 //Var that decides if obj state is anchored or not //for PandL this means the mob will wander if 0 + var/norest = 1 //Var that makes mobject in animal state unrest automatically //simple workaround to infinite resting + var/on = 1 //Just another var to turn off the mob object processing + var/morphitem = /obj/item/weapon/wrench //Since its the most used item for anchoring this wil be default + var/powertoggle //off by default + var/altpowertoggle = 1 //on by default, turn off/on on click by hand + +mob/living/simple_animal/mobject/New() + ..() + icon = animal_icon + icon_living = animal_icon_state + +mob/living/simple_animal/mobject/attack_hand(mob/user as mob) //Togglecode + if(obj_on) + if(altpowertoggle) + if(on) + on = !on + else + on = 1 + +mob/living/simple_animal/mobject/attackby(obj/item/I, mob/user) //Togglecode + if(istype(I,morphitem)) + if(obj_on) + obj_on = !obj_on + else + obj_on = 1 + else if(istype(I,powertoggle)) + if(obj_on) + if(on) + on = !on + else + on = 1 + else + ..() + +//Life() process() Duality +mob/living/simple_animal/mobject/Life() + if(!obj_on && icon != animal_icon) + icon = animal_icon + icon_living = animal_icon_state + update_icons() + if(obj_on) + if(icon!=obj_icon) + icon = obj_icon + icon_living = obj_icon_state + update_icons() + if(willanchor) + anchored = 1 + process() + if(PandL) + ..() + else + if(norest && resting) + resting = !resting + if(anchored) + anchored = !anchored + ..() + +mob/living/simple_animal/mobject/proc/process() //proccess performed instead of Life in OBJ form. + if(!on) + return //A way to disable process() //for PandL this will also disable Life() + +mob/living/simple_animal/mobject/death() + ..() + icon = animal_icon + update_icons() + playsound(location, 'sound/effects/sparks1.ogg', 100, 0) + +mob/living/simple_animal/mobject/metamorphicfennec + name = "Metamorphic fox" + desc = "Something about this seems, off." + animal_icon = 'icons/mob/vore.dmi' + animal_icon_state = "fennec" + obj_icon = 'icons/mob/pai.dmi' + obj_icon_state = "fox" + //Process handling + PandL = 1 + willanchor = 0 + hostile = 0 + retaliate = 0 + icon_dead = "fennec_dead" //oof diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 566af1d805..c1751ef5ba 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -113,7 +113,15 @@ var/projectiletype // The projectiles I shoot var/projectilesound // The sound I make when I do it var/casingtype // What to make the hugely laggy casings pile out of - + var/ranged_message = "fires" //Fluff text for ranged mobs + var/ranged_cooldown = 0 //What the starting cooldown is on ranged attacks + var/ranged_cooldown_time = 30 //How long, in deciseconds, the cooldown of ranged attacks is + var/ranged_ignores_vision = FALSE //if it'll fire ranged attacks even if it lacks vision on its target, only works with environment smash + var/check_friendly_fire = 0 // Should the ranged mob check for friendlies when shooting + var/retreat_distance = null //If our mob runs from players when they're too close, set in tile distance. By default, mobs do not retreat. + var/minimum_distance = 1 //Minimum approach distance, so ranged mobs chase targets down, but still keep their distance set in tiles to the target, set higher to make mobs keep distance + var/move_shoot = 0 + //Mob melee settings var/melee_damage_lower = 2 // Lower bound of randomized melee damage var/melee_damage_upper = 6 // Upper bound of randomized melee damage @@ -575,9 +583,13 @@ annoyed = 50 a_intent = I_HURT RequestHelp() + if(move_shoot) + MoveAndShoot() MoveToTarget() if(STANCE_ATTACKING) annoyed = 50 + if(move_shoot) + MoveAndShoot() AttackTarget() /mob/living/simple_animal/proc/handle_supernatural() @@ -1258,23 +1270,33 @@ ai_log("AttackTarget() special",3) if(SpecialAtkTarget()) //Might not succeed/be allowed, do something else. return 1 + //AAAAH! if(distance <= 1) ai_log("AttackTarget() melee",3) PunchTarget() return 1 + //Open fire! - else if(ranged && (distance <= shoot_range)) + else if(ranged && (distance <= shoot_range) && ranged_cooldown <= world.time) ai_log("AttackTarget() ranged",3) ShootTarget(target_mob) return 1 - //They ran away! + else ai_log("AttackTarget() out of range!",3) stoplag(1) // Unfortunately this is needed to protect from ClosestDistance() sometimes not updating fast enough to prevent an infinite loop. handle_stance(STANCE_ATTACK) return 0 +/mob/living/simple_animal/proc/MoveAndShoot() + ai_log("MoveAndShoot() vs. [target_mob]",1) + var/distance = get_dist(src, target_mob) + face_atom(target_mob) + if(distance <= shoot_range && distance >= 2 && ranged_cooldown <= world.time) + ai_log("MoveAndShoot() moving and shooting",3) + ShootTarget(target_mob) + //Attack the target in melee /mob/living/simple_animal/proc/PunchTarget() if(!Adjacent(target_mob)) @@ -1347,7 +1369,7 @@ Shoot(target, src.loc, src) if(casingtype) new casingtype - + ranged_cooldown = world.time + ranged_cooldown_time return 1 //Check firing lines for faction_friends (if we're not cooperative, we don't care) @@ -1754,3 +1776,6 @@ /mob/living/simple_animal/get_nametag_desc(mob/user) return "[tt_desc]" + + + diff --git a/code/modules/mob/living/simple_animal/vore/alphachocobo.dm b/code/modules/mob/living/simple_animal/vore/alphachocobo.dm index 1f0f042515..da312cd6ff 100644 --- a/code/modules/mob/living/simple_animal/vore/alphachocobo.dm +++ b/code/modules/mob/living/simple_animal/vore/alphachocobo.dm @@ -15,7 +15,7 @@ melee_damage_upper = 30 attack_armor_pen = 25 attacktext = list("bit") - + pixel_x = -16 pixel_y = -16 old_x = -16 @@ -24,7 +24,7 @@ response_help = "rubs the" response_disarm = "gently pushes aside the" response_harm = "hits the" - + speak_chance = 1 speak = list("Wark!", "Chrp?", @@ -40,9 +40,10 @@ vore_pounce_chance = 100 vore_default_mode = DM_HOLD vore_icons = SA_ICON_LIVING - -/mob/living/simple_animal/alpha_chocobo/init_vore() - ..() + vore_capacity = 2 + +/mob/living/simple_animal/alpha_chocobo/init_vore() + ..() var/obj/belly/B = vore_selected B.name = "Stomach" B.desc = "With a quick gulp youre squeezed down into the large roc's spacious belly, though the stomach seems to be able to stretch a lot it still hugs you tightly in an almost possesive way and its owner lets out a satisfied squak." \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/vore/awoo.dm b/code/modules/mob/living/simple_animal/vore/awoo.dm index fbd6d8dac5..d71d9ba97b 100644 --- a/code/modules/mob/living/simple_animal/vore/awoo.dm +++ b/code/modules/mob/living/simple_animal/vore/awoo.dm @@ -57,5 +57,7 @@ // Activate Noms! /mob/living/simple_animal/retaliate/awoo vore_active = 1 + vore_capacity = 2 vore_pounce_chance = 40 + vore_ignores_undigestable = 0 vore_icons = SA_ICON_LIVING diff --git a/code/modules/mob/living/simple_animal/vore/bee.dm b/code/modules/mob/living/simple_animal/vore/bee.dm index 79c15059e1..7026b00ee7 100644 --- a/code/modules/mob/living/simple_animal/vore/bee.dm +++ b/code/modules/mob/living/simple_animal/vore/bee.dm @@ -42,4 +42,19 @@ // Activate Noms! /mob/living/simple_animal/retaliate/bee vore_active = 1 - vore_icons = SA_ICON_LIVING \ No newline at end of file + vore_capacity = 2 + vore_ignores_undigestable = 0 + vore_icons = SA_ICON_LIVING + + +//CHOMPEDIT Hook in for loot drop code. +/mob/living/simple_animal/retaliate/bee/death() + ..() + if(prob(50)) + visible_message("\The [src] dropped some ore!") + var/location = get_turf(src) + new /obj/item/weapon/ore/iron(location) + if(prob(20)) + visible_message("\The [src] dropped some ore!") + var/location = get_turf(src) + new /obj/item/weapon/ore/silver(location) diff --git a/code/modules/mob/living/simple_animal/vore/carp.dm b/code/modules/mob/living/simple_animal/vore/carp.dm index e4bcc95d4e..8d8ad9eca2 100644 --- a/code/modules/mob/living/simple_animal/vore/carp.dm +++ b/code/modules/mob/living/simple_animal/vore/carp.dm @@ -21,12 +21,14 @@ pixel_x = -16 pixel_y = -16 vore_capacity = 2 + vore_ignores_undigestable = 0 // Activate Noms! /mob/living/simple_animal/hostile/carp/large icon = 'icons/mob/vore64x64.dmi' vore_active = 1 vore_pounce_chance = 50 - vore_capacity = 1 + vore_capacity = 2 + vore_ignores_undigestable = 0 vore_max_size = RESIZE_HUGE vore_icons = SA_ICON_LIVING diff --git a/code/modules/mob/living/simple_animal/vore/chungus.dm b/code/modules/mob/living/simple_animal/vore/chungus.dm index aca60f0e7e..72da3f801f 100644 --- a/code/modules/mob/living/simple_animal/vore/chungus.dm +++ b/code/modules/mob/living/simple_animal/vore/chungus.dm @@ -16,6 +16,7 @@ melee_damage_lower = 5 melee_damage_upper = 15 grab_resist = 100 + attack_sound = 'sound/weapons/bite.ogg' speak_chance = 4 speak = list("Eenhhhhhhh...","What's up, doc?","Wabbit season?") diff --git a/code/modules/mob/living/simple_animal/vore/corrupt_hounds.dm b/code/modules/mob/living/simple_animal/vore/corrupt_hounds.dm index 83244887b0..46f360c571 100644 --- a/code/modules/mob/living/simple_animal/vore/corrupt_hounds.dm +++ b/code/modules/mob/living/simple_animal/vore/corrupt_hounds.dm @@ -52,8 +52,9 @@ vore_active = TRUE - vore_capacity = 1 + vore_capacity = 2 vore_pounce_chance = 15 + vore_ignores_undigestable = 0 vore_icons = SA_ICON_LIVING | SA_ICON_REST vore_stomach_name = "fuel processor" vore_stomach_flavor = "You have ended up in the fuel processor of this corrupted machine. This place was definitely not designed with safety and comfort in mind. The heated and cramped surroundings oozing potent fluids all over your form, eager to do nothing less than breaking you apart to fuel its rampage for the next few days... hours... minutes? Oh dear..." diff --git a/code/modules/mob/living/simple_animal/vore/deathclaw.dm b/code/modules/mob/living/simple_animal/vore/deathclaw.dm index 5033e1eb18..37f2e4ec0d 100644 --- a/code/modules/mob/living/simple_animal/vore/deathclaw.dm +++ b/code/modules/mob/living/simple_animal/vore/deathclaw.dm @@ -5,6 +5,7 @@ icon_dead = "deathclaw-dead" icon_living = "deathclaw" icon_state = "deathclaw" + isEdible = 0 attacktext = list("mauled") @@ -40,4 +41,31 @@ vore_max_size = RESIZE_HUGE vore_min_size = RESIZE_SMALL vore_pounce_chance = 0 // Beat them into crit before eating. + vore_ignores_undigestable = 0 vore_icons = SA_ICON_LIVING + +//CHOMPEDIT Adding mining friendly dedclaws +/mob/living/simple_animal/hostile/deathclaw/minor //or miner + name = "minor deathclaw" + desc = "Big! The size of two men! Claws as long as my hand! Ripped apart! Ripped apart!" + maxHealth = 150 + health = 150 + melee_damage_lower = 5 + melee_damage_upper = 30 + +//Activate Lootdrops +/mob/living/simple_animal/hostile/deathclaw/minor/death() + ..() + if(prob(80)) + visible_message("\The [src] dropped some ore!") + var/location = get_turf(src) + new /obj/item/weapon/ore/diamond(location) + if(prob(40)) + visible_message("\The [src] dropped some ore!") + var/location = get_turf(src) + new /obj/item/weapon/ore/uranium(location) + if(prob(1)) + visible_message("\The [src] suddenly regenerates!") + var/location = get_turf(src) + new /mob/living/simple_animal/hostile/deathclaw/minor(location) + qdel(src) diff --git a/code/modules/mob/living/simple_animal/vore/dino.dm b/code/modules/mob/living/simple_animal/vore/dino.dm index 18af3d28e1..50c7a9e80b 100644 --- a/code/modules/mob/living/simple_animal/vore/dino.dm +++ b/code/modules/mob/living/simple_animal/vore/dino.dm @@ -5,6 +5,7 @@ icon_dead = "dino-dead" icon_living = "dino" icon_state = "dino" + isEdible = 0 // By default, this is what most vore mobs are capable of. response_help = "pets" @@ -35,8 +36,9 @@ // Activate Noms! /mob/living/simple_animal/hostile/dino vore_active = 1 + vore_ignores_undigestable = 0 swallowTime = 1 SECOND // Hungry little bastards. vore_icons = SA_ICON_LIVING /mob/living/simple_animal/hostile/dino/virgo3b - faction = "virgo3b" \ No newline at end of file + faction = "virgo3b" diff --git a/code/modules/mob/living/simple_animal/vore/dragon.dm b/code/modules/mob/living/simple_animal/vore/dragon.dm index 4e895f3dd6..0e968b00b8 100644 --- a/code/modules/mob/living/simple_animal/vore/dragon.dm +++ b/code/modules/mob/living/simple_animal/vore/dragon.dm @@ -5,6 +5,7 @@ icon_dead = "reddragon-dead" icon_living = "reddragon" icon_state = "reddragon" + isEdible = 0 faction = "dragon" maxHealth = 500 // Boss @@ -30,6 +31,15 @@ pixel_x = -16 pixel_y = 0 +//CHOMPEDIT Just an easteregg on a mob that isnt really used but still. +/mob/living/simple_animal/hostile/dragon/New() + ..() + if(prob(1))//almost forgot this woops + name = "Slackwyrm" //Just an itty bitty easteregg dont mind me + desc = "A fierce dragon, well this one seems a bit more lazy. http://www.joshuawright.net/slack-wyrm-001.html" // + //Thanks to Josh Wright, the maker of slackwyrm for allowing this easteregg to exist. + + /mob/living/simple_animal/hostile/dragon/Process_Spacemove(var/check_drift = 0) return 1 //No drifting in space for space dragons! @@ -43,6 +53,7 @@ vore_active = 1 vore_capacity = 2 vore_pounce_chance = 0 // Beat them into crit before eating. + vore_ignores_undigestable = 0 vore_icons = SA_ICON_LIVING // Why a weaker subtype? diff --git a/code/modules/mob/living/simple_animal/vore/fennec.dm b/code/modules/mob/living/simple_animal/vore/fennec.dm index 1f7a869a4a..49a3e3161b 100644 --- a/code/modules/mob/living/simple_animal/vore/fennec.dm +++ b/code/modules/mob/living/simple_animal/vore/fennec.dm @@ -34,5 +34,6 @@ vore_bump_chance = 10 vore_bump_emote = "playfully lunges at" vore_pounce_chance = 40 + vore_ignores_undigestable = 0 vore_default_mode = DM_HOLD vore_icons = SA_ICON_LIVING diff --git a/code/modules/mob/living/simple_animal/vore/frog.dm b/code/modules/mob/living/simple_animal/vore/frog.dm index ae4389914b..017dd02954 100644 --- a/code/modules/mob/living/simple_animal/vore/frog.dm +++ b/code/modules/mob/living/simple_animal/vore/frog.dm @@ -24,6 +24,8 @@ /mob/living/simple_animal/hostile/frog vore_active = 1 vore_pounce_chance = 50 + vore_capacity = 2 + vore_ignores_undigestable = 0 vore_icons = SA_ICON_LIVING /mob/living/simple_animal/hostile/frog/space diff --git a/code/modules/mob/living/simple_animal/vore/horse.dm b/code/modules/mob/living/simple_animal/vore/horse.dm index 59bbfa4550..8eab675c69 100644 --- a/code/modules/mob/living/simple_animal/vore/horse.dm +++ b/code/modules/mob/living/simple_animal/vore/horse.dm @@ -34,4 +34,5 @@ // Activate Noms! /mob/living/simple_animal/horse vore_active = 1 + vore_ignores_undigestable = 0 vore_icons = SA_ICON_LIVING diff --git a/code/modules/mob/living/simple_animal/vore/jelly.dm b/code/modules/mob/living/simple_animal/vore/jelly.dm index 9d12c207cf..bcf809888b 100644 --- a/code/modules/mob/living/simple_animal/vore/jelly.dm +++ b/code/modules/mob/living/simple_animal/vore/jelly.dm @@ -30,9 +30,25 @@ emote_hear = list("squishes","spluts","splorts","sqrshes","makes slime noises") emote_see = list("undulates quietly") +//CHOMPEDIT ACTIVATING LOOT DROPS FOR JELLO NERDS +/mob/living/simple_animal/hostile/jelly/death() + ..() + var/location = get_turf(src) //lets just define this here once instead of ewverytime an if is true, less work. + if(prob(99)) + visible_message("\The [src] dropped some gel!") + new /obj/item/weapon/reagent_containers/food/snacks/gelbowl(location) //gelatinous blobs, hoe bland. + if(prob(80)) + visible_message("\The [src] dropped some can!") + new /obj/item/weapon/reagent_containers/food/drinks/cans/lemon_lime(location) //blobs have bad taste + if(prob(20)) + visible_message("\The [src] dropped some ore!") + new /obj/item/weapon/ore/uranium(location) + // Activate Noms! /mob/living/simple_animal/hostile/jelly vore_active = 1 vore_pounce_chance = 20 //Should be a percentage + vore_capacity = 2 + vore_ignores_undigestable = 0 vore_icons = SA_ICON_LIVING swallowTime = 10 SECONDS //Hungry little bastards. diff --git a/code/modules/mob/living/simple_animal/vore/lizardman.dm b/code/modules/mob/living/simple_animal/vore/lizardman.dm new file mode 100644 index 0000000000..26261fcbce --- /dev/null +++ b/code/modules/mob/living/simple_animal/vore/lizardman.dm @@ -0,0 +1,42 @@ +/mob/living/simple_animal/hostile/lizardman //CHOMPERS addition, an aggressive angry lizardman. + name = "lizardman" + desc = "That is one buff, angry lizard." + tt_desc = "E Anolis cuvieri muscular" + icon = 'icons/mob/vore32x64.dmi' + icon_state = "lizardman" + icon_living = "lizardman" + icon_dead = "lizardman-dead" + faction = "lizard" + isEdible = 0 + + maxHealth = 50 + health = 50 + speed = 4 + + investigates = TRUE + melee_damage_lower = 5 + melee_damage_upper = 15 + grab_resist = 100 + attack_sound = 'sound/weapons/bite.ogg' + + speak_chance = 4 + speak = list("Gwar!","Rawr!","Hiss.") + speak_emote = list("growls","hisses") + say_maybe_target = list("Rawr?") + say_got_target = list("GWAR!!") + response_help = "pets the" + response_disarm = "bops the" + response_harm = "hits the" + attacktext = list("bit") + friendly = list("nuzzles", "licks", "noses softly at", "noseboops", "headbumps against", "leans on", "nibbles affectionately on") + + //Variables for when people play as the lizardmen. + show_stat_health = 1 // Does the percentage health show in the stat panel for the mob + ai_inactive = 0 // Set to 1 to turn off most AI actions + has_hands = 1 // Set to 1 to enable the use of hands and the hands hud + humanoid_hands = 1 // Can a player in this mob use things like guns or AI cards? + + vore_active = TRUE + vore_capacity = 1 + vore_pounce_chance = 1 + vore_icons = SA_ICON_LIVING diff --git a/code/modules/mob/living/simple_animal/vore/metroidsSimple.dm b/code/modules/mob/living/simple_animal/vore/metroidsSimple.dm index ec940ba07a..31723d9974 100644 --- a/code/modules/mob/living/simple_animal/vore/metroidsSimple.dm +++ b/code/modules/mob/living/simple_animal/vore/metroidsSimple.dm @@ -1,103 +1,33 @@ -/mob/living/simple_animal/hostile/metroid - name = "baby metroid" - desc = "The baby the baby the baby the baby." - tt_desc = "Minimus Headamus Suckumus" - icon = 'icons/mob/vore.dmi' - icon_dead = "metroid_dead" - icon_living = "metroidbaby" - icon_state = "metroidbaby" - - faction = "metroids" - maxHealth = 50 - health = 50 - -//Metroids aren't affected by most atmospheres except cold. - min_oxy = 0 - max_oxy = 0 - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 - minbodytemp = T0C-30 - heat_damage_per_tick = 0 - cold_damage_per_tick = 40 - - melee_damage_lower = 1 - melee_damage_upper = 5 - - speak_chance = 2 - emote_hear = list("makes a wooshing sound") - emote_see = list("SKREE's") - -/mob/living/simple_animal/hostile/metroid/death() - playsound(src, 'sound/effects/metroiddeath.ogg', 50, 1) - ..() - +var/global/list/queen_amount = 0 //We only gonna want 1 queen in the world. /* -/mob/living/simple_animal/hostile/metroid/super - name = "super metroid" - desc = "Some sort of person eaty thing!" - icon = 'icons/mob/vore.dmi' - icon_dead = "metroid_dead" - icon_living = "metroid" - icon_state = "metroid" - - faction = "metroids" - maxHealth = 200 - health = 200 - -//Metroids aren't affected by most atmospheres except cold. - min_oxy = 0 - max_oxy = 0 - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 - minbodytemp = T0C-30 - heat_damage_per_tick = 0 - cold_damage_per_tick = 40 - - melee_damage_lower = 2 - melee_damage_upper = 5 - - speak_chance = 2 - emote_hear = list("makes a wooshing sound") - emote_see = list("SKREE's") - -/mob/living/simple_animal/hostile/metroid/super - vore_active = 1 - vore_pounce_chance = 75 //Pro Tip: Don't let them touch you. - vore_icons = SA_ICON_LIVING - swallowTime = 10 SECONDS //Hungry little bastards. +//The metroids' base variables! */ -/mob/living/simple_animal/hostile/metroid/mine - name = "minetroid" - desc = "Some sort of person eaty thing! But weak compared to regular Metroids!" +/mob/living/simple_animal/hostile/metroid + name = "metroid" + desc = "Some sort of person eaty thing!" tt_desc = "Headamus Suckumus" - icon = 'icons/mob/vore.dmi' + icon = 'icons/mob/metroid/small.dmi' icon_dead = "metroid_dead" icon_living = "metroid" icon_state = "metroid" - faction = "metroids" intelligence_level = SA_ANIMAL hovering = TRUE maxHealth = 25 health = 25 speed = 4 - turns_per_move = 5 response_help = "pets the" response_disarm = "gently pushes aside the" response_harm = "hits the" + harm_intent_damage = 5 + isEdible = 0 //They cannot be eaten while alive. + var/canEvolve = 1 //A variable for admins to turn off and on for when they like assign a player as a mob. I want to add a verb so that they can do it on command when the conditions are right in the future. + var/obj/machinery/atmospherics/unary/vent_pump/entry_vent //Graciously stolen from spider code -//Minetroids aren't affected by atmospheres. +//Metroids aren't affected by atmospheres. min_oxy = 0 max_oxy = 0 min_tox = 0 @@ -106,6 +36,7 @@ max_co2 = 0 min_n2 = 0 max_n2 = 0 + minbodytemp = 0 melee_damage_lower = 10 @@ -117,212 +48,1169 @@ emote_hear = list("makes a wooshing sound") emote_see = list("SKREE's") - meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat + meat_type = /obj/item/toy/figure/samus + + var/mob/living/victim = null // the person the metroid is currently feeding on + var/optimal_combat = FALSE // Used to dumb down the combat AI somewhat. If true, the metroid tends to be really dangerous to fight alone due to stunlocking. + var/power_charge = 0 + var/evo_point = 0 + var/evo_limit = 0 + var/next = null + +//Stuff for if a person is playing as a metroid. + show_stat_health = 1 // Does the percentage health show in the stat panel for the mob + ai_inactive = 0 // Set to 1 to turn off most AI actions + has_hands = 1 // Set to 1 to enable the use of hands and the hands hud + humanoid_hands = 1 // Can a player in this mob use things like guns or AI cards? + //hand_form = "hands" // Used in IsHumanoidToolUser. 'Your X are not fit-'. + //hud_gears // Slots to show on the hud (typically none) + //ui_icons // Icon file path to use for the HUD, otherwise generic icons are used + //r_hand_sprite = "piranha_r" // If they have hands, //TODO make a leaf sprite for this + //l_hand_sprite = "piranha_l" // they could use some icons. + player_msg = "SUCC." // Message to print to players about 'how' to play this mob on login. + + + + +/mob/living/simple_animal/hostile/metroid //activate noms + vore_active = 1 + vore_pounce_chance = 25 + vore_icons = SA_ICON_LIVING + isEdible = 0 + +/mob/living/simple_animal/hostile/metroid/death() + playsound(src, 'sound/effects/metroiddeath.ogg', 50, 1) + ..() + + /mob/living/simple_animal/hostile/metroid/mine + name = "Mochtroid" + desc = "Some sort of person eaty thing! But weak compared to regular Metroids!" + tt_desc = "Headamus Suckumus Weakamus" + icon = 'icons/mob/metroid/small.dmi' + icon_dead = "metroid_dead" + icon_living = "mochtroid" + icon_state = "mochtroid" + vore_active = 1 vore_pounce_chance = 50 vore_icons = SA_ICON_LIVING - swallowTime = 10 SECONDS //Hungry little bastards. + swallowTime = 10 SECONDS //You'll have time to crawl away. /mob/living/simple_animal/hostile/metroid/mine/death() playsound(src, 'sound/effects/metroiddeath.ogg', 50, 1) ..() + if(prob(20)) + visible_message("\The [src] dropped some toy!") + var/location = get_turf(src) + new /obj/item/toy/figure/samus(location) + + + + + +/mob/living/simple_animal/hostile/metroid/evolution/baby + name = "baby metroid" + desc = "The baby the baby the baby the baby the baby the baby the baby the baby." + tt_desc = "Minimus Headamus Suckumus" + icon = 'icons/mob/metroid/small.dmi' + icon_dead = "baby_dead" + icon_living = "baby" + icon_state = "baby" + intelligence_level = SA_ANIMAL + speak_emote = list("churrs") + health = 200 + maxHealth = 200 + melee_damage_lower = 1 + melee_damage_upper = 5 + melee_miss_chance = 0 + armor = list( + "melee" = 50, + "bullet" = 30, + "laser" = 80, + "energy" = 90, + "bomb" = 70, + "bio" = 100, + "rad" = 100) + gender = NEUTER + faction = "metroids" + move_to_delay = 3 + + //Metroids aren't affected by most atmospheres except cold. + minbodytemp = T0C-30 + cold_damage_per_tick = 100 + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + + + response_help = "pets" + + speak = list( + "Skree...", + "Ereeeer..." + ) + emote_hear = list() + emote_see = list( + "SKREE!" + ) + + cooperative = 1 + evo_point = 800 + evo_limit = 1000 + next = "/mob/living/simple_animal/hostile/metroid/evolution/super" + vore_active = 0 + +/mob/living/simple_animal/hostile/metroid/evolution/baby/New() + playsound(src, 'sound/metroid/metroidsee.ogg', 100, 1) + ..() + + + +//------------------------------------------------------------------------------------------------------------ + + + + +/mob/living/simple_animal/hostile/metroid/evolution/super + name = "super metroid" + desc = "Some kind of head sucky thing!" + tt_desc = "Maximus Headamus Suckumus" + icon = 'icons/mob/metroid/small.dmi' + icon_dead = "metroid_dead" + icon_living = "metroid" + icon_state = "metroid" + intelligence_level = SA_ANIMAL + speak_emote = list("churrs") + health = 250 + maxHealth = 250 + melee_damage_lower = 2 + melee_damage_upper = 5 + melee_miss_chance = 0 + armor = list( + "melee" = 50, + "bullet" = 30, + "laser" = 90, + "energy" = 90, + "bomb" = 70, + "bio" = 100, + "rad" = 100) + gender = NEUTER + faction = "metroids" + move_to_delay = 3 + + //Metroids aren't affected by most atmospheres except cold. + minbodytemp = T0C-30 + cold_damage_per_tick = 100 + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + + response_help = "pets" + + speak = list( + "Skree...", + "Ereeeer..." + ) + emote_hear = list() + emote_see = list( + "SKREE!" + ) + + cooperative = 1 + evo_point = 1200 + evo_limit = 1400 + next = "/mob/living/simple_animal/hostile/metroid/combat/alpha" + + vore_active = 1 + vore_bump_chance = 0 + vore_capacity = 1 + vore_icons = SA_ICON_LIVING + vore_pounce_chance = 25 //Metroids only eat incapacitated targets + vore_default_mode = DM_DIGEST + swallowTime = 1 SECONDS //Hungry little bastards. + vore_escape_chance = 25 + +/mob/living/simple_animal/hostile/metroid/evolution/super/New() + playsound(src, 'sound/metroid/metroidsee.ogg', 100, 1) + ..() + +/mob/living/simple_animal/hostile/metroid/evolution/super/death() + playsound(src, 'sound/metroid/metroiddeath.ogg', 100, 1) + ..() + + + + +//------------------------------------------------------------------------------------------------------------ + + + +/mob/living/simple_animal/hostile/metroid/combat/alpha + name = "alpha metroid" + desc = "Some kind of head rammy thing!" + tt_desc = "Minimus Headamus Rammamus" + icon = 'icons/mob/metroid/small.dmi' + icon_dead = "alpha_dead" + icon_living = "alpha" + icon_state = "alpha" + intelligence_level = SA_ANIMAL + health = 300 + maxHealth = 300 + melee_damage_lower = 10 + melee_damage_upper = 15 + melee_miss_chance = 5 + attacktext = list("rammed") + armor = list( + "melee" = 60, + "bullet" = 45, + "laser" = 50, + "energy" = 70, + "bomb" = 10, + "bio" = 100, + "rad" = 100) + gender = NEUTER + faction = "metroids" + move_to_delay = 3 + + //Alphas lose their vulnerability to cold. + minbodytemp = 0 + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + unsuitable_atoms_damage = 0 + + response_help = "pets" + + speak = list( + "Skree...", + "Ereeeer..." + ) + emote_hear = list() + emote_see = list( + "SKREE!" + ) + + cooperative = 1 + evo_point = 1400 + evo_limit = 1600 + next = "/mob/living/simple_animal/hostile/metroid/combat/gamma" + +/mob/living/simple_animal/hostile/metroid/combat/alpha/New() + playsound(src, 'sound/metroid/metroidsee.ogg', 100, 1) + ..() + +/mob/living/simple_animal/hostile/metroid/combat/alpha/death() + playsound(src, 'sound/metroid/metroiddeath.ogg', 100, 1) + ..() + +/mob/living/simple_animal/hostile/metroid/combat/alpha //active noms + vore_active = 1 + vore_bump_chance = 0 + vore_capacity = 1 + vore_icons = SA_ICON_LIVING + vore_pounce_chance = 15 //Alphas will try knocking targets over since they lost their stun ability from the initial phases. + vore_default_mode = DM_DIGEST + swallowTime = 3 SECONDS + vore_escape_chance = 25 + + + + + + +//------------------------------------------------------------------------------------------------------------ + + + +/mob/living/simple_animal/hostile/metroid/combat/gamma + name = "gamma metroid" + desc = "Some kind of head rammy thing! This one shoots electricity!" + tt_desc = "Maximus Headamus Rammamus" + icon = 'icons/mob/metroid/small.dmi' + icon_dead = "gamma_dead" + icon_living = "gamma" + icon_state = "gamma" + intelligence_level = SA_ANIMAL + health = 400 + maxHealth = 400 + melee_damage_lower = 10 + melee_damage_upper = 20 + melee_miss_chance = 5 + attacktext = list("rammed") + armor = list( + "melee" = 60, + "bullet" = 50, + "laser" = 50, + "energy" = 90, + "bomb" = 10, + "bio" = 100, + "rad" = 100) + gender = NEUTER + faction = "metroids" + move_to_delay = 4 + + move_shoot = 1 //Move and shoot at the same time. + ranged_cooldown = 0 //What the starting cooldown is on ranged attacks + ranged_cooldown_time = 150 //How long, in deciseconds, the cooldown of ranged attacks is + projectilesound = 'sound/weapons/taser2.ogg' + projectiletype = /obj/item/projectile/beam/stun/weak + firing_lines = 1 + cooperative = 1 + + + //Not affected by atmos. + minbodytemp = 0 + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + unsuitable_atoms_damage = 0 + + response_help = "pets" + + speak = list( + "Skree...", + "Ereeeer..." + ) + emote_hear = list() + emote_see = list( + "SKREE!" + ) + + cooperative = 1 + var/emp_chance = 20 // Beware synths + evo_point = 1400 + evo_limit = 1600 + next = "/mob/living/simple_animal/hostile/metroid/combat/zeta" + +/mob/living/simple_animal/hostile/metroid/combat/gamma/New() + playsound(src, 'sound/metroid/metroidgamma.ogg', 100, 1) + ..() + +/mob/living/simple_animal/hostile/metroid/combat/gamma/death() + playsound(src, 'sound/metroid/metroiddeath.ogg', 100, 1) + ..() + +/mob/living/simple_animal/hostile/metroid/combat/gamma //active noms + vore_active = 1 + vore_bump_chance = 0 + vore_capacity = 1 + vore_icons = SA_ICON_LIVING + vore_pounce_chance = 15 + vore_default_mode = DM_DIGEST + swallowTime = 3 SECONDS + vore_escape_chance = 20 + + + +//------------------------------------------------------------------------------------------------------------ + + + +/mob/living/simple_animal/hostile/metroid/combat/zeta + name = "zeta metroid" + desc = "Some kind of feet stompy thing!" + tt_desc = "Minimus Feetamus Walkamus" + icon = 'icons/mob/metroid/large.dmi' + icon_dead = "zeta_dead" + icon_living = "zeta" + icon_state = "zeta" + intelligence_level = SA_ANIMAL + health = 500 + maxHealth = 500 + melee_damage_lower = 15 + melee_damage_upper = 25 + melee_miss_chance = 5 + attack_armor_pen = 10 + attacktext = list("slashed") + armor = list( + "melee" = 70, + "bullet" = 60, + "laser" = 50, + "energy" = 70, + "bomb" = 10, + "bio" = 100, + "rad" = 100) + gender = NEUTER + faction = "metroids" + move_to_delay = 4 + + move_shoot = 1 //Move and shoot at the same time. + ranged_cooldown = 0 //What the starting cooldown is on ranged attacks + ranged_cooldown_time = 60 //How long, in deciseconds, the cooldown of ranged attacks is + rapid = 0 // Three-round-burst fire mode //decided to disalbe for the zeta + projectiletype = /obj/item/projectile/energy/metroidacid // The projectiles I shoot + projectilesound = 'sound/weapons/slashmiss.ogg' // The sound I make when I do it + + //Unaffected by atmos. + minbodytemp = 0 + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + unsuitable_atoms_damage = 0 + + pixel_x = -16 + pixel_y = -16 + old_x = -16 + old_y = -16 + + response_help = "pets" + + speak = list( + "Ereeeer...", + "Rerrr..." + ) + emote_hear = list() + emote_see = list( + "RAWR!" + ) + + cooperative = 1 + evo_point = 1600 + evo_limit = 1800 + next = "/mob/living/simple_animal/hostile/metroid/combat/omega" + +/mob/living/simple_animal/hostile/metroid/combat/zeta/New() + playsound(src, 'sound/metroid/metroidzeta.ogg', 100, 1) + ..() + +/mob/living/simple_animal/hostile/metroid/combat/zeta/death() + playsound(src, 'sound/metroid/metroiddeath.ogg', 100, 1) + ..() + +/mob/living/simple_animal/hostile/metroid/combat/zeta //active noms + vore_active = 1 + vore_bump_chance = 0 + vore_capacity = 1 + vore_icons = SA_ICON_LIVING + vore_pounce_chance = 20 + vore_default_mode = DM_DIGEST + swallowTime = 3 SECONDS + vore_escape_chance = 15 + + + + +//------------------------------------------------------------------------------------------------------------ + + + +/mob/living/simple_animal/hostile/metroid/combat/omega + name = "omega metroid" + desc = "Those are some big claws!" + tt_desc = "Maximus Feetamus Walkamus" + icon = 'icons/mob/metroid/large.dmi' + icon_dead = "omega_dead" + icon_living = "omega" + icon_state = "omega" + intelligence_level = SA_ANIMAL + health = 600 + maxHealth = 600 + melee_damage_lower = 25 + melee_damage_upper = 40 + melee_miss_chance = 5 + attack_armor_pen = 20 + attacktext = list("slashed") + armor = list( + "melee" = 75, + "bullet" = 60, + "laser" = 55, + "energy" = 90, + "bomb" = 10, + "bio" = 100, + "rad" = 100) + gender = NEUTER + faction = "metroids" + speed = 4 + move_to_delay = 5 + + move_shoot = 1 //Move and shoot at the same time. + ranged_cooldown = 0 //What the starting cooldown is on ranged attacks + ranged_cooldown_time = 150 //How long, in deciseconds, the cooldown of ranged attacks is + rapid = 1 // Three-round-burst fire mode + projectiletype = /obj/item/projectile/energy/metroidacid // The projectiles I shoot + projectilesound = 'sound/weapons/slashmiss.ogg' // The sound I make when I do it + + //Unaffected by atmos. + minbodytemp = 0 + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + unsuitable_atoms_damage = 0 + + old_x = -16 + old_y = 0 + default_pixel_x = -16 + pixel_x = -16 + pixel_y = 0 + + response_help = "pets" + + speak = list( + "Rurrr...", + ) + emote_hear = list() + emote_see = list( + "ROAR!" + ) + + cooperative = 1 + evo_point = 2600 + evo_limit = 3000 + next = "/mob/living/simple_animal/hostile/metroid/combat/queen" + +/mob/living/simple_animal/hostile/metroid/combat/omega/New() + playsound(src, 'sound/metroid/metroidomega.ogg', 100, 1) + ..() + +/mob/living/simple_animal/hostile/metroid/combat/omega/death() + playsound(src, 'sound/metroid/metroidomegadeath.ogg', 100, 1) + ..() + +/mob/living/simple_animal/hostile/metroid/combat/omega //active noms + vore_active = 1 + vore_bump_chance = 0 + vore_capacity = 2 + vore_icons = SA_ICON_LIVING + vore_pounce_chance = 40 + vore_default_mode = DM_DIGEST + swallowTime = 3 SECONDS + vore_escape_chance = 5 + + + + +//------------------------------------------------------------------------------------------------------------ + + + +/mob/living/simple_animal/hostile/metroid/combat/queen + name = "queen metroid" + desc = "The mother of all Metroids - allowed to have grown too far!" + tt_desc = "Maximus Queenamus Deathamus" + icon = 'icons/mob/metroid/queen.dmi' + icon_dead = "queen_dead" + icon_living = "queen" + icon_state = "queen" + intelligence_level = SA_ANIMAL + health = 1000 + maxHealth = 1000 + melee_damage_lower = 30 + melee_damage_upper = 60 + melee_miss_chance = 5 + attack_armor_pen = 20 + attacktext = list("gnashed") + armor = list( + "melee" = 75, + "bullet" = 60, + "laser" = 60, + "energy" = 90, + "bomb" = 10, + "bio" = 100, + "rad" = 100) + gender = NEUTER + faction = "metroids" + move_to_delay = 6 + + move_shoot = 1 //Move and shoot at the same time. + ranged_cooldown = 0 //What the starting cooldown is on ranged attacks + ranged_cooldown_time = 120 //How long, in deciseconds, the cooldown of ranged attacks is + rapid = 1 // Three-round-burst fire mode + projectiletype = /obj/item/projectile/energy/metroidacid // The projectiles I shoot + projectilesound = 'sound/weapons/slashmiss.ogg' // The sound I make when I do it + + //Unaffected by atmos. + minbodytemp = 0 + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + unsuitable_atoms_damage = 0 + + pixel_x = -16 + pixel_y = -16 + old_x = -16 + old_y = -16 + + response_help = "pets" + + emote_hear = list() + emote_see = list( + "ROAR!" + ) + + cooperative = 1 + evo_point = 1100 + evo_limit = INFINITY + next = null + +/mob/living/simple_animal/hostile/metroid/combat/queen/New() + playsound(src, 'sound/metroid/metroidqueen.ogg', 100, 1) + queen_amount++ + ..() + +/mob/living/simple_animal/hostile/metroid/combat/queen/death() + playsound(src, 'sound/metroid/metroidqueendeath.ogg', 100, 1) + queen_amount-- + ..() + + +/mob/living/simple_animal/hostile/metroid/combat/queen //active noms + vore_active = 1 + vore_bump_chance = 0 + vore_capacity = 4 + vore_icons = SA_ICON_LIVING + vore_pounce_chance = 60 //It's the queen, and it's hungry. + vore_default_mode = DM_DIGEST + swallowTime = 3 SECONDS + vore_escape_chance = 0 + + +//------------------------------------------------------------------------------------------------------------ + /* -/mob/living/simple_animal/hostile/metroid/alpha - name = "super metroid" - desc = "Some sort of person rammy thing!" - icon = 'icons/mob/vore.dmi' - icon_dead = "metroid_dead" - icon_living = "metroid" - icon_state = "metroid" +//Objects related to the Metroids. +//Projectile for the Metroids. +*/ - faction = "metroids" - maxHealth = 225 - health = 225 -//Metroids aren't affected by most atmospheres except cold. - min_oxy = 0 - max_oxy = 0 - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 - minbodytemp = T0C-30 - heat_damage_per_tick = 0 - cold_damage_per_tick = 40 +/obj/item/projectile/energy/metroidacid + + name = "metroid acid" + icon_state = "neurotoxin" + damage = 10 + damage_type = TOX + agony = 10 + check_armour = "bio" + armor_penetration = 50 + +//EGG! Metroid egg and its mechanics. Ripped from spiders. +/obj/effect/metroid/egg + name = "egg cluster" + desc = "It seems to pulse slightly with an inner life" + icon = 'icons/mob/metroid/small.dmi' + icon_state = "egg" + var/amount_grown = 0 + var/metroid_type = /mob/living/simple_animal/hostile/metroid/evolution/baby + New() + pixel_x = rand(3,-3) + pixel_y = rand(3,-3) + processing_objects |= src - melee_damage_lower = 10 - melee_damage_upper = 15 +/obj/effect/metroid/egg/New(var/location, var/atom/parent) + get_light_and_color(parent) + ..() - speak_chance = 2 - emote_hear = list("makes a wooshing sound") - emote_see = list("SKREE's") +/obj/effect/metroid/egg/Destroy() + processing_objects -= src + if(istype(loc, /obj/item/organ/external)) + var/obj/item/organ/external/O = loc + O.implants -= src -// Activate Noms! -/mob/living/simple_animal/hostile/metroid/alpha - vore_active = 1 - vore_pounce_chance = 75 //Pro Tip: Don't let them touch you. - vore_icons = SA_ICON_LIVING - swallowTime = 10 SECONDS //Hungry little bastards. + return ..() + +/obj/effect/metroid/egg/process() + amount_grown += rand(0,2) + if(amount_grown >= 100) + new metroid_type(src.loc, src) + qdel(src) -/mob/living/simple_animal/hostile/metroid/gamma - name = "super metroid" - desc = "Some sort of person zappy thing!" - icon = 'icons/mob/vore.dmi' - icon_dead = "metroid_dead" - icon_living = "metroid" - icon_state = "metroid" - faction = "metroids" - maxHealth = 275 - health = 275 +//------------------------------------------------------------------------------------------------------------ -//Evolutions aren't affected by atmospheres. - min_oxy = 0 - max_oxy = 0 - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 - minbodytemp = 0 - melee_damage_lower = 0 - melee_damage_upper = 0 + - speak_chance = 2 - emote_hear = list("makes a wooshing sound") - emote_see = list("SKREE's") + -// Activate Noms! -/mob/living/simple_animal/hostile/metroid/gamma - vore_active = 1 - vore_pounce_chance = 75 //Pro Tip: Don't let them touch you. - vore_icons = SA_ICON_LIVING - swallowTime = 10 SECONDS //Hungry little bastards. +/* +//LIFE STUFF, AND MECHANICS! +//FOR THE BABY AND SUPER FORMS! +*/ -/mob/living/simple_animal/hostile/metroid/zeta - name = "super metroid" - desc = "Some sort of person stompy thing!" - icon = 'icons/mob/vore.dmi' - icon_dead = "metroid_dead" - icon_living = "metroid" - icon_state = "metroid" +/mob/living/simple_animal/hostile/metroid/evolution/Life() + . = ..() - faction = "metroids" - maxHealth = 350 - health = 350 + if(canEvolve == 1 && nutrition >= evo_limit && (buckled || vore_fullness == 1)) //spit dat crap out if nutrition gets too high! + release_vore_contents() + prey_excludes.Cut() + stop_consumption() + + if(canEvolve == 1 && nutrition >= evo_point && !buckled && vore_fullness == 0 && !victim) + playsound(src, 'sound/metroid/metroidgrow.ogg', 50, 1) + paralysis = 7998 + sleep(50) + paralysis = 0 + expand_troid() + return + if(stance == 7) //Necessary to fix a bug where if their vore prey or latching victim is laying down when they evolve, they get stuck in stance 7 and do nothing. + stance = 4 + return + else + handle_idle() -//Evolutions aren't affected by atmospheres. - min_oxy = 0 - max_oxy = 0 - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 - minbodytemp = 0 +/mob/living/simple_animal/hostile/metroid/proc/expand_troid() + new next(get_turf(src)) + visible_message("\The [src] suddenly evolves!") + qdel(src) + + +/mob/living/simple_animal/hostile/metroid/evolution/handle_regular_status_updates() + if(stat != DEAD) - melee_damage_lower = 0 - melee_damage_upper = 0 + if(victim) + handle_consumption() - speak_chance = 2 - emote_hear = list("makes a wooshing sound") - emote_see = list("SKREE's") -// Activate Noms! -/mob/living/simple_animal/hostile/metroid/zeta - vore_active = 1 - vore_pounce_chance = 75 //Pro Tip: Don't let them touch you. - vore_icons = SA_ICON_LIVING - swallowTime = 10 SECONDS //Hungry little bastards. + handle_stuttering() + + ..() -/mob/living/simple_animal/hostile/metroid/omega - name = "super metroid" - desc = "Some sort of person smashy thing!" - icon = 'icons/mob/vore.dmi' - icon_dead = "metroid_dead" - icon_living = "metroid" - icon_state = "metroid" +/mob/living/simple_animal/hostile/metroid/evolution/proc/handle_idle() + //Do we have a vent ? Good, let's take a look + for(entry_vent in view(1, src)) + if(!victim && !buckled && vore_fullness == 0 && prob(90)) //10 % chance to consider a vent, to try and avoid constant vent switching + return + visible_message("\The [src] starts trying to slide itself into the vent!") + sleep(50) //Let's stop the metroid for five seconds to do its parking job + ..() + if(!victim && !buckled && vore_fullness == 0 && entry_vent.network && entry_vent.network.normal_members.len) + var/list/vents = list() + for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in entry_vent.network.normal_members) + vents.Add(temp_vent) + if(!vents.len) + entry_vent = null + return + var/obj/machinery/atmospherics/unary/vent_pump/exit_vent = pick(vents) + spawn() + visible_message("\The [src] suddenly disappears into the vent!") + loc = exit_vent + var/travel_time = round(get_dist(loc, exit_vent.loc)/2) + spawn(travel_time) + if(!exit_vent || exit_vent.welded) + forceMove(get_turf(entry_vent)) + entry_vent = null + visible_message("\The [src] suddenly appears from the vent!") + return - faction = "metroids" - maxHealth = 450 - health = 450 + forceMove(get_turf(exit_vent)) + entry_vent = null + visible_message("\The [src] suddenly appears from the vent!") + else + entry_vent = null -//Evolutions aren't affected by atmospheres. - min_oxy = 0 - max_oxy = 0 - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 - minbodytemp = 0 +/mob/living/simple_animal/hostile/metroid/evolution/proc/adjust_nutrition(input) + nutrition = between(0, nutrition + input, evo_limit) //Just is a thing to handle the stun from the metroid. - melee_damage_lower = 0 - melee_damage_upper = 0 + if(input > 0) + if(prob(input * 2)) // Gain around one level per 50 nutrition + power_charge = min(power_charge++, 10) - speak_chance = 2 - emote_hear = list("makes a wooshing sound") - emote_see = list("SKREE's") + +/mob/living/simple_animal/hostile/metroid/evolution/PunchTarget() //this segment determines what the mob does depending on its intent. + if(victim) + return // Already eatting someone. + if(!client) // AI controlled. + if( (!target_mob.lying && prob(60) || (!target_mob.lying && optimal_combat) )) // "Smart" metroids always stun first. + a_intent = I_DISARM // Stun them first. + else if(can_consume(target_mob) && target_mob.lying) + a_intent = I_GRAB // Then eat them. + else + a_intent = I_HURT // Otherwise robust them. + ai_log("PunchTarget() will [a_intent] [target_mob]",2) + ..() -// Activate Noms! -/mob/living/simple_animal/hostile/metroid/omega - vore_active = 1 - vore_pounce_chance = 75 //Pro Tip: Don't let them touch you. - vore_icons = SA_ICON_LIVING - swallowTime = 10 SECONDS //Hungry little bastards. +/mob/living/simple_animal/hostile/metroid/evolution/proc/can_consume(var/mob/living/L) //This checks to see if the mob can latch onto the target and marks it TRUE. + if(!L || !istype(L)) + to_chat(src, "This subject is incomparable...") + return FALSE + if(L.isSynthetic()) + to_chat(src, "This subject is not biological...") + return FALSE + if(L.getarmor(null, "bio") >= 75) + to_chat(src, "I cannot reach this subject's biological matter...") + return FALSE + if(istype(L, /mob/living/simple_animal/hostile/metroid)) + to_chat(src, "I cannot feed on other metroids...") + return FALSE + if(!Adjacent(L)) + to_chat(src, "This subject is too far away...") + return FALSE + if(istype(L, /mob/living/carbon) && L.getCloneLoss() >= L.getMaxHealth() * 1.5 || istype(L, /mob/living/simple_animal) && L.stat == DEAD) + to_chat(src, "This subject does not have an edible life energy...") + return FALSE + if(L.has_buckled_mobs()) + for(var/A in L.buckled_mobs) + if(istype(A, /mob/living/simple_animal/hostile/metroid)) + if(A != src) + to_chat(src, "\The [A] is already feeding on this subject...") + return FALSE + return TRUE + +/mob/living/simple_animal/hostile/metroid/evolution/proc/start_consuming(var/mob/living/L) //This segment gets the mob to latch onto the target. + if(!can_consume(L)) + return + if(!Adjacent(L)) + return + step_towards(src, L) // Get on top of them to feed. + if(loc != L.loc) + return + if(L.buckle_mob(src, forced = TRUE)) + victim = L + update_icon() + playsound(src, 'sound/metroid/metroidattach.ogg', 100, 1) + victim.visible_message("\The [src] latches onto [victim]!", + "\The [src] latches onto you!") +// stop_automated_movement = 1 + +/mob/living/simple_animal/hostile/metroid/evolution/proc/stop_consumption() + if(!victim) + return + victim.unbuckle_mob() + playsound(loc, 'sound/metroid/metroiddetach.ogg', 50, 1, -1) + victim.visible_message("\The [src] slides off of [victim]!", + "\The [src] slides off of you!") + victim = null + update_icon() + sleep(50) +// stop_automated_movement = 0 + + +/mob/living/simple_animal/hostile/metroid/evolution/proc/handle_consumption() + if(victim && can_consume(victim) && !stat) + + var/armor_modifier = abs((victim.getarmor(null, "bio") / 100) - 1) + if(istype(victim, /mob/living/carbon)) + victim.adjustCloneLoss(rand(5,6) * armor_modifier) + victim.adjustToxLoss(rand(1,2) * armor_modifier) + if(victim.health <= 0) + victim.adjustToxLoss(rand(2,4) * armor_modifier) + + else if(istype(victim, /mob/living/simple_animal)) + victim.adjustBruteLoss(rand(4, 12)) + + else + to_chat(src, "[pick("This subject is incompatable", \ + "This subject does not have a life energy", "This subject is empty", "I am not satisified", \ + "I can not feed from this subject", "I do not feel nourished", "This subject is not food")]...") + stop_consumption() + + adjust_nutrition(50 * armor_modifier) + playsound(src, 'sound/metroid/metroidattack.ogg', 50, 1) + + adjustOxyLoss(-10 * armor_modifier) //Heal yourself + adjustBruteLoss(-10 * armor_modifier) + adjustFireLoss(-10 * armor_modifier) + adjustCloneLoss(-10 * armor_modifier) + updatehealth() + if(victim) + victim.updatehealth() + else + stop_consumption() + +/mob/living/simple_animal/hostile/metroid/evolution/DoPunch(var/mob/living/L) //Metroid melee. + var/damage_to_do = rand(melee_damage_lower, melee_damage_upper) + var/armor_modifier = abs((L.getarmor(null, "bio") / 100) - 1) + + if(!Adjacent(L)) // Might've moved away in the meantime. + return + + if(istype(L)) + + if(ishuman(L)) + var/mob/living/carbon/human/H = L + // Metroid attacks can be blocked with shields. + if(H.check_shields(damage = 0, damage_source = null, attacker = src, def_zone = null, attack_text = "the attack")) + return + + switch(a_intent) + if(I_HELP) + ai_log("DoPunch() against [L], helping.",2) + L.visible_message("[src] gently pokes [L]!", + "[src] gently pokes you!") + do_attack_animation(L) + + if(I_DISARM) //The metroid does all this too try to knock the player down. + ai_log("DoPunch() against [L], disarming.",2) + var/stun_power = between(0, power_charge + rand(0, 3), 10) + + if(ishuman(L)) + stun_power *= max(H.species.siemens_coefficient,0) + + + if(prob(stun_power * 10)) + power_charge = max(0, power_charge - 3) + L.visible_message("[src] has shocked [L]!", "[src] has shocked you!") + playsound(src, 'sound/weapons/Egloves.ogg', 75, 1) + L.Weaken(4) + L.Stun(4) + do_attack_animation(L) + if(L.buckled) + L.buckled.unbuckle_mob() // To prevent an exploit where being buckled prevents metroids from jumping on you. + L.stuttering = max(L.stuttering, stun_power) + + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(5, 1, L) + s.start() + + if(prob(stun_power * 10) && stun_power >= 8) + L.adjustFireLoss(power_charge * rand(1, 2)) + + else if(prob(40)) + L.visible_message("[src] has pounced at [L]!", "[src] has pounced at you!") + playsound(src, 'sound/metroid/metroidswoosh.ogg', 75, 1) + L.Weaken(2) + do_attack_animation(L) + if(L.buckled) + L.buckled.unbuckle_mob() // To prevent an exploit where being buckled prevents metroids from jumping on you. + else + L.visible_message("[src] has tried to pounce at [L]!", "[src] has tried to pounce at you!") + playsound(src, 'sound/weapons/punchmiss.ogg', 75, 1) + do_attack_animation(L) + L.updatehealth() + return L + + if(I_GRAB) //The metroid does this to start sucking their head off. + ai_log("DoPunch() against [L], grabbing.",2) + start_consuming(L) + + + if(I_HURT) //The metroid does this if it can't latch onto the target or it decides not to try knocking them down. + ai_log("DoPunch() against [L], hurting.",2) + + L.attack_generic(src, damage_to_do, pick(attacktext)) + playsound(src, 'sound/weapons/bite.ogg', 75, 1) + + // Give the Metroid some nutrition, if applicable, even if not attached. + if(!L.isSynthetic()) + if(ishuman(L)) + if(L.getCloneLoss() < L.getMaxHealth() * 1.5) + adjust_nutrition(damage_to_do * armor_modifier) + + else if(istype(L, /mob/living/simple_animal)) + if(!ismetroid(L)) + var/mob/living/simple_animal/SA = L + if(!SA.stat) + L.attack_generic(src, damage_to_do, pick(attacktext)) + adjust_nutrition(damage_to_do * 5) -/mob/living/simple_animal/hostile/metroid/queen - name = "super metroid" - desc = "How the hell could you let this happen." - icon = 'icons/mob/vore.dmi' - icon_dead = "metroid_dead" - icon_living = "metroid" - icon_state = "metroid" + if(istype(L,/obj/mecha)) + var/obj/mecha/M = L + M.attack_generic(src, rand(melee_damage_lower, melee_damage_upper), pick(attacktext)) - faction = "metroids" - maxHealth = 575 - health = 575 -//Evolutions aren't affected by atmospheres. - min_oxy = 0 - max_oxy = 0 - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 - minbodytemp = 0 - melee_damage_lower = 0 - melee_damage_upper = 0 +/mob/living/simple_animal/hostile/metroid/evolution/attack_hand(mob/living/carbon/human/M as mob) + if(victim) // Are we eating someone? + var/fail_odds = 30 + if(victim == M) // Harder to get the metroid off if its eating you right now. + fail_odds = 60 - speak_chance = 2 - emote_hear = list("makes a wooshing sound") - emote_see = list("SKREE's") + if(prob(fail_odds)) + visible_message("[M] attempts to wrestle \the [name] off!") + playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) -// Activate Noms! -/mob/living/simple_animal/hostile/metroid/queen - vore_active = 1 - vore_pounce_chance = 75 //Pro Tip: Don't let them touch you. - vore_icons = SA_ICON_LIVING - swallowTime = 10 SECONDS //Hungry little bastards. -*/ \ No newline at end of file + else + visible_message(" [M] manages to wrestle \the [name] off!") + stop_consumption() + step_away(src,M) + paralysis = 7998 + sleep(50) + paralysis = 0 + + +/mob/living/simple_animal/hostile/metroid/evolution/FindTarget() //This makes it so it doesn't go after another target while succing. + if(victim) // Don't worry about finding another target if we're sucking on someone's head. + return + ..() + + +/mob/living/simple_animal/hostile/metroid/evolution/ClosestDistance() + if(target_mob.stat == DEAD) + return 1 // Melee (eat) the target if dead, don't shoot it. + return ..() + + +/mob/living/simple_animal/hostile/metroid/evolution/handle_resist() + if(buckled && victim && isliving(buckled) && victim == buckled) //This ensures that when it latches onto a prey, it stays latched until otherwise. It's gotta be buckled to its victim, and the victim must be alive. + return + else + ..() + + + +/mob/living/simple_animal/hostile/metroid/evolution/baby/Found(mob/living/L) + if(isliving(L)) + if(SA_attackable(L)) + if(L.faction == faction && !attack_same) + if(ishuman(L)) + var/mob/living/carbon/human/H = L + if(istype(H.species, /datum/species/monkey)) // istype() is so they'll eat the alien monkeys too. + return H // Monkeys are always food. + else + return + + if(ishuman(L)) + var/mob/living/carbon/human/H = L + if(istype(H.species, /datum/species/monkey)) // istype() is so they'll eat the alien monkeys too. + return H // Monkeys are always food. + return + + + + + + +/* +//LIFE PROCS! +//FOR THE COMBAT FORMS +*/ + + + +/mob/living/simple_animal/hostile/metroid/combat/Life() + . = ..() + + if(canEvolve == 1 && nutrition >= evo_limit && vore_fullness == TRUE) //spit dat crap out if nutrition gets too high! + release_vore_contents() + prey_excludes.Cut() + + if(canEvolve == 1 && nutrition >= evo_point && vore_fullness == 0 && next != "/mob/living/simple_animal/hostile/metroid/combat/queen") + playsound(src, 'sound/metroid/metroidgrow.ogg', 50, 1) + paralysis = 7998 + sleep(50) + paralysis = 0 + expand_troid() + return + + else if(queen_amount == 0 && prob(5) && canEvolve == 1 && nutrition >= evo_point && vore_fullness == 0 && next == "/mob/living/simple_animal/hostile/metroid/combat/queen") + playsound(src, 'sound/metroid/metroidgrow.ogg', 50, 1) + paralysis = 7998 + sleep(50) + paralysis = 0 + expand_troid() + + else if(next == null && canEvolve == 1 && nutrition >= evo_point) + playsound(src, 'sound/metroid/metroidgrow.ogg', 50, 1) + src.visible_message("\The [src] begins to lay an egg.") + stop_automated_movement = 1 + spawn(50) + new /obj/effect/metroid/egg(loc, src) + stop_automated_movement = 0 + nutrition = 400 + return + + if(stance == 7) //Necessary to fix a bug where if their prey or latching victim is laying down when they evolve, they get stuck in stance 7 and do nothing. + stance = 4 + return + + + + +/mob/living/simple_animal/hostile/metroid/combat/proc/adjust_nutrition(input) + nutrition = (nutrition + input) //It handles the metroid's nutrition gain from melee. + + + +/mob/living/simple_animal/hostile/metroid/combat/PunchTarget() //this segment determines what the mob does depending on its intent. + if(!client) // AI controlled. + a_intent = I_HURT // Otherwise robust them. + ai_log("PunchTarget() will [a_intent] [target_mob]",2) + ..() + + + +/mob/living/simple_animal/hostile/metroid/combat/DoPunch(var/mob/living/L) //Metroid actions vs the player. + var/damage_to_do = rand(melee_damage_lower, melee_damage_upper) + var/armor_modifier = abs((L.getarmor(null, "bio") / 100) - 1) + + if(!Adjacent(L)) // Might've moved away in the meantime. + return + + if(istype(L)) + if(ishuman(L)) + switch(a_intent) + if(I_HELP) + ai_log("DoPunch() against [L], helping.",2) + L.visible_message("[src] gently pokes [L]!", + "[src] gently pokes you!") + do_attack_animation(L) + + + if(I_HURT) //The metroid does this if it can't latch onto the target or it decides not to try knocking them down. + ai_log("DoPunch() against [L], hurting.",2) + + + + L.attack_generic(src, damage_to_do, pick(attacktext)) + playsound(src, 'sound/weapons/bite.ogg', 75, 1) + + // Give the Metroid some nutrition, if applicable, even if not attached. + if(!L.isSynthetic()) + if(ishuman(L)) + if(L.getCloneLoss() < L.getMaxHealth() * 1.5) + adjust_nutrition(25 + damage_to_do * armor_modifier) + + else if(istype(L, /mob/living/simple_animal)) + if(!ismetroid(L)) + var/mob/living/simple_animal/SA = L + if(!SA.stat) + L.attack_generic(src, damage_to_do, pick(attacktext)) + adjust_nutrition(damage_to_do * 4) + + + if(istype(L,/obj/mecha)) + var/obj/mecha/M = L + M.attack_generic(src, rand(melee_damage_lower, melee_damage_upper), pick(attacktext)) + + + +/mob/living/simple_animal/hostile/metroid/combat/ClosestDistance() + if(target_mob.stat == DEAD) + return 1 // Melee (eat) the target if dead, don't shoot it. + return ..() \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/vore/panther.dm b/code/modules/mob/living/simple_animal/vore/panther.dm index 454ef4d927..064da54c9b 100644 --- a/code/modules/mob/living/simple_animal/vore/panther.dm +++ b/code/modules/mob/living/simple_animal/vore/panther.dm @@ -32,4 +32,5 @@ vore_active = 1 vore_capacity = 2 vore_pounce_chance = 10 + vore_ignores_undigestable = 0 vore_icons = SA_ICON_LIVING | SA_ICON_REST diff --git a/code/modules/mob/living/simple_animal/vore/rat.dm b/code/modules/mob/living/simple_animal/vore/rat.dm index 75d201699d..53b2e73c12 100644 --- a/code/modules/mob/living/simple_animal/vore/rat.dm +++ b/code/modules/mob/living/simple_animal/vore/rat.dm @@ -16,6 +16,7 @@ melee_damage_lower = 5 melee_damage_upper = 15 grab_resist = 100 + attack_sound = 'sound/weapons/bite.ogg' speak_chance = 4 speak = list("Squeek!","SQUEEK!","Squeek?") @@ -37,8 +38,9 @@ pixel_y = 0 vore_active = TRUE - vore_capacity = 1 + vore_capacity = 2 vore_pounce_chance = 45 + vore_ignores_undigestable = 0 vore_icons = SA_ICON_LIVING | SA_ICON_REST var/life_since_foodscan = 0 @@ -127,6 +129,30 @@ food = null return . = ..() + //TFF - Time to let rats, specifically our dear Jenner, react to newspapers. Yayyyyyyy! + if(istype(O, /obj/item/weapon/newspaper)) + if (retaliate && prob(vore_pounce_chance/2)) // This is a gamble! + user.Weaken(5) //They get tackled anyway whether they're edible or not. + user.visible_message("\the [user] swats \the [src] with \the [O] and promptly gets tackled!!") + if (will_eat(user)) + stop_automated_movement = 1 + animal_nom(user) + update_icon() + stop_automated_movement = 0 + else if (!target_mob) // no using this to clear a retaliate mob's target + target_mob = user //just because you're not tasty doesn't mean you get off the hook. A swat for a swat. + AttackTarget() + LoseTarget() // only make one attempt at an attack rather than going into full rage mode + else + user.visible_message("\the [user] swats \the [src] with \the [O]!!") + release_vore_contents() + for(var/mob/living/L in living_mobs(0)) //add everyone on the tile to the do-not-eat list for a while + if(!(L in prey_excludes)) // Unless they're already on it, just to avoid fuckery. + prey_excludes += L + spawn(3600) + if(src && L) + prey_excludes -= L + ..() /mob/living/simple_animal/hostile/rat/passive/Found(var/atom/found_atom) if(!SA_attackable(found_atom)) @@ -157,3 +183,9 @@ /mob/living/simple_animal/hostile/rat/death() playsound(src, 'sound/effects/mouse_squeak_loud.ogg', 50, 1) ..() + +/mob/living/simple_animal/hostile/rat/event + maxHealth = 50 + health = 50 + speed = 4 + vore_pounce_chance = 1 diff --git a/code/modules/mob/living/simple_animal/vore/redpanda.dm b/code/modules/mob/living/simple_animal/vore/redpanda.dm index 6047425f18..1fb6c9d20c 100644 --- a/code/modules/mob/living/simple_animal/vore/redpanda.dm +++ b/code/modules/mob/living/simple_animal/vore/redpanda.dm @@ -34,6 +34,7 @@ vore_bump_chance = 10 vore_bump_emote = "playfully lunges at" vore_pounce_chance = 40 + vore_ignores_undigestable = 0 vore_default_mode = DM_HOLD // above will only matter if someone toggles it anyway vore_icons = SA_ICON_LIVING @@ -55,3 +56,40 @@ health = 100 melee_damage_lower = 10 melee_damage_upper = 20 + +/mob/living/simple_animal/redpanda/alt + icon = 'icons/mob/vore48x48.dmi' + icon_state = "wah_alt" + icon_living = "wah_alt" + icon_dead = "wah_alt_dead" + + pixel_x = -7 + +/mob/living/simple_animal/redpanda/alt/waaah + name = "waaah" + desc = "It's a waaah! Waaaaaaaaaah!" + tt_desc = "Ailurus waaahius" + icon_state = "wah_altwaaah" + icon_living = "wah_altwaaah" + icon_dead = "wah_altwaaah_dead" + + maxHealth = 150 + health = 150 + + response_help = "pats the" + response_disarm = "gently pushes aside the" + response_harm = "hits the" + + harm_intent_damage = 5 + melee_damage_lower = 5 + melee_damage_upper = 2 + attacktext = list("bapped rapidly!") + + turns_per_move = 1 + + speak_chance = 25 + speak = list("Waaah!", + "Waaah?", + "Waaaaaaaaaah!") + emote_hear = list("wahs!","wahs even more!") + emote_see = list("trundles around wahing","rears up onto their hind legs and wahs at everyone!") \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/vore/shadekin/shadekin.dm b/code/modules/mob/living/simple_animal/vore/shadekin/shadekin.dm index be47169bf0..b91937f38c 100644 --- a/code/modules/mob/living/simple_animal/vore/shadekin/shadekin.dm +++ b/code/modules/mob/living/simple_animal/vore/shadekin/shadekin.dm @@ -161,7 +161,7 @@ // TODO - Customizable per mob B.emote_lists[DM_HOLD] = list( "The walls gently squeeze against you. The wet sounds of shifting flesh against your form fill the air.", - "The hot, humid air rushes around you for a moment as the creature urps. The walls clench in around you for a moment, before relaxxing again.", + "The hot, humid air rushes around you for a moment as the creature urps. The walls clench in around you for a moment, before relaxing again.", "Your body is soaked in the fluids that cling to the churning walls. They squeeze across your form gently, conforming to your shape.", "You can feel the world around you shift and sway as the creature moves! The flesh is stretchy, doughy. You can sink into it a little ways before it bounces back, curling you into a small shape." ) @@ -200,7 +200,7 @@ . = ..() if(ability_flags & AB_PHASE_SHIFTED) density = FALSE - + //Convert spare nutrition into energy at a certain ratio if(. && nutrition > initial(nutrition) && energy < 100) nutrition = max(0, nutrition-5) @@ -208,7 +208,7 @@ /mob/living/simple_animal/shadekin/update_icon() . = ..() - + cut_overlay(tailimage) tailimage.icon_state = icon_state diff --git a/code/modules/mob/living/simple_animal/vore/shadekin/types.dm b/code/modules/mob/living/simple_animal/vore/shadekin/types.dm index fa8f4942a5..5b80d7f73a 100644 --- a/code/modules/mob/living/simple_animal/vore/shadekin/types.dm +++ b/code/modules/mob/living/simple_animal/vore/shadekin/types.dm @@ -1,3 +1,48 @@ +/////////////////////////////////////////////////////////////////CHOMPEDIT Custom shadekin mini tutorial +//Proto shadekin; AKA; Basic how to make your own shadekin; -Shark + +//Step 1; sprites; +//File for body = icons/mob/vore_shadekin.dmi +//File for tail = icons/mob/vore_shadekin64.dmi +//Sprites can be either made inside of DM or you can use a Program of your choice and save the files as PNG and then import them +//If you need help learning how to use DMs interface to import/export sprites and make states you can always ask in the discord. + +//Step 2; Code +//Now this depends on what type of eye colour you want +//For a red we use +///mob/living/simple_animal/shadekin/red +//then we simply add our shadekins name at the end (unless its used already) +/mob/living/simple_animal/shadekin/red/proto + name ="Proto" + //This here will be our shadekins name + + desc = "An invisible entity not meant for use." + //here goes a lil tidbit people can see when examining the shadekin. Multiple lines works just as on the vore part + + icon_state = "proto" + //this will most likely also be your shadekins name, it corresponds to the name you gave the tail and body state in the DMIs + //so if you named the body state "proto" and "proto-1" then icon_state should be called "proto" + + vore_stomach_flavor = "You stared into the void,\ + the void decided you look tasty,\ + now you are in the void, pretty wet" + //This is what people see when they drop into your gut! the backslashes at the end of the sentence indicate the next text will be on its own line! + + + player_msg = "Proto is you, Proto shouldn't exist" + //This message pops up when you are put into your shadekin + //I recommend you use it as a way to remind yourself of how you want to act generally as your shadekin. + +//Step 3; PR +// Assuming you already have a Fork of chompstation, make sure you got your files in order +// and then simply make a new pull request to our github. + +//Now once you pushed the new DMIs with your added sprites to our github. +//And you finished writing this code section for your shadekin and pushed that too. You are done. +//If this is your first time I recommend getting someone to look over your work. + +/////////////////////////////////////////////////////////////////CHOMPEDIT END + ///////////////////////////////////////////////////////////////// /mob/living/simple_animal/shadekin/red name = "red-eyed shadekin" @@ -247,7 +292,7 @@ name = "Rivyr" desc = "She appears to be a fluffer of some sort. Deep blue eyes and curious attitude." icon_state = "rivyr" - eye_desc = "" + eye_desc = "deep blue eyes" vore_stomach_flavor = "Blue flesh gleams in the fading light as you slip down the little mar’s gullet! \ Gooey flesh and heat surrounds your form as you’re tucked away into the darkness of her stomach! Thick slimes cling \ to you, but they seem to be harmless. The organ gently churns around you, clinging to your shape and forcing \ @@ -257,44 +302,108 @@ //thanks john /mob/living/simple_animal/shadekin/blue/niko - name = "Niko" - desc = "They appear to be a Neko of some sort, containing Glowing yellow eyes and cattitude." - icon_state = "niko" - eye_desc = "" - vore_stomach_flavor = "Look, if you had one shot, one opportunity. To seize everything you ever wanted. One moment. Would you capture it or just let it slip?" - player_msg = "You are NOT a cat, your objective is to... wait this is the wrong game." - glow_range = 5 - glow_toggle = 1 - luminosity = 5 - energy_adminbuse = 1 - hostile = "FALSE" - retaliate = "FALSE" - eye_state = 0 - attacktext = list("clawed") + name = "Niko" + desc = "They appear to be a Neko of some sort, containing Glowing yellow eyes and cattitude." + icon_state = "niko" + eye_desc = "yellow eyes" + vore_stomach_flavor = "Look, if you had one shot, one opportunity. To seize everything you ever wanted. One moment. Would you capture it or just let it slip?" + player_msg = "You are NOT a cat, your objective is to... wait this is the wrong game." + glow_range = 5 + glow_toggle = 1 + luminosity = 5 + energy_adminbuse = 1 + hostile = "FALSE" + retaliate = "FALSE" + eye_state = 0 + attacktext = list("clawed") /mob/living/simple_animal/shadekin/blue/luna - name = "Luna" - desc = "She appears to be a fuzzy critter of some sort. Her eyes shimmer a dark blue, glancing around curiously." - icon_state = "luna" - eye_desc = "e_blue" - vore_stomach_flavor = "Dark blue flesh fills your vision as you slip past the Shadekin's tongue and into the darkness \ - of her gullet. The flesh around you seems squishy and pliable and malleable to say the least, warmth rolling up \ - your body as the humid air rises across the deeper you slide into the darkness of her stomach. As you splash \ - inside, you curl up comfortably inside the walls that churn and squeeze around you, any fidgeting quickly \ - subdued by the strength of the walls, and any movement of your predator seems to coax a light sway from \ - your current prison. The slime inside stuck fairly well, though harmless - your aches and pains slowly soothing \ - up and fading away." - player_msg = "You are a shadekin that goes by the name of Luna. Curious, you have tasked yourself and yourself alone \ - with studying this foreign world. Learn their language. Learn their culture. Adapt. Everything is wonderful and new, \ - and your mind is set on retaining knowledge of these odd planescape." + name = "Luna" + desc = "She appears to be a fuzzy critter of some sort. Her eyes shimmer a dark blue, glancing around curiously." + icon_state = "luna" + eye_desc = "blue eyes" + vore_stomach_flavor = "Dark blue flesh fills your vision as you slip past the Shadekin's tongue and into the darkness \ + of her gullet. The flesh around you seems squishy and pliable and malleable to say the least, warmth rolling up \ + your body as the humid air rises across the deeper you slide into the darkness of her stomach. As you splash \ + inside, you curl up comfortably inside the walls that churn and squeeze around you, any fidgeting quickly \ + subdued by the strength of the walls, and any movement of your predator seems to coax a light sway from \ + your current prison. The slime inside stuck fairly well, though harmless - your aches and pains slowly soothing \ + up and fading away." + player_msg = "You are a shadekin that goes by the name of Luna. Curious, you have tasked yourself and yourself alone \ + with studying this foreign world. Learn their language. Learn their culture. Adapt. Everything is wonderful and new, \ + and your mind is set on retaining knowledge of these odd planescape." //"All your chickens are belong to me!" - Zylas /mob/living/simple_animal/shadekin/purple/zylas - name ="Zylas" - desc = "He's a chubby looking creature, black and grey fur accompanied by purple eyes and a large hoody." - icon_state = "zylashoody" - eye_desc = "e_purple" - vore_stomach_flavor = "You are trapped in a cramped tight space. The color purple seems to dominate your vision. \ - His walls rolled over your form as you lay trapped in his depths. There wasnt a drop of fluid in sight inside that \ - stomach. Instead, you could feel your energy slowly draining away over time, like... he was leeching off you." - player_msg = "You are Zylas. You enjoy scaring the local population and eating every chicken you find." + name ="Zylas" + desc = "He's a chubby looking creature, black and grey fur accompanied by purple eyes and a large hoody." + icon_state = "zylashoody" + eye_desc = "purple eyes" + vore_stomach_flavor = "You are trapped in a cramped tight space. The color purple seems to dominate your vision. \ + His walls rolled over your form as you lay trapped in his depths. There wasnt a drop of fluid in sight inside that \ + stomach. Instead, you could feel your energy slowly draining away over time, like... he was leeching off you." + player_msg = "You are Zylas. You enjoy scaring the local population and eating every chicken you find." + +//"Two scarves. No more, No Less." -Muninn +/mob/living/simple_animal/shadekin/blue/muninn + name ="Muninn" + desc = "A gray furred shadekin, a little on the hefty side. Rocks two scarves, one on the neck, one on the tail. \ + He seems eager to take in the various sights and sounds of the station" + icon_state = "muninn" + eye_desc = "blue eyes" + vore_stomach_flavor = "You're stuck in a warm, tight stomach. \ + A blue glow, as soft as the walls surrounding you, illuminates the cramped chamber. \ + Muninn's walls gently squeeze over your form, like a tight, yet comfortable hug. \ + The gut itself was relatively dry, only slightly damp. \ + As Muninn ambles along, you'd gently sway within. It's quite the nice place to stay for a while." + player_msg = "You are Muninn. Today you feel... Curious." + +//"Here's a little lesson in the trickeries" -Muninn +/mob/living/simple_animal/shadekin/purple/muninn + name ="Muninn" + desc = "A gray furred shadekin, a little on the hefty side. Rocks two scarves, one on the neck, one on the tail.\ + He seems a little mischevious... better keep an eye on him." + icon_state = "muninn" + eye_desc = "purple eyes" + vore_stomach_flavor = "You're stuck in a warm, tight stomach. \ + A purple glow, as soft as the walls surrounding you, illuminates the cramped chamber. \ + Muninn's walls gently squeeze over your form, like a tight hug. \ + The gut itself was relatively dry, only slightly damp. \ + It didn't seem that Muninn was digesting you. More like... sapping your energy and making you feel tired. \ + A nap in this comfortable chamber wouldn't be the worst thing, would it?" + player_msg = "You are Muninn. Today you feel... Mischevious." + +//"Hunger." - Rakshasa +/mob/living/simple_animal/shadekin/red/rakshasa + name ="Rakshasa" + desc = "A scary, black shadekin. Thier body oozes whatever goop they are made of.\ + He seems a little mischevious... better keep an eye on him." + icon_state = "rakshasa" + eye_desc = "red eyes" + eye_state = "RED_EYES" + vore_stomach_flavor = "You're floating in a warm, viscous goop, too dark to see. \ + Your efforts to find light have failed. Darkness consumes you. \ + Rakshasa's gelatenous body squeezes over your form, leaving no inch unmolested. \ + The hot goop you float in makes it hard to breathe; all consuming of space and light. \ + Your body feels hot, growing weaker, more tired. Draining. Darkness coming. \ + You struggle to stay awake while floating helplessly in the goo." + player_msg = "You are Rakshasa. You are not to directly harm crew, only consume. You never speak a language." + energy_adminbuse = 1 + maxHealth = 999999999999 + health = 999999999999 + eye_icon_state = "e_rakshasa" + +//Whealty's shadekin anno! +/mob/living/simple_animal/shadekin/purple/anno + name ="Anno" + desc = "A white furred shadekin with a chubby form. His ears seem to be close to even in length and his snout seems longer than the usual.\ + He seems energetic and playful." + icon_state = "anno" + eye_desc = "purple eyes" + vore_stomach_flavor = "You're stuck in a warm, tight stomach. \ + A purple glow, as soft as the walls surrounding you, illuminates the cramped chamber. \ + Anno's stomach walls squeeze and hug over your form somewhat tightly. \ + The gut itself was wetish and slightly slick. \ + The gut seemed somewhat inviting with the warmth and softness, yet there was an ominous feeling to it with all the noises it made.\ + You'll probably be safe in here. Probably." + player_msg = "You are Anno, you are energetic and playful" diff --git a/code/modules/mob/living/simple_animal/vore/snake.dm b/code/modules/mob/living/simple_animal/vore/snake.dm index 8d60989478..e901bfee16 100644 --- a/code/modules/mob/living/simple_animal/vore/snake.dm +++ b/code/modules/mob/living/simple_animal/vore/snake.dm @@ -5,6 +5,7 @@ icon_dead = "snake-dead" icon_living = "snake" icon_state = "snake" + isEdible = 0 faction = "snake" maxHealth = 200 @@ -24,5 +25,7 @@ /mob/living/simple_animal/hostile/giant_snake vore_active = 1 vore_pounce_chance = 25 + vore_capacity = 3 //Giant snake, high capacity + vore_ignores_undigestable = 0 vore_icons = SA_ICON_LIVING swallowTime = 2 SECONDS // Hungry little bastards. diff --git a/code/modules/mob/living/simple_animal/vore/solargrub.dm b/code/modules/mob/living/simple_animal/vore/solargrub.dm index 6e34a1c2d1..cf1fbe56af 100644 --- a/code/modules/mob/living/simple_animal/vore/solargrub.dm +++ b/code/modules/mob/living/simple_animal/vore/solargrub.dm @@ -9,7 +9,7 @@ List of things solar grubs should be able to do: */ #define SINK_POWER 1 - +var/global/list/moth_amount = 0 /mob/living/simple_animal/retaliate/solargrub name = "juvenile solargrub" desc = "A young sparkling solargrub" @@ -18,6 +18,10 @@ List of things solar grubs should be able to do: icon_living = "solargrub" icon_dead = "solargrub-dead" + var/charge = null //CHOMPEDIT The amount of power we sucked off, in K as in THOUSANDS. + var/can_evolve = 1 //CHOMPEDIT VAR to decide whether this subspecies is allowed to become a queen + var/adult_form = "/mob/living/simple_animal/retaliate/solarmoth" //CHOMPEDIT VAR that decides what mob the queen form is. ex /mob/living/simple_animal/retaliate/solarmoth + faction = "grubs" maxHealth = 50 //grubs can take a lot of harm health = 50 @@ -53,6 +57,12 @@ List of things solar grubs should be able to do: var/datum/powernet/PN // Our powernet var/obj/structure/cable/attached // the attached cable var/emp_chance = 20 // Beware synths + + + //VARS that were previously in LIFE but why tho, im porting all comments the original coder did too. + var/apc_drain_rate = 750 //Going to see if grubs are better as a minimal bother. previous value : 4000 + var/powerdraw = 100000 // previous value 150000 + /mob/living/simple_animal/retaliate/solargrub/PunchTarget() if(target_mob&& prob(emp_chance)) @@ -63,7 +73,6 @@ List of things solar grubs should be able to do: /mob/living/simple_animal/retaliate/solargrub/Life() . = ..() if(!. || ai_inactive) return - if(stance == STANCE_IDLE) //first, check for potential cables nearby to powersink var/turf/S = loc @@ -77,8 +86,8 @@ List of things solar grubs should be able to do: sparks.start() anchored = 1 PN = attached.powernet - PN.draw_power(100000) // previous value 150000 - var/apc_drain_rate = 750 //Going to see if grubs are better as a minimal bother. previous value : 4000 + PN.draw_power(powerdraw) + charge = charge + (powerdraw/1000) //This adds raw powerdraw to charge(Charge is in Ks as in 1 = 1000) for(var/obj/machinery/power/terminal/T in PN.nodes) if(istype(T.master, /obj/machinery/power/apc)) var/obj/machinery/power/apc/A = T.master @@ -90,11 +99,27 @@ List of things solar grubs should be able to do: anchored = 0 PN = null + + if(prob(1) && charge >= 32000 && can_evolve == 1 && moth_amount <= 1) //it's reading from the moth_amount global list to determine if it can evolve. + anchored = 0 + PN = attached.powernet + release_vore_contents() + prey_excludes.Cut() + moth_amount++ + death_star() + + +/mob/living/simple_animal/retaliate/solargrub/proc/death_star() + visible_message("\The [src]'s shell rips open and evolves!") + new adult_form(get_turf(src)) + qdel(src) + /mob/living/simple_animal/retaliate/solargrub //active noms vore_bump_chance = 50 vore_bump_emote = "applies minimal effort to try and slurp up" vore_active = 1 - vore_capacity = 1 + vore_capacity = 3 //Raising to three rather than two only due to how common they are + vore_ignores_undigestable = 0 vore_pounce_chance = 0 //grubs only eat incapacitated targets vore_default_mode = DM_DIGEST @@ -116,4 +141,4 @@ List of things solar grubs should be able to do: . = ..() if(. == 0 && !is_dead()) set_light(2.5, 1, COLOR_YELLOW) - return 1 + return 1 \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/vore/solargrub_subtype.dm b/code/modules/mob/living/simple_animal/vore/solargrub_subtype.dm new file mode 100644 index 0000000000..ccdeb15fd7 --- /dev/null +++ b/code/modules/mob/living/simple_animal/vore/solargrub_subtype.dm @@ -0,0 +1,37 @@ +//What belongs here? all non grubs that reuse grub code, Let's start off with grub like SMES mimics + +/mob/living/simple_animal/retaliate/solargrub/smes + name = "juvenile SMESgrub" + desc = "A young sparkling SMESgrub" + icon = 'icons/obj/power.dmi' + icon_state = "smes" + icon_living = "smes" + icon_dead = "smes" + +/mob/living/simple_animal/retaliate/solargrub/smes/big + name = "Greater SMESgrub" + desc = "A big sparkling SMESgrub" + icon = 'icons/obj/power.dmi' + icon_state = "smes" + icon_living = "smes" + icon_dead = "smes" + +/mob/living/simple_animal/retaliate/solargrub/smes/big/New() + expand_size(2) + +/mob/living/simple_animal/retaliate/solargrub/smes/proc/expand_size(var/size=null) + size_multiplier = size + update_icons() + +/obj/machinery/power/smes/buildable/outpost_substation/grub/New() + ..(0) + component_parts += new /obj/item/weapon/smes_coil/weak(src) + RCon_tag = "Unidentified_Power_Storage" + recalc_coils() + charge = 600000 //Let's do this after recalc to avoid overload issues + +/mob/living/simple_animal/retaliate/solargrub/smes/death() + ..() + /*var/obj/machinery/power/drop = */new /obj/machinery/power/smes/buildable/outpost_substation/grub(location) + //drop.charge = charge //Solargrubs dont fucking keep track of charge wtf + qdel(src) diff --git a/code/modules/mob/living/simple_animal/vore/solarmoth.dm b/code/modules/mob/living/simple_animal/vore/solarmoth.dm new file mode 100644 index 0000000000..bb763d3268 --- /dev/null +++ b/code/modules/mob/living/simple_animal/vore/solarmoth.dm @@ -0,0 +1,184 @@ +/mob/living/simple_animal/retaliate/solarmoth + name = "solarmoth" + desc = "A majestic sparkling solarmoth. Also a slight engineering hazard." + icon = 'icons/mob/solarmoth.dmi' //all of these are placeholders + icon_state = "solarmoth" + icon_living = "solarmoth" + icon_dead = "solarmoth-dead" + + faction = "grubs" + maxHealth = 400 + health = 400 + move_to_delay = 5 + + melee_damage_lower = 1 + melee_damage_upper = 5 + + speak_chance = 1 + emote_see = list("flutters") + speed = 3 + + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/grubmeat + + response_help = "pokes" + response_disarm = "pushes" + response_harm = "roughly pushes" + + // solar moths are not affected by atmos + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + minbodytemp = 0 + heat_damage_per_tick = 0 //Even if the atmos stuff doesn't work, at least it won't take any damage. + + armor = list( + "melee" = 0, + "bullet" = 90, + "laser" = 100, + "energy" = 100, + "bomb" = 100, + "bio" = 100, + "rad" = 100) + + var/mycolour = COLOR_BLUE //Variable Lighting colours + var/original_temp = null //Value to remember temp + var/set_temperature = T0C + 10000 //Sets the target point of 10k degrees celsius + var/heating_power = 100000 //This controls the strength at which it heats the environment. + var/emp_heavy = 2 + var/emp_med = 4 + var/emp_light = 7 + var/emp_long = 10 + var/poison_per_bite = 5 //grubs cause a shock when they bite someone + var/poison_type = "shockchem" + var/poison_chance = 50 + var/emp_chance = 20 // Beware synths + isEdible = 0 //You can look, but you can't lick. + +/mob/living/simple_animal/retaliate/solarmoth/PunchTarget() + //this does not require us to hit the target therefore its before we check it -shark + if(target_mob&& prob(emp_chance)) + target_mob.emp_act(4) //The weakest strength of EMP + visible_message("The moth releases a powerful shock!") + + + . = ..() + if(.) // Let's first check IF we even hit someone before injecting -shark + if(isliving(.)) + var/mob/living/L = . + if(L.reagents) + if(prob(poison_chance)) + L << "You feel a shock rushing through your veins." + L.reagents.add_reagent(poison_type, poison_per_bite) + +/* Why did we even have PunchTarget() defined twice, why does byond allow this, wot. -shark +/mob/living/simple_animal/retaliate/solarmoth/PunchTarget() + . = ..() + if(isliving(.)) + var/mob/living/L = . + if(L.reagents) + if(prob(poison_chance)) + L << "You feel a shock rushing through your veins." + L.reagents.add_reagent(poison_type, poison_per_bite) +*/ + +/mob/living/simple_animal/retaliate/solarmoth/Life() + . = ..() + if(icon_state != icon_dead) //I mean on death() Life() should disable but i guess doesnt hurt to make sure -shark + var/datum/gas_mixture/env = loc.return_air() //Gets all the information on the local air. + var/transfer_moles = 0.25 * env.total_moles //The bigger the room, the harder it is to heat the room. + var/datum/gas_mixture/removed = env.remove(transfer_moles) + var/heat_transfer = removed.get_thermal_energy_change(set_temperature) + if(heat_transfer > 0 && env.temperature < T0C + 200) //This should start heating the room at a moderate pace up to 200 degrees celsius. + heat_transfer = min(heat_transfer , heating_power) //limit by the power rating of the heater + removed.add_thermal_energy(heat_transfer) + + else if(heat_transfer > 0 && env.temperature < set_temperature) //Set temperature is 10,000 degrees celsius. So this thing will start cooking crazy hot between the temperatures of 200C and 10,000C. + heating_power = original_temp*100 //Changed to work variable -shark //FLAME ON! This will make the moth heat up the room at an incredible rate. + heat_transfer = min(heat_transfer , heating_power) //limit by the power rating of the heater. Except it's hot, so yeah. + removed.add_thermal_energy(heat_transfer) + + else + return + + env.merge(removed) + + + + //Since I'm changing hyper mode to be variable we need to store old power + original_temp = heating_power //We remember our old goal, for use in non perpetual heating level increase + +/mob/living/simple_animal/retaliate/solarmoth/proc/explode() + src.anchored = 0 + set_light(0) + if(empulse(src, emp_heavy, emp_med, emp_light, emp_long)) + qdel(src) + return + +/mob/living/simple_animal/retaliate/solarmoth/death() + explode() + ..() + +/mob/living/simple_animal/retaliate/solarmoth/gib() //This baby will explode no matter what you do to it. + explode() + ..() + + + +/mob/living/simple_animal/retaliate/solarmoth/handle_light() + . = ..() + if(. == 0 && !is_dead()) + set_light(9.5, 1, mycolour) //9.5 makes the brightness range super huge. + return 1 + + +/mob/living/simple_animal/retaliate/solarmoth //active noms + vore_bump_chance = 50 + vore_bump_emote = "applies minimal effort to try and slurp up" + vore_active = 1 + vore_capacity = 1 + vore_pounce_chance = 0 //moths only eat incapacitated targets. It's too lazy burning you to a crisp to try to pounce you + vore_default_mode = DM_DIGEST + +/mob/living/simple_animal/retaliate/solarmoth/lunarmoth + name = "lunarmoth" + desc = "A majestic sparkling lunarmoth. Also a slight engineering hazard." + + var/nospampls = 0 + + cold_damage_per_tick = 0 + //ATMOS + set_temperature = T0C - 10000 + heating_power = -100000 + //light + mycolour = COLOR_WHITE + +/mob/living/simple_animal/retaliate/solarmoth/lunarmoth/proc/chilltheglass() //Why does a coldfusion moth do this? science -shark + nospampls = 1 + if(prob(25)) + for(var/obj/machinery/light/light in range(5, src)) + if(prob(50)) + light.broken() + if(prob(10)) + for(var/obj/structure/window/window in range(5, src)) + if(prob(50)) + window.shatter() + if(prob(20)) + for(var/obj/machinery/door/firedoor/door in range(14, src)) //double viewrange + if(prob(5)) + visible_message("Emergency Shutter malfunction!") + door.blocked = 0 + door.open(1) + + spawn(100) + nospampls = 0 + +/mob/living/simple_animal/retaliate/solarmoth/lunarmoth/Life() + ..() + if(!nospampls) + chilltheglass() //shatter and broken calls for glass and lights. Also some special thing. + \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/vore/wolf.dm b/code/modules/mob/living/simple_animal/vore/wolf.dm index fe3a970ac0..f17942285d 100644 --- a/code/modules/mob/living/simple_animal/vore/wolf.dm +++ b/code/modules/mob/living/simple_animal/vore/wolf.dm @@ -24,4 +24,5 @@ // Activate Noms! /mob/living/simple_animal/hostile/wolf vore_active = 1 + vore_ignores_undigestable = 0 vore_icons = SA_ICON_LIVING diff --git a/code/modules/mob/living/simple_animal/vore/zz_vore_overrides.dm b/code/modules/mob/living/simple_animal/vore/zz_vore_overrides.dm index faa47fe8d7..3cbda2609e 100644 --- a/code/modules/mob/living/simple_animal/vore/zz_vore_overrides.dm +++ b/code/modules/mob/living/simple_animal/vore/zz_vore_overrides.dm @@ -25,6 +25,7 @@ /mob/living/simple_animal/hostile/alien vore_active = 1 + vore_ignores_undigestable = 0 icon = 'icons/mob/vore.dmi' icon_state = "xenohunter" icon_living = "xenohunter" @@ -34,6 +35,7 @@ /mob/living/simple_animal/hostile/alien/drone vore_active = 1 + vore_ignores_undigestable = 0 icon = 'icons/mob/vore.dmi' icon_state = "xenodrone" icon_living = "xenodrone" @@ -43,6 +45,7 @@ /mob/living/simple_animal/hostile/alien/sentinel vore_active = 1 + vore_ignores_undigestable = 0 icon = 'icons/mob/vore.dmi' icon_state = "xenosentinel" icon_living = "xenosentinel" @@ -52,6 +55,7 @@ /mob/living/simple_animal/hostile/alien/queen vore_active = 1 + vore_ignores_undigestable = 0 icon = 'icons/mob/vore.dmi' icon_state = "xenoqueen" icon_living = "xenoqueen" @@ -61,6 +65,7 @@ /mob/living/simple_animal/hostile/alien/queen/empress vore_active = 1 + vore_ignores_undigestable = 0 icon = 'icons/mob/vore64x64.dmi' icon_state = "queen_s" icon_living = "queen_s" @@ -76,14 +81,17 @@ vore_pounce_chance = 75 /mob/living/simple_animal/hostile/alien/sentinel/praetorian + vore_ignores_undigestable = 0 icon = 'icons/mob/vore64x64.dmi' vore_icons = SA_ICON_LIVING | SA_ICON_REST /mob/living/simple_animal/hostile/alien/queen/empress/mother + vore_ignores_undigestable = 0 vore_icons = 0 // NO VORE SPRITES /mob/living/simple_animal/hostile/bear vore_active = 1 + vore_ignores_undigestable = 0 icon = 'icons/mob/vore.dmi' icon_state = "spacebear" icon_living = "spacebear" @@ -93,9 +101,11 @@ /mob/living/simple_animal/hostile/bear/hudson name = "Hudson" + vore_ignores_undigestable = 0 /mob/living/simple_animal/hostile/bear/brown vore_active = 1 + vore_ignores_undigestable = 0 icon = 'icons/mob/vore.dmi' name = "brown bear" icon_state = "brownbear" @@ -107,12 +117,16 @@ /mob/living/simple_animal/hostile/carp icon = 'icons/mob/vore.dmi' vore_active = 1 + vore_capacity = 2 + vore_escape_time = 60 SECONDS + vore_ignores_undigestable = 0 vore_icons = SA_ICON_LIVING /mob/living/simple_animal/hostile/creature/vore vore_active = 1 // NO VORE SPRITES vore_capacity = 0 + vore_ignores_undigestable = 0 vore_pounce_chance = 0 // Only pounces if you're crit. vore_escape_chance = 0 // As such, if you're a dibshit who feeds yourself to it, you're staying down. // Overrides to non-vore version @@ -122,6 +136,7 @@ /mob/living/simple_animal/hostile/mimic vore_active = 1 + vore_ignores_undigestable = 0 // NO VORE SPRITES vore_capacity = 0 vore_pounce_chance = 33 @@ -220,9 +235,15 @@ // NO VORE SPRITES vore_max_size = RESIZE_SMALL +//TFF 21/5/19 - make deer spawn with belly? +/mob/living/simple_animal/deer + vore_active = 1 + vore_capacity = 2 /mob/living/simple_animal/hostile/carp/pike vore_active = 1 + vore_capacity = 2 + vore_ignores_undigestable = 0 // NO VORE SPRITES /mob/living/simple_animal/hostile/carp/holodeck diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 32902d7d48..2533a653d6 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -7,6 +7,8 @@ var/datum/mind/mind var/stat = 0 //Whether a mob is alive or dead. TODO: Move this to living - Nodrak + var/location = null //CHOMPEDIT the variable that death() stores the place the mob died in + var/isEdible = 1 //CHOMPEDIT switch to enable/disable mob vore for mobs, RESPECT THEIR PREFS //Not in use yet var/obj/effect/organstructure/organStructure = null diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 2c82a53c32..c7e10082d2 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -288,7 +288,8 @@ tickcomp = ((1/(world.tick_lag))*1.3) - 1.3 move_delay = move_delay + tickcomp - if(istype(mob.buckled))// VOREStation Removal - , /obj/vehicle)) + //TFF 18/4/19: Port VOREStation wheelchair speed nerf fix + if(istype(mob.buckled, /obj/vehicle) || istype(mob.buckled, /mob)) //VOREStation Edit: taur riding. I think. //manually set move_delay for vehicles so we don't inherit any mob movement penalties //specific vehicle move delays are set in code\modules\vehicles\vehicle.dm move_delay = world.time + tickcomp @@ -323,6 +324,12 @@ move_delay += 2 return mob.buckled.relaymove(mob,direct) + if(waddleToggle) + if(!mob.buckled) + animate(mob, pixel_z = 4, time = 0) + animate(pixel_z = 0, transform = turn(matrix(), pick(-12, 0, 12)), time=2) + animate(pixel_z = 0, transform = matrix(), time = 0) + //We are now going to move moving = 1 //Something with pulling things @@ -561,4 +568,4 @@ /obj/item/weapon/storage/on_loc_moved(atom/oldloc) for(var/obj/O in contents) - O.on_loc_moved(oldloc) \ No newline at end of file + O.on_loc_moved(oldloc) diff --git a/code/modules/mob/new_player/login.dm b/code/modules/mob/new_player/login.dm index 34a540ac45..8a47e980d1 100644 --- a/code/modules/mob/new_player/login.dm +++ b/code/modules/mob/new_player/login.dm @@ -2,8 +2,9 @@ var/obj/effect/lobby_image = new /obj/effect/lobby_image +//TFF 7/5/19 - Hellooooo, we're Chompers, not Polaris here. >W> /obj/effect/lobby_image - name = "Polaris" + name = "CHOMPStation" desc = "How are you reading this?" screen_loc = "1,1" diff --git a/code/modules/mob/new_player/sprite_accessories_ch.dm b/code/modules/mob/new_player/sprite_accessories_ch.dm index 65277ad228..7c72f15c3b 100644 --- a/code/modules/mob/new_player/sprite_accessories_ch.dm +++ b/code/modules/mob/new_player/sprite_accessories_ch.dm @@ -1,6 +1,5 @@ /datum/sprite_accessory/marking/ch icon = 'icons/mob/human_races/markings_ch.dmi' - orca_head name = "Orca head" icon_state = "orca_head" @@ -28,6 +27,24 @@ color_blend_mode = ICON_MULTIPLY body_parts = list(BP_L_ARM,BP_R_ARM) species_allowed = list(SPECIES_AKULA) + + zangoose_belly + name = "Mongoose Cat Belly Marking" + icon_state = "test" + body_parts = list(BP_TORSO) + species_allowed = list(SPECIES_HUMAN, SPECIES_UNATHI, SPECIES_TAJ, SPECIES_NEVREAN, SPECIES_AKULA, SPECIES_ZORREN_FLAT, SPECIES_ZORREN_HIGH, SPECIES_VULPKANIN, SPECIES_XENOCHIMERA, SPECIES_XENOHYBRID, SPECIES_VASILISSAN, SPECIES_RAPALA, SPECIES_PROTEAN, SPECIES_ALRAUNE) //This lets all races use the default hairstyles. + + head_paint_front + name = "Head Paint Front" + icon_state = "paintfront" + color_blend_mode = ICON_MULTIPLY + body_parts = list(BP_HEAD) + + head_paint_back + name = "Head Paint" + icon_state = "paint" + color_blend_mode = ICON_MULTIPLY + body_parts = list(BP_HEAD) /datum/sprite_accessory/tail/special/orca_tail name = "Orca Tail" diff --git a/code/modules/mob/new_player/sprite_accessories_vr.dm b/code/modules/mob/new_player/sprite_accessories_vr.dm index 17a264956b..be2a2e3f13 100644 --- a/code/modules/mob/new_player/sprite_accessories_vr.dm +++ b/code/modules/mob/new_player/sprite_accessories_vr.dm @@ -976,3 +976,9 @@ icon_state = "heterochromia" body_parts = list(BP_HEAD) species_allowed = list(SPECIES_HUMAN, SPECIES_UNATHI, SPECIES_TAJ, SPECIES_NEVREAN, SPECIES_AKULA, SPECIES_ZORREN_FLAT, SPECIES_ZORREN_HIGH, SPECIES_VULPKANIN, SPECIES_XENOCHIMERA, SPECIES_XENOHYBRID, SPECIES_VASILISSAN, SPECIES_RAPALA, SPECIES_PROTEAN, SPECIES_ALRAUNE) //This lets all races use the default hairstyles. + + grointojaw + name = "Groin to mouth marking" + icon_state = "grointojaw" + color_blend_mode = ICON_MULTIPLY + body_parts = list(BP_TORSO, BP_HEAD, BP_GROIN) \ No newline at end of file diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 96d0fa7be0..f6ab5dd658 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -181,6 +181,9 @@ var/datum/preferences/B = O.client.prefs for(var/language in B.alternate_languages) O.add_language(language) +//TFF: Ports VOREStation's resize module transformation proc. + O.resize(B.size_multiplier, animate = FALSE) //TFF: Add size + O.fuzzy = B.fuzzy //TFF: prefs for borgs. callHook("borgify", list(O)) O.Namepick() diff --git a/code/modules/mob/vore-icons.md b/code/modules/mob/vore-icons.md new file mode 100644 index 0000000000..21baf4f7ff --- /dev/null +++ b/code/modules/mob/vore-icons.md @@ -0,0 +1,30 @@ +# How to VORE icons + +#### Vore Icon STATE names are GENERATED based on 2 things. +* 1. The state we are using Example if we use living our vore icon var is SA_ICON_LIVING +* 2. The amount of prey in a boi. + +### What effects does this have? + +Well as an example we can use the panther who actually DOES have multive vore, + +`vore_capacity = 2` + +And has not just 1 vore icon type but 2 + +`vore_icons = SA_ICON_LIVING | SA_ICON_REST` + +Our Icon_State is `"panther"` +And our living state is the `"panther"` + +Now since we have a capacity of 2 not 1 the game will assign 4 vore slots for icon states. +These are generated out of our prior mentioned states + +The game assigns `"panther-1"` for 1 victim in gut LIVING and `"panther-2"` for 2 victim in gut LIVNING +Rest sprite follows a similiar idea simply being as follows +the base state `"panther-rest"` and then single vore `"panther-rest-1"` double vore `"panther-rest-2"` + +The REST state doesnt seem to be set within the panther.dm so it stands to reason that the game is looking for the state itself +Meaning that if my asusmption here is true you can simply add `-rest` to you original state name and the game should recognize it as rest state. + +So if we had our original state `"synx"` our 1 person vore icon state would be `"synx-1"` and so forth. diff --git a/code/modules/nifsoft/nif.dm b/code/modules/nifsoft/nif.dm index 81d9228bca..dd1ca079c4 100644 --- a/code/modules/nifsoft/nif.dm +++ b/code/modules/nifsoft/nif.dm @@ -15,7 +15,7 @@ You can also set the stat of a NIF to NIF_TEMPFAIL without any issues to disable //Nanotech Implant Foundation /obj/item/device/nif name = "nanite implant framework" - desc = "A somewhat diminished knockoff of a Kitsuhana nano working surface, in a box. Can print new \ + desc = "A somewhat diminished knockoff of a Vey-Med nano working surface, in a box. Can print new \ implants inside living hosts on the fly based on software uploads. Must be surgically \ implanted in the head to work. May eventually wear out and break." @@ -33,7 +33,7 @@ You can also set the stat of a NIF to NIF_TEMPFAIL without any issues to disable var/tmp/list/nifsofts_life = list() // Ones that want to be talked to on life() var/owner // Owner character name var/examine_msg //Message shown on examine. - + var/tmp/vision_flags = 0 // Flags implants set for faster lookups var/tmp/health_flags = 0 var/tmp/combat_flags = 0 @@ -72,9 +72,9 @@ You can also set the stat of a NIF to NIF_TEMPFAIL without any issues to disable //Put loaded data here if we loaded any save_data = islist(load_data) ? load_data.Copy() : list() var/saved_examine_msg = save_data["examine_msg"] - + //If it's an empty string, they want it blank. If null, it's never been saved, give default. - if(isnull(saved_examine_msg)) + if(isnull(saved_examine_msg)) saved_examine_msg = "There's a certain spark to their eyes." examine_msg = saved_examine_msg @@ -114,7 +114,7 @@ You can also set the stat of a NIF to NIF_TEMPFAIL without any issues to disable var/obj/item/organ/brain = H.internal_organs_by_name[O_BRAIN] if(istype(brain)) should_be_in = brain.parent_organ - + if(istype(H) && !H.nif && H.species && (loc == H.get_organ(should_be_in))) if(!bioadap && (H.species.flags & NO_SCAN)) //NO_SCAN is the default 'too complicated' flag return FALSE @@ -135,7 +135,7 @@ You can also set the stat of a NIF to NIF_TEMPFAIL without any issues to disable var/obj/item/organ/brain = H.internal_organs_by_name[O_BRAIN] if(istype(brain)) should_be_in = brain.parent_organ - + parent = H.get_organ(should_be_in) //Ok, nevermind then! if(!istype(parent)) @@ -559,9 +559,9 @@ You can also set the stat of a NIF to NIF_TEMPFAIL without any issues to disable durability = 10 /obj/item/device/nif/authentic - name = "\improper Kitsuhana NIF" - desc = "An actual Kitsuhana working surface, in a box. From a society slightly less afraid \ - of self-replicating nanotechnology. Basically just a high-endurance NIF." + name = "\improper Vey-Med NIF" + desc = "An actual Vey-Med working surface, in a box. They are said to have been stolen \ + from an internal company shipment. Basically just a high-endurance NIF." durability = 1000 /obj/item/device/nif/bioadap diff --git a/code/modules/nifsoft/nifsoft.dm b/code/modules/nifsoft/nifsoft.dm index 4307435da9..fb4ed71354 100644 --- a/code/modules/nifsoft/nifsoft.dm +++ b/code/modules/nifsoft/nifsoft.dm @@ -242,7 +242,7 @@ stored = /datum/nifsoft/package/security /datum/nifsoft/package/security - software = list(/datum/nifsoft/ar_sec,/datum/nifsoft/flashprot) + software = list(/datum/nifsoft/ar_sec,/datum/nifsoft/cameramonitor,/datum/nifsoft/flashprot) //TFF: Add Station Alarms - Sec version /obj/item/weapon/storage/box/nifsofts_security name = "security nifsoft disks" @@ -265,7 +265,7 @@ stored = /datum/nifsoft/package/engineering /datum/nifsoft/package/engineering - software = list(/datum/nifsoft/ar_eng,/datum/nifsoft/uvblocker) + software = list(/datum/nifsoft/ar_eng,/datum/nifsoft/alarmmonitor,/datum/nifsoft/uvblocker) //TFF: Add Station Alarms - Eng version /obj/item/weapon/storage/box/nifsofts_engineering name = "engineering nifsoft disks" @@ -321,4 +321,4 @@ /obj/item/weapon/storage/box/nifsofts_mining/New() ..() for(var/i = 0 to 7) - new /obj/item/weapon/disk/nifsoft/mining(src) \ No newline at end of file + new /obj/item/weapon/disk/nifsoft/mining(src) diff --git a/code/modules/nifsoft/software/05_health.dm b/code/modules/nifsoft/software/05_health.dm index 2337d58029..a8a3cef720 100644 --- a/code/modules/nifsoft/software/05_health.dm +++ b/code/modules/nifsoft/software/05_health.dm @@ -1,32 +1,4 @@ -/datum/nifsoft/crewmonitor - name = "Crew Monitor" - desc = "A link to the local crew monitor sensors. Useful for finding people in trouble." - list_pos = NIF_CREWMONITOR - access = access_medical - cost = 1250 - p_drain = 0.025 - var/datum/nano_module/crew_monitor/arscreen - - New() - ..() - arscreen = new(nif) - - Destroy() - qdel_null(arscreen) - return ..() - - activate() - if((. = ..())) - arscreen.ui_interact(nif.human,"main",null,1,nif_state) - return TRUE - - deactivate() - if((. = ..())) - return TRUE - - stat_text() - return "Show Monitor" - +//TFF: Removed Crew Monitor, moved to an appropriate file. /datum/nifsoft/medichines_org name = "Medichines" desc = "An internal swarm of nanites to make sure you stay in good shape and to promote healing, or to preserve you if you are critically injured." @@ -61,16 +33,20 @@ if(HP_percent >= 0.9) if(mode) nif.notify("User Status: NORMAL. Medichines deactivating.") + H << 'sound/voice/nifmed_normal.ogg' deactivate() return TRUE else if(!mode && HP_percent < 0.8) nif.notify("User Status: INJURED. Commencing medichine routines.",TRUE) + H << 'sound/voice/nifmed_injured.ogg' activate() else if(mode == 1 && HP_percent < 0.2) nif.notify("User Status: DANGER. Seek medical attention!",TRUE) + H << 'sound/voice/nifmed_danger.ogg' mode = 2 else if(mode == 2 && HP_percent < -0.4) nif.notify("User Status: CRITICAL. Notifying medical, and starting emergency stasis!",TRUE) + H << 'sound/voice/nifmed_critical.ogg' mode = 3 if(!ishuman(H.loc)) //Not notified in case of vore, for gameplay purposes. var/turf/T = get_turf(H) @@ -229,4 +205,4 @@ return TRUE stat_text() - return "Store Backup" \ No newline at end of file + return "Store Backup" diff --git a/code/modules/nifsoft/software/06_screens.dm b/code/modules/nifsoft/software/06_screens.dm new file mode 100644 index 0000000000..4d33bf1d50 --- /dev/null +++ b/code/modules/nifsoft/software/06_screens.dm @@ -0,0 +1,88 @@ +//TFF: Ports monitors for NIFs from VOREStation. Adding notes for what does what. + +/datum/nifsoft/crewmonitor //TFF: Medical access - like with AR-M glasses, allows one to keep track of who needs medical help. + name = "Crew Monitor" + desc = "A link to the local crew monitor sensors. Useful for finding people in trouble." + list_pos = NIF_MEDMONITOR + access = access_medical + cost = 1250 + p_drain = 0.025 + var/datum/nano_module/crew_monitor/arscreen + + New() + ..() + arscreen = new(nif) + + Destroy() + qdel_null(arscreen) + return ..() + + activate() + if((. = ..())) + arscreen.ui_interact(nif.human,"main",null,1,nif_state) + return TRUE + + deactivate() + if((. = ..())) + return TRUE + + stat_text() + return "Show Monitor" + +/datum/nifsoft/alarmmonitor //TFF: Monitor for station alarms - Engy access + name = "Alarm Monitor" + desc = "A link to the local alarm monitors. Useful for detecting alarms in a pinch." + list_pos = NIF_ENGMONITOR + access = access_engine + cost = 1250 + p_drain = 0.025 + var/datum/nano_module/alarm_monitor/engineering/arscreen + + New() + ..() + arscreen = new(nif) + + Destroy() + qdel_null(arscreen) + return ..() + + activate() + if((. = ..())) + arscreen.ui_interact(nif.human,"main",null,1,nif_state) + return TRUE + + deactivate() + if((. = ..())) + return TRUE + + stat_text() + return "Show Monitor" + +/datum/nifsoft/cameramonitor //TFF: Sec access - Alarm Monitor, Sec version, allows Sec to see if there's a busted camera or motion where there shouldn't be motion. + name = "Security Monitor" + desc = "A link to the local camera alarm monitors. Useful for knowing where the trouble is." + list_pos = NIF_SECMONITOR + access = access_security + cost = 1250 + p_drain = 0.025 + var/datum/nano_module/alarm_monitor/security/arscreen + + New() + ..() + arscreen = new(nif) + + Destroy() + qdel_null(arscreen) + return ..() + + activate() + if((. = ..())) + arscreen.ui_interact(nif.human,"main",null,1,nif_state) + return TRUE + + deactivate() + if((. = ..())) + return TRUE + + stat_text() + return "Show Monitor" diff --git a/code/modules/organs/organ_external_vr.dm b/code/modules/organs/organ_external_vr.dm index 0e3fb07d9e..654b392d35 100644 --- a/code/modules/organs/organ_external_vr.dm +++ b/code/modules/organs/organ_external_vr.dm @@ -1,4 +1,6 @@ //Sideways override for nanoform limbs (ugh) +/obj/item/organ/external + var/transparent = 0 //For better slime limbs /obj/item/organ/external/robotize(var/company, var/skip_prosthetics = FALSE, var/keep_organs = FALSE) var/original_robotic = robotic if(original_robotic >= ORGAN_NANOFORM) diff --git a/code/modules/organs/organ_icon.dm b/code/modules/organs/organ_icon.dm index 69f897fa58..47e5ff34ea 100644 --- a/code/modules/organs/organ_icon.dm +++ b/code/modules/organs/organ_icon.dm @@ -190,7 +190,7 @@ var/global/list/limb_icon_cache = list() /obj/item/organ/external/proc/apply_colouration(var/icon/applying) - if(nonsolid) + if(transparent) //VOREStation Edit applying.MapColors("#4D4D4D","#969696","#1C1C1C", "#000000") if(species && species.get_bodytype(owner) != SPECIES_HUMAN) applying.SetIntensity(1) // Unathi, Taj and Skrell have -very- dark base icons. VOREStation edit fixes this and brings the number back to 1 @@ -212,14 +212,14 @@ var/global/list/limb_icon_cache = list() //VOREStation Edit - Support for species.color_mult if(species && species.color_mult) applying.Blend(rgb(s_col[1], s_col[2], s_col[3]), ICON_MULTIPLY) - icon_cache_key += "_color_[s_col[1]]_[s_col[2]]_[s_col[3]]_[ICON_MULTIPLY]" + icon_cache_key += "_color_[s_col[1]]_[s_col[2]]_[s_col[3]]_[transparent]_[ICON_MULTIPLY]" else applying.Blend(rgb(s_col[1], s_col[2], s_col[3]), ICON_ADD) - icon_cache_key += "_color_[s_col[1]]_[s_col[2]]_[s_col[3]]_[ICON_ADD]" + icon_cache_key += "_color_[s_col[1]]_[s_col[2]]_[s_col[3]]_[transparent]_[ICON_ADD]" //VOREStation Edit End // Translucency. - if(nonsolid) applying += rgb(,,,180) // SO INTUITIVE TY BYOND + if(transparent) applying += rgb(,,,180) // SO INTUITIVE TY BYOND //VOREStation Edit return applying diff --git a/code/modules/organs/robolimbs_vr.dm b/code/modules/organs/robolimbs_vr.dm index ee689e3237..d4979b85a4 100644 --- a/code/modules/organs/robolimbs_vr.dm +++ b/code/modules/organs/robolimbs_vr.dm @@ -5,8 +5,8 @@ //////////////// For-specific-character fluff ones ///////////////// // arokha : Aronai Kadigan -/datum/robolimb/kitsuhana - company = "Kitsuhana" +/datum/robolimb/dsi_aronai + company = "DSI - Aronai" desc = "This limb seems rather vulpine and fuzzy, with realistic-feeling flesh." icon = 'icons/mob/human_races/cyberlimbs/_fluff_vr/aronai.dmi' blood_color = "#5dd4fc" @@ -16,8 +16,8 @@ suggested_species = "Tajara" whitelisted_to = list("arokha") -/obj/item/weapon/disk/limb/kitsuhana - company = "Kitsuhana" +/obj/item/weapon/disk/limb/dsi_aronai + company = "DSI - Aronai" // silencedmp5a5 : Serdykov Antoz /datum/robolimb/white_kryten diff --git a/code/modules/organs/subtypes/slime_vr.dm b/code/modules/organs/subtypes/slime_vr.dm index 270b194f5d..5ae87eb61e 100644 --- a/code/modules/organs/subtypes/slime_vr.dm +++ b/code/modules/organs/subtypes/slime_vr.dm @@ -1,22 +1,43 @@ /obj/item/organ/external/chest/unbreakable/slime + transparent = 1 max_damage = 50 + /obj/item/organ/external/groin/unbreakable/slime + transparent = 1 max_damage = 30 + /obj/item/organ/external/arm/unbreakable/slime + transparent = 1 max_damage = 8 + /obj/item/organ/external/arm/right/unbreakable/slime + transparent = 1 max_damage = 8 + /obj/item/organ/external/leg/unbreakable/slime + transparent = 1 max_damage = 8 + /obj/item/organ/external/leg/right/unbreakable/slime + transparent = 1 max_damage = 8 + /obj/item/organ/external/foot/unbreakable/slime + transparent = 1 max_damage = 8 + /obj/item/organ/external/foot/right/unbreakable/slime + transparent = 1 max_damage = 8 + /obj/item/organ/external/hand/unbreakable/slime + transparent = 1 max_damage = 8 + /obj/item/organ/external/hand/right/unbreakable/slime + transparent = 1 max_damage = 8 + /obj/item/organ/external/head/unbreakable/slime + transparent = 1 max_damage = 8 diff --git a/code/modules/paperwork/paperplane.dm b/code/modules/paperwork/paperplane.dm index 3b4833a533..92f2aa6d28 100644 --- a/code/modules/paperwork/paperplane.dm +++ b/code/modules/paperwork/paperplane.dm @@ -11,6 +11,35 @@ var/obj/item/weapon/paper/internalPaper +//CHOMPEDIT This should let micros ride paper airplanes + +/obj/item/weapon/paperplane/attackby(var/obj/item/I, var/mob/user) + if(istype(I,/obj/item/weapon/holder/micro)) + var/full = 0 + for(var/mob/M in src) + full++ + if(full >= 2) + to_chat(user,"You can't fit anyone else into \the [src]!") + else + var/obj/item/weapon/holder/micro/holder = I + if(holder.held_mob && holder.held_mob in holder) + to_chat(holder.held_mob,"[user] stuffs you into \the [src]!") + holder.held_mob.forceMove(src) + to_chat(user,"You stuff \the [holder.held_mob] into \the [src]!") + else + ..() + +/obj/item/weapon/paperplane/proc/clear_mobs(var/mob/user) + for(var/mob/M in src) + M.forceMove(get_turf(user)) + to_chat(M,"[user] shakes you out of \the [src]!") + to_chat(user,"You shake [M] out of \the [src]!") + + + +//END CHOMPEDIT + + /obj/item/weapon/paperplane/New(loc, obj/item/weapon/paper/newPaper) . = ..() pixel_y = rand(-8, 8) @@ -46,6 +75,7 @@ overlays += stampoverlay /obj/item/weapon/paperplane/attack_self(mob/user) + clear_mobs(user) to_chat(user, "You unfold [src].") var/atom/movable/internal_paper_tmp = internalPaper internal_paper_tmp.forceMove(loc) diff --git a/code/modules/power/cells/power_cells_ch.dm b/code/modules/power/cells/power_cells_ch.dm new file mode 100644 index 0000000000..a192ce0587 --- /dev/null +++ b/code/modules/power/cells/power_cells_ch.dm @@ -0,0 +1,59 @@ +/obj/item/weapon/cell/high/hightech + name = "Self-charging power cell" + origin_tech = list(TECH_POWER = 7) + icon_state = "hcell" + maxcharge = 2000//Trade in charge for recharge + matter = list(DEFAULT_WALL_MATERIAL = 1000, "glass" = 100) + description_info = "This 'cell' holds a max charge of 2k and self recharges over time." + self_recharge = TRUE + +/obj/item/weapon/cell/high/hightech/empty/New() + ..() + charge = 0 + +/obj/item/weapon/cell/device/weapon/hightech + name = "Self-charging weapon power cell" + icon_state = "wcell" + maxcharge = 1000 + charge_amount = 20 + desc = "This 'cell' holds a max charge of 1k and self recharges over time. It is specialized for weaponary although a bit too small for some weapons" + self_recharge = TRUE + origin_tech = list(TECH_POWER = 7, TECH_MATERIAL = 6,TECH_BLUESPACE = 6,TECH_COMBAT = 1) + +/obj/item/weapon/cell/device/hightech + name = "Self-charging device power cell" + maxcharge = 1000 + charge_amount = 20 + desc = "This 'cell' holds a max charge of 1k and self recharges over time. It is specialized for devices." + self_recharge = TRUE + origin_tech = list(TECH_POWER = 7, TECH_MATERIAL = 6,TECH_BLUESPACE = 6) + +/obj/item/weapon/cell/device/weapon/hightech/empty/initialize() + . = ..() + charge = 0 + update_icon() + +/obj/item/weapon/cell/device/hightech/empty/initialize() + . = ..() + charge = 0 + update_icon() + +//////DESIGN SECTION TO BE MOVED TO DESIGNS////////////// + +/datum/design/item/powercell/weapon/hightech + name = "Self-charging weapon cell" + id = "selfch_cell_weapon" + req_tech = list(TECH_POWER = 5, TECH_MATERIAL = 5,TECH_BLUESPACE = 5,TECH_COMBAT = 3) + materials = list(DEFAULT_WALL_MATERIAL = 2000,"glass" = 500, "silver" = 500) + build_path = /obj/item/weapon/cell/device/weapon/hightech + category = "Misc" + sort_string = "DAAAF" //Unique Letter String, this decides how the list of printable items is arranged + +/datum/design/item/powercell/device/hightech + name = "Self-charging device cell" + id = "selfch_cell_device" + req_tech = list(TECH_POWER = 5, TECH_MATERIAL = 5,TECH_BLUESPACE = 5) + materials = list(DEFAULT_WALL_MATERIAL = 2000,"glass" = 500, "silver" = 500) + build_path = /obj/item/weapon/cell/device/hightech + category = "Misc" + sort_string = "DAAAG" //Unique Letter String, this decides how the list of printable items is arranged diff --git a/code/modules/power/tesla/coil.dm b/code/modules/power/tesla/coil.dm index 07dedf5b2b..569ad6e3eb 100644 --- a/code/modules/power/tesla/coil.dm +++ b/code/modules/power/tesla/coil.dm @@ -100,8 +100,10 @@ anchored = FALSE density = TRUE +//TFF 3/6/19 - Port Cit RP fix for infinite frames can_buckle = TRUE buckle_lying = FALSE + circuit = /obj/item/weapon/circuitboard/grounding_rod /obj/machinery/power/grounding_rod/update_icon() if(panel_open) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index e76989eb79..7b7a4d6e93 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -340,7 +340,7 @@ if(target.z != user.z) return add_fingerprint(user) - + user.break_cloak() if(!special_check(user)) @@ -350,7 +350,7 @@ if (world.time % 3) //to prevent spam user << "[src] is not ready to fire again!" return - + var/shoot_time = (burst - 1)* burst_delay //These should apparently be disabled to allow for the automatic system to function without causing near-permanant paralysis. Re-enabling them while we sort that out. @@ -438,6 +438,15 @@ set_light(0) //VOREStation Edit End + //CHOMPEDIT: Recoil knockdown for micros + if(iscarbon(user)) + var/mob/living/carbon/nerd = user + var/mysize = nerd.size_multiplier + if(mysize <= 0.5) + nerd.Weaken(1) + nerd.adjustBruteLoss(5-mysize*4) + //CHOMPEDIT: Knockdown code end + // Similar to the above proc, but does not require a user, which is ideal for things like turrets. /obj/item/weapon/gun/proc/Fire_userless(atom/target) if(!target) diff --git a/code/modules/projectiles/guns/energy/netgun_vr.dm b/code/modules/projectiles/guns/energy/netgun_vr.dm index 8678d2c5dc..8b84a468a0 100644 --- a/code/modules/projectiles/guns/energy/netgun_vr.dm +++ b/code/modules/projectiles/guns/energy/netgun_vr.dm @@ -1,6 +1,6 @@ /obj/item/weapon/gun/energy/netgun - name = "\improper KHI \"Hunter\" capture gun" - desc = "A Kitsuhana-designed 'non-lethal capture device' stunner and energy net launcher, \ + name = "\improper HI \"Hunter\" capture gun" + desc = "A Hesphaistos Industries-designed 'non-lethal capture device' stunner and energy net launcher, \ for when you want criminals to stop acting like they're on a 20th century British comedy sketch show." icon = 'icons/obj/gun_vr.dmi' icon_state = "hunter" diff --git a/code/modules/projectiles/guns/energy/stun_vr.dm b/code/modules/projectiles/guns/energy/stun_vr.dm index b0bfd53e46..0a1ceeb597 100644 --- a/code/modules/projectiles/guns/energy/stun_vr.dm +++ b/code/modules/projectiles/guns/energy/stun_vr.dm @@ -3,4 +3,20 @@ fire_delay = 4 /obj/item/weapon/gun/energy/stunrevolver - charge_cost = 400 \ No newline at end of file + charge_cost = 400 + +//CHOMPEDIT: +/obj/item/weapon/gun/energy/stunrevolver/oneshot + desc = "A heavily modified LAEP20 Zeus. It fires a beam instead of an electrode. The massive recoil makes it only useful as a last resort weapon." + charge_cost = 2400 + projectile_type = /obj/item/projectile/beam/stun/oneshot + +/obj/item/weapon/gun/energy/stunrevolver/oneshot/Fire(atom/target, mob/living/user, clickparams, pointblank=0, reflex=0) + ..() + if(iscarbon(user)) + var/mob/living/carbon/nerd = user + var/mysize = nerd.size_multiplier + nerd.Weaken(3-mysize) //200% gets the knockdown micros usually get now from firing a gun. Micros get their base knockdown + this. + nerd.adjustBruteLoss(10-mysize*4) //This means 200% = 10-8; 100% = 10-4; etc + + diff --git a/code/modules/projectiles/guns/modular_guns.dm b/code/modules/projectiles/guns/modular_guns.dm index 8f81e971c4..c1a67cf984 100644 --- a/code/modules/projectiles/guns/modular_guns.dm +++ b/code/modules/projectiles/guns/modular_guns.dm @@ -18,12 +18,15 @@ /obj/item/weapon/stock_parts/capacitor/, /obj/item/weapon/stock_parts/capacitor/adv, /obj/item/weapon/stock_parts/capacitor/super, + /obj/item/weapon/stock_parts/capacitor/quadratic, /obj/item/weapon/stock_parts/micro_laser/, /obj/item/weapon/stock_parts/micro_laser/high, /obj/item/weapon/stock_parts/micro_laser/ultra, + /obj/item/weapon/stock_parts/micro_laser/quad, /obj/item/weapon/stock_parts/manipulator/, /obj/item/weapon/stock_parts/manipulator/nano, /obj/item/weapon/stock_parts/manipulator/pico, + /obj/item/weapon/stock_parts/manipulator/femto, ) //Excessively long because it won't accept subtypes for some reason! @@ -171,4 +174,4 @@ one_handed_penalty = 4 //dual wielding = no. cell_type = /obj/item/weapon/cell //We're bigger. We can use much larger power cells. origin_tech = list(TECH_COMBAT = 6, TECH_MAGNET = 6, TECH_MATERIAL = 5, TECH_BLUESPACE = 4) //its a damn cannon capable of holding a huge amount of parts. - burst_delay = 4 //preventing extreme silliness. \ No newline at end of file + burst_delay = 4 //preventing extreme silliness. diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index 9755f604ab..364f587bec 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -18,6 +18,7 @@ muzzle_type = /obj/effect/projectile/laser/muzzle tracer_type = /obj/effect/projectile/laser/tracer impact_type = /obj/effect/projectile/laser/impact + /obj/item/projectile/beam/practice name = "laser" @@ -210,4 +211,12 @@ /obj/item/projectile/beam/stun/med name = "stun beam" icon_state = "stun" - agony = 35 \ No newline at end of file + agony = 35 + +//CHOMPEDIT: Charge beam that drains all power +/obj/item/projectile/beam/stun/oneshot + name = "Overdrive Stun beam" + light_color = "#AA00FF" + //shotcost = 2400 + agony = 240 +//CHOMPEDIT END. diff --git a/code/modules/projectiles/projectile/beams_vr.dm b/code/modules/projectiles/projectile/beams_vr.dm index 5ba1fa56b2..8acd441a7b 100644 --- a/code/modules/projectiles/projectile/beams_vr.dm +++ b/code/modules/projectiles/projectile/beams_vr.dm @@ -1,15 +1,15 @@ /obj/item/projectile/beam/disable - name = "disabler beam" - icon_state = "omnilaser" - nodamage = 1 - taser_effect = 1 - agony = 100 //One shot stuns for the time being until adjustments are fully made. - damage_type = HALLOSS - light_color = "#00CECE" + name = "disabler beam" + icon_state = "omnilaser" + nodamage = 1 + taser_effect = 1 + agony = 100 //One shot stuns for the time being until adjustments are fully made. + damage_type = HALLOSS + light_color = "#00CECE" - muzzle_type = /obj/effect/projectile/laser_omni/muzzle - tracer_type = /obj/effect/projectile/laser_omni/tracer - impact_type = /obj/effect/projectile/laser_omni/impact + muzzle_type = /obj/effect/projectile/laser_omni/muzzle + tracer_type = /obj/effect/projectile/laser_omni/tracer + impact_type = /obj/effect/projectile/laser_omni/impact /obj/item/projectile/beam/stun agony = 35 @@ -41,3 +41,17 @@ muzzle_type = /obj/effect/projectile/laser_blue/muzzle tracer_type = /obj/effect/projectile/laser_blue/tracer impact_type = /obj/effect/projectile/laser_blue/impact + +//CHOMPEDIT Randomized beam, random dam type +/obj/item/projectile/beam/chaosrng + name = "unstable beam" + icon_state = "omnilaser" + + damage_type = HALLOSS + + var/list/damtypes = list(HALLOSS , BURN , BRUTE , CLONE , OXY , TOX) +/obj/item/projectile/beam/chaosrng/on_hit(var/atom/hit) + ..() + damage_type = pick(damtypes) +//CHOMPEDIT End. + diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm index a80118099d..14ed8ac7df 100644 --- a/code/modules/reagents/Chemistry-Machinery.dm +++ b/code/modules/reagents/Chemistry-Machinery.dm @@ -31,7 +31,7 @@ /obj/machinery/chem_master/New() ..() - var/datum/reagents/R = new/datum/reagents(120) + var/datum/reagents/R = new/datum/reagents(900) //TFF: Ports Polaris edit to prevent the ChemMaster from ever losing a ton of chems. reagents = R R.my_atom = src 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 bdccd1b07d..4d4de7b0ab 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm @@ -279,6 +279,21 @@ ingest_met = REM color = "#000000" +/datum/reagent/hotwater + name = "Hot Water" + id = "hotwater" + description = "A ubiquitous chemical substance that is composed of hydrogen and oxygen, now heated." + taste_description = "water" + reagent_state = LIQUID + ingest_met = REM * 10 + color = "#0064C877" + + cup_name = "cup of hot water" + cup_desc = "Good for brewing tea." + + glass_name = "hot water" + glass_desc = "Good for brewing tea." + /datum/reagent/enzyme name = "Universal Enzyme" id = "enzyme" @@ -705,6 +720,16 @@ glass_name = "watermelon juice" glass_desc = "Delicious juice made from watermelon." +/datum/reagent/drink/juice/nutbutter + name = "Peanut paste" + id = "nutbutter" + description = "Raw extracts from peanuts, got a creamy nutty flavour." + taste_description = "peanut extract" + color = "#853333" + + glass_name = "Peanut paste" + glass_desc = "Raw extracts from peanuts, got a creamy nutty flavour." + // Everything else /datum/reagent/drink/milk @@ -782,7 +807,7 @@ adj_sleepy = -3 adj_temp = 20 - glass_name = "cup of tea" + glass_name = "tea" glass_desc = "Tasty black tea, it has antioxidants, it's good for you!" cup_icon_state = "cup_tea" @@ -894,6 +919,48 @@ cup_name = "cup of berry tea" cup_desc = "A tasty mixture of berries and tea. It's apparently good for you!" +/datum/reagent/drink/tea/cherrytea + name = "Cherry Tea" + id = "cherrytea" + description = "A tasty mixture of cherries and tea. It's apparently good for you!" + color = "#c15962" + taste_description = "black tea with lots of cherries" + + glass_name = "cherry tea" + glass_desc = "A tasty mixture of cherries and tea. It's apparently good for you!" + + cup_name = "cup of cherry tea" + cup_desc = "A tasty mixture of cherries and tea. It's apparently good for you!" + +/datum/reagent/drink/tea/watermelontea + name = "Watermelon Tea" + id = "watermelontea" + description = "A tasty mixture of watermelon and tea. It's apparently good for you!" + color = "#9f2c2c" + taste_description = "black tea with sweet watermelon for flavouring" + + glass_name = "watermelon tea" + glass_desc = "A tasty mixture of watermelon and tea. It's apparently good for you!" + + cup_name = "cup of watermelon tea" + cup_desc = "A tasty mixture of watermelon and tea. It's apparently good for you!" + +/datum/reagent/drink/tea/matcha_latte //Putting this as tea to inherit tea variables. Should not have the same toxloss as matcha so it can be placed in a dispenser without breaking balance. + name = "Matcha latte" + id = "matcha_latte" + description = "A nice and tasty beverage to enjoy while studying." + taste_description = "creamy, vegetal sweetness" + color = "#b1c48c" + adj_temp = 5 + + glass_name = "matcha latte" + glass_desc = "A nice and refreshing beverage while you are studying." + + cup_icon_state = "cup_latte" + cup_name = "cup of matcha latte" + cup_desc = "A nice and refreshing beverage while you are studying." + + /datum/reagent/drink/coffee name = "Coffee" id = "coffee" @@ -979,7 +1046,6 @@ glass_desc = "A nice and refreshing beverage while you are reading." glass_name = "soy latte" - glass_desc = "A nice and refrshing beverage while you are reading." cup_icon_state = "cup_latte" cup_name = "cup of soy latte" @@ -998,11 +1064,11 @@ adj_temp = 5 glass_name = "cafe latte" - glass_desc = "A nice, strong and refreshing beverage while you are reading." + glass_desc = "A nice, strong, and refreshing beverage while you are reading." cup_icon_state = "cup_latte" cup_name = "cup of cafe latte" - cup_desc = "A nice and refreshing beverage while you are reading." + cup_desc = "A nice, strong, and refreshing beverage while you are reading." /datum/reagent/drink/coffee/cafe_latte/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) ..() @@ -1495,6 +1561,77 @@ glass_name = "Love Potion" glass_desc = "Love me tender, love me sweet." +/datum/reagent/drink/juice/gelatin + name = "Gelatin" + id = "gelatin" + description = "It doesnt taste like anything." + taste_description = "nothing" + nutrition = 0 + color = "#aaabcf" + + glass_name = "Gelatin" + glass_desc = "It's like flavourless slime." + +/datum/reagent/drink/bubbleteawatermelon + name = "Watermelon bubble tea" + id = "bubbleteawatermelon" + description = "A tea with milk and watermelon in it and gelatin balls as well." + taste_description = "creamy tea and watermelon" + color = "#b83333" + + glass_name = "watermelon bubble tea" + glass_desc = "A sweet tea with tasty little flavoured gelatin balls in it, this one is with watermelon." + +/datum/reagent/drink/bubbleteastrawberry + name = "Strawberry bubble tea" + id = "bubbleteastrawberry" + description = "A tea with milk and strawberry in it and gelatin balls as well." + taste_description = "creamy tea and strawberry" + color = "#eb6c77" + + glass_name = "strawberry bubble tea" + glass_desc = "A sweet tea with tasty little flavoured gelatin balls in it, this one is with strawberry." + +/datum/reagent/drink/bubbleteacherry + name = "Cherry bubble tea" + id = "bubbleteacherry" + description = "A tea with milk and cherry in it and gelatin balls as well." + taste_description = "creamy tea and cherry" + color = "#801e28" + + glass_name = "cherry bubble tea" + glass_desc = "A sweet tea with tasty little flavoured gelatin balls in it, this one is with cherry." + +/datum/reagent/drink/bubbleteacoffee + name = "Coffee bubble tea" + id = "bubbleteacoffee" + description = "A tea with milk and coffee in it and gelatin balls as well." + taste_description = "creamy tea and coffee" + color = "#482910" + + glass_name = "coffee bubble tea" + glass_desc = "A sweet tea with tasty little flavoured gelatin balls in it, this one is with coffee." + +/datum/reagent/drink/bubbleteabanana + name = "Banana bubble tea" + id = "bubbleteabanana" + description = "A tea with milk and banana in it and gelatin balls as well." + taste_description = "creamy tea and banana" + color = "#c3af00" + + glass_name = "banana bubble tea" + glass_desc = "A sweet tea with tasty little flavoured gelatin balls in it, this one is with banana." + +/datum/reagent/drink/horchata + name = "Horchata" + id = "horchata" + description = "A sweet and cold rice milk beverage." + taste_description = "sweet rice milk and cinnamon" + color = "#ebcdc1" + adj_temp = -5 + + glass_name = "horchata" + glass_desc = "A sweet and cold rice milk beverage." /* Alcohol */ @@ -2998,7 +3135,7 @@ glass_name = "Eggnog" glass_desc = "A seasonal drink made from egg, alcohol, dairy products and sugar." - + /datum/reagent/ethanol/spiderdrink name = "Brimming glass of spiders" id = "spiderdrink" @@ -3008,4 +3145,293 @@ strength = 15 glass_name = "Brimming glass of spiders" - glass_desc = "A glass filled to the brim with tiny drunk spiderlings. Lets hope they dont escape." \ No newline at end of file + glass_desc = "A glass filled to the brim with tiny drunk spiderlings. Lets hope they dont escape." + +/datum/reagent/ethanol/snaps + name = "Akvavit" + id = "snaps" + description = "Burns the nose and throat and soothes it with a herby aftertaste...Barely." + taste_description = "strong spirit and a little dill" + color = "e6d670" // rgb: 230, 214, 112 + strength = 15 + + glass_name = "akvavit" + glass_desc = "Burns the nose and throat, and soothes it with a herby aftertaste...Barely." + +/datum/reagent/ethanol/bluetrain + name = "blue train" + id = "bluetrain" + description = "A drink only a fool or a very desperate creature would consume." + taste_description = "someone who decided to pour ice cold motor oil down your throat and finish it off with a large shot of burning pure alcohol." + color = "#c8a5dc" + adj_temp = -10 + targ_temp = 220 + strength = 10 + + glass_name = "blue train" + glass_desc = "A glass of what can only be described as the bastard child between coolant and alcohol made by a madman." + +/datum/reagent/drink/lowpower + name = "The low power" + id = "lowpower" + description = "Smells, and tastes like lemon.. with a hint of Ozone, for whatever reason. It glows softly." + taste_description = "creamy lemonade, with some zest" + color = "#5d8d39" + + glass_name = "lowpower" + glass_desc = "Smells, and tastes like lemon.. with a hint of Ozone, for whatever reason. It glows softly." + +/datum/reagent/drink/lowpower/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) + ..() + if(alien == IS_DIONA) + return + M.adjustToxLoss(-0.5 * removed) + +/datum/reagent/ethanol/coffee/jackbrew + name = "Jack's brew" + id = "jackbrew" + description = "Irish coffee, and hyperzine. A common mix for panicked drinkers, EMTS, Paramedics, and CMOs alone on the job." + taste_description = "wishing you could give up on the day" + color = "#4C3100" + strength = 15 + + glass_name = "Jack's brew" + glass_desc = "Irish coffee, and hyperzine. A common mix for panicked drinkers, EMTS, Paramedics, and CMOs alone on the job." + +/datum/reagent/ethanol/coffee/jackbrew/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) + if(alien == IS_TAJARA) + removed *= 1.25 + if(alien == IS_SLIME) + M.make_jittery(4) //Hyperactive fluid pumping results in unstable 'skeleton', resulting in vibration. + if(dose >= 5) + M.nutrition = (M.nutrition - (removed * 2)) //Sadly this movement starts burning food in higher doses. + ..() + if(prob(5)) + M.emote(pick("twitch", "blink_r", "shiver", "weh")) + M.add_chemical_effect(CE_SPEEDBOOST, 1) + +/datum/reagent/ethanol/bookwyrm + name = "Bookwyrm's bite" + id = "bookwyrm" + description = "You'd probably fancy a nice nap by the fireplace after drinking this." + taste_description = "Mint, lime and a cold cozy nap" + color = "#5678c3" + strength = 20 + adj_temp = -10 + targ_temp = 273 //Dilluted cold front wont be the death of anyone who cant handle sipping liquid nitrogen. + + glass_name = "Bookwyrm's bite" + glass_desc = "A cold lime mint drink. Dont drink to much or you might fall asleep." + +/datum/reagent/ethanol/bookwyrm/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) + if(alien == IS_DIONA) + return + + var/threshold = 1 + if(alien == IS_SKRELL) + threshold = 1.2 + + if(alien == IS_SLIME) + threshold = 6 //Evens to 3 due to the fact they are considered 'small' for flaps. + + var/effective_dose = dose + if(issmall(M)) + effective_dose *= 2 + + if(effective_dose < 1 * threshold) + if(effective_dose == metabolism * 2 || prob(5)) + M.emote("yawn") + else if(effective_dose < 1.5 * threshold) + M.eye_blurry = max(M.eye_blurry, 10) + else if(effective_dose < 5 * threshold) + if(prob(50)) + M.Weaken(2) + M.drowsyness = max(M.drowsyness, 20) + else + if(alien == IS_SLIME) //They don't have eyes, and they don't really 'sleep'. Fumble their general senses. + M.eye_blurry = max(M.eye_blurry, 30) + if(prob(20)) + M.ear_deaf = max(M.ear_deaf, 4) + M.Confuse(2) + else + M.Weaken(2) + else + M.sleeping = max(M.sleeping, 20) + M.drowsyness = max(M.drowsyness, 60) + +/datum/reagent/drink/highpower + name = "The High power" + id = "highpower" + description = "A strange, softly crackling drink, smelling just like lightning's just struck, twice. It's rather difficult to make this without busting the lights." + taste_description = "copper, ozone, and pain" + color = "#a2f563" + + glass_name = "highpower" + glass_desc = "A strange, softly crackling drink, smelling just like lightning's just struck, twice. It's rather difficult to make this without busting the lights." + +/datum/reagent/drink/highpower/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) + if(alien == IS_DIONA) + return + if(prob(5)) + M.say("!skin's crackles with energy and seems to be in pain.") + M.custom_pain("You feel painful electricity running through your body, like adrenaline, and like your blood's boiling!",30) + M.AdjustWeakened(3) //Getting sapped makes the victim fall + M.Stun(3) + M.add_chemical_effect(CE_SPEEDBOOST, 1) + +/datum/reagent/ethanol/flapper + name = "Flapper" + id = "flapper" + description = "A common drink among blood-drinkers, and those who just wanna drink. Tinnibat be damned." + taste_description = "a bloody good time" + color = "#763424" + strength = 15 + + glass_name = "flapper" + glass_desc = "A common drink among blood-drinkers, and those who just wanna drink. Tinnibat be damned." + +/datum/reagent/toxin/oilslide + name = "Oil slide" + id = "oilslide" + description = "Tasty, if you're a synth, not so much for organics." + taste_description = "oil, slime, and fuel! Tastes also like synthetic backwash" + color = "#331a1a" + + glass_name = "oilslide" + glass_desc = "Tasty, if you're a synth, not so much for organics." + +/datum/reagent/ethanol/sitonmyface + name = "Sit on my face" + id = "sitonmyface" + description = "A drink made of irish coffee and nuts, mostly known for its vulgar name. Makes for a great pickup line though!" + taste_description = "creamy coffee and alcohol, and nuts" + color = "#896750" + strength = 15 + + glass_name = "Sit on my face" + glass_desc = "A drink made of irish coffee and nuts, mostly known for its vulgar name. Makes for a great pickup line though!" + +/datum/reagent/ethanol/hachi + name = "Hachi" + id = "hachi" + description = "An unusual fusion of bourbon and sake infused with lemon juice, and mushrooms. Sweet, savory, but mostly weird." + taste_description = "sweet lemons, black pepper, and savory mushroom" + color = "#DC971D" + strength = 20 + +/datum/reagent/drink/freshtea + name = "Green tea" + id = "freshtea" //Not meant to be obtainable, this is to define effects for teas made from grown teas. + description = "Tasty green tea, it has antioxidants, it's good for you! Fresh means it's even healthier!" + taste_description = "green tea" + color = "#cac162" + adj_dizzy = -4 + adj_drowsy = -1 + adj_sleepy = -3 + adj_temp = 20 + + glass_name = "green tea" + glass_desc = "Tasty green tea, it has antioxidants, it's good for you!" + + cup_icon_state = "cup_tea" + cup_name = "cup of tea" + cup_desc = "Tasty green tea, it has antioxidants, it's good for you!" + +/datum/reagent/drink/freshtea/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) + ..() + if(alien == IS_DIONA) + return + M.adjustToxLoss(-2 * removed) //Higher toxin removal than other tea to reflect difficulty in preparing, still worse than dylovene. + +/datum/reagent/drink/freshtea/green + name = "Green tea" + id = "freshteagreen" + description = "Floral green tea, it has antioxidants, it's good for you! Fresh means it's even healthier!" + taste_description = "floral with vegetal notes and a slightly bitter aftertaste" + color = "#cac162" + + glass_name = "green tea" + glass_desc = "Floral green tea, it has antioxidants, it's fresh and good for you!" + + cup_icon_state = "cup_tea" + cup_name = "cup of tea" + cup_desc = "Floral green tea, it has antioxidants, it's fresh and good for you!" + +/datum/reagent/drink/tealeavesgreen + name = "Green tea leaves" + id = "tealeavesgreen" + description = "Prepared green tea, just waiting for hot water." + taste_description = "overwhelmingly bitter with faint floral notes" + color = "#56761d" + + glass_name = "tea leaves" + glass_desc = "Dry tea leaves in a cup. Just add hot water!" + +/datum/reagent/drink/teamush + name = "Tea mush" + id = "teamush" + description = "Mashed tea leaves, a bit like grass clippings. You can't make proper tea out of this now." + taste_description = "overwhelmingly bitter plant" + color = "#7db72d" + + glass_name = "blended plant" + glass_desc = "Chunky, mashed up plant of some sort. Looks kinda gross." + +/datum/reagent/drink/instantteapowdergreen + name = "Instant green tea powder" + id = "instantteapowdergreen" + description = "Green tea powder missing all the goodness of green tea." //Heathen. + taste_description = "strong bitterness with a subtle chemical aftertaste" + color = "#56761d" + + glass_name = "tea powder" + glass_desc = "Instant green tea powder. Just add water for imitation green tea!" + +/datum/reagent/drink/instantteagreen + name = "Instant green tea" + id = "instantteagreen" + description = "Convenient green tea missing all the goodness of actual green tea." //It's not even hot. + taste_description = "bitterness with a subtle chemical aftertaste" + color = "#cac162" + + glass_name = "green tea" + glass_desc = "Green tea. It smells a bit off." + + cup_icon_state = "cup_tea" + cup_name = "cup of tea" + cup_desc = "Green tea. It smells a bit off." + +/datum/reagent/drink/matchapowder + name = "Matcha powder" + id = "matchapowder" + description = "Finely ground green tea. This is about the highest quality matcha you can prepare without traditional methods." + taste_description = "heavy bitterness" + color = "#86a443" + + glass_name = "matcha powder" + glass_desc = "Matcha powder, waiting for brewing." + +/datum/reagent/drink/matcha + name = "Matcha" + id = "matcha" + description = "A form of green tea where the leaf is ground and suspended in water rather than steeped. This is considered cooking grade." + taste_description = "floral, full-bodied bitterness with a subtle, earthy sweetness" + color = "#9bc265" + adj_dizzy = -4 + adj_drowsy = -1 + adj_sleepy = -3 + adj_temp = 20 + + glass_name = "matcha" + glass_desc = "Heavenly matcha. Good for body and spirit." + + cup_icon_state = "cup_tea" + cup_name = "cup of matcha" + cup_desc = "Heavenly matcha. Good for body and spirit." + +/datum/reagent/drink/matcha/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) + ..() + if(alien == IS_DIONA) + return + M.adjustToxLoss(-3 * removed) //Almost on par with dylovene despite being harder to obtain in bulk. Nerf if this causes problems. + diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm index ef5b9d6797..6e22ad1be2 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm @@ -51,6 +51,24 @@ if(W.damage <= 0) O.wounds -= W +/datum/reagent/alizene + name = "Alizene" + id = "alizene" + description = "A derivative from bicaridine enhanced by serazine to more effectively mend flesh, but is ineffective against internal hemorrhage." + taste_description = "bittersweet" + taste_mult = 3 + reagent_state = LIQUID + color = "#b37979" + overdose = REAGENTS_OVERDOSE + scannable = 1 + +/datum/reagent/alizene/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + var/chem_effective = 1 + if(alien == IS_SLIME) + chem_effective = 0.75 + if(alien != IS_DIONA) + M.heal_organ_damage(12 * removed * chem_effective, 0) + /datum/reagent/kelotane name = "Kelotane" id = "kelotane" @@ -107,6 +125,22 @@ M.hallucination = max(0, M.hallucination - 9 * removed * chem_effective) M.adjustToxLoss(-4 * removed * chem_effective) +/datum/reagent/serazine + name = "Serazine" + id = "serazine" + description = "A sweet tasting flower extract, it has very mild anti toxic properties and can be used to make potent drugs." + taste_description = "sweet nectar" + reagent_state = LIQUID + color = "#df9898" + scannable = 1 + +/datum/reagent/serazine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + var/chem_effective = 1 + if(alien != IS_DIONA) + M.drowsyness = max(0, M.drowsyness - 3 * removed * chem_effective) + M.hallucination = max(0, M.hallucination - 6 * removed * chem_effective) + M.adjustToxLoss(-2 * removed * chem_effective) + /datum/reagent/carthatoline name = "Carthatoline" id = "carthatoline" @@ -369,6 +403,7 @@ /datum/reagent/hyperzine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(alien == IS_TAJARA) removed *= 1.25 + M.druggy = max(M.druggy, 5) //CHOMPEDIT Tajara drugs yo if(alien == IS_SLIME) M.make_jittery(4) //Hyperactive fluid pumping results in unstable 'skeleton', resulting in vibration. if(dose >= 5) @@ -622,19 +657,26 @@ mrate_static = TRUE overdose = REAGENTS_OVERDOSE scannable = 1 - data = 0 + //data = 0 /datum/reagent/spaceacillin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) ..() +// if(!delay) +// delay = world.time if(alien == IS_SLIME) - if(volume <= 0.1 && data != -1) - data = -1 +// if(volume <= 0.1 && data != -1) +// data = -1 +// else +// var/delay = (5 MINUTES) +// if(world.time > data + delay) +// data = world.time +// to_chat(M, "Your senses feel unfocused, and divided.") + +// Erik's Edit: Fixes spam chems! + if(volume <= metabolism) to_chat(M, "You regain focus...") - else - var/delay = (5 MINUTES) - if(world.time > data + delay) - data = world.time - to_chat(M, "Your senses feel unfocused, and divided.") + if(dose <= metabolism) + to_chat(M, "Your senses feel unfocused, and divided.") M.add_chemical_effect(CE_ANTIBIOTIC, dose >= overdose ? ANTIBIO_OD : ANTIBIO_NORM) /datum/reagent/corophizine @@ -805,8 +847,6 @@ /* Antidepressants */ -#define ANTIDEPRESSANT_MESSAGE_DELAY 5*60*10 - /datum/reagent/methylphenidate name = "Methylphenidate" id = "methylphenidate" @@ -815,22 +855,29 @@ reagent_state = LIQUID color = "#BF80BF" metabolism = 0.01 + ingest_met = 0.25 mrate_static = TRUE - data = 0 - var/delay = 0 +// data = 0 +// var/delay = 0 /datum/reagent/methylphenidate/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) - if(!delay) - delay = world.time +// if(!delay) +// delay = world.time if(alien == IS_DIONA) return - if(volume <= 0.1 && data != -1 && world.time > delay + ANTIDEPRESSANT_MESSAGE_DELAY) - delay = world.time +// if(volume <= 0.1 && data != -1 && world.time > delay + ANTIDEPRESSANT_MESSAGE_DELAY) +// delay = world.time +// M << "You lose focus..." +// else +// if(world.time > delay + ANTIDEPRESSANT_MESSAGE_DELAY) +// delay = world.time +// M << "Your mind feels focused and undivided." + +// Erik's Edit: Fixes spam chems! + if(volume <= metabolism) M << "You lose focus..." - else - if(world.time > delay + ANTIDEPRESSANT_MESSAGE_DELAY) - delay = world.time - M << "Your mind feels focused and undivided." + if(dose <= metabolism) + M << "Your mind feels focused and undivided." /datum/reagent/citalopram name = "Citalopram" @@ -840,22 +887,29 @@ reagent_state = LIQUID color = "#FF80FF" metabolism = 0.01 + ingest_met = 0.25 mrate_static = TRUE - data = 0 - var/delay = 0 +// data = 0 +// var/delay = 0 /datum/reagent/citalopram/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) - if(!delay) - delay = world.time +// if(!delay) +// delay = world.time if(alien == IS_DIONA) return - if(volume <= 0.1 && world.time > delay + ANTIDEPRESSANT_MESSAGE_DELAY) - delay = world.time +// if(volume <= 0.1 && world.time > delay + ANTIDEPRESSANT_MESSAGE_DELAY) +// delay = world.time +// to_chat(M, "Your mind feels a little less stable...") +// else +// if(world.time > delay + ANTIDEPRESSANT_MESSAGE_DELAY) +// delay = world.time +// to_chat(M, "Your mind feels stable... a little stable.") + +// Erik's Edit: Fixes spam chems! + if(volume <= metabolism) to_chat(M, "Your mind feels a little less stable...") - else - if(world.time > delay + ANTIDEPRESSANT_MESSAGE_DELAY) - delay = world.time - to_chat(M, "Your mind feels stable... a little stable.") + if(dose <= metabolism) + to_chat(M, "Your mind feels stable... a little stable.") /datum/reagent/paroxetine name = "Paroxetine" @@ -865,24 +919,35 @@ reagent_state = LIQUID color = "#FF80BF" metabolism = 0.01 + ingest_met = 0.25 mrate_static = TRUE - data = 0 - var/delay = 0 + //data = 0 + //var/delay = 0 /datum/reagent/paroxetine/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(alien == IS_DIONA) return - if(volume <= 0.1 && world.time > delay + ANTIDEPRESSANT_MESSAGE_DELAY) - delay = world.time +// if(volume <= 0.1 && world.time > delay + ANTIDEPRESSANT_MESSAGE_DELAY) +// delay = world.time +// M << "Your mind feels much less stable..." +// else +// if(world.time > delay + ANTIDEPRESSANT_MESSAGE_DELAY) +// delay = world.time +// if(prob(90)) +// M << "Your mind feels much more stable." +// else +// M << "Your mind breaks apart..." +// M.hallucination += 200 + +// Erik's Edit: Fixes spam chems! + if(volume <= metabolism) M << "Your mind feels much less stable..." - else - if(world.time > delay + ANTIDEPRESSANT_MESSAGE_DELAY) - delay = world.time - if(prob(90)) - M << "Your mind feels much more stable." - else - M << "Your mind breaks apart..." - M.hallucination += 200 + if(dose <= metabolism) + if(prob(90)) + M << "Your mind feels much more stable." + else + M << "Your mind breaks apart..." + M.hallucination += 200 /datum/reagent/qerr_quem name = "Qerr-quem" @@ -892,19 +957,26 @@ reagent_state = LIQUID color = "#e6efe3" metabolism = 0.01 + ingest_met = 0.25 mrate_static = TRUE - data = 0 +// data = 0 /datum/reagent/qerr_quem/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(alien == IS_DIONA) return - if(volume <= 0.1 && data != -1) - data = -1 +// if(volume <= 0.1 && data != -1) +// data = -1 +// to_chat(M, "You feel antsy, your concentration wavers...") +// else +// if(world.time > data + ANTIDEPRESSANT_MESSAGE_DELAY) +// data = world.time +// to_chat(M, "You feel invigorated and calm.") + +// Erik's Edit: Fixes spam chems! + if(volume <= metabolism) to_chat(M, "You feel antsy, your concentration wavers...") - else - if(world.time > data + ANTIDEPRESSANT_MESSAGE_DELAY) - data = world.time - to_chat(M, "You feel invigorated and calm.") + if(dose <= metabolism) + 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 diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine_vr.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine_vr.dm index 64f12964e4..2a03da4792 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine_vr.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine_vr.dm @@ -134,18 +134,11 @@ scannable = 1 // Mechs can scan this ye metabolism = 0.03 //Slow metabolism. This value was plucked out of nowhere. Can be changed. -/datum/reagent/bullvalene/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) //Credit to Cameron for making my life easier with getFireLoss and such! - if(alien == IS_SLIME) +/datum/reagent/bullvalene/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + if(alien == IS_SLIME || alien == IS_DIONA) return - if(alien != IS_DIONA) - return - else - if(M.getOxyLoss()) //OXYGEN | This check if there is oxygen damage - M.adjustOxyLoss(-1) //This remove the oxygen damage - M.adjustToxLoss(0.8) //This add toxin damage - if(M.getFireLoss()) //BURN - M.adjustFireLoss(-1) - M.adjustToxLoss(0.8) - if(M.getBruteLoss()) //BRUTE - M.adjustBruteLoss(-1) - M.adjustToxLoss(0.8) \ No newline at end of file + if(M.getBruteLoss() || M.getFireLoss() || M.getOxyLoss()) + M.adjustOxyLoss(-1) + M.adjustFireLoss(-1) + M.adjustBruteLoss(-1) + M.adjustToxLoss(0.8) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm index e3c087b5fa..f39cc9f50e 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm @@ -400,8 +400,10 @@ color = "#13BC5E" /datum/reagent/mutagen/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) - if(prob(33)) - affect_blood(M, alien, removed) + if(prob(25)) + if(istype(M,/mob/living/carbon/human)) + var/mob/living/carbon/human/h = M + h.monkeyize()//CHOMPEDIT: Primal forms! /datum/reagent/mutagen/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) if(prob(67)) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents_chomp.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents_chomp.dm index ae5c5d2c06..54a7e37954 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents_chomp.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents_chomp.dm @@ -48,3 +48,189 @@ T.add_vomit_floor(src, 1) */ +////////////////////////////////////////////// +////////////////C U B E S//////////////////// +//////////////////////////////////////////// +/datum/chemical_reaction/cube/sagaru + name = "Saguwu" + id = "cubedsagaru" + result = null + required_reagents = list("cheese" = 1, "blood" = 1, "clonexadone" = 10,) + result_amount = 1 + +/datum/chemical_reaction/cube/sagaru/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + for(var/i = 1, i <= created_volume, i++) + new /obj/item/weapon/reagent_containers/food/snacks/monkeycube/sarucube(location) + return + +//this kinda counts +//LIQUID EGG +/datum/reagent/liquidspideregg + name = "spider eggs" + id = "spideregg" + description = "These are eggs, spiders crawl out of these.. probably not healthy inside of a person." + taste_description = "SO MANY LEGS" + reagent_state = LIQUID + color = "#FFFFFF" + overdose = REAGENTS_OVERDOSE * 100 + metabolism = REM * 0.1 + scannable = 1 + var/amount_grown = 0 + var/min_growth = 0 + var/max_growth = 2 + var/spiders_min = 6 + var/spiders_max = 24 + var/spider_type = /obj/effect/spider/spiderling + +/datum/reagent/liquidspideregg/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + if(prob(1)) + M.custom_pain("You can feel movement within your body!",45) + amount_grown += rand(min_growth,max_growth) + if(amount_grown >= 100) + min_growth++ + max_growth++ + amount_grown = 0 + var/num = rand(spiders_min, spiders_max) + var/obj/item/organ/external/O = null + if(istype(M.loc, /obj/item/organ/external)) + O = M.loc + + for(var/i=0, iYour flesh rapidly mutates!" + //TFF 14/4/19: Port VoreStation TF fix + to_chat(M, "Your flesh rapidly mutates!") + + var/list/backup_implants = list() + for(var/obj/item/organ/I in H.organs) + for(var/obj/item/weapon/implant/backup/BI in I.contents) + backup_implants += BI + if(backup_implants.len) + for(var/obj/item/weapon/implant/backup/BI in backup_implants) + BI.forceMove(src) + H.set_species("Promethean") - H.verbs += /mob/living/carbon/human/proc/shapeshifter_select_shape - H.verbs += /mob/living/carbon/human/proc/shapeshifter_select_colour - H.verbs += /mob/living/carbon/human/proc/shapeshifter_select_hair - H.verbs += /mob/living/carbon/human/proc/shapeshifter_select_gender - H.verbs += /mob/living/carbon/human/proc/regenerate - H.verbs += /mob/living/proc/set_size H.shapeshifter_set_colour("#05FF9B") //They can still change their color. + //TFF 14/4/19: Port VoreStation TF fix + if(backup_implants.len) + var/obj/item/organ/external/torso = H.get_organ(BP_TORSO) + for(var/obj/item/weapon/implant/backup/BI in backup_implants) + BI.forceMove(torso) + torso.implants += BI + /datum/chemical_reaction/slime/sapphire_mutation name = "Slime Mutation Toxins" id = "slime_mutation_tox" @@ -59,17 +70,17 @@ strength = 10//Don't drink it mrate_static = TRUE -/datum/reagent/purplesap +/datum/reagent/purplesap name = "Purple sap" id = "purplesap" - description = "Purple liquid. It is very sticky and smells of amonia." + description = "Purple liquid. It is very sticky and smells of ammonia." color = "#7a48a0" - taste_description = "Amonia" + taste_description = "Ammonia" -/datum/reagent/orangesap +/datum/reagent/orangesap name = "Orange sap" id = "orangesap" description = "Orange liquid. It wobbles around a bit like jelly." color = "#e0962f" - taste_description = "Amonia" + taste_description = "Ammonia" diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm index 47eac480f0..f9b3f0864b 100644 --- a/code/modules/reagents/Chemistry-Recipes.dm +++ b/code/modules/reagents/Chemistry-Recipes.dm @@ -365,6 +365,13 @@ required_reagents = list("inaprovaline" = 1, "carbon" = 1) inhibitors = list("sugar" = 1) // Messes up with inaprovaline result_amount = 2 + +/datum/chemical_reaction/alizine + name = "Alizine" + id = "alizine" + result = "alizine" + required_reagents = list("bicaridine" = 1, "serazine" = 1, "tungsten" = 1) + result_amount = 3 /datum/chemical_reaction/myelamine name = "Myelamine" @@ -1899,6 +1906,20 @@ required_reagents = list("tea" = 5, "berryjuice" = 1) result_amount = 6 +/datum/chemical_reaction/drinks/cherrytea + name = "Cherry Tea" + id = "cherrytea" + result = "cherrytea" + required_reagents = list("tea" = 5, "cherryjelly" = 1) + result_amount = 6 + +/datum/chemical_reaction/drinks/watermelontea + name = "Watermelon Tea" + id = "watermelontea" + result = "watermelontea" + required_reagents = list("tea" = 5, "watermelonjuice" = 1) + result_amount = 6 + /datum/chemical_reaction/drinks/sakebomb name = "Sake Bomb" id = "sakebomb" @@ -2223,6 +2244,111 @@ required_reagents = list("spidertoxin" = 1, "clonexadone" = 5, "absinthe" = 4) result_amount = 10 +/datum/chemical_reaction/drinks/bubbleteawatermelon + name = "Watermelon bubble tea" + id = "bubbleteawatermelon" + result = "bubbleteawatermelon" + required_reagents = list("gelatin" = 2, "watermelontea" = 6, "milk" = 2) + result_amount = 10 + +/datum/chemical_reaction/drinks/bubbleteastrawberry + name = "Strawberry bubble tea" + id = "bubbleteastrawberry" + result = "bubbleteastrawberry" + required_reagents = list("gelatin" = 2, "berrytea" = 6, "milk" = 2) + result_amount = 10 + +/datum/chemical_reaction/drinks/bubbleteacherry + name = "Cherry bubble tea" + id = "bubbleteacherry" + result = "bubbleteacherry" + required_reagents = list("gelatin" = 2, "cherrytea" = 6, "milk" = 2) + result_amount = 10 + +/datum/chemical_reaction/drinks/bubbleteacoffee + name = "Coffee bubble tea" + id = "bubbleteacoffee" + result = "bubbleteacoffee" + required_reagents = list("gelatin" = 2, "tea" = 5, "cafe_latte" = 3) + result_amount = 10 + +/datum/chemical_reaction/drinks/bubbleteabanana + name = "Banana bubble tea" + id = "bubbleteabanana" + result = "bubbleteabanana" + required_reagents = list("gelatin" = 2, "tea" = 5, "banana" = 1, "milk" = 2) + result_amount = 10 + +/datum/chemical_reaction/drinks/horchata + name = "Horchata" + id = "horchata" + result = "horchata" + required_reagents = list("milk" = 1, "sugar" = 2, "rice" = 2) + result_amount = 5 + +/datum/chemical_reaction/drinks/bluetrain + name = "Blue train" + id = "bluetrain" + result = "bluetrain" + required_reagents = list("coolant" = 2, "ethanol" = 2, "nutriment" = 1) + result_amount = 5 + +/datum/chemical_reaction/drinks/lowpower + name = "The low power" + id = "lowpower" + result = "lowpower" + required_reagents = list("lemonade" = 1, "cream" = 1, "limejuice" = 1) + result_amount = 3 + +/datum/chemical_reaction/drinks/jackbrew + name = "Jack's brew" + id = "jackbrew" + result = "jackbrew" + required_reagents = list("irishcoffee" = 1, "hyperzine" = 1) + result_amount = 2 + +/datum/chemical_reaction/drinks/bookwyrm + name = "Bookwyrm's bite" + id = "bookwyrm" + result = "bookwyrm" + required_reagents = list("coldfront" = 1, "limejuice" = 1, "stoxin" = 1) + result_amount = 3 + +/datum/chemical_reaction/drinks/highpower + name = "The high power" + id = "highpower" + result = "highpower" + required_reagents = list("lowpower" = 1, "iron" = 1, "uranium" = 1) + result_amount = 3 + +/datum/chemical_reaction/drinks/flapper + name = "Flapper" + id = "flapper" + result = "flapper" + required_reagents = list("whiskey" = 1, "blood" = 1, "ice" = 1) + result_amount = 3 + +/datum/chemical_reaction/toxin/oilslide + name = "Oil slide" + id = "oilslide" + result = "oilslide" + required_reagents = list("moonshine" = 1, "lube" = 1, "fuel" = 1) + result_amount = 3 + +/datum/chemical_reaction/drinks/sitonmyface + name = "Sit on my face" + id = "sitonmyface" + result = "sitonmyface" + required_reagents = list("kahlua" = 1, "irishcream" = 1, "nutbutter" = 1) + result_amount = 3 + +/datum/chemical_reaction/drinks/hachi + name = "Hachi" + id = "hachi" + result = "hachi" + required_reagents = list("burbon" = 2, "sake" = 1, "lemonjuice" = 1, "mushroom" = 1) + result_amount = 5 + //R-UST Port /datum/chemical_reaction/hyrdophoron name = "Hydrophoron" @@ -2257,4 +2383,4 @@ id = "qerr_quem" result = "qerr_quem" required_reagents = list("nicotine" = 1, "carbon" = 1, "sugar" = 2) - result_amount = 4 \ No newline at end of file + result_amount = 4 diff --git a/code/modules/reagents/Chemistry-Recipes_ch.dm b/code/modules/reagents/Chemistry-Recipes_ch.dm new file mode 100644 index 0000000000..e8c6bff15c --- /dev/null +++ b/code/modules/reagents/Chemistry-Recipes_ch.dm @@ -0,0 +1,62 @@ +/datum/chemical_reaction/claridyl + name = "claridyl" + id = "claridyl" + result = "claridyl" + required_reagents = list("lithium" = 1, "radium" = 1, "sugar" = 1) + result_amount = 1 + +/datum/chemical_reaction/dyloteane + name = "dyloteane" + id = "dyloteane" + result = "dyloteane" + required_reagents = list("anti_toxin" = 1, "tea" = 1) + result_amount = 1 + +/datum/chemical_reaction/dyloteane/super + name = "dyloteanesuper" + id = "dyloteanesuper" + result = "dyloteane" + required_reagents = list("anti_toxin" = 1, "tea" = 1,"sugar" = 1) + result_amount = 10 //by the powers of england for sugaring your tea you gain *10 result + +/datum/chemical_reaction/eden + name = "eden" + id = "eden" + result = "eden" + required_reagents = list("anti_toxin" = 60, "phoron" = 60) + result_amount = 1 + +/datum/chemical_reaction/eden/snake + id = "eden_snake" + result = "eden_snake" + required_reagents = list("eden" = 1, "ethanol" = 1) + +/datum/chemical_reaction/freshtea/green + id = "freshteagreen" + result = "freshteagreen" + required_reagents = list ("tealeavesgreen" = 1, "hotwater" = 9) + result_amount = 10 + +/datum/chemical_reaction/instantteapowder/green + id = "instantteapowdergreen" + result = "instantteapowdergreen" + required_reagents = list ("teamush" = 10, "frostoil" = 1) + result_amount = 10 + +/datum/chemical_reaction/instanttea/green + id = "instantteagreen" + result = "instantteagreen" + required_reagents = list ("instantteapowdergreen" = 1, "water" = 9) + result_amount = 10 + +/datum/chemical_reaction/matcha + id = "matcha" + result = "matcha" + required_reagents = list ("matchapowder" = 1, "hotwater" = 2) + result_amount = 2 + +/datum/chemical_reaction/tea/matcha_latte + id = "matcha_latte" + result = "matcha_latte" + required_reagents = list ("matchapowder" = 1, "milk" = 5) + result_amount = 5 \ No newline at end of file diff --git a/code/modules/reagents/Chemistry-Recipes_vr.dm b/code/modules/reagents/Chemistry-Recipes_vr.dm index 1cc22c48be..bccfc57640 100644 --- a/code/modules/reagents/Chemistry-Recipes_vr.dm +++ b/code/modules/reagents/Chemistry-Recipes_vr.dm @@ -114,6 +114,14 @@ result = "myelamine" required_reagents = list("bicaridine" = 1, "iron" = 2, "kelotane" = 1, "bluesap" = 1) result_amount = 1 +//Old version of above slightly modified +/datum/chemical_reaction/myelamineold //This is the clotting agent used by clotting packs. + name = "Myelamineold" + id = "myelamineold" + result = "myelamine" + required_reagents = list("bicaridine" = 1, "iron" = 2, "kelotane" = 1, "spidertoxin" = 1) + result_amount = 1 + /datum/chemical_reaction/hannoa name = "Hannoa" @@ -129,6 +137,12 @@ required_reagents = list("dermaline" = 1, "orangesap" = 1, "Copper" = 1) result_amount = 1 +/datum/chemical_reaction/nutrient + name = "Nutriment" + id = "nutriment" + result = "nutriment" + required_reagents = list("purplesap" = 1, "orangesap" = 1, "bluesap" = 1) + result_amount = 3 /////////////////////////////////////////////////////////////////////////////////// /// Special drinks diff --git a/code/modules/reagents/dispenser/cartridge_presets.dm b/code/modules/reagents/dispenser/cartridge_presets.dm index a29d7ac9f8..261ed5ef3f 100644 --- a/code/modules/reagents/dispenser/cartridge_presets.dm +++ b/code/modules/reagents/dispenser/cartridge_presets.dm @@ -71,6 +71,7 @@ cream spawn_reagent = "cream" mint spawn_reagent = "mint" berry spawn_reagent = "berryjuice" + matcha_latte spawn_reagent = "matcha_latte" // ERT inaprov spawn_reagent = "inaprovaline" @@ -102,3 +103,45 @@ chloral spawn_reagent = "chloralhydrate" cryoxadone spawn_reagent = "cryoxadone" clonexadone spawn_reagent = "clonexadone" + + // Chems that are used but not meant for cargo supplies, at least for now. + champagne spawn_reagent = "champagne" + grapesoda spawn_reagent = "grapesoda" + singulo spawn_reagent = "singulo" + doctor_delight spawn_reagent = "doctor_delight" + nothing spawn_reagent = "nothing" + banana spawn_reagent = "banana" + honey spawn_reagent = "honey" + egg spawn_reagent = "egg" + coco spawn_reagent = "coco" + cherryjelly spawn_reagent = "cherryjelly" + carrot spawn_reagent = "carrot" + apple spawn_reagent = "apple" + tomato spawn_reagent = "tomato" + nutbutter spawn_reagent = "nutbutter" //ha + soymilk spawn_reagent = "soymilk" + grenadine spawn_reagent = "grenadine" + gingerale spawn_reagent = "gingerale" + royrogers spawn_reagent = "royrogers" + patron spawn_reagent = "patron" + goldschlager spawn_reagent = "goldschlager" + gelatin spawn_reagent = "gelatin" + melonliquor spawn_reagent = "melonliquor" + bluecuracao spawn_reagent = "bluecuracao" + thirteenloko spawn_reagent = "thirteenloko" + deadrum spawn_reagent = "deadrum" + sake spawn_reagent = "sake" + acidspit spawn_reagent = "acidspit" + amasec spawn_reagent = "amasec" + beepsky_smash spawn_reagent = "beepsky_smash" + atomicbomb spawn_reagent = "atomicbomb" + nuka_cola spawn_reagent = "nuka_cola" + threemileisland spawn_reagent = "threemileisland" + manhattan_proj spawn_reagent = "manhattan_proj" + psilocybin spawn_reagent = "psilocybin" + moonshine spawn_reagent = "moonshine" + specialwhiskey spawn_reagent = "specialwhiskey" + unathiliquor spawn_reagent = "unathiliquor" + winebrandy spawn_reagent = "winebrandy" + snaps spawn_reagent = "snaps" + \ No newline at end of file diff --git a/code/modules/reagents/dispenser/dispenser2_energy.dm b/code/modules/reagents/dispenser/dispenser2_energy.dm index 4465b0b769..1038a02325 100644 --- a/code/modules/reagents/dispenser/dispenser2_energy.dm +++ b/code/modules/reagents/dispenser/dispenser2_energy.dm @@ -58,5 +58,5 @@ /obj/machinery/chemical_dispenser/bar_coffee dispense_reagents = list( "coffee", "cafe_latte", "soy_latte", "hot_coco", "milk", "cream", "tea", "ice", - "orangejuice", "lemonjuice", "limejuice", "berryjuice", "mint" + "orangejuice", "lemonjuice", "limejuice", "berryjuice", "mint", "matcha_latte" ) \ No newline at end of file diff --git a/code/modules/reagents/dispenser/dispenser_presets.dm b/code/modules/reagents/dispenser/dispenser_presets.dm index 05477d9cdd..6505eb36ab 100644 --- a/code/modules/reagents/dispenser/dispenser_presets.dm +++ b/code/modules/reagents/dispenser/dispenser_presets.dm @@ -137,6 +137,5 @@ /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon, /obj/item/weapon/reagent_containers/chem_disp_cartridge/lime, /obj/item/weapon/reagent_containers/chem_disp_cartridge/berry, - - + /obj/item/weapon/reagent_containers/chem_disp_cartridge/matcha_latte ) \ No newline at end of file diff --git a/code/modules/reagents/dispenser/supply.dm b/code/modules/reagents/dispenser/supply.dm index e183da7f79..8f7423dc31 100644 --- a/code/modules/reagents/dispenser/supply.dm +++ b/code/modules/reagents/dispenser/supply.dm @@ -120,7 +120,8 @@ /obj/item/weapon/reagent_containers/chem_disp_cartridge/milk, /obj/item/weapon/reagent_containers/chem_disp_cartridge/cream, /obj/item/weapon/reagent_containers/chem_disp_cartridge/tea, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/ice + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ice, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/matcha_latte ) cost = 50 containertype = /obj/structure/closet/crate diff --git a/code/modules/reagents/reagent_containers/drinkingglass/metaglass.dm b/code/modules/reagents/reagent_containers/drinkingglass/metaglass.dm index 543d5dbd90..ef7db6975a 100644 --- a/code/modules/reagents/reagent_containers/drinkingglass/metaglass.dm +++ b/code/modules/reagents/reagent_containers/drinkingglass/metaglass.dm @@ -9,6 +9,12 @@ matter = list("glass" = 500) icon = 'icons/obj/drinks.dmi' +/obj/item/weapon/reagent_containers/food/drinks/metaglass/metapint + name = "metamorphic pint glass" + desc = "This glass changes shape and form depending on the drink inside... fancy!" + icon_state = "pglass_empty" + volume = 60 + /obj/item/weapon/reagent_containers/food/drinks/metaglass/on_reagent_change() if (reagents.reagent_list.len > 0) var/datum/reagent/R = reagents.get_master_reagent() @@ -38,12 +44,17 @@ else price_tag = null else - icon_state = "glass_empty" - name = "metamorphic glass" - desc = "This glass changes shape and form depending on the drink inside... fancy!" - center_of_mass = list("x"=16, "y"=10) - return - + if(type == /obj/item/weapon/reagent_containers/food/drinks/metaglass/metapint) + icon_state = "pglass_empty" + name = "metamorphic pint glass" + desc = "This glass changes shape and form depending on the drink inside... fancy!" + center_of_mass = list("x"=16, "y"=10) + else + icon_state = "glass_empty" + name = "metamorphic glass" + desc = "This glass changes shape and form depending on the drink inside... fancy!" + center_of_mass = list("x"=16, "y"=10) + return /* Drinks Data @@ -296,7 +307,7 @@ Drinks Data glass_icon_state = "atomicbombglass" glass_center_of_mass = list("x"=15, "y"=7) -/datum/reagent/ethanol/b52 +/datum/reagent/ethanol/coffee/b52 glass_icon_state = "b52glass" /datum/reagent/ethanol/bahama_mama @@ -374,7 +385,7 @@ Drinks Data glass_icon_state = "gintonicglass" /datum/reagent/ethanol/goldschlager - glass_icon_state = "ginvodkaglass" + glass_icon_state = "goldschlagerglass" glass_center_of_mass = list("x"=16, "y"=12) /datum/reagent/ethanol/hippies_delight @@ -511,6 +522,68 @@ Drinks Data /datum/reagent/ethanol/eggnog glass_icon_state = "eggnogglass" glass_center_of_mass = list("x"=16, "y"=6) - + /datum/reagent/ethanol/spiderdrink - glass_icon_state = "glassofspiders" \ No newline at end of file + glass_icon_state = "glassofspiders" + +/datum/reagent/drink/bubbleteawatermelon + glass_icon_state = "bubbleteawatermelonglass" + glass_center_of_mass = list("x"=16, "y"=9) + +/datum/reagent/drink/bubbleteastrawberry + glass_icon_state = "bubbleteastrawberryglass" + glass_center_of_mass = list("x"=16, "y"=9) + +/datum/reagent/drink/bubbleteacherry + glass_icon_state = "bubbleteacherryglass" + glass_center_of_mass = list("x"=16, "y"=9) + +/datum/reagent/drink/bubbleteacoffee + glass_icon_state = "bubbleteacoffeeglass" + glass_center_of_mass = list("x"=16, "y"=9) + +/datum/reagent/drink/bubbleteabanana + glass_icon_state = "bubbleteabananaglass" + glass_center_of_mass = list("x"=16, "y"=9) + +/datum/reagent/drink/horchata + glass_icon_state = "horchata" + glass_center_of_mass = list("x"=16, "y"=7) + +/datum/reagent/toxin/bluetrain + glass_icon_state = "bluetrain" + glass_center_of_mass = list("x"=16, "y"=8) + +/datum/reagent/drink/lovepotion + glass_icon_state = "lovepotion" + +/datum/reagent/drink/lowpower + glass_icon_state = "lowpower" + +/datum/reagent/ethanol/coffee/jackbrew + glass_icon_state = "jackbrew" + +/datum/reagent/ethanol/bookwyrm + glass_icon_state = "bookwyrm" + +/datum/reagent/drink/highpower + glass_icon_state = "highpower" + +/datum/reagent/ethanol/flapper + glass_icon_state = "flapper" + +/datum/reagent/toxin/oilslide + glass_icon_state = "oilslide" + +/datum/reagent/ethanol/sitonmyface + glass_icon_state = "sitonmyface" + +/datum/reagent/ethanol/hachi + glass_icon_state = "hachi" + +/datum/reagent/ethanol/mojito + glass_icon_state = "mojito" + + +/datum/reagent/slimedrink + glass_icon_state = "slimedrink" diff --git a/code/modules/reagents/reagent_containers/food/drinks/bottle.dm b/code/modules/reagents/reagent_containers/food/drinks/bottle.dm index 0a09b22fe9..3aee3fc815 100644 --- a/code/modules/reagents/reagent_containers/food/drinks/bottle.dm +++ b/code/modules/reagents/reagent_containers/food/drinks/bottle.dm @@ -416,6 +416,16 @@ /obj/item/weapon/reagent_containers/food/drinks/bottle/redeemersbrew/New() ..() reagents.add_reagent("unathiliquor", 100) + +/obj/item/weapon/reagent_containers/food/drinks/bottle/snaps + name = "Akvavit" + desc = "This could go well with lunch." + icon_state = "snapsbottle" + center_of_mass = list("x"=17, "y"=3) + +/obj/item/weapon/reagent_containers/food/drinks/bottle/snaps/New() + ..() + reagents.add_reagent("snaps", 100) //////////////////////////JUICES AND STUFF /////////////////////// diff --git a/code/modules/reagents/reagent_containers/food/snacks_vr.dm b/code/modules/reagents/reagent_containers/food/snacks_vr.dm index 0b3db9b065..aef487a4df 100644 --- a/code/modules/reagents/reagent_containers/food/snacks_vr.dm +++ b/code/modules/reagents/reagent_containers/food/snacks_vr.dm @@ -277,6 +277,181 @@ reagents.add_reagent("shockchem", 6) bitesize = 7 +/obj/item/weapon/reagent_containers/food/snacks/gelbowl + name = "bowl of gelatin" + desc = "This bowl contains boring and flavourless gelatin, its probably better to make something tasty with it rather than eat it like this." + icon = 'icons/obj/food.dmi' + icon_state = "gelbowl" + trash = /obj/item/trash/snack_bowl + nutriment_amt = 0 + nutriment_desc = list("something?" = 1, "nothing" = 4) + +/obj/item/weapon/reagent_containers/food/snacks/gelbowl/New() + ..() + reagents.add_reagent("gelatin", 15) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/sauerkraut + name = "Sauerkraut" + desc = "What happens when you mix salt and minced cabbage and forget it on a shelf." + icon = 'icons/obj/food.dmi' + icon_state = "sauerkraut" + trash = /obj/item/trash/snack_bowl + nutriment_amt = 3 + nutriment_desc = list("sour cabbage" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/sauerkraut/New() + ..() + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/tamales + name = "Tamales" + desc = "Hot, steamy, moist meat bread wrapped in a corn leaf to retain moisture and flavor." + icon = 'icons/obj/food.dmi' + icon_state = "tamales" + nutriment_amt = 9 + nutriment_desc = list("moist bread" = 5, "beefy" = 4, "tangy and savory vegetables" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/tamales/New() + ..() + reagents.add_reagent("protein", 5) + bitesize = 6 + +/obj/item/weapon/reagent_containers/food/snacks/bigos + name = "Bigos" + desc = "What happens when you put minced sour cabbage and whats left in the fridge in a pot, start slowcooking it and then forget it for three hours." + icon = 'icons/obj/food.dmi' + icon_state = "bigos" + trash = /obj/item/trash/snack_bowl + nutriment_amt = 6 + nutriment_desc = list("sour cabbage" = 4, "sausage" = 3, "mildly sweet vegetables" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/bigos/New() + ..() + reagents.add_reagent("protein", 4) + reagents.add_reagent("water", 3) + bitesize = 7 + +/obj/item/weapon/reagent_containers/food/snacks/concha + name = "concha" + desc = "A sweet bread roll baked with a strawberry topping thats crunchy and delicious, it kinda looks like a shell." + icon = 'icons/obj/food.dmi' + icon_state = "concha" + nutriment_amt = 5 + nutriment_desc = list("sweet bread" = 3, "strawberry" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/concha/New() + ..() + bitesize = 3 + +/obj/item/weapon/reagent_containers/food/snacks/pandenata + name = "Pan de nata" + desc = "Large spongy and soft biscuits that taste creamy and sweet, a treat like this would be perfect on a lazy day." + icon = 'icons/obj/food.dmi' + icon_state = "pandenata" + nutriment_amt = 5 + nutriment_desc = list("sweet creamy bread" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/pandenata/New() + ..() + bitesize = 4 + +/obj/item/weapon/reagent_containers/food/snacks/tocino + name = "Tocino" + desc = "A form of bacon made from cuts of pork that has cured in wine, sugar and salt for a while, best served on a hot skillet so remains warm and tasty til the last bite." + icon = 'icons/obj/food.dmi' + icon_state = "tocino" + trash = /obj/item/trash/plate + nutriment_amt = 8 + nutriment_desc = list("crispy sweet meat" = 3, "savory sauce" = 2, "salty" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/tocino/New() + ..() + reagents.add_reagent("protein", 5) + bitesize = 5 + +/obj/item/weapon/reagent_containers/food/snacks/garlicbread + name = "Garlic bread" + desc = "Two slices of bread cooked with garlic, cheese and herbs on top to make a delicious sidedish." + icon = 'icons/obj/food.dmi' + icon_state = "garlicbread" + nutriment_amt = 5 + nutriment_desc = list("onions and melted cheese" = 2, "bread and seasonings" = 2) + +/obj/item/weapon/reagent_containers/food/snacks/garlicbread/New() + ..() + bitesize = 4 + +/obj/item/weapon/reagent_containers/food/snacks/steamtealeaf + name = "Steamed tea leaf" + desc = "A freshly picked tea leaf steamed to inhibit oxidation. Needs rolling." + icon = 'icons/obj/food.dmi' + icon_state = "tealeafsteam" + nutriment_amt = 0 + nutriment_desc = list("nothing" = 1) + +/obj/item/weapon/reagent_containers/food/snacks/steamtealeaf/New() + ..() + bitesize = 1 + +/obj/item/weapon/reagent_containers/food/snacks/steamtealeaf/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W,/obj/item/weapon/material/kitchen/rollingpin)) + new /obj/item/weapon/reagent_containers/food/snacks/steamrolltealeaf(src) + user << "You roll the steamed tea leaf." + qdel(src) + +/obj/item/weapon/reagent_containers/food/snacks/steamrolltealeaf + name = "Rolled steamed tea leaf" + desc = "A steamed tea leaf ready for drying." + icon = 'icons/obj/food.dmi' + icon_state = "tealeafsteamroll" + nutriment_amt = 0 + nutriment_desc = list("nothing" = 1) + +/obj/item/weapon/reagent_containers/food/snacks/steamrolltealeaf/New() + ..() + bitesize = 1 + +/obj/item/weapon/reagent_containers/food/snacks/greentealeaf + name = "Green tea leaf" + desc = "Green tea! Just grind and mix with hot water." + icon = 'icons/obj/food.dmi' + icon_state = "greentealeaf" + nutriment_amt = 0 + nutriment_desc = list("nothing" = 1) + +/obj/item/weapon/reagent_containers/food/snacks/greentealeaf/New() + ..() + reagents.add_reagent("tealeavesgreen", 6) + bitesize = 1 + +/obj/item/weapon/reagent_containers/food/snacks/tencha + name = "Tencha" + desc = "A dried, crumbly green tea leaf. Needs deveined." + icon = 'icons/obj/food.dmi' + icon_state = "tencha" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/matchaleaf + slices_num = 1 + nutriment_amt = 0 + nutriment_desc = list("nothing" = 1) + +/obj/item/weapon/reagent_containers/food/snacks/tencha/New() + ..() + bitesize = 1 + +/obj/item/weapon/reagent_containers/food/snacks/matchaleaf + name = "Matcha" + desc = "Low grade matcha. Ready for grinding." + icon = 'icons/obj/food.dmi' + icon_state = "matchaleaf" + nutriment_amt = 0 + nutriment_desc = list("nothing" = 0) + +/obj/item/weapon/reagent_containers/food/snacks/matchaleaf/New() + ..() + reagents.add_reagent("matchapowder", 5) + bitesize = 1 + /obj/item/weapon/reagent_containers/food/snacks/monkeycube/sobakacube name = "sobaka cube" monkey_type = "Sobaka" @@ -308,3 +483,12 @@ /obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/wolpincube name = "wolpin cube" monkey_type = "Wolpin" +// BEGIN_INTERNALS +// END_INTERNALS +// BEGIN_FILE_DIR +#define FILE_DIR . +// END_FILE_DIR +// BEGIN_PREFERENCES +// END_PREFERENCES +// BEGIN_INCLUDE +// END_INCLUDE diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index c439daac29..6a3e3f49a0 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -44,7 +44,8 @@ /obj/machinery/smartfridge/, /obj/machinery/biogenerator, /obj/structure/frame, - /obj/machinery/radiocarbon_spectrometer + /obj/machinery/radiocarbon_spectrometer, + /obj/machinery/feeder ) /obj/item/weapon/reagent_containers/glass/New() diff --git a/code/modules/reagents/reagent_containers/glass/bottle.dm b/code/modules/reagents/reagent_containers/glass/bottle.dm index 26e88caec0..29308d6c68 100644 --- a/code/modules/reagents/reagent_containers/glass/bottle.dm +++ b/code/modules/reagents/reagent_containers/glass/bottle.dm @@ -181,3 +181,11 @@ icon = 'icons/obj/chemical.dmi' icon_state = "bottle-4" prefill = list("frostoil" = 60) + + +/obj/item/weapon/reagent_containers/glass/bottle/hotwater + name = "Hot Water Bottle" + desc = "A small bottle. Contains hot water." + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle-4" + prefill = list("hotwater" = 60) \ No newline at end of file diff --git a/code/modules/recycling/conveyor2.dm b/code/modules/recycling/conveyor2.dm index d1be4f08da..3aaaa6e555 100644 --- a/code/modules/recycling/conveyor2.dm +++ b/code/modules/recycling/conveyor2.dm @@ -1,3 +1,8 @@ +//TFF 2/5/19: Port Polaris's conveyor movement fixes - set define value from 2 to -1 for reverse direction in movement. +#define OFF 0 +#define FORWARDS 1 +#define BACKWARDS -1 + //conveyor2 is pretty much like the original, except it supports corners, but not diverters. //note that corner pieces transfer stuff clockwise when running forward, and anti-clockwise backwards. @@ -10,7 +15,7 @@ layer = ABOVE_TURF_LAYER anchored = 1 circuit = /obj/item/weapon/circuitboard/conveyor - var/operating = 0 // 1 if running forward, -1 if backwards, 0 if off + var/operating = OFF // 1 if running forward, -1 if backwards, 0 if off var/operable = 1 // true if can operate (no broken segments in this belt run) var/forwards // this is the default (forward) direction, set by the map dir var/backwards // hopefully self-explanatory @@ -28,12 +33,7 @@ if(newdir) set_dir(newdir) - if(dir & (dir-1)) // Diagonal. Forwards is *away* from dir, curving to the right. - forwards = turn(dir, 135) - backwards = turn(dir, 45) - else - forwards = dir - backwards = turn(dir, 180) + update_dir() //TFF 2/5/19: Port Polaris's conveyor movement fixes if(on) operating = 1 @@ -48,22 +48,36 @@ RefreshParts() /obj/machinery/conveyor/proc/setmove() - if(operating == 1) + if(operating == FORWARDS) //TFF: Port Polaris updoot. movedir = forwards - else if(operating == -1) + else if(operating == BACKWARDS) //TFF: Port Polaris updoot. movedir = backwards - else operating = 0 + else + operating = OFF update() +//TFF 2/5/19: Port Polaris's conveyor movement fixes - handle proper movement directions when conveyor is on. +/obj/machinery/conveyor/set_dir() + .=..() + update_dir() + +/obj/machinery/conveyor/proc/update_dir() + if(!(dir in cardinal)) // Diagonal. Forwards is *away* from dir, curving to the right. + forwards = turn(dir, 135) + backwards = turn(dir, 45) + else + forwards = dir + backwards = turn(dir, 180) + /obj/machinery/conveyor/proc/update() if(stat & BROKEN) icon_state = "conveyor-broken" - operating = 0 + operating = OFF return if(!operable) - operating = 0 + operating = OFF if(stat & NOPOWER) - operating = 0 + operating = OFF icon_state = "conveyor[operating]" // machine process diff --git a/code/modules/research/circuitprinter.dm b/code/modules/research/circuitprinter.dm index dae6575577..fa93442f2e 100644 --- a/code/modules/research/circuitprinter.dm +++ b/code/modules/research/circuitprinter.dm @@ -142,13 +142,14 @@ using metal and glass, it uses glass and reagents (usually sulphuric acid). for(var/mat in materials) max_res_amount -= materials[mat] + //TFF 2/5/19: Polaris fix for Synthesisers inserting more than what is present if(materials[S.material.name] + amnt <= max_res_amount) - if(S && S.amount >= 1) + if(S && S.get_amount() >= 1) var/count = 0 overlays += "fab-load-metal" spawn(10) overlays -= "fab-load-metal" - while(materials[S.material.name] + amnt <= max_res_amount && S.amount >= 1) + while(materials[S.material.name] + amnt <= max_res_amount && S.get_amount() >= 1) materials[S.material.name] += amnt S.use(1) count++ diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index ca5a88db4b..b0f78d7ce3 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -113,6 +113,13 @@ other types of metals and chemistry for reagents). build_path = /obj/item/weapon/stock_parts/capacitor/super sort_string = "CAAAC" +/datum/design/item/stock_part/quadratic_capacitor + id = "quadratic_capacitor" + req_tech = list(TECH_POWER = 10, TECH_MATERIAL = 9) + materials = list(DEFAULT_WALL_MATERIAL = 100, "glass" = 100, "gold" = 20) + build_path = /obj/item/weapon/stock_parts/capacitor/quadratic + sort_string = "CAAAD" + /datum/design/item/stock_part/micro_mani id = "micro_mani" req_tech = list(TECH_MATERIAL = 1, TECH_DATA = 1) @@ -134,6 +141,13 @@ other types of metals and chemistry for reagents). build_path = /obj/item/weapon/stock_parts/manipulator/pico sort_string = "CAABC" +/datum/design/item/stock_part/femto_mani + id = "femto_mani" + req_tech = list(TECH_MATERIAL = 10, TECH_DATA = 9) + materials = list(DEFAULT_WALL_MATERIAL = 30, "diamond" = 50) + build_path = /obj/item/weapon/stock_parts/manipulator/femto + sort_string = "CAABD" + /datum/design/item/stock_part/basic_matter_bin id = "basic_matter_bin" req_tech = list(TECH_MATERIAL = 1) @@ -154,6 +168,13 @@ other types of metals and chemistry for reagents). materials = list(DEFAULT_WALL_MATERIAL = 80) build_path = /obj/item/weapon/stock_parts/matter_bin/super sort_string = "CAACC" + +/datum/design/item/stock_part/bluespace_matter_bin + id = "bluespace_matter_bin" + req_tech = list(TECH_MATERIAL = 10, TECH_BLUESPACE = 9) + materials = list(DEFAULT_WALL_MATERIAL = 80,"phoron" = 30) + build_path = /obj/item/weapon/stock_parts/matter_bin/bluespace + sort_string = "CAACD" /datum/design/item/stock_part/basic_micro_laser id = "basic_micro_laser" @@ -176,6 +197,13 @@ other types of metals and chemistry for reagents). build_path = /obj/item/weapon/stock_parts/micro_laser/ultra sort_string = "CAADC" +/datum/design/item/stock_part/quad_ultra_micro_laser + id = "quadultra_micro_laser" + req_tech = list(TECH_MAGNET = 10, TECH_MATERIAL = 9) + materials = list(DEFAULT_WALL_MATERIAL = 20, "glass" = 40, "uranium" = 30) + build_path = /obj/item/weapon/stock_parts/micro_laser/quad + sort_string = "CAADD" + /datum/design/item/stock_part/basic_sensor id = "basic_sensor" req_tech = list(TECH_MAGNET = 1) @@ -196,6 +224,13 @@ other types of metals and chemistry for reagents). materials = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 20, "silver" = 10) build_path = /obj/item/weapon/stock_parts/scanning_module/phasic sort_string = "CAAEC" + +/datum/design/item/stock_part/triphasic_sensor + id = "triphasic_sensor" + req_tech = list(TECH_MAGNET = 10, TECH_MATERIAL = 9) + materials = list(DEFAULT_WALL_MATERIAL = 100, "glass" = 50, "silver" = 10) + build_path = /obj/item/weapon/stock_parts/scanning_module/triphasic + sort_string = "CAAED" /datum/design/item/stock_part/RPED name = "Rapid Part Exchange Device" @@ -260,6 +295,15 @@ other types of metals and chemistry for reagents). category = "Misc" sort_string = "DAAAD" +/datum/design/item/powercell/high/hightech + name = "Self-charging power cell" + id = "selfch_cell" + req_tech = list(TECH_POWER = 5, TECH_MATERIAL = 4,TECH_BLUESPACE = 4) + materials = list(DEFAULT_WALL_MATERIAL = 2000,"glass" = 500) + build_path = /obj/item/weapon/cell/high/hightech + category = "Misc" + sort_string = "DAAAE" + /datum/design/item/powercell/device name = "device" build_type = PROTOLATHE diff --git a/code/modules/research/designs_vr.dm b/code/modules/research/designs_vr.dm index a78da35191..c0f70e1490 100644 --- a/code/modules/research/designs_vr.dm +++ b/code/modules/research/designs_vr.dm @@ -308,3 +308,12 @@ id = "rigmod_orescanner" build_path = /obj/item/rig_module/device/orescanner sort_string = "HCAAI" + +//TFF: ports VOREStation resize module for printing from the fabricator. +/datum/design/item/robot_upgrade/sizeshift + name = "Size Alteration Module" + desc = "Used to allow robot to freely alter their size." + id = "borg_sizeshift_module" + req_tech = list(TECH_BLUESPACE = 3, TECH_MATERIAL = 3, TECH_POWER = 2) + materials = list(DEFAULT_WALL_MATERIAL = 4000, "glass" = 4000) + build_path = /obj/item/borg/upgrade/sizeshift \ No newline at end of file diff --git a/code/modules/research/protolathe.dm b/code/modules/research/protolathe.dm index b90937343c..8ff4477ed3 100644 --- a/code/modules/research/protolathe.dm +++ b/code/modules/research/protolathe.dm @@ -130,13 +130,14 @@ for(var/mat in materials) max_res_amount -= materials[mat] + //TFF 2/5/19: Polaris fix for Synthesisers inserting more than what is present if(materials[S.material.name] + amnt <= max_res_amount) - if(S && S.amount >= 1) + if(S && S.get_amount() >= 1) var/count = 0 overlays += "fab-load-metal" spawn(10) overlays -= "fab-load-metal" - while(materials[S.material.name] + amnt <= max_res_amount && S.amount >= 1) + while(materials[S.material.name] + amnt <= max_res_amount && S.get_amount() >= 1) materials[S.material.name] += amnt S.use(1) count++ diff --git a/code/modules/resleeving/documents.dm b/code/modules/resleeving/documents.dm index 8b917df9d3..080160fce3 100644 --- a/code/modules/resleeving/documents.dm +++ b/code/modules/resleeving/documents.dm @@ -27,7 +27,7 @@

    Foreword: A Licensed Technology

    This message must remain attached to all documentation regarding Nanotrasen Resleeving Technology.
    - All Nanotrasen Resleeving Technology (NRT) is licensed to Nanotrasen by Kitsuhana Heavy Industries. It should only be used in the ways set forth in this guide. + All Nanotrasen Resleeving Technology (NRT) is licensed to Nanotrasen by Vey-Med. It should only be used in the ways set forth in this guide. Special consideration to the moral and ethical use of this technology should be undertaken before applying it in the field. Make sure you understand the technology fully before using the machinery.
    Contents diff --git a/code/modules/resleeving/implant.dm b/code/modules/resleeving/implant.dm index 0bfe571a8b..0bf5e91309 100644 --- a/code/modules/resleeving/implant.dm +++ b/code/modules/resleeving/implant.dm @@ -15,7 +15,7 @@ Implant Specifications:
    Name: [using_map.company_name] Employee Backup Implant
    Life: ~8 hours.
    -Important Notes: Implant is life-limited due to KHI licensing restrictions. Dissolves into harmless biomaterial after around ~8 hours, the typical work shift.
    +Important Notes: Implant is life-limited due to VM licensing restrictions. Dissolves into harmless biomaterial after around ~8 hours, the typical work shift.

    Implant Details:
    Function: Contains a small swarm of nanobots that perform neuron scanning to create mind-backups.
    @@ -41,7 +41,7 @@ //New, modern implanter instead of old style implanter. /obj/item/weapon/backup_implanter name = "backup implanter" - desc = "After discovering that Nanotrasen was just re-using the same implanters over and over again on organics, leading to cross-contamination, Kitsuhana Heavy industries designed this self-cleaning model. Holds four backup implants at a time." + desc = "After discovering that Nanotrasen was just re-using the same implanters over and over again on organics, leading to cross-contamination, Vey-Med designed this self-cleaning model. Holds four backup implants at a time." icon = 'icons/obj/device_alt.dmi' icon_state = "bimplant" item_state = "syringe_0" @@ -95,6 +95,9 @@ /obj/item/weapon/backup_implanter/attack(mob/M as mob, mob/user as mob) if (!istype(M, /mob/living/carbon)) return + var/mob/living/carbon/implantee = M//CHOMPEDIT implant check + if (implantee.hasImplant) + return if (user && imps.len) M.visible_message("[user] is injecting a backup implant into [M].") @@ -108,6 +111,7 @@ var/obj/item/weapon/implant/backup/imp = imps[imps.len] if(imp.implanted(M)) + implantee.hasImplant = 1 //CHOMPEDIT Chanigng our hasimplant var to 1 to symbolize we were backed up imp.forceMove(M) imps -= imp imp.imp_in = M @@ -148,5 +152,5 @@ //Purely for fluff /obj/item/weapon/implant/backup/full - name = "khi backup implant" - desc = "A normal KHI wireless cortical stack with neutrino and QE transmission for constant-stream consciousness upload." + name = "vm backup implant" + desc = "A normal VM wireless cortical stack with neutrino and QE transmission for constant-stream consciousness upload." diff --git a/code/modules/resleeving/sleevecard.dm b/code/modules/resleeving/sleevecard.dm index 46143e7b72..5fa6e65e78 100644 --- a/code/modules/resleeving/sleevecard.dm +++ b/code/modules/resleeving/sleevecard.dm @@ -3,7 +3,7 @@ /obj/item/device/sleevecard name = "sleevecard" - desc = "This KHI-upgraded pAI module has enough capacity to run a whole mind of human-level intelligence." + desc = "This VM-upgraded pAI module has enough capacity to run a whole mind of human-level intelligence." icon = 'icons/obj/pda.dmi' icon_state = "pai" diff --git a/code/modules/ventcrawl/ventcrawl.dm b/code/modules/ventcrawl/ventcrawl.dm index 1a4271050d..d54a15517b 100644 --- a/code/modules/ventcrawl/ventcrawl.dm +++ b/code/modules/ventcrawl/ventcrawl.dm @@ -156,7 +156,7 @@ var/list/ventcrawl_machinery = list( if(HAZARD_HIGH_PRESSURE to INFINITY) to_chat(src, "You feel a roaring wind pushing you away from the vent!") - fade_towards(vent_found,45) + //fade_towards(vent_found,45) //CHOMPEDIT removing fade animation if(!do_after(src, 45, vent_found, 1, 1)) return if(!can_ventcrawl()) @@ -198,4 +198,4 @@ var/list/ventcrawl_machinery = list( client.screen -= global_hud.centermarker client.eye = src - pipes_shown.len = 0 \ No newline at end of file + pipes_shown.len = 0 diff --git a/code/modules/virus2/disease2.dm b/code/modules/virus2/disease2.dm index 3670f60bea..77b6c3a94c 100644 --- a/code/modules/virus2/disease2.dm +++ b/code/modules/virus2/disease2.dm @@ -122,7 +122,7 @@ infect_virus2(M,src) //fever - mob.bodytemperature = max(mob.bodytemperature, min(310+5*min(stage,max_stage) ,mob.bodytemperature+5*min(stage,max_stage))) + //mob.bodytemperature = max(mob.bodytemperature, min(310+5*min(stage,max_stage) ,mob.bodytemperature+5*min(stage,max_stage))) (No more fever with all diseases, we want them to be beneficial without killing people) clicks+=speed /datum/disease2/disease/proc/cure(var/mob/living/carbon/mob) diff --git a/code/modules/virus2/effect.dm b/code/modules/virus2/effect.dm index d7db2633ad..7a0d6abdec 100644 --- a/code/modules/virus2/effect.dm +++ b/code/modules/virus2/effect.dm @@ -88,6 +88,8 @@ if(prob(10)) spawn(50) if(O) + mob.say("I don't feel so good...") + sleep(50) O.droplimb(0,DROPLIMB_BLUNT) else if(prob(75)) diff --git a/code/modules/vore/appearance/sprite_accessories_taur_vr.dm b/code/modules/vore/appearance/sprite_accessories_taur_vr.dm index 5961e04683..4a33ced54d 100644 --- a/code/modules/vore/appearance/sprite_accessories_taur_vr.dm +++ b/code/modules/vore/appearance/sprite_accessories_taur_vr.dm @@ -143,18 +143,27 @@ /datum/sprite_accessory/tail/taur/roiz_long_lizard // Not ACTUALLY a taur, but it uses 32x64 so it wouldn't fit in tails.dmi, and having it as a tail bugs up the sprite. name = "Long Lizard Tail (Roiz Lizden)" icon_state = "roiz_tail_s" - do_colouration = 0 - ckeys_allowed = list("spoopylizz") + do_colouration = 1 //TFF 25/4/19: Make colourable as per request. +// ckeys_allowed = list("spoopylizz") /datum/sprite_accessory/tail/taur/wolf name = "Wolf (Taur)" icon_state = "wolf_s" suit_sprites = 'icons/mob/taursuits_wolf_vr.dmi' + +/datum/sprite_accessory/tail/taur/fatwolf + name = "Fat Wolf (Taur)" + icon_state = "fatwolf_s" /datum/sprite_accessory/tail/taur/wolf/wolf_2c name = "Wolf dual-color (Taur)" icon_state = "wolf_s" extra_overlay = "wolf_markings" + +/datum/sprite_accessory/tail/taur/wolf/fatwolf_2c + name = "Fat Wolf dual-color (Taur)" + icon_state = "fatwolf_s" + extra_overlay = "fatwolf_markings" /datum/sprite_accessory/tail/taur/wolf/synthwolf name = "SynthWolf dual-color (Taur)" @@ -327,21 +336,61 @@ name = "Feline (Taur)" icon_state = "feline_s" +/datum/sprite_accessory/tail/taur/fatfeline + name = "Fat Feline (Taur)" + icon_state = "fatfeline_s" + +/datum/sprite_accessory/tail/taur/feline_wag + name = "Feline (Taur) (vwag)" + icon_state = "feline_s" + ani_state = "feline_w" + +/datum/sprite_accessory/tail/taur/fatfeline_wag + name = "Fat Feline (Taur) (vwag)" + icon_state = "fatfeline_s" + ani_state = "fatfeline_w" + /datum/sprite_accessory/tail/taur/feline/feline_2c name = "Feline dual-color (Taur)" icon_state = "feline_s" extra_overlay = "feline_markings" - + +/datum/sprite_accessory/tail/taur/feline/fatfeline_2c + name = "Fat Feline dual-color (Taur)" + icon_state = "fatfeline_s" + extra_overlay = "fatfeline_markings" + /datum/sprite_accessory/tail/taur/feline/feline_spots name = "Feline spots (Taur)" icon_state = "feline_s" extra_overlay = "feline_spots" - + +/datum/sprite_accessory/tail/taur/feline/feline_spots_wag + name = "Feline spots (Taur) (vwag)" + icon_state = "feline_s" + ani_state = "feline_w" + extra_overlay = "feline_spots" + extra_overlay_w = "feline_spots_w" + /datum/sprite_accessory/tail/taur/feline/synthfeline name = "SynthFeline dual-color (Taur)" icon_state = "synthfeline_s" extra_overlay = "synthfeline_markings" +/datum/sprite_accessory/tail/taur/goia_wag + name = "Goia (Taur) (vwag)" + icon_state = "goia_s" + ani_state = "goia_w" + extra_overlay = "goia_markings" + extra_overlay_w = "goia_markings_w" + +/datum/sprite_accessory/tail/taur/goiaBF_wag + name = "Goia with backfur (Taur) (vwag)" + icon_state = "goia_s" + ani_state = "goia_w" + extra_overlay = "goiaBF_markings" + extra_overlay_w = "goiaBF_markings_w" + /datum/sprite_accessory/tail/taur/slug name = "Slug (Taur)" icon_state = "slug_s" @@ -387,23 +436,55 @@ icon_state = "otie_s" extra_overlay = "otie_markings" +//TFF 25/4/19: Add Mermaid taur body selection. Requested addition! +/datum/sprite_accessory/tail/taur/mermaid + name = "Mermaid (Taur)" + icon_state = "mermaid_s" + + msg_owner_help_walk = "You carefully slide around %prey." + msg_prey_help_walk = "%owner's huge fin slides past beside you!" + + msg_owner_help_run = "You carefully slide around %prey." + msg_prey_help_run = "%owner's huge fine slides past beside you!" + + msg_owner_disarm_run = "Your fin comes up above %prey, pushing them down to the ground!" + msg_prey_disarm_run = "%owner's fin comes up you, forcing you down to the ground!" + + msg_owner_disarm_walk = "You push down on %prey with your fin, pinning them down under you!" + msg_prey_disarm_walk = "%owner pushes down on you with their fin, pinning you down below them!" + + msg_owner_harm_run = "While sliding across the ground, you go right over %prey, crushing them!" + msg_prey_harm_run = "%owner slides over your body, carelessly crushing you with their heavy fin!" + + msg_owner_harm_walk = "Your heavy fin slowly and methodically slides down upon %prey, crushing against the floor below!" + msg_prey_harm_walk = "%owner's thick, heavy fin slowly and methodically slides down upon your body, mercilessly crushing you into the floor below!" + + msg_owner_grab_success = "You slide over %prey with your large, thick fin, smushing them against the ground before bending around them, trapping them between the base of the fin and the end of it!" + msg_prey_grab_success = "%owner slithers over you with their large, thick fin, smushing you against the ground before bending around you, trapping you between the fin's base and the end of it!" + + msg_owner_grab_fail = "You squish %prey under your large, thick fin, forcing them onto the ground!" + msg_prey_grab_fail = "%owner pins you under their large, thick fin, forcing you onto the ground!" + + msg_prey_stepunder = "You jump over %prey's thick fin." + msg_owner_stepunder = "%owner bounds over your fin." + //wickedtemp: Chakat Tempest /datum/sprite_accessory/tail/taur/feline/tempest name = "Feline (wickedtemp) (Taur)" icon_state = "tempest_s" - ckeys_allowed = list("wickedtemp") +// ckeys_allowed = list("wickedtemp") //silencedmp5a5: Serdykov Antoz /datum/sprite_accessory/tail/taur/wolf/serdy name = "CyberSerdy (silencedmp5a5) (Taur)" icon_state = "serdy_s" - ckeys_allowed = list("silencedmp5a5") +// ckeys_allowed = list("silencedmp5a5") //liquidfirefly: Ariana Scol /datum/sprite_accessory/tail/taur/centipede name = "Centipede (liquidfirefly) (Taur)" icon_state = "ariana_s" - ckeys_allowed = list("liquidfirefly") +// ckeys_allowed = list("liquidfirefly") do_colouration = 0 msg_owner_disarm_run = "You quickly push %prey to the ground with your leg!" @@ -426,7 +507,7 @@ name = "Alraune (natje) (Taur)" icon_state = "alraune_s" ani_state = "alraune_closed_s" - ckeys_allowed = list("natje") +// ckeys_allowed = list("natje") do_colouration = 0 can_ride = 0 diff --git a/code/modules/vore/appearance/sprite_accessories_vr.dm b/code/modules/vore/appearance/sprite_accessories_vr.dm index c97624be16..008bcc466e 100644 --- a/code/modules/vore/appearance/sprite_accessories_vr.dm +++ b/code/modules/vore/appearance/sprite_accessories_vr.dm @@ -93,10 +93,13 @@ desc = "" icon_state = "oni-h1" + /datum/sprite_accessory/ears/demon_horns1 - name = "demon horns" + name = "demon/unathi horns" desc = "" icon_state = "demon-horns1" + do_colouration = 1 + color_blend_mode = ICON_MULTIPLY /datum/sprite_accessory/ears/demon_horns2 name = "demon horns, colorable(outward)" @@ -294,6 +297,20 @@ color_blend_mode = ICON_MULTIPLY extra_overlay = "tesharilowinner" +/datum/sprite_accessory/ears/headpaint + name = "Head Paint" + desc = "" + icon_state = "paint" + do_colouration = 1 + color_blend_mode = ICON_MULTIPLY + extra_overlay = "paintfront" + +/datum/sprite_accessory/ears/alien_slug + name = "Alien slug ears" + desc = "The ears of a slug from space" + icon_state = "alien_slug" + do_colouration = 1 + color_blend_mode = ICON_MULTIPLY // Special snowflake ears go below here. @@ -301,79 +318,79 @@ name = "quintail kitsune ears (Molenar)" desc = "" icon_state = "molenar-kitsune" - ckeys_allowed = list("molenar") +// ckeys_allowed = list("molenar") /datum/sprite_accessory/ears/lilimoth_antennae name = "citheronia antennae (Kira72)" desc = "" icon_state = "lilimoth_antennae" - ckeys_allowed = list("kira72") +// ckeys_allowed = list("kira72") /datum/sprite_accessory/ears/molenar_deathclaw name = "deathclaw ears (Molenar)" desc = "" icon_state = "molenar-deathclaw" - ckeys_allowed = list("molenar") +// ckeys_allowed = list("molenar") /datum/sprite_accessory/ears/miria_fluffdragon name = "fluffdragon ears (Miria Masters)" desc = "" icon_state = "miria-fluffdragonears" - ckeys_allowed = list("miriamasters") +// ckeys_allowed = list("miriamasters") /datum/sprite_accessory/ears/miria_kitsune name = "kitsune ears (Miria Masters)" desc = "" icon_state = "miria-kitsuneears" - ckeys_allowed = list("miriamasters") +// ckeys_allowed = list("miriamasters") /datum/sprite_accessory/ears/runac name = "fennecsune ears (Runac)" desc = "" icon_state = "runac" - ckeys_allowed = list("rebcom1807") +// ckeys_allowed = list("rebcom1807") /datum/sprite_accessory/ears/kerena name = "wingwolf ears (Kerena)" desc = "" icon_state = "kerena" - ckeys_allowed = list("somekindofpony") +// ckeys_allowed = list("somekindofpony") /datum/sprite_accessory/ears/rosey name = "tritail kitsune ears (Rosey)" desc = "" icon_state = "rosey" - ckeys_allowed = list("joey4298") +// ckeys_allowed = list("joey4298") -/datum/sprite_accessory/ears/aronai - name = "aronai ears/head (Aronai)" - desc = "" - icon_state = "aronai" - ckeys_allowed = list("arokha") +///datum/sprite_accessory/ears/aronai //Commenting out as considering it's an entire custom head sprite it shouldn't be publicly available +// name = "aronai ears/head (Aronai)" +// desc = "" +// icon_state = "aronai" +// ckeys_allowed = list("arokha") /datum/sprite_accessory/ears/holly name = "tigress ears (Holly Sharp)" desc = "" icon_state = "tigressears" - ckeys_allowed = list("hoodoo") +// ckeys_allowed = list("hoodoo") /datum/sprite_accessory/ears/molenar_inkling name = "teal mature inkling hair (Kari Akiren)" desc = "" icon_state = "molenar-tentacle" - ckeys_allowed = list("molenar") +// ckeys_allowed = list("molenar") /datum/sprite_accessory/ears/shock name = "pharoah hound ears (Shock Diamond)" desc = "" icon_state = "shock" - ckeys_allowed = list("icowom","cameron653") +// ckeys_allowed = list("icowom","cameron653") /datum/sprite_accessory/ears/alurane name = "alurane ears/hair (Pumila)" desc = "" icon_state = "alurane-ears" - ckeys_allowed = list("natje") +// ckeys_allowed = list("natje") /* //////////////////////////// @@ -477,19 +494,19 @@ name = "demon wings (Sepulchre)" desc = "" icon_state = "sepulchre_wings" - ckeys_allowed = list("sepulchre") +// ckeys_allowed = list("sepulchre") /datum/sprite_accessory/wing/miria_fluffdragon name = "fluffdragon wings (Miria Masters)" desc = "" icon_state = "miria-fluffdragontail" - ckeys_allowed = list("miriamasters") +// ckeys_allowed = list("miriamasters") /datum/sprite_accessory/wing/scree name = "green taj wings (Scree)" desc = "" icon_state = "scree-wings" - ckeys_allowed = list("scree") +// ckeys_allowed = list("scree") /datum/sprite_accessory/wing/liquidfirefly_gazer //I g-guess this could be considered wings? name = "gazer eyestalks" @@ -513,13 +530,19 @@ name = "wingwolf wings (Kerena)" desc = "" icon_state = "kerena-wings" - ckeys_allowed = list("somekindofpony") +// ckeys_allowed = list("somekindofpony") /datum/sprite_accessory/wing/snag name = "xenomorph backplate" desc = "" icon_state = "snag-backplate" +/datum/sprite_accessory/wing/snagc + name = "xenomorph backplate, colorable" + desc = "" + icon_state = "csnag-backplate" + do_colouration = 1 + /datum/sprite_accessory/wing/nevrean name = "nevrean wings/fantail" desc = "" @@ -705,6 +728,12 @@ desc = "" icon_state = "beethorax" +/datum/sprite_accessory/tail/beethorax_color + name = "bee thorax (colorable)" + desc = "" + icon_state = "beethorax2" + do_colouration = 1 + /datum/sprite_accessory/tail/doublekitsune name = "double kitsune tail, colorable" desc = "" @@ -740,61 +769,61 @@ name = "quintail kitsune tails (Molenar)" desc = "" icon_state = "molenar-kitsune" - ckeys_allowed = list("molenar") +// ckeys_allowed = list("molenar") /datum/sprite_accessory/tail/miria_fluffdragon name = "fluffdragon tail (Miria Masters)" desc = "" icon_state = "miria-fluffdragontail" - ckeys_allowed = list("miriamasters") +// ckeys_allowed = list("miriamasters") /datum/sprite_accessory/tail/miria_kitsune name = "Black kitsune tails (Miria Masters)" desc = "" icon_state = "miria-kitsunetail" - ckeys_allowed = list("miriamasters") +// ckeys_allowed = list("miriamasters") /datum/sprite_accessory/tail/molenar_deathclaw name = "deathclaw bits (Molenar)" desc = "" icon_state = "molenar-deathclaw" - ckeys_allowed = list("molenar","silvertalismen","jertheace") +// ckeys_allowed = list("molenar","silvertalismen","jertheace") /datum/sprite_accessory/tail/runac name = "fennecsune tails (Runac)" desc = "" icon_state = "runac" - ckeys_allowed = list("rebcom1807") +// ckeys_allowed = list("rebcom1807") /datum/sprite_accessory/tail/reika //Leaving this since it was too hard to split the wings from the tail. name = "fox tail (+ beewings) (Reika)" desc = "" icon_state = "reika" - ckeys_allowed = list("rikaru19xjenkins") +// ckeys_allowed = list("rikaru19xjenkins") /datum/sprite_accessory/tail/rosey name = "tritail kitsune tails (Rosey)" desc = "" icon_state = "rosey_three" - ckeys_allowed = list("joey4298") +// ckeys_allowed = list("joey4298") /datum/sprite_accessory/tail/rosey2 name = "pentatail kitsune tails (Rosey)" //I predict seven tails next. ~CK desc = "" icon_state = "rosey_five" - ckeys_allowed = list("joey4298") +// ckeys_allowed = list("joey4298") /datum/sprite_accessory/tail/scree name = "green taj tail (Scree)" desc = "" icon_state = "scree" - ckeys_allowed = list("scree") +// ckeys_allowed = list("scree") /datum/sprite_accessory/tail/aronai name = "aronai tail (Aronai)" desc = "" icon_state = "aronai" - ckeys_allowed = list("arokha") +// ckeys_allowed = list("arokha") /datum/sprite_accessory/tail/ketrai_wag name = "fennix tail (vwag)" @@ -820,7 +849,7 @@ name = "tigress tail (Holly)" desc = "" icon_state = "tigresstail" - ckeys_allowed = list("hoodoo") +// ckeys_allowed = list("hoodoo") /datum/sprite_accessory/tail/satyr name = "goat legs, colorable" @@ -904,6 +933,14 @@ do_colouration = 1 color_blend_mode = ICON_MULTIPLY +/datum/sprite_accessory/tail/snaketail_stripes + name = "snake tail with stripes, dual-color" + desc = "" + icon_state = "snaketail" + do_colouration = 1 + color_blend_mode = ICON_MULTIPLY + extra_overlay = "snaketail_stripes" + /datum/sprite_accessory/tail/vulpan_alt name = "vulpkanin alt style, colorable" desc = "" @@ -1140,4 +1177,12 @@ desc = "" icon_state = "zenghu_taj" -//Taurs moved to a separate file due to extra code around them +/datum/sprite_accessory/tail/alien_slug + name = "Alien slug tail" + desc = "The tail of a slug from space" + icon_state = "alien_slug" + do_colouration = 1 + color_blend_mode = ICON_MULTIPLY + extra_overlay = "alien_slug_markings" + +//Taurs moved to a separate file due to extra code around them \ No newline at end of file diff --git a/code/modules/vore/eating/belly_obj_vr.dm b/code/modules/vore/eating/belly_obj_vr.dm index d5c6987d65..764c9c1abd 100644 --- a/code/modules/vore/eating/belly_obj_vr.dm +++ b/code/modules/vore/eating/belly_obj_vr.dm @@ -39,7 +39,7 @@ //Actual full digest modes var/tmp/static/list/digest_modes = list(DM_HOLD,DM_DIGEST,DM_ABSORB,DM_DRAIN,DM_UNABSORB,DM_HEAL,DM_SHRINK,DM_GROW,DM_SIZE_STEAL) //Digest mode addon flags - var/tmp/static/list/mode_flag_list = list("Numbing" = DM_FLAG_NUMBING, "Itemweak" = DM_FLAG_ITEMWEAK, "Stripping" = DM_FLAG_STRIPPING) + var/tmp/static/list/mode_flag_list = list("Numbing" = DM_FLAG_NUMBING, "Itemweak" = DM_FLAG_ITEMWEAK, "Stripping" = DM_FLAG_STRIPPING, "Leave Remains" = DM_FLAG_LEAVEREMAINS) //TFF 30/4/19: Ports VoreStation Remains Option - add new belly mode addon to toggle //Transformation modes var/tmp/static/list/transform_modes = list(DM_TRANSFORM_MALE,DM_TRANSFORM_FEMALE,DM_TRANSFORM_KEEP_GENDER,DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR,DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR_EGG,DM_TRANSFORM_REPLICA,DM_TRANSFORM_REPLICA_EGG,DM_TRANSFORM_KEEP_GENDER_EGG,DM_TRANSFORM_MALE_EGG,DM_TRANSFORM_FEMALE_EGG, DM_EGG) @@ -258,6 +258,18 @@ /obj/belly/proc/nom_mob(var/mob/prey, var/mob/user) if(owner.stat == DEAD) return + if(!prey.isEdible) //CHOMPEDIT: Trying to make pred mobs prey? N O U + + var/mob/living/simple_animal/preydator = prey + if(preydator.icon_state == preydator.icon_living && preydator.size_multiplier >= 1) + user.visible_message("\the [user] promptly gets tackled by \the [prey] for trying to break their prefs! !!") + user.Weaken(5) + if (preydator.will_eat(user)) + preydator.stop_automated_movement = 1 + preydator.animal_nom(user) + preydator.update_icon() + preydator.stop_automated_movement = 0 + return if (prey.buckled) prey.buckled.unbuckle_mob() diff --git a/code/modules/vore/eating/bellymodes_tf_vr.dm b/code/modules/vore/eating/bellymodes_tf_vr.dm index 1f638f4f98..fa23e95fa5 100644 --- a/code/modules/vore/eating/bellymodes_tf_vr.dm +++ b/code/modules/vore/eating/bellymodes_tf_vr.dm @@ -97,7 +97,7 @@ change_ears(P) change_tail_nocolor(P) change_wing_nocolor(P) - change_species(P,1) + change_species(P,1,1) //TFF 14/4/19: Port VoreStation TF fix ///////////////////////////// DM_TRANSFORM_REPLICA ///////////////////////////// else if(mode == DM_TRANSFORM_REPLICA) @@ -122,7 +122,7 @@ change_ears(P) change_tail(P) change_wing(P) - change_species(P,1) + change_species(P,1,2) //TFF 14/4/19: Port VoreStation TF fix ///////////////////////////// DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR_EGG ///////////////////////////// else if(mode == DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR_EGG) @@ -134,7 +134,7 @@ change_ears(P) change_tail_nocolor(P) change_wing_nocolor(P) - change_species(P,1) + change_species(P,1,1) //TFF 14/4/19: Port VoreStation TF fix continue if(!P.absorbed) @@ -177,7 +177,7 @@ change_ears(P) change_tail(P) change_wing(P) - change_species(P,1) + change_species(P,1,2) //TFF 14/4/19: Port VoreStation TF fix continue if(!P.absorbed) diff --git a/code/modules/vore/eating/bellymodes_vr.dm b/code/modules/vore/eating/bellymodes_vr.dm index 62fc770e49..a9c8195cdc 100644 --- a/code/modules/vore/eating/bellymodes_vr.dm +++ b/code/modules/vore/eating/bellymodes_vr.dm @@ -60,7 +60,7 @@ //Numbing flag if(mode_flags & DM_FLAG_NUMBING) - if(H.bloodstr.get_reagent_amount("numbenzyme") < 2) + if(H.bloodstr.get_reagent_amount("numbenzyme") < 2 && !H.synthetic) H.bloodstr.add_reagent("numbenzyme",4) //Stripping flag @@ -113,6 +113,9 @@ to_chat(M,"" + digest_alert_prey + "") play_sound = pick(death_sounds) + //TFF 30/4/19: Ports VoreStation Remains Option - handler to leave remains + if((mode_flags & DM_FLAG_LEAVEREMAINS) && M.digest_leave_remains) + handle_remains_leaving(M) digestion_death(M) owner.update_icons() if(compensation > 0) @@ -125,6 +128,15 @@ continue + //CHOMPEDIT: Snowflake synx hook + if(istype(M,/mob/living/simple_animal/retaliate/synx)) + var/syntox = digest_brute+digest_burn + owner.adjustToxLoss(syntox) + M.adjustBruteLoss(-syntox*2) //Should automaticaly clamp to 0 + M.adjustFireLoss(-syntox*2) //Should automaticaly clamp to 0 + + //END SYNX hook. + // Deal digestion damage (and feed the pred) var/old_brute = M.getBruteLoss() var/old_burn = M.getFireLoss() @@ -172,7 +184,7 @@ if(M.absorbed && owner.nutrition >= 100) M.absorbed = 0 - to_chat(M,"You suddenly feel solid again ") + to_chat(M,"You suddenly feel solid again.") to_chat(owner,"You feel like a part of you is missing.") owner.nutrition -= 100 to_update = TRUE diff --git a/code/modules/vore/eating/contaminate_vr.dm b/code/modules/vore/eating/contaminate_vr.dm index e1d6a0f6c1..1f21eff605 100644 --- a/code/modules/vore/eating/contaminate_vr.dm +++ b/code/modules/vore/eating/contaminate_vr.dm @@ -25,8 +25,9 @@ var/image/gurgled_overlay = image('icons/effects/sludgeoverlay_vr.dmi') /obj/item/proc/can_gurgle() if(flags & PHORONGUARD) return FALSE - else if(phoronproof == TRUE) - return FALSE +//TFF 2/8/19 - removed to prevent contamination damage. +// else if(phoronproof == TRUE) +// return FALSE else if(unacidable) return FALSE else @@ -91,6 +92,9 @@ var/image/gurgled_overlay = image('icons/effects/sludgeoverlay_vr.dmi') return ..() +/obj/item/device/pda/gurgle_contaminate(var/atom/movable/item_storage = null) + return FALSE + ////////////// // Special handling of gurgle_contaminate ////////////// diff --git a/code/modules/vore/eating/digest_act_vr.dm b/code/modules/vore/eating/digest_act_vr.dm index 862387d72d..aa77f113f1 100644 --- a/code/modules/vore/eating/digest_act_vr.dm +++ b/code/modules/vore/eating/digest_act_vr.dm @@ -39,7 +39,9 @@ return FALSE //Sorta important to not digest your own beacons. /obj/item/weapon/storage/glass_ornament/digest_act(...) return FALSE - +//TFF 23/4/19: Indigestible collar addition +/obj/item/clothing/accessory/collar/holo/indigestible/digest_act(...) + return FALSE ///////////// // Some special treatment ///////////// @@ -51,10 +53,10 @@ . = ..() /obj/item/weapon/card/id/digest_act(var/atom/movable/item_storage = null) - desc = "A partially digested card that has seen better days. The damage appears to be only cosmetic, but the access codes need to be reprogrammed at the HoP office." + desc = "A partially digested card that has seen better days. The damage appears to be only cosmetic." icon = 'icons/obj/card_vr.dmi' icon_state = "[initial(icon_state)]_digested" - // access = list() // No access /Removing this because everyone thinks it's dumb. -Erik + // access = list() // No access /Removing this because everyone thinks it's dumb. -Erik //Fixing description -shark return FALSE /obj/item/weapon/reagent_containers/food/digest_act(var/atom/movable/item_storage = null) diff --git a/code/modules/vore/eating/leave_remains_vr.dm b/code/modules/vore/eating/leave_remains_vr.dm new file mode 100644 index 0000000000..46ac2f873e --- /dev/null +++ b/code/modules/vore/eating/leave_remains_vr.dm @@ -0,0 +1,164 @@ +//TFF 30/4/19: Ports VoreStation Remains Option - add new file to handle leaving some remains after digestion kills you +/obj/belly/proc/handle_remains_leaving(var/mob/living/M) + + if(istype(M,/mob/living/carbon/human)) //Are we even humanoid? + var/mob/living/carbon/human/H = M + + if((H.species.name in remainless_species) || H.isSynthetic()) //Don't leave anything if there is nothing to leave + return + + else + var/bones_amount = rand(2,3) //some random variety in amount of bones left + + if(prob(20)) //ribcage surviving whole is some luck + new /obj/item/weapon/digestion_remains/ribcage(src,owner) + bones_amount-- + + while(bones_amount) //throw in the rest + new /obj/item/weapon/digestion_remains(src,owner) + bones_amount-- + + var/skull_amount = 1 + switch(H.species.name) //oh boy here we go, finding us a right skull + if(SPECIES_HUMAN) + new /obj/item/weapon/digestion_remains/skull(src,owner) + skull_amount-- + if(SPECIES_TAJ) + new /obj/item/weapon/digestion_remains/skull/tajaran(src,owner) + skull_amount-- + if(SPECIES_UNATHI) + new /obj/item/weapon/digestion_remains/skull/unathi(src,owner) + skull_amount-- + if(SPECIES_SKRELL) + new /obj/item/weapon/digestion_remains/skull/skrell(src,owner) + skull_amount-- + if(SPECIES_VASILISSAN) + new /obj/item/weapon/digestion_remains/skull/vasilissan(src,owner) + skull_amount-- + if(SPECIES_AKULA) + new /obj/item/weapon/digestion_remains/skull/akula(src,owner) + skull_amount-- + if(SPECIES_RAPALA) + new /obj/item/weapon/digestion_remains/skull/rapala(src,owner) + skull_amount-- + if(SPECIES_VULPKANIN) + new /obj/item/weapon/digestion_remains/skull/vulpkanin(src,owner) + skull_amount-- + if(SPECIES_SERGAL) + new /obj/item/weapon/digestion_remains/skull/sergal(src,owner) + skull_amount-- + if(SPECIES_ZORREN_FLAT || SPECIES_ZORREN_HIGH) + new /obj/item/weapon/digestion_remains/skull/zorren(src,owner) + skull_amount-- + if(SPECIES_NEVREAN) + new /obj/item/weapon/digestion_remains/skull/nevrean(src,owner) + skull_amount-- + if(SPECIES_TESHARI) + new /obj/item/weapon/digestion_remains/skull/teshari(src,owner) + skull_amount-- + if(SPECIES_VOX) + new /obj/item/weapon/digestion_remains/skull/vox(src,owner) + skull_amount-- + if(SPECIES_XENOHYBRID) + new /obj/item/weapon/digestion_remains/skull/xenohybrid(src,owner) + skull_amount-- + if(skull_amount && H.species.selects_bodytype) //We still haven't found correct skull... + if(H.species.base_species == SPECIES_HUMAN) + new /obj/item/weapon/digestion_remains/skull/unknown(src,owner) + else + new /obj/item/weapon/digestion_remains/skull/unknown/anthro(src,owner) + else if(skull_amount) //Something entirely different... + new /obj/item/weapon/digestion_remains/skull/unknown(src,owner) + else + return + +/obj/item/weapon/digestion_remains + name = "bone" + desc = "A bleached bone. It's very non-descript and its hard to tell what species or part of the body it came from." + icon = 'icons/obj/bones_vr.dmi' + icon_state = "generic" + force = 0 + throwforce = 0 + item_state = "bone" + w_class = ITEMSIZE_SMALL + var/pred_ckey + var/pred_name + +/obj/item/weapon/digestion_remains/New(var/newloc,var/mob/living/pred) + ..(newloc) + pred_ckey = pred.ckey + pred_name = pred.name + +/obj/item/weapon/digestion_remains/attack_self(mob/user) + if(user.a_intent == I_HURT) + to_chat(user,"As you squeeze the [name], it crumbles into dust and falls apart into nothing!") + qdel(src) + +/obj/item/weapon/digestion_remains/ribcage + name = "ribcage" + desc = "A bleached ribcage. It's very white and definitely has seen better times. Hard to tell what it belonged to." + icon_state = "ribcage" + +/obj/item/weapon/digestion_remains/skull + name = "skull" + desc = "A bleached skull. It looks very weakened. Seems like it belonged to a human." + icon_state = "skull" + +/obj/item/weapon/digestion_remains/skull/tajaran + desc = "A bleached skull. It looks very weakened. Seems like it belonged to a tajara." + icon_state = "skull_taj" + +/obj/item/weapon/digestion_remains/skull/unathi + desc = "A bleached skull. It looks very weakened. Seems like it belonged to an unathi." + icon_state = "skull_unathi" + +/obj/item/weapon/digestion_remains/skull/skrell + desc = "A bleached skull. It looks very weakened. Seems like it belonged to a skrell." + icon_state = "skull" + +/obj/item/weapon/digestion_remains/skull/vasilissan + desc = "A bleached skull. It looks very weakened. Seems like it belonged to a vasilissan." + icon_state = "skull" + +/obj/item/weapon/digestion_remains/skull/akula + desc = "A bleached skull. It looks very weakened. Seems like it belonged to an akula." + icon_state = "skull_unathi" + +/obj/item/weapon/digestion_remains/skull/rapala + desc = "A bleached skull. It looks very weakened. Seems like it belonged to a rapala." + icon_state = "skull" + +/obj/item/weapon/digestion_remains/skull/vulpkanin + desc = "A bleached skull. It looks very weakened. Seems like it belonged to a vulpkanin." + icon_state = "skull_taj" + +/obj/item/weapon/digestion_remains/skull/sergal + desc = "A bleached skull. It looks very weakened. Seems like it belonged to a sergal." + icon_state = "skull_taj" + +/obj/item/weapon/digestion_remains/skull/zorren + desc = "A bleached skull. It looks very weakened. Seems like it belonged to a zorren." + icon_state = "skull_taj" + +/obj/item/weapon/digestion_remains/skull/nevrean + desc = "A bleached skull. It looks very weakened. Seems like it belonged to a nevrean." + icon_state = "skull_taj" + +/obj/item/weapon/digestion_remains/skull/teshari + desc = "A bleached skull. It looks very weakened. Seems like it belonged to a teshari." + icon_state = "skull_taj" + +/obj/item/weapon/digestion_remains/skull/vox + desc = "A bleached skull. It looks very weakened. Seems like it belonged to a vox." + icon_state = "skull_taj" + +/obj/item/weapon/digestion_remains/skull/unknown + desc = "A bleached skull. It looks very weakened. You can't quite tell what species it belonged to." + icon_state = "skull" + +/obj/item/weapon/digestion_remains/skull/unknown/anthro + icon_state = "skull_taj" + +/obj/item/weapon/digestion_remains/skull/xenohybrid + desc = "A bleached skull. It looks very weakened. Seems like it belonged to something with an elongated head." + icon_state = "skull_xenohybrid" \ No newline at end of file diff --git a/code/modules/vore/eating/living_vr.dm b/code/modules/vore/eating/living_vr.dm index 4e845ccc33..8d1717b320 100644 --- a/code/modules/vore/eating/living_vr.dm +++ b/code/modules/vore/eating/living_vr.dm @@ -1,7 +1,11 @@ ///////////////////// Mob Living ///////////////////// /mob/living var/digestable = 1 // Can the mob be digested inside a belly? + //TFF 30/4/19: Ports VoreStation Remains Option - set var for leaving remains + var/digest_leave_remains = 0 // Will this mob leave bones/skull/etc after the melty demise? var/allowmobvore = 1 // Will simplemobs attempt to eat the mob? + //TFF 30/4/19: Ports VoreStation Mechanical Vore Prefs - set var for displaying vore prefs on examine + var/showvoreprefs = 1 // Determines if the mechanical vore preferences button will be displayed on the mob or not. var/obj/belly/vore_selected // Default to no vore capability. var/list/vore_organs = list() // List of vore containers inside a mob var/absorbed = 0 // If a mob is absorbed into another @@ -194,6 +198,8 @@ var/datum/vore_preferences/P = client.prefs_vr P.digestable = src.digestable + //TFF 30/4/19: Ports VoreStation Remains Option + P.digest_leave_remains = src.digest_leave_remains P.allowmobvore = src.allowmobvore P.vore_taste = src.vore_taste P.can_be_drop_prey = src.can_be_drop_prey @@ -219,6 +225,8 @@ var/datum/vore_preferences/P = client.prefs_vr digestable = P.digestable + //TFF 30/4/19: Ports VoreStation Remains Option + P.digest_leave_remains = src.digest_leave_remains allowmobvore = P.allowmobvore vore_taste = P.vore_taste can_be_drop_prey = P.can_be_drop_prey @@ -329,6 +337,7 @@ if(!confirm == "Okay" || loc != B) return //Actual escaping + absorbed = 0 //Make sure we're not absorbed forceMove(get_turf(src)) //Just move me up to the turf, let's not cascade through bellies, there's been a problem, let's just leave. for(var/mob/living/simple_animal/SA in range(10)) SA.prey_excludes[src] = world.time @@ -611,3 +620,27 @@ set category = "Preferences" set desc = "Switch sharp/fuzzy scaling for current mob." appearance_flags ^= PIXEL_SCALE + +//TFF 30/4/19: Ports VoreStation Mechanical Vore Prefs & Remains-leaving in 1 go +/mob/living/examine(mob/user) + . = ..() + if(showvoreprefs) + to_chat(user, "\[Mechanical Vore Preferences\]") + +/mob/living/Topic(href, href_list) //Can't find any instances of Topic() being overridden by /mob/living in polaris' base code, even though /mob/living/carbon/human's Topic() has a ..() call + if(href_list["vore_prefs"]) + display_voreprefs(usr) + return ..() + +/mob/living/proc/display_voreprefs(mob/user) //Called by Topic() calls on instances of /mob/living (and subtypes) containing vore_prefs as an argument + if(!user) + CRASH("display_voreprefs() was called without an associated user.") + var/dispvoreprefs = "[src]'s vore preferences


    " + dispvoreprefs += "Digestable: [digestable ? "Enabled" : "Disabled"]
    " + dispvoreprefs += "Leaves Remains: [digest_leave_remains ? "Enabled" : "Disabled"]
    " + dispvoreprefs += "Mob Vore: [allowmobvore ? "Enabled" : "Disabled"]
    " + dispvoreprefs += "Drop-nom prey: [can_be_drop_prey ? "Enabled" : "Disabled"]
    " + dispvoreprefs += "Drop-nom pred: [can_be_drop_pred ? "Enabled" : "Disabled"]
    " + user << browse("Vore prefs: [src]
    [dispvoreprefs]
    ", "window=[name];size=200x300;can_resize=0;can_minimize=0") + onclose(user, "[name]") + return diff --git a/code/modules/vore/eating/transforming_vr.dm b/code/modules/vore/eating/transforming_vr.dm index b978bf8963..a0398350fb 100644 --- a/code/modules/vore/eating/transforming_vr.dm +++ b/code/modules/vore/eating/transforming_vr.dm @@ -210,42 +210,44 @@ return 1 return 0 -/obj/belly/proc/change_species(var/mob/living/carbon/human/M, message=0) +//TFF: Port VoreStation TF fix +/obj/belly/proc/change_species(var/mob/living/carbon/human/M, message=0, color_action = 0) //color_action: 0 for default species, 1 to preserve, 2 to transfer from pred var/mob/living/carbon/human/O = owner if(!istype(M) || !istype(O)) return - if (M.species == "Promethean" && O.species != "Promethean") //If the person was a promethean before TF, remove all their verbs! - M.verbs -= /mob/living/carbon/human/proc/shapeshifter_select_shape - M.verbs -= /mob/living/carbon/human/proc/shapeshifter_select_colour - M.verbs -= /mob/living/carbon/human/proc/shapeshifter_select_hair - M.verbs -= /mob/living/carbon/human/proc/shapeshifter_select_gender - M.verbs -= /mob/living/carbon/human/proc/regenerate - M.verbs -= /mob/living/proc/set_size +//TFF: Port VoreStation TF fix + M.verbs -= M.species.inherent_verbs //Take away their unique stuff - M.species = O.species + var/list/backup_implants = list() + for(var/obj/item/organ/I in M.organs) + for(var/obj/item/weapon/implant/backup/BI in I.contents) + backup_implants += BI + if(backup_implants.len) + for(var/obj/item/weapon/implant/backup/BI in backup_implants) + BI.forceMove(src) + if(color_action == 1) + M.set_species(O.species.name,0,1,M) + else if(color_action == 2) + M.set_species(O.species.name,0,1,O) + else + M.set_species(O.species.name) M.custom_species = O.custom_species - M.species.create_organs(M) //This is the only way to make it so Unathi TF doesn't result in people dying from organ rejection. - for(var/obj/item/organ/I in M.organs) //This prevents organ rejection - I.species = O.species - for(var/obj/item/organ/I in M.internal_organs) //This prevents organ rejection - I.species = O.species - for(var/obj/item/organ/external/Z in M.organs)//Just in case. - Z.sync_colour_to_human(M) - M.fixblood() + +//TFF: Port VoreStation TF fix M.update_icons_body() M.update_tail_showing() + +//TFF: Port VoreStation TF fix. + if(backup_implants.len) + var/obj/item/organ/external/torso = M.get_organ(BP_TORSO) + for(var/obj/item/weapon/implant/backup/BI in backup_implants) + BI.forceMove(torso) + torso.implants += BI + if(message) to_chat(M, "You lose sensation of your body, feeling only the warmth of everything around you... ") to_chat(O, "Your body shifts as you make dramatic changes to your captive's body.") - if (M.species == "Promethean") //Did they get TF'd into a promethean? - M.verbs += /mob/living/carbon/human/proc/shapeshifter_select_shape - M.verbs += /mob/living/carbon/human/proc/shapeshifter_select_colour - M.verbs += /mob/living/carbon/human/proc/shapeshifter_select_hair - M.verbs += /mob/living/carbon/human/proc/shapeshifter_select_gender - M.verbs += /mob/living/carbon/human/proc/regenerate - M.verbs += /mob/living/proc/set_size - M.shapeshifter_select_shape() /obj/belly/proc/put_in_egg(var/atom/movable/M, message=0) var/mob/living/carbon/human/O = owner diff --git a/code/modules/vore/eating/vore_vr.dm b/code/modules/vore/eating/vore_vr.dm index d6939e9c95..84c421c214 100644 --- a/code/modules/vore/eating/vore_vr.dm +++ b/code/modules/vore/eating/vore_vr.dm @@ -42,6 +42,8 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE /datum/vore_preferences //Actual preferences var/digestable = TRUE + //TFF 30/4/19: Ports VoreStation Remains Option - set boolean for leaving remains + var/digest_leave_remains = FALSE var/allowmobvore = TRUE var/list/belly_prefs = list() var/vore_taste = "nothing in particular" @@ -92,9 +94,9 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE return 0 //Need to know what character to load! slot = client.prefs.default_slot - + load_path(client_ckey,slot) - + if(!path) return 0 //Path couldn't be set? if(!fexists(path)) //Never saved before save_vore() //Make the file first @@ -108,6 +110,8 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE json_from_file = patch_version(json_from_file,version) digestable = json_from_file["digestable"] + //TFF 30/4/19: Ports VoreStation Remains Option - add json stuff for whether a char's player allows said char to leave bones behind + digest_leave_remains = json_from_file["digest_leave_remains"] allowmobvore = json_from_file["allowmobvore"] vore_taste = json_from_file["vore_taste"] can_be_drop_prey = json_from_file["can_be_drop_prey"] @@ -117,6 +121,9 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE //Quick sanitize if(isnull(digestable)) digestable = TRUE + //TFF 30/4/19: Ports VoreStation Remains Option - sanitise for setting to false if left null + if(isnull(digest_leave_remains)) + digest_leave_remains = FALSE if(isnull(allowmobvore)) allowmobvore = TRUE if(isnull(can_be_drop_prey)) @@ -130,11 +137,13 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE /datum/vore_preferences/proc/save_vore() if(!path) return 0 - + var/version = 1 //For "good times" use in the future var/list/settings_list = list( "version" = version, "digestable" = digestable, + //TFF 30/4/19: Ports VoreStation Remains Option - add toggleable setting to the list on Vore Panel + "digest_leave_remains" = digest_leave_remains, "allowmobvore" = allowmobvore, "vore_taste" = vore_taste, "can_be_drop_prey" = can_be_drop_prey, @@ -147,7 +156,7 @@ V::::::V V::::::VO:::::::OOO:::::::ORR:::::R R:::::REE::::::EEEEEE if(!json_to_file) log_debug("Saving: [path] failed jsonencode") return 0 - + //Write it out if(fexists(path)) fdel(path) //Byond only supports APPENDING to files, not replacing. diff --git a/code/modules/vore/eating/vorepanel_vr.dm b/code/modules/vore/eating/vorepanel_vr.dm index f76cc11c59..c2d66dc0ce 100644 --- a/code/modules/vore/eating/vorepanel_vr.dm +++ b/code/modules/vore/eating/vorepanel_vr.dm @@ -285,6 +285,13 @@ if(0) dat += "Toggle Digestable" + //TFF 30/4/19: Ports VoreStation Remains Option - add option to leave remains after you digest a meal + switch(user.digest_leave_remains) + if(1) + dat += "Toggle Leaving Remains" + if(0) + dat += "Toggle Leaving Remains" + switch(user.allowmobvore) if(1) dat += "Toggle Mob Vore" @@ -742,20 +749,21 @@ selected = user.vore_organs[1] user.vore_selected = user.vore_organs[1] +//TFF 30/4/19: We're not Virgo here, change to the right server name if(href_list["saveprefs"]) if(!user.save_vore_prefs()) - alert("ERROR: Virgo-specific preferences failed to save!","Error") + alert("ERROR: ChompStation-specific preferences failed to save!","Error") else - to_chat(user,"Virgo-specific preferences saved!") + to_chat(user,"ChompStation-specific preferences saved!") if(href_list["applyprefs"]) var/alert = alert("Are you sure you want to reload character slot preferences? This will remove your current vore organs and eject their contents.","Confirmation","Reload","Cancel") if(!alert == "Reload") return 0 if(!user.apply_vore_prefs()) - alert("ERROR: Virgo-specific preferences failed to apply!","Error") + alert("ERROR: ChompStation-specific preferences failed to apply!","Error") else - to_chat(user,"Virgo-specific preferences applied from active slot!") + to_chat(user,"ChompStation-specific preferences applied from active slot!") if(href_list["setflavor"]) var/new_flavor = html_encode(input(usr,"What your character tastes like (40ch limit). This text will be printed to the pred after 'X tastes of...' so just put something like 'strawberries and cream':","Character Flavor",user.vore_taste) as text|null) @@ -803,6 +811,23 @@ if(user.client.prefs_vr) user.client.prefs_vr.digestable = user.digestable + //TFF 30/4/19: Ports VoreStation Remains Option - add option that goes paw in paw with belly setting; allow yourself to leave bones behind after you're digested + //TFF 2/8/19 - Add admin message notification for setting this ON. + if(href_list["toggledlm"]) + var/choice = alert(user, "This button allows preds to have your remains be left in their belly after you are digested. This will only happen if pred sets their belly to do so. Remains consist of skeletal parts. Setting this will notify admins. Currently you are [user.digest_leave_remains? "" : "not"] leaving remains.", "", "Allow Post-digestion Remains", "Cancel", "Disallow Post-digestion Remains") + switch(choice) + if("Cancel") + return 0 + if("Allow Post-digestion Remains") + user.digest_leave_remains = TRUE + if("Disallow Post-digestion Remains") + user.digest_leave_remains = FALSE + + message_admins("[key_name(user)] toggled their ability to leave remains to [user.digest_leave_remains] ([user ? "JMP" : "null"])") + + if(user.client.prefs_vr) + user.client.prefs_vr.digest_leave_remains = user.digest_leave_remains + if(href_list["togglemv"]) var/choice = alert(user, "This button is for those who don't like being eaten by mobs. Messages admins when changed, so don't try to use it for mechanical benefit. Set it once and save it. Mobs are currently: [user.allowmobvore ? "Allowed to eat" : "Prevented from eating"] you.", "", "Allow Mob Predation", "Cancel", "Prevent Mob Predation") switch(choice) diff --git a/code/modules/vore/fluffstuff/custom_boxes_vr.dm b/code/modules/vore/fluffstuff/custom_boxes_vr.dm index 57b83c9876..b1eebc896a 100644 --- a/code/modules/vore/fluffstuff/custom_boxes_vr.dm +++ b/code/modules/vore/fluffstuff/custom_boxes_vr.dm @@ -216,7 +216,29 @@ /obj/item/clothing/shoes/fluff/morthighs, /obj/item/clothing/gloves/fluff/morsleeves, /obj/item/clothing/under/fluff/morunder) + +// kazzc: Kassc +/obj/item/weapon/storage/box/fluff/Kassc + name = "" + desc = "" + has_items = list( + /obj/item/clothing/accessory/medal/silver/valor) +// keithwinters: Keith Winters +/obj/item/weapon/storage/box/fluff/Keith_Winters + name = "" + desc = "" + has_items = list( + /obj/item/clothing/accessory/medal/silver/valor) + +// nadyr: Taaa +/obj/item/weapon/storage/box/fluff/Taaa + name = "" + desc = "" + has_items = list( + /obj/item/clothing/accessory/medal/silver/valor, + /obj/item/clothing/accessory/medal/conduct, + /obj/item/clothing/accessory/medal/gold/heroism) /* Swimsuits, for general use, to avoid arriving to work with your swimsuit. diff --git a/code/modules/vore/fluffstuff/custom_clothes_vr.dm b/code/modules/vore/fluffstuff/custom_clothes_vr.dm index 1e7c5bd22f..fc37b581df 100644 --- a/code/modules/vore/fluffstuff/custom_clothes_vr.dm +++ b/code/modules/vore/fluffstuff/custom_clothes_vr.dm @@ -799,9 +799,9 @@ H.update_inv_head() /obj/item/weapon/rig/light/hacker/fluff/aronai - name = "KHI-99-AAR suit module" + name = "VM-99-AAR suit module" suit_type = "nano" - desc = "A thin collapsable spacesuit for synths from Kitsuhana Heavy Industries." + desc = "A thin collapsable spacesuit for synths from Vey-Med." airtight = 1 //Not because it should be airtight but because suit coolers don't work w/o it. armor = list(melee = 25, bullet = 15, laser = 15, energy = 60, bomb = 30, bio = 70, rad = 100) air_type = null //No O2 tank, why would it have one? @@ -892,8 +892,8 @@ desc = "ROW ROW, FIGHT THE POWER." flash_prot = 1 //Why not. -//Kitsuhana Uniforms -/obj/item/clothing/under/rank/khi +//Gilthari Uniforms +/obj/item/clothing/under/rank/ge name = "Delete Me" desc = "Why did you spawn this one? Dork." sensor_mode = 3 @@ -904,49 +904,49 @@ icon_override = 'icons/vore/custom_clothes_vr.dmi' item_state = "" -/obj/item/clothing/under/rank/khi/cmd //Command version - name = "KHI command suit" - desc = "Kitsuhana Heavy Industries uniform. An extra-comfortable command one, at that. I guess if you DON'T want anarchy for some reason." +/obj/item/clothing/under/rank/ge/cmd //Command version + name = "GE command suit" + desc = "Gilthari Exports uniform. An extra-comfortable command one, at that." icon_state = "khi_uniform_cmd_i" item_state = "khi_uniform_cmd" worn_state = "khi_uniform_cmd" armor = list(melee = 5, bullet = 10, laser = 10, energy = 0, bomb = 0, bio = 0, rad = 0) -/obj/item/clothing/under/rank/khi/sec //Security version - name = "KHI security suit" - desc = "Kitsuhana Heavy Industries uniform. This one has angry red security stripes. Keepin' the peace in style." +/obj/item/clothing/under/rank/ge/sec //Security version + name = "GE security suit" + desc = "Gilthari Exports uniform. This one has angry red security stripes. Keepin' the peace in style." icon_state = "khi_uniform_sec_i" item_state = "khi_uniform_sec" worn_state = "khi_uniform_sec" armor = list(melee = 10, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) -/obj/item/clothing/under/rank/khi/med //Medical version - name = "KHI medical suit" - desc = "Kitsuhana Heavy Industries uniform. The medical version. Why not just get a new body, anyway?" +/obj/item/clothing/under/rank/ge/med //Medical version + name = "GE medical suit" + desc = "Gilthari Exports uniform. The medical version. Why not just get a new body, anyway?" icon_state = "khi_uniform_med_i" item_state = "khi_uniform_med" worn_state = "khi_uniform_med" armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 50, rad = 5) -/obj/item/clothing/under/rank/khi/eng //Engineering version - name = "KHI engineering suit" - desc = "Kitsuhana Heavy Industries uniform. One fit for an engineer, by the looks of it. Building the future, one disaster at a time." +/obj/item/clothing/under/rank/ge/eng //Engineering version + name = "GE engineering suit" + desc = "Gilthari Exports uniform. One fit for an engineer, by the looks of it. Building the future, one disaster at a time." icon_state = "khi_uniform_eng_i" item_state = "khi_uniform_eng" worn_state = "khi_uniform_eng" armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 10) -/obj/item/clothing/under/rank/khi/sci //Science version - name = "KHI science suit" - desc = "Kitsuhana Heavy Industries uniform. For performing science in, based on the color! Only SCIENCE can save us now." +/obj/item/clothing/under/rank/ge/sci //Science version + name = "GE science suit" + desc = "Gilthari Exports uniform. For performing science in, based on the color! Only SCIENCE can save us now." icon_state = "khi_uniform_sci_i" item_state = "khi_uniform_sci" worn_state = "khi_uniform_sci" armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 5, bio = 0, rad = 5) -/obj/item/clothing/under/rank/khi/fluff/aronai //Aro fluff version - name = "KHI meditech suit" - desc = "Kitsuhana Heavy Industries uniform. This one has the colors of a resleeving or mnemonics engineer. It has 'Aronai' written inside the top." +/obj/item/clothing/under/rank/ge/fluff/aronai //Aro fluff version + name = "GE meditech suit" + desc = "Gilthari Exports uniform. This one has the colors of a resleeving or mnemonics engineer. It has 'Aronai' written inside the top." icon_state = "khi_uniform_aro_i" item_state = "khi_uniform_aro" worn_state = "khi_uniform_aro" @@ -1806,4 +1806,66 @@ Departamental Swimsuits, for general use icon_state = "zao_cap" icon_override = 'icons/vore/custom_clothes_vr.dmi' - item_state = "zao_cap_mob" \ No newline at end of file + item_state = "zao_cap_mob" + + +/obj/item/clothing/suit/storage/toggle/denim_jacket/sleeveless/black + name = "black denim vest" + desc = "A black denim vest." + icon_state = "blk_jacket" + icon_override = "icons/mob/suit_vr.dmi" + icon = 'icons/mob/suit_vr.dmi' + +/obj/item/clothing/glasses/goggles/flip + name = "goggles" + icon_override = "icons/mob/eyes_vr.dmi" + icon = 'icons/mob/eyes_vr.dmi' + desc = "Just some plain old goggles." + icon_state = "Goggles-g" + item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses") + item_flags = AIRTIGHT + body_parts_covered = EYES + action_button_name = "Flip Goggles" + var/up = 0 + + sprite_sheets = list( + "Teshari" = 'icons/mob/species/seromi/eyes_vr.dmi' + ) + +/obj/item/clothing/shoes/boots/jackboots/tall + name = "tall jackboots" + desc = "Modified pair of jackboots, made to be taller by some fashion designer." + icon_state = "tallboots" + icon_override = 'icons/mob/feet_vr.dmi' + icon = 'icons/mob/feet_vr.dmi' + item_state_slots = list(slot_r_hand_str = "tallboots", slot_l_hand_str = "jackboots") + species_restricted = null + + +/obj/item/clothing/glasses/goggles/flip/attack_self() + toggle() + +/obj/item/clothing/glasses/goggles/flip/verb/toggle() + set category = "Object" + set name = "Adjust goggles" + set src in usr + + if(usr.canmove && !usr.stat && !usr.restrained()) + if(src.up) + src.up = !src.up + flags_inv |= HIDEEYES + body_parts_covered |= EYES + icon_state = initial(icon_state) + flash_protection = initial(flash_protection) + tint = initial(tint) + to_chat(usr, "You flip \the [src] down to protect your eyes.") + else + src.up = !src.up + flags_inv &= ~HIDEEYES + body_parts_covered &= ~EYES + icon_state = "[initial(icon_state)]up" + flash_protection = FLASH_PROTECTION_NONE + tint = TINT_NONE + to_chat(usr, "You push \the [src] up out of your face.") + update_clothing_icon() + usr.update_action_buttons() \ No newline at end of file diff --git a/code/modules/vore/fluffstuff/custom_items_vr.dm b/code/modules/vore/fluffstuff/custom_items_vr.dm index f2616cafc0..a328ff6099 100644 --- a/code/modules/vore/fluffstuff/custom_items_vr.dm +++ b/code/modules/vore/fluffstuff/custom_items_vr.dm @@ -478,7 +478,7 @@
    Purpose
    -

    The Kitsuhana Life Crystal is a small device typically worn around the neck for the purpose of reporting your status to the HAVENS (Kitsuhana's High-AVailability ENgram Storage) system, so that appropriate measures can be taken in the case of your body's demise. The whole device is housed inside a pleasing-to-the-eye elongated diamond.

    +

    The Vey-Med Life Crystal is a small device typically worn around the neck for the purpose of reporting your status to the HAVENS (Vey-Med's High-AVailability ENgram Storage) system, so that appropriate measures can be taken in the case of your body's demise. The whole device is housed inside a pleasing-to-the-eye elongated diamond.

    Upon your body's desmise, the crystal will send a transmission to HAVENS. Depending on your membership level, the appropriate actions can be taken to ensure that you are back up and enjoying existence as soon as possible.

    Nanotrasen has negotiated a FREE Star membership for you in the HAVENS system, though an upgrade can be obtained depending on your citizenship and reputation level.

    @@ -615,6 +615,128 @@ taurtype = /datum/sprite_accessory/tail/taur/feline/tempest no_message = "These saddlebags seem to be fitted for someone else, and keep slipping off!" +//TFF 29/4/19: Add standardised reagent generators for loadout +/obj/item/weapon/implant/reagent_generator/milk + name = "milk generation implant" + desc = "It's an implant you can use to make milk from yourself!" + generated_reagents = list("milk" = 2) + reagent_name = "milk" + usable_volume = 1000 + + empty_message = list("Your breasts are almost completely drained!") + full_message = list("Your teats feel heavy and swollen!") + emote_descriptor = list("squeezes milk", "tugs on their breasts, milking them") + self_emote_descriptor = list("squeeze") + random_emote = list("moos quietly") + verb_name = "Milk" + verb_desc = "Grab their nipples and milk them into a container! May cause blushing and groaning." + +/obj/item/weapon/implanter/reagent_generator/milk + implant_type = /obj/item/weapon/implant/reagent_generator/milk + +/obj/item/weapon/implant/reagent_generator/egg + name = "egg laying implant" + desc = "This is an implant that allows the user to lay eggs." + generated_reagents = list("egg" = 2) + usable_volume = 500 + transfer_amount = 50 + + empty_message = list("Your lower belly feels smooth and empty. Sorry, we're out of eggs!", "The reduced pressure in your lower belly tells you there are no more eggs.") + full_message = list("Your lower belly looks swollen with irregular bumps, and it feels heavy.", "Your lower abdomen feels really heavy, making it a bit hard to walk.") + emote_descriptor = list("an egg right out of their belly!", "into their belly firmly, forcing them to lay an egg!", "them really tight, making them lay an egg promptly!") + var/verb_descriptor = list("squeezes", "pushes", "hugs") + var/self_verb_descriptor = list("squeeze", "push", "hug") + var/short_emote_descriptor = list("lays", "forces out", "pushes out") + self_emote_descriptor = list("lay", "force out", "push out") + random_emote = list("moans softly with a blush on their face", "yelps in embarrassment", "grunts a little") + assigned_proc = /mob/living/carbon/human/proc/use_reagent_implant_egg + +/obj/item/weapon/implant/reagent_generator/egg/implanted(mob/living/carbon/source) + processing_objects += src + to_chat(source, "You implant [source] with \the [src].") + source.verbs |= assigned_proc + return 1 + +/obj/item/weapon/implanter/reagent_generator/egg + implant_type = /obj/item/weapon/implant/reagent_generator/egg + +/mob/living/carbon/human/proc/use_reagent_implant_egg() + set name = "Lay Egg" + set desc = "Force them to lay an egg by squeezing into their lower body!" + set category = "Object" + set src in view(1) + + //do_reagent_implant(usr) + if(!isliving(usr) || !usr.canClick()) + return + + if(usr.incapacitated() || usr.stat > CONSCIOUS) + return + + var/obj/item/weapon/implant/reagent_generator/egg/rimplant + for(var/obj/item/organ/external/E in organs) + for(var/obj/item/weapon/implant/I in E.implants) + if(istype(I, /obj/item/weapon/implant/reagent_generator)) + rimplant = I + break + if (rimplant) + if(rimplant.reagents.total_volume <= rimplant.transfer_amount) + to_chat(src, "[pick(rimplant.empty_message)]") + return + + new /obj/item/weapon/reagent_containers/food/snacks/egg(get_turf(src)) + + var/index = rand(0,3) + + if (usr != src) + var/emote = rimplant.emote_descriptor[index] + var/verb_desc = rimplant.verb_descriptor[index] + var/self_verb_desc = rimplant.self_verb_descriptor[index] + usr.visible_message("[usr] [verb_desc] [emote]", + "You [self_verb_desc] [emote]") + else + visible_message("[src] [pick(rimplant.short_emote_descriptor)] an egg.", + "You [pick(rimplant.self_emote_descriptor)] an egg.") + if(prob(15)) + visible_message("[src] [pick(rimplant.random_emote)].") // M-mlem. + + rimplant.reagents.remove_any(rimplant.transfer_amount) + +//TFF 7/5/19 - addition of honey generator on request +/obj/item/weapon/implant/reagent_generator/honey + generated_reagents = list("honey" = 2) + reagent_name = "honey" + usable_volume = 1000 + + empty_message = list("You appear to be all out of nectar", "You feel as though you are lacking a majority of your nectar.") + full_message = list("You appear to be full of nectar.", "You feel as though you are full of nectar!") + emote_descriptor = list("squeezes nectar", "extracts nectar") + self_emote_descriptor = list("squeeze", "extract") + verb_name = "Extract Honey" + verb_desc = "Obtain their nectar and put it into a container!" + +/obj/item/weapon/implanter/reagent_generator/honey + implant_type = /obj/item/weapon/implant/reagent_generator/honey + +//kcin 6/6/19 - i want to slurp slime +/obj/item/weapon/implant/reagent_generator/slime + name = "slime generation implant" + desc = "It's an implant you can use to make slime from yourself!" + generated_reagents = list("slimedrink" = 2) + reagent_name = "slimedrink" + usable_volume = 1000 + + empty_message = list("You look quite ghostly!") + full_message = list("Your are nearly opaque!") + emote_descriptor = list("drips slime", "lets some of their slime drip") + self_emote_descriptor = list("drip") + random_emote = list("blrbles softly") + verb_name = "Drip" + verb_desc = "You Catch slime in your container." + +/obj/item/weapon/implanter/reagent_generator/milk + implant_type = /obj/item/weapon/implant/reagent_generator/milk + //WickedTempest: Chakat Tempest /obj/item/weapon/implant/reagent_generator/tempest generated_reagents = list("milk" = 2) diff --git a/code/modules/vore/fluffstuff/custom_permits_vr.dm b/code/modules/vore/fluffstuff/custom_permits_vr.dm index fc5d47e37c..ffe652cf7d 100644 --- a/code/modules/vore/fluffstuff/custom_permits_vr.dm +++ b/code/modules/vore/fluffstuff/custom_permits_vr.dm @@ -21,10 +21,12 @@ name = "Tasald Ajax Corlethian's Sidearm Permit" desc = "A card indicating that the owner is allowed to carry a sidearm. It is issued by CentCom, so it is valid until it expires on August 2nd, 2562." +/* //tomtyph: Sarika /obj/item/clothing/accessory/permit/gun/fluff/tomtyph name = "Sarika's Sidearm Permit" desc = "A card indicating that the owner is allowed to carry a sidearm. It is issued by CentCom, so it is valid until it expires on December 7th, 2563." +*/ //LE expired // dhaeleena:Dhaeleena M'iar /obj/item/clothing/accessory/permit/gun/fluff/dhaeleena_miar diff --git a/code/modules/vore/fluffstuff/guns/bsharpoon.dm b/code/modules/vore/fluffstuff/guns/bsharpoon.dm index 259ef32b52..f72ca2b2fe 100644 --- a/code/modules/vore/fluffstuff/guns/bsharpoon.dm +++ b/code/modules/vore/fluffstuff/guns/bsharpoon.dm @@ -92,3 +92,98 @@ flick("harpoon-1-change",src) icon_state = "harpoon-2" transforming = 0 + +/obj/item/weapon/teleport_cane + name = "Gentleman's Cane of Teleportation" + desc = "Stylish, yet very functional" + + icon = 'icons/obj/weapons.dmi' + icon_state = "cane" + item_icons = list(slot_l_hand_str = 'icons/mob/items/lefthand_melee.dmi', slot_r_hand_str = 'icons/mob/items/righthand_melee.dmi') + + w_class = ITEMSIZE_NORMAL + + throw_speed = 4 + throw_range = 20 + + origin_tech = list(TECH_BLUESPACE = 5) + + var/mode = 1 // 1 mode - teleport you to turf 0 mode teleport turf to you + var/last_fire = 0 + var/transforming = 0 + +/obj/item/weapon/teleport_cane/afterattack(atom/A, mob/user as mob) + var/current_fire = world.time + if(!user || !A) + return + if(transforming) + to_chat(user,"You can't use while \the [src] transforming!") + return + if(!(current_fire - last_fire >= 30 SECONDS)) + to_chat(user,"\The [src] is recharging...") + return + if(is_jammed(A) || is_jammed(user)) + to_chat(user,"\The [src] magic fizzles due to interference!") + last_fire = current_fire + playsound(user, 'sound/weapons/wave.ogg', 60, 1) + return + var/turf/T = get_turf(A) + if(!T || T.check_density()) + to_chat(user,"That's a little too solid to teleport into!") + return + var/turf/ownturf = get_turf(src) + if(ownturf.z != T.z || get_dist(T,ownturf) > world.view) + to_chat(user, "The target is out of range!") + return + + last_fire = current_fire + playsound(user, 'sound/weapons/wave.ogg', 60, 1) + + user.visible_message("[user] uses \the [src]!","You use \the [src]!") + + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(4, 1, A) + s.start() + s = new /datum/effect/effect/system/spark_spread + s.set_up(4, 1, user) + s.start() + + var/turf/FromTurf = mode ? get_turf(user) : get_turf(A) + var/turf/ToTurf = mode ? get_turf(A) : get_turf(user) + + for(var/obj/O in FromTurf) + if(O.anchored) continue + if(prob(5)) + O.forceMove(pick(trange(24,user))) + else + O.forceMove(ToTurf) + + for(var/mob/living/M in FromTurf) + if(prob(5)) + M.forceMove(pick(trange(24,user))) + else + M.forceMove(ToTurf) + +/obj/item/weapon/teleport_cane/attack_self(mob/living/user as mob) + return chande_fire_mode(user) + +/obj/item/weapon/teleport_cane/verb/chande_fire_mode(mob/user as mob) + set name = "Change use mode" + set category = "Object" + set src in oview(1) + if(transforming) return + mode = !mode + transforming = 1 + to_chat(user,"You change \the [src]'s mode to [mode ? "transmiting" : "receiving"].") + update_icon() + +/obj/item/weapon/teleport_cane/update_icon() + if(transforming) + switch(mode) + if(0) + flick("cane", src) + icon_state = "cane" + if(1) + flick("cane",src) + icon_state = "cane" + transforming = 0 \ No newline at end of file diff --git a/code/modules/vore/fluffstuff/guns/nsfw.dm b/code/modules/vore/fluffstuff/guns/nsfw.dm index bc570697d6..e5e511a560 100644 --- a/code/modules/vore/fluffstuff/guns/nsfw.dm +++ b/code/modules/vore/fluffstuff/guns/nsfw.dm @@ -1,12 +1,12 @@ // -------------- NSFW ------------- /obj/item/weapon/gun/projectile/nsfw - name = "KHI-102b \'NSFW\'" + name = "HI-102b \'NSFW\'" desc = "Variety is the spice of life! The 'Nanotech Selectable-Fire Weapon' is an unholy hybrid of an ammo-driven \ energy weapon that allows the user to mix and match their own fire modes. Up to three combinations of \ energy beams can be configured at once. Ammo not included." description_info = "This gun is an energy weapon that uses interchangable microbatteries in a magazine. Each battery is a different beam type, and up to three can be loaded in the magazine. Each battery usually provides four discharges of that beam type, and multiple from the same type may be loaded to increase the number of shots for that type." - description_fluff = "The Kitsuhana 'Nanotech Selectable Fire Weapon' allows one to customize their loadout in the field, or before deploying, to achieve various results in a weapon they are already familiar with wielding." + description_fluff = "The Hesphaistos Industries 'Nanotech Selectable Fire Weapon' allows one to customize their loadout in the field, or before deploying, to achieve various results in a weapon they are already familiar with wielding." description_antag = "" icon = 'icons/vore/custom_guns_vr.dmi' @@ -339,7 +339,7 @@ projectile_type = /obj/item/projectile/beam/growlaser */ /obj/item/weapon/storage/secure/briefcase/nsfw_pack - name = "\improper KHI-102b \'NSFW\' gun kit" + name = "\improper HI-102b \'NSFW\' gun kit" desc = "A storage case for a multi-purpose handgun. Variety hour!" max_w_class = ITEMSIZE_NORMAL @@ -351,7 +351,7 @@ new path(src) /obj/item/weapon/storage/secure/briefcase/nsfw_pack_hos - name = "\improper KHI-102b \'NSFW\' gun kit" + name = "\improper HI-102b \'NSFW\' gun kit" desc = "A storage case for a multi-purpose handgun. Variety hour!" max_w_class = ITEMSIZE_NORMAL diff --git a/code/modules/vore/fluffstuff/guns/protector.dm b/code/modules/vore/fluffstuff/guns/protector.dm index 173c00b637..19444311d6 100644 --- a/code/modules/vore/fluffstuff/guns/protector.dm +++ b/code/modules/vore/fluffstuff/guns/protector.dm @@ -1,11 +1,11 @@ // -------------- Protector ------------- /obj/item/weapon/gun/energy/protector - name = "\improper KHI-98a \'Protector\'" - desc = "The KHI-98a is the first firearm custom-designed for Nanotrasen by KHI. It features a powerful stun mode, and \ + name = "\improper WT-98a \'Protector\'" + desc = "The HI-98a is a firearm custom-designed for Nanotrasen by HI. It features a powerful stun mode, and \ an alert-level-locked lethal mode, only usable on code blue and higher. It also features an integrated flashlight!" description_info = "This gun can only be fired in lethal mode while on higher security alert levels. It is legal for sec to carry for this reason, since it cannot be used for lethal force until SOP allows it, in essence." - description_fluff = "The first 'commission' from a Kitsuhana citizen for NanoTrasen, this gun has a wireless connection to the computer's datacore to ensure it can't be used without authorization from heads of staff who have raised the alert level. Until then, *click*!" + description_fluff = "A for NanoTrasen, this gun has a wireless connection to the computer's datacore to ensure it can't be used without authorization from heads of staff who have raised the alert level. Until then, *click*!" description_antag = "The gun can be emagged to remove the lethal security level restriction, allowing it to be fired on lethal mode at all times." icon = 'icons/vore/custom_guns_vr.dmi' diff --git a/code/modules/vore/persist/persist_vr.dm b/code/modules/vore/persist/persist_vr.dm index 7b9f3d497d..ebf0af6ad3 100644 --- a/code/modules/vore/persist/persist_vr.dm +++ b/code/modules/vore/persist/persist_vr.dm @@ -58,7 +58,7 @@ // For now as a safety measure we will only save if the name matches. if(prefs.real_name != persister.real_name) - log_debug("Persist (P4P): Skipping [persister] becuase ORIG:[persister.real_name] != CURR:[prefs.real_name].") + log_debug("Persist (P4P): Skipping [persister] because ORIG:[persister.real_name] != CURR:[prefs.real_name].") return return prefs diff --git a/code/modules/vore/resizing/sizegun_vr.dm b/code/modules/vore/resizing/sizegun_vr.dm index 12adf709b0..84d8d50a5c 100644 --- a/code/modules/vore/resizing/sizegun_vr.dm +++ b/code/modules/vore/resizing/sizegun_vr.dm @@ -82,3 +82,53 @@ H.updateicon() else return 1 + + + +//CHOMP ADDITIONS.//Anything below here. + +// +//BADvanced size gun +// +/obj/item/weapon/gun/energy/sizegun/not_advanced + name = "Corrupted size gun" + desc = "A highly advanced ray gun with a knob on the side to adjust the size you desire. Or at least that's what it used to be." + projectile_type = /obj/item/projectile/beam/sizelaser/chaos + charge_cost = 60 //1/3 of the base price for a normal one. +// +//CHAOS laser +// +/obj/item/projectile/beam/sizelaser/chaos //The Defintiely not advanced sizeguns laser. + name = "chaos size beam" + light_color = "#FF0000" + light_range = 3 + light_power = 9 //should be plenty visible. + var/list/chaos_colors = list( + "#FF0000", + "#00FF00", + "#0000FF", + "#FFFF00", + "#00FFFF", + "#FF00FF", + "#000000", + "#FFFFFF", + "#F0F0F0", + "#0F0F0F", + ) + + on_hit(var/atom/target) + light_color = pick(chaos_colors) + var/chaos = rand(25,200) + var/mob/living/M = target + if(ishuman(target)) + var/mob/living/carbon/human/H = M + H.resize(chaos/100) + H.show_message(" The beam fires into your body, changing your size!") + H.updateicon() + else if (istype(target, /mob/living/)) + var/mob/living/H = M + H.resize(chaos/100) + H.updateicon() + else + return 1 + diff --git a/code/modules/xenoarcheaology/finds/fossils.dm b/code/modules/xenoarcheaology/finds/fossils.dm index 8df5b92623..4f0d3bc73c 100644 --- a/code/modules/xenoarcheaology/finds/fossils.dm +++ b/code/modules/xenoarcheaology/finds/fossils.dm @@ -94,11 +94,13 @@ icon_state = "shell" desc = "It's a fossilised shell." -/obj/item/weapon/fossil/plant - name = "Fossilised plant" - icon_state = "plant1" - desc = "It's fossilised plant remains." - animal = 0 - /obj/item/weapon/fossil/plant/New() icon_state = "plant[rand(1,4)]" + +/obj/item/weapon/fossil/plant/attackby(var/obj/item/I, var/mob/user) + if(istype(I, /obj/item/weapon/pickaxe/brush)) + new /obj/item/seeds/random(get_turf(user),name) + if(prob(25)) + new /obj/item/seeds/random(get_turf(user),name) + visible_message("\The [src] is brushed away, revealing ancient seeds.") + qdel(src) \ No newline at end of file diff --git a/code/modules/xenoarcheaology/tools/equipment.dm b/code/modules/xenoarcheaology/tools/equipment.dm index 1c2b1f9773..7e85bc8a40 100644 --- a/code/modules/xenoarcheaology/tools/equipment.dm +++ b/code/modules/xenoarcheaology/tools/equipment.dm @@ -17,7 +17,7 @@ desc = "A pressure resistant excavation suit partially capable of insulating against exotic alien energies." icon_state = "cespace_suit" item_state = "cespace_suit" - armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 100) + armor = list(melee = 50, bullet = 5, laser = 20, energy = 5, bomb = 0, bio = 100, rad = 100) allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit) slowdown = 1 @@ -26,4 +26,8 @@ desc = "A pressure resistant excavation hood partially capable of insulating against exotic alien energies." icon_state = "cespace_helmet" item_state = "cespace_helmet" - armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 100) + armor = list(melee = 50, bullet = 5, laser = 20, energy = 5, bomb = 0, bio = 100, rad = 100) + +/obj/item/clothing/suit/space/anomaly/New() + ..() + can_breach = 0 diff --git a/code/unit_tests/map_tests.dm b/code/unit_tests/map_tests.dm index 5950743cf6..5b7abf5aea 100644 --- a/code/unit_tests/map_tests.dm +++ b/code/unit_tests/map_tests.dm @@ -14,7 +14,9 @@ /area/mine, /area/vacant/vacant_shop, /area/turbolift, - /area/submap ) + /area/submap, + /area/hallway/secondary/entry/D2/shuttleDoors + ) var/list/exempt_from_atmos = typesof(/area/maintenance, /area/storage, diff --git a/config/custom_items.txt b/config/custom_items.txt index 0264df9b21..36405fcd1c 100644 --- a/config/custom_items.txt +++ b/config/custom_items.txt @@ -477,6 +477,18 @@ item_path: /obj/item/device/modkit_conversion/fluff/harmonyspace } # ######## K CKEYS +{ +ckey: kazzc +character_name: Kassc Zeravla +item_path: /obj/item/weapon/storage/box/fluff/Kassc +} + +{ +ckey: keithwinters +character_name: Keith Winters +item_path: /obj/item/weapon/storage/box/fluff/Keith_Winters +} + { ckey: ketrai character_name: Ketrai @@ -596,6 +608,12 @@ req_titles: Head of Security # ######## N CKEYS +{ +ckey: nadyr +character_name: Taaa +item_path: /obj/item/weapon/storage/box/fluff/Taaa +} + { ckey: natje character_name: Awen Henry @@ -845,19 +863,20 @@ ckey: tonyvld character_name: Tony Bingham item_path: /obj/item/clothing/head/fluff/runac } -{ -ckey: tomtyph -character_name: Sarika -item_path: /obj/item/weapon/gun/projectile/revolver/mateba/fluff/tasald_corlethian/tomtyph -} -{ -ckey: tomtyph -character_name: Sarika -item_path: /obj/item/clothing/accessory/permit/gun/fluff/tomtyph -item_name: Sarika's Sidearm Permit -item_desc: A card indicating that the owner is allowed to carry a sidearm. It is issued by CentCom, registered to Sarika for a single-action revolver. -} +# { +# ckey: tomtyph +# character_name: Sarika +# item_path: /obj/item/weapon/gun/projectile/revolver/mateba/fluff/tasald_corlethian/tomtyph +# +# } +# { +# ckey: tomtyph +# character_name: Sarika +# item_path: /obj/item/clothing/accessory/permit/gun/fluff/tomtyph +# item_name: Sarika's Sidearm Permit +# item_desc: A card indicating that the owner is allowed to carry a sidearm. It is issued by CentCom, registered to Sarika for a single-action revolver. +# } # Expiry # ######## U CKEYS # ######## V CKEYS diff --git a/config/example/config.txt b/config/example/config.txt index d54e2456a2..f47e4a914a 100644 --- a/config/example/config.txt +++ b/config/example/config.txt @@ -406,6 +406,9 @@ ENGINE_MAP Supermatter Engine,Edison's Bane # Controls if the 'time off' system is used for determining if players can play 'Off-Duty' jobs (requires SQL) # TIME_OFF +# If 'time off' system is on, controls whether or not players can switch on/off duty midround using timeclocks +# PTO_JOB_CHANGE + # Applies a limit to the number of assistants and visitors respectively # LIMIT_INTERNS 6 # LIMIT_VISITORS 6 diff --git a/html/Razgriz1032 - Tactical Jumpsuit Roll.yml b/html/Razgriz1032 - Tactical Jumpsuit Roll.yml new file mode 100644 index 0000000000..976aab9c92 --- /dev/null +++ b/html/Razgriz1032 - Tactical Jumpsuit Roll.yml @@ -0,0 +1,6 @@ +author: Razgriz1032 + +delete-after: True + +changes: + - rscadd: Added ability to roll down tactical jumpsuit, or roll up sleeves. diff --git a/html/changelog.html b/html/changelog.html index 6bbbc501a7..bf983b0205 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -53,9 +53,120 @@ -->
    -

    22 March 2018

    -

    Chaoko99 updated:

    -

    01 April 2018

    +

    04 June 2019

    +

    Darlantanis updated:

    + +

    ExcabyteDiscord updated:

    + +

    Razgriz1032 updated:

    + +

    TheFurryFeline updated:

    + +

    WheatleytheOwl updated:

    + + +

    27 May 2019

    +

    Darlantanis updated:

    + +

    ExabyteDiscord updated:

    + + +

    26 May 2019

    +

    Darlantanis updated:

    + +

    Razgriz1032 updated:

    + +

    TheFurryFeline updated:

    + + +

    25 May 2019

    +

    Darlantanis updated:

    + +

    Kazzc updated:

    + +

    Razgriz1032 updated:

    + +

    TheFurryFeline updated:

    + + +

    18 May 2019

    +

    TheFurryFeline updated:

    + +

    kcin2001 updated:

    + + +

    15 May 2019

    +

    TheFurryFeline updated:

    + +

    24 May 2018

    Anewbe updated: