mirror of
https://github.com/KabKebab/GS13.git
synced 2026-07-12 16:38:18 +01:00
Merge remote-tracking branch 'upstream/master' into Funny-Coder-Bus
This commit is contained in:
@@ -91,6 +91,17 @@ SUBSYSTEM_DEF(mapping)
|
||||
seedRuins(space_ruins, CONFIG_GET(number/space_budget), /area/space, space_ruins_templates)
|
||||
SSmapping.seedStation()
|
||||
loading_ruins = FALSE
|
||||
/*
|
||||
//Hyper change - preload Reebe for midround purposes. I'll change this when I find a decent way to load maps midround.
|
||||
var/list/errorList = list()
|
||||
var/list/reebes = SSmapping.LoadGroup(errorList, "Reebe", "map_files/generic", "City_of_Cogs.dmm", default_traits = ZTRAITS_REEBE, silent = TRUE)
|
||||
if(errorList.len) // reebe failed to load
|
||||
message_admins("Reebe failed to load!")
|
||||
log_game("Reebe failed to load!")
|
||||
return FALSE
|
||||
for(var/datum/parsed_map/PM in reebes)
|
||||
PM.initTemplateBounds()
|
||||
*/
|
||||
#endif
|
||||
repopulate_sorted_areas()
|
||||
// Set up Z-level transitions.
|
||||
|
||||
@@ -252,6 +252,11 @@
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_BULLET_ACT, P, def_zone)
|
||||
. = P.on_hit(src, 0, def_zone)
|
||||
|
||||
//used on altdisarm() for special interactions between the shoved victim (target) and the src, with user being the one shoving the target on it.
|
||||
// IMPORTANT: if you wish to add a new own shove_act() to a certain object, remember to add SHOVABLE_ONTO to its obj_flags bitfied var first.
|
||||
/atom/proc/shove_act(mob/living/target, mob/living/user)
|
||||
return FALSE
|
||||
|
||||
/atom/proc/in_contents_of(container)//can take class or object instance as argument
|
||||
if(ispath(container))
|
||||
if(istype(src.loc, container))
|
||||
|
||||
@@ -150,6 +150,7 @@ Credit where due:
|
||||
var/datum/team/clockcult/main_clockcult
|
||||
|
||||
/datum/game_mode/clockwork_cult/pre_setup()
|
||||
/* //Reebe should be preloaded
|
||||
var/list/errorList = list()
|
||||
var/list/reebes = SSmapping.LoadGroup(errorList, "Reebe", "map_files/generic", "City_of_Cogs.dmm", default_traits = ZTRAITS_REEBE, silent = TRUE)
|
||||
if(errorList.len) // reebe failed to load
|
||||
@@ -158,6 +159,7 @@ Credit where due:
|
||||
return FALSE
|
||||
for(var/datum/parsed_map/PM in reebes)
|
||||
PM.initTemplateBounds()
|
||||
*/
|
||||
if(CONFIG_GET(flag/protect_roles_from_antagonist))
|
||||
restricted_jobs += protected_jobs
|
||||
if(CONFIG_GET(flag/protect_assistant_from_antagonist))
|
||||
|
||||
@@ -17,10 +17,10 @@ GLOBAL_VAR_INIT(dynamic_latejoin_delay_max, (25 MINUTES))
|
||||
GLOBAL_VAR_INIT(dynamic_midround_delay_min, (15 MINUTES))
|
||||
GLOBAL_VAR_INIT(dynamic_midround_delay_max, (35 MINUTES))
|
||||
|
||||
GLOBAL_VAR_INIT(dynamic_event_delay_min, (3 MINUTES))
|
||||
GLOBAL_VAR_INIT(dynamic_event_delay_max, (10 MINUTES))
|
||||
GLOBAL_VAR_INIT(dynamic_event_delay_min, (4 MINUTES))
|
||||
GLOBAL_VAR_INIT(dynamic_event_delay_max, (12 MINUTES))
|
||||
|
||||
GLOBAL_VAR_INIT(dynamic_threat_delay, (5 MINUTES))
|
||||
GLOBAL_VAR_INIT(dynamic_threat_delay, (4 MINUTES))
|
||||
|
||||
// Are HIGHLANDER_RULESETs allowed to stack?
|
||||
GLOBAL_VAR_INIT(dynamic_no_stacking, TRUE)
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
var/list/exclusive_roles = list()
|
||||
/// If set, there needs to be a certain amount of players doing those roles (among the players who won't be drafted) for the rule to be drafted IMPORTANT: DOES NOT WORK ON ROUNDSTART RULESETS.
|
||||
var/list/enemy_roles = list()
|
||||
/// If enemy_roles was set, this is the amount of enemy job workers needed per threat_level range (0-10,10-20,etc) IMPORTANT: DOES NOT WORK ON ROUNDSTART RULESETS.
|
||||
/// If enemy_roles was set, this is the amount of enemy job workers needed per GLOB.dynamic_chaos_level range (0-0.5, 0.5-1.0) IMPORTANT: DOES NOT WORK ON ROUNDSTART RULESETS.
|
||||
var/required_enemies = list(1,1,0,0,0,0,0,0,0,0)
|
||||
/// The rule needs this many candidates (post-trimming) to be executed (example: Cult needs 4 players at round start)
|
||||
var/required_candidates = 0
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
if (M.mind && M.mind.assigned_role && (M.mind.assigned_role in enemy_roles) && (!(M in candidates) || (M.mind.assigned_role in restricted_roles)))
|
||||
job_check++ // Checking for "enemies" (such as sec officers). To be counters, they must either not be candidates to that rule, or have a job that restricts them from it
|
||||
|
||||
var/threat = max(min(round(mode.threat_level/10),9),1) //min() to stop index errors at 100 threat //Max to stop breaking at 0 threat.
|
||||
if (job_check < required_enemies[threat])
|
||||
var/chaos = min(max(round(GLOB.dynamic_chaos_level * 2), 0), 9)
|
||||
if (job_check < required_enemies[chaos])
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
@@ -249,7 +249,7 @@
|
||||
else if(mode.threat_level > 15 && mode.threat > 15 && prob(30))
|
||||
name = "Clogged Vents: Catastrophic"
|
||||
cost = 15
|
||||
required_enemies = list(4,4,4,3,3,3,2,1,1,1)
|
||||
required_enemies = list(4,4,4,3,3,3,2,1,1,0)
|
||||
typepath = /datum/round_event/vent_clog/catastrophic
|
||||
chaos_min = 1.8
|
||||
else
|
||||
@@ -307,14 +307,15 @@
|
||||
/datum/dynamic_ruleset/event/meteor_wave/ready()
|
||||
if(world.time-SSticker.round_start_time > 35 MINUTES && mode.threat_level > 40 && mode.threat >= 25 && prob(30))
|
||||
name = "Meteor Wave: Threatening"
|
||||
cost = 10
|
||||
cost = 5
|
||||
typepath = /datum/round_event/meteor_wave/threatening
|
||||
requirements = list(101,101,30,25,20,20,20,20,20,15)
|
||||
chaos_min = 1.8
|
||||
else if(world.time-SSticker.round_start_time > 45 MINUTES && mode.threat_level > 50 && mode.threat >= 40 && prob(30))
|
||||
name = "Meteor Wave: Catastrophic"
|
||||
cost = 0
|
||||
cost = 10
|
||||
typepath = /datum/round_event/meteor_wave/catastrophic
|
||||
required_enemies = list(3,3,3,3,3,3,3,3,3,3)
|
||||
required_enemies = list(3,3,3,3,3,2,2,1,1,0)
|
||||
requirements = list(101,101,40,30,30,30,30,30,30,30)
|
||||
chaos_min = 2.0
|
||||
else
|
||||
@@ -336,11 +337,11 @@
|
||||
//config_tag = "anomaly_bluespace"
|
||||
typepath = /datum/round_event/anomaly/anomaly_bluespace
|
||||
enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain")
|
||||
required_enemies = list(1,1,1,0,0,0,0,0,0,0)
|
||||
required_enemies = list(2,2,2,1,1,1,1,1,1,0)
|
||||
weight = 3
|
||||
earliest_start = 20 MINUTES
|
||||
repeatable_weight_decrease = 2
|
||||
cost = 3
|
||||
cost = 0
|
||||
requirements = list(101,101,5,5,5,5,5,5,5,5)
|
||||
high_population_requirement = 5
|
||||
repeatable = TRUE
|
||||
@@ -353,7 +354,7 @@
|
||||
//config_tag = "anomaly_flux"
|
||||
typepath = /datum/round_event/anomaly/anomaly_flux
|
||||
enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain")
|
||||
required_enemies = list(1,1,1,0,0,0,0,0,0,0)
|
||||
required_enemies = list(2,2,2,2,2,2,2,2,2,0)
|
||||
weight = 3
|
||||
earliest_start = 20 MINUTES
|
||||
repeatable_weight_decrease = 2
|
||||
@@ -388,7 +389,7 @@
|
||||
repeatable_weight_decrease = 1
|
||||
cost = 0
|
||||
enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain","Cyborg")
|
||||
required_enemies = list(2,2,2,2,2,1,1,1,1,1)
|
||||
required_enemies = list(2,2,2,2,2,1,1,1,1,0)
|
||||
requirements = list(101,101,10,10,10,10,10,10,10,10)
|
||||
high_population_requirement = 10
|
||||
repeatable = TRUE
|
||||
@@ -405,7 +406,7 @@
|
||||
repeatable_weight_decrease = 1
|
||||
cost = 0
|
||||
enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain","Cyborg")
|
||||
required_enemies = list(3,3,3,2,2,2,2,2,2,2)
|
||||
required_enemies = list(3,3,3,2,2,2,2,2,2,0)
|
||||
requirements = list(101,101,10,10,10,10,10,10,10,10)
|
||||
high_population_requirement = 10
|
||||
repeatable = TRUE
|
||||
@@ -428,6 +429,7 @@
|
||||
occurances_max = 1
|
||||
requirements = list(10,5,0,0,0,0,0,0,0,0) //SECURE THAT DISK
|
||||
cost = 50
|
||||
chaos_min = 0.5
|
||||
|
||||
/datum/dynamic_ruleset/event/operative/get_weight()
|
||||
var/datum/round_event_control/operative/loneop = locate(/datum/round_event_control/operative) in SSevents.control
|
||||
@@ -453,7 +455,7 @@
|
||||
weight = 1
|
||||
earliest_start = 30 MINUTES
|
||||
repeatable_weight_decrease = 1
|
||||
cost = -10
|
||||
cost = 0
|
||||
enemy_roles = list("Chief Engineer","Station Engineer","Atmospheric Technician","Research Director","Scientist","Captain","Cyborg")
|
||||
required_enemies = list(2,1,1,1,1,1,0,0,0,0)
|
||||
requirements = list(101,25,20,15,15,15,10,10,10,10)
|
||||
@@ -472,7 +474,7 @@
|
||||
cost = 4
|
||||
requirements = list(101,5,5,1,1,1,1,1,1,1)
|
||||
high_population_requirement = 10
|
||||
earliest_start = 0 MINUTES
|
||||
earliest_start = 10 MINUTES
|
||||
repeatable = TRUE
|
||||
//property_weights = list("extended" = 1)
|
||||
occurances_max = 3
|
||||
@@ -482,7 +484,7 @@
|
||||
name = "Communications Blackout"
|
||||
//config_tag = "communications_blackout"
|
||||
typepath = /datum/round_event/communications_blackout
|
||||
cost = 4
|
||||
cost = 2
|
||||
weight = 10
|
||||
repeatable_weight_decrease = 2
|
||||
enemy_roles = list("Chief Engineer","Station Engineer")
|
||||
@@ -549,7 +551,7 @@
|
||||
repeatable_weight_decrease = 2
|
||||
enemy_roles = list("Chief Engineer","Station Engineer")
|
||||
required_enemies = list(1,1,1,0,0,0,0,0,0,0)
|
||||
requirements = list(5,5,4,3,2,1,1,0,0,0)
|
||||
requirements = list(3,3,2,2,1,1,0,0,0,0)
|
||||
high_population_requirement = 5
|
||||
repeatable = TRUE
|
||||
occurances_max = 10
|
||||
@@ -557,12 +559,12 @@
|
||||
/datum/dynamic_ruleset/event/heart_attack
|
||||
name = "Random Heart Attack"
|
||||
typepath = /datum/round_event/heart_attack
|
||||
cost = 15
|
||||
cost = 0
|
||||
weight = 2
|
||||
earliest_start = 30 MINUTES
|
||||
repeatable_weight_decrease = 1
|
||||
enemy_roles = list("Medical Doctor","Chief Medical Officer")
|
||||
required_enemies = list(2,2,2,2,2,2,2,2,2,2)
|
||||
required_enemies = list(2,2,2,2,2,2,2,2,2,0)
|
||||
requirements = list(101,101,101,10,5,5,5,5,5,5)
|
||||
high_population_requirement = 5
|
||||
repeatable = TRUE
|
||||
@@ -577,7 +579,7 @@
|
||||
weight = 2
|
||||
repeatable_weight_decrease = 2
|
||||
enemy_roles = list("Chemist","Chief Medical Officer","Geneticist","Medical Doctor","AI","Captain")
|
||||
required_enemies = list(1,1,1,1,1,1,1,1,1,1)
|
||||
required_enemies = list(1,1,1,1,1,1,1,1,1,0)
|
||||
requirements = list(5,5,5,5,5,5,5,5,5,5)
|
||||
high_population_requirement = 5
|
||||
//property_weights = list("extended" = 1,"chaos" = 1)
|
||||
@@ -590,7 +592,7 @@
|
||||
cost = 0
|
||||
weight = 1
|
||||
enemy_roles = list("Head of Security","Security Officer","AI","Captain","Shaft Miner")
|
||||
required_enemies = list(2,2,2,2,2,2,2,2,2,2)
|
||||
required_enemies = list(2,2,2,2,2,2,2,2,2,0)
|
||||
requirements = list(101,101,40,35,30,30,30,30,25,20)
|
||||
high_population_requirement = 30
|
||||
earliest_start = 40 MINUTES
|
||||
@@ -607,7 +609,7 @@
|
||||
weight = 2
|
||||
repeatable_weight_decrease = 1
|
||||
enemy_roles = list("AI","Medical Doctor","Station Engineer","Head of Personnel","Captain")
|
||||
required_enemies = list(2,2,2,2,2,2,2,2,2,2)
|
||||
required_enemies = list(2,2,2,2,2,2,2,2,2,0)
|
||||
requirements = list(5,5,5,5,5,5,5,5,5,5)
|
||||
high_population_requirement = 5
|
||||
//property_weights = list("extended" = 1)
|
||||
@@ -622,7 +624,7 @@
|
||||
weight = 1
|
||||
earliest_start = 40 MINUTES
|
||||
enemy_roles = list("AI","Security Officer","Head of Security","Captain","Station Engineer","Atmos Technician","Chief Engineer")
|
||||
required_enemies = list(4,4,4,4,3,3,3,3,3,2)
|
||||
required_enemies = list(4,4,4,4,3,3,3,3,2,0)
|
||||
requirements = list(101,101,50,40,40,40,40,35,30,30)
|
||||
high_population_requirement = 5
|
||||
//property_weights = list("extended" = -2)
|
||||
@@ -638,7 +640,7 @@
|
||||
required_candidates = 1
|
||||
weight = 4
|
||||
cost = -5
|
||||
requirements = list(30,30,20,20,15,10,10,10,10,5) // yes, it can even happen in "extended"!
|
||||
requirements = list(101,30,20,20,15,10,10,10,10,5) // yes, it can even happen in "extended"!
|
||||
//property_weights = list("story_potential" = 1, "extended" = 1, "valid" = -2)
|
||||
high_population_requirement = 5
|
||||
occurances_max = 1
|
||||
@@ -664,7 +666,7 @@
|
||||
controller = /datum/round_event_control/immovable_rod
|
||||
typepath = /datum/round_event/immovable_rod
|
||||
enemy_roles = list("Research Director","Chief Engineer","Station Engineer","Captain","Chaplain","AI")
|
||||
required_enemies = list(2,2,2,2,2,2,1,1,1,1)
|
||||
required_enemies = list(2,2,2,2,2,2,1,1,1,0)
|
||||
requirements = list(101,101,18,16,14,12,10,8,6,6)
|
||||
high_population_requirement = 15
|
||||
cost = 0
|
||||
@@ -798,7 +800,7 @@
|
||||
name = "Grey Tide"
|
||||
typepath = /datum/round_event/grey_tide
|
||||
enemy_roles = list("Chief Engineer","Station Engineer","Captain","Atmospheric Technician","AI","Cyborg")
|
||||
required_enemies = list(3,2,2,2,2,2,1,1,1,1)
|
||||
required_enemies = list(3,2,2,2,2,2,1,1,1,0)
|
||||
requirements = list(101,101,5,5,5,5,5,5,5,5)
|
||||
high_population_requirement = 0
|
||||
repeatable = TRUE
|
||||
@@ -809,9 +811,9 @@
|
||||
/datum/dynamic_ruleset/event/sentience
|
||||
name = "Random Human-level Intelligence"
|
||||
typepath = /datum/round_event/ghost_role/sentience
|
||||
requirements = list(0,0,0,0,0,0,0,0,0,0)
|
||||
requirements = list(101,101,0,0,0,0,0,0,0,0)
|
||||
high_population_requirement = 0
|
||||
weight = 5
|
||||
weight = 1
|
||||
|
||||
/datum/dynamic_ruleset/event/shuttle_loan
|
||||
name = "Shuttle Loan"
|
||||
@@ -829,7 +831,7 @@
|
||||
name = "Spacevine"
|
||||
typepath = /datum/round_event/spacevine
|
||||
enemy_roles = list("Cook","Botanist","Security Officer","Captain","Station Engineer")
|
||||
required_enemies = list(2,2,2,1,1,1,1,1,1,1)
|
||||
required_enemies = list(2,2,2,1,1,1,1,1,1,0)
|
||||
requirements = list(101,101,10,9,8,7,5,5,5,0)
|
||||
cost = 2
|
||||
high_population_requirement = 0
|
||||
@@ -843,10 +845,10 @@
|
||||
name = "Spontaneous Appendicitis"
|
||||
typepath = /datum/round_event/spontaneous_appendicitis
|
||||
enemy_roles = list("Medical Doctor","Chief Medical Officer")
|
||||
required_enemies = list(2,2,1,1,1,1,1,1,1,1)
|
||||
required_enemies = list(2,2,1,1,1,1,1,1,1,0)
|
||||
requirements = list(5,5,5,5,5,5,5,5,0,0)
|
||||
high_population_requirement = 5
|
||||
weight = 8
|
||||
weight = 5
|
||||
repeatable = TRUE
|
||||
repeatable_weight_decrease = 5
|
||||
repeatable_weight_decrease = 3
|
||||
occurances_max = 3
|
||||
@@ -18,6 +18,7 @@
|
||||
var/list/dead_players = list()
|
||||
var/list/list_observers = list()
|
||||
var/list/ghost_eligible = list()
|
||||
var/controller //round event controller for the event - Required for certain events dependendant on variables within their controllers
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts
|
||||
weight = 0
|
||||
@@ -99,9 +100,8 @@
|
||||
continue // Dead players cannot count as opponents
|
||||
if (M.mind && M.mind.assigned_role && (M.mind.assigned_role in enemy_roles) && (!(M in candidates) || (M.mind.assigned_role in restricted_roles)))
|
||||
job_check++ // Checking for "enemies" (such as sec officers). To be counters, they must either not be candidates to that rule, or have a job that restricts them from it
|
||||
|
||||
var/threat = min(round(mode.threat_level/10),9)
|
||||
if (job_check < required_enemies[threat])
|
||||
var/chaos = min(max(round(GLOB.dynamic_chaos_level * 2), 0), 9)
|
||||
if (job_check < required_enemies[chaos])
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -113,8 +113,20 @@
|
||||
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/execute()
|
||||
var/application_successful = send_applications(ghost_eligible)
|
||||
return assigned.len > 0 && application_successful
|
||||
message_admins("<span class='deadsay'><b>[name]</b> has just been randomly triggered!</span>") //STOP ASSUMING IT'S BADMINS!
|
||||
log_game("Midround triggering: [name]")
|
||||
var/datum/round_event/E
|
||||
//occurances_current++
|
||||
if(controller)
|
||||
var/datum/round_event_control/C = locate(controller) in SSevents.control
|
||||
E = C.runEvent()
|
||||
else
|
||||
var/application_successful = send_applications(ghost_eligible)
|
||||
return assigned.len > 0 && application_successful
|
||||
|
||||
testing("[time2text(world.time, "hh:mm:ss")] [E.type]")
|
||||
|
||||
return E
|
||||
|
||||
/// This sends a poll to ghosts if they want to be a ghost spawn from a ruleset.
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/proc/send_applications(list/possible_volunteers = list())
|
||||
@@ -221,7 +233,7 @@
|
||||
high_population_requirement = 10
|
||||
flags = TRAITOR_RULESET
|
||||
chaos_min = 2.0
|
||||
chaos_max = 4.0
|
||||
chaos_max = 3.5
|
||||
|
||||
/datum/dynamic_ruleset/midround/autotraitor/acceptable(population = 0, threat = 0)
|
||||
var/player_count = mode.current_players[CURRENT_LIVING_PLAYERS].len
|
||||
@@ -380,7 +392,7 @@
|
||||
required_candidates = 1
|
||||
weight = 3
|
||||
cost = 20
|
||||
requirements = list(101,101,55,50,45,40,35,30,25,20)
|
||||
requirements = list(101,101,101,45,40,35,30,25,20,15)
|
||||
high_population_requirement = 35
|
||||
required_type = /mob/living/silicon/ai
|
||||
var/ion_announce = 33
|
||||
@@ -428,7 +440,7 @@
|
||||
antag_datum = /datum/antagonist/wizard
|
||||
antag_flag = ROLE_WIZARD
|
||||
enemy_roles = list("Security Officer","Detective","Head of Security", "Captain")
|
||||
required_enemies = list(2,2,1,1,1,1,1,1,0,0)
|
||||
required_enemies = list(2,2,1,1,1,1,1,1,1,0)
|
||||
required_candidates = 1
|
||||
weight = 1
|
||||
cost = 20
|
||||
@@ -462,13 +474,13 @@
|
||||
antag_flag = ROLE_OPERATIVE
|
||||
antag_datum = /datum/antagonist/nukeop
|
||||
enemy_roles = list("AI", "Cyborg", "Security Officer", "Warden","Detective","Head of Security", "Captain")
|
||||
required_enemies = list(3,3,3,3,3,2,2,1,1,0)
|
||||
required_enemies = list(3,3,3,3,3,2,2,2,2,1)
|
||||
required_candidates = 5
|
||||
weight = 5
|
||||
cost = 35
|
||||
requirements = list(101,101,100,70,60,50,40,40,40,40)
|
||||
cost = 20
|
||||
requirements = list(101,100,95,85,70,60,50,40,30,20)
|
||||
high_population_requirement = 10
|
||||
var/operative_cap = list(2,2,2,2,3,3,4,4,5,5)
|
||||
var/operative_cap = list(1,1,1,2,2,3,3,4,4,5)
|
||||
var/datum/team/nuclear/nuke_team
|
||||
flags = HIGHLANDER_RULESET
|
||||
chaos_min = 4.0
|
||||
@@ -505,15 +517,17 @@
|
||||
name = "Blob"
|
||||
antag_datum = /datum/antagonist/blob
|
||||
antag_flag = ROLE_BLOB
|
||||
enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain")
|
||||
enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain", "Station Engineer")
|
||||
required_enemies = list(2,2,1,1,1,1,1,0,0,0)
|
||||
required_candidates = 1
|
||||
weight = 4
|
||||
weight = 3
|
||||
cost = 20
|
||||
requirements = list(101,101,60,50,45,40,40,40,30,20)
|
||||
requirements = list(101,101,101,60,50,40,40,40,30,20)
|
||||
//requirements = list(0,0,0,0,0,0,0,0,0,0)
|
||||
high_population_requirement = 50
|
||||
repeatable = TRUE
|
||||
chaos_min = 3.5
|
||||
chaos_min = 4.0
|
||||
controller = /datum/round_event_control/blob
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/blob/generate_ruleset_body(mob/applicant)
|
||||
var/body = applicant.become_overmind()
|
||||
@@ -534,11 +548,13 @@
|
||||
required_candidates = 1
|
||||
weight = 3
|
||||
cost = 15
|
||||
requirements = list(101,101,100,70,60,50,40,40,30,20)
|
||||
requirements = list(101,101,101,50,40,35,30,30,30,20)
|
||||
//requirements = list(0,0,0,0,0,0,0,0,0,0)
|
||||
high_population_requirement = 50
|
||||
repeatable = TRUE
|
||||
var/list/vents = list()
|
||||
chaos_min = 3.5
|
||||
controller = /datum/round_event_control/alien_infestation
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/xenomorph/execute()
|
||||
// 50% chance of being incremented by one
|
||||
@@ -580,7 +596,7 @@
|
||||
enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain")
|
||||
required_enemies = list(2,2,1,1,1,1,1,0,0,0)
|
||||
required_candidates = 1
|
||||
weight = 3
|
||||
weight = 4
|
||||
cost = 10
|
||||
requirements = list(101,50,40,30,20,20,20,20,15,10)
|
||||
high_population_requirement = 50
|
||||
@@ -626,18 +642,18 @@
|
||||
antag_flag = ROLE_ABDUCTOR
|
||||
// Has two antagonist flags, in fact
|
||||
enemy_roles = list("AI", "Cyborg", "Security Officer", "Warden","Detective","Head of Security", "Captain")
|
||||
required_enemies = list(3,3,2,2,1,1,0,0,0,0)
|
||||
required_enemies = list(3,3,2,2,2,2,2,2,2,0)
|
||||
required_candidates = 2
|
||||
weight = 4
|
||||
weight = 3
|
||||
cost = 10
|
||||
requirements = list(101,101,50,45,40,30,20,20,10,10)
|
||||
requirements = list(101,101,101,101,40,30,30,30,30,30)
|
||||
blocking_rules = list(/datum/dynamic_ruleset/roundstart/nuclear,/datum/dynamic_ruleset/midround/from_ghosts/nuclear)
|
||||
high_population_requirement = 15
|
||||
var/datum/team/abductor_team/team
|
||||
//property_weights = list("extended" = -2, "valid" = 1, "trust" = -1, "chaos" = 2)
|
||||
repeatable_weight_decrease = 4
|
||||
repeatable = TRUE
|
||||
chaos_min = 2.0
|
||||
chaos_min = 4.0
|
||||
|
||||
/datum/dynamic_ruleset/midround/from_ghosts/abductors/ready(forced = FALSE)
|
||||
team = new /datum/team/abductor_team
|
||||
@@ -671,7 +687,7 @@
|
||||
required_enemies = list(3,2,2,2,2,1,1,1,1,0)
|
||||
required_candidates = 1
|
||||
weight = 4
|
||||
cost = 15
|
||||
cost = 10
|
||||
requirements = list(101,101,101,40,35,30,25,20,20,20)
|
||||
high_population_requirement = 30
|
||||
//property_weights = list("story_potential" = 1, "extended" = -2, "valid" = 2)
|
||||
|
||||
@@ -300,7 +300,7 @@
|
||||
flags = HIGHLANDER_RULESET
|
||||
var/cultist_cap = list(2,2,2,3,3,4,4,4,4,4)
|
||||
var/datum/team/cult/main_cult
|
||||
chaos_min = 4.9
|
||||
chaos_min = 4.5
|
||||
admin_required = TRUE
|
||||
|
||||
/datum/dynamic_ruleset/roundstart/bloodcult/ready(forced = FALSE)
|
||||
@@ -356,7 +356,7 @@
|
||||
required_candidates = 5
|
||||
weight = 3
|
||||
cost = 20
|
||||
requirements = list(101,100,90,80,70,60,50,40,30,20)
|
||||
requirements = list(101,100,95,85,70,60,50,40,30,20)
|
||||
high_population_requirement = 10
|
||||
pop_per_requirement = 5
|
||||
flags = HIGHLANDER_RULESET
|
||||
@@ -559,11 +559,13 @@
|
||||
required_candidates = 4
|
||||
weight = 4
|
||||
cost = 0
|
||||
requirements = list(101,101,100,90,80,70,60,50,40,30)
|
||||
requirements = list(101,101,100,95,85,70,60,50,40,30)
|
||||
//requirements = list(0,0,0,0,0,0,0,0,0,0)
|
||||
high_population_requirement = 101
|
||||
flags = HIGHLANDER_RULESET
|
||||
var/ark_time
|
||||
chaos_min = 4.9
|
||||
var/servants = list(1,1,1,1,2,2,3,3,4,4)
|
||||
chaos_min = 4.5
|
||||
admin_required = TRUE
|
||||
|
||||
/datum/dynamic_ruleset/roundstart/clockcult/pre_execute()
|
||||
@@ -575,20 +577,23 @@
|
||||
return FALSE
|
||||
for(var/datum/parsed_map/PM in reebes)
|
||||
PM.initTemplateBounds()
|
||||
|
||||
/*
|
||||
var/starter_servants = 4
|
||||
var/number_players = num_players()
|
||||
if(number_players > 30)
|
||||
number_players -= 30
|
||||
starter_servants += round(number_players / 10)
|
||||
starter_servants = min(starter_servants, 8)
|
||||
*/
|
||||
var/indice_pop = min(10,round(mode.roundstart_pop_ready/5)+1)
|
||||
var/starter_servants = servants[indice_pop]
|
||||
for (var/i in 1 to starter_servants)
|
||||
var/mob/servant = pick(candidates)
|
||||
candidates -= servant
|
||||
assigned += servant.mind
|
||||
servant.mind.assigned_role = ROLE_SERVANT_OF_RATVAR
|
||||
servant.mind.special_role = ROLE_SERVANT_OF_RATVAR
|
||||
ark_time = 30 + round((number_players / 5))
|
||||
ark_time = 30 + round((mode.roundstart_pop_ready / 5))
|
||||
ark_time = min(ark_time, 35)
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -668,7 +668,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
name = "bdsm whip"
|
||||
desc = "A less lethal version of the whip the librarian has. Still hurts, but just the way you like it."
|
||||
icon_state = "whip"
|
||||
item_state = "chain"
|
||||
item_state = "crop"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi'
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
|
||||
@@ -27,6 +27,8 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an
|
||||
dir = SOUTH
|
||||
var/message_cooldown
|
||||
var/breakout_time = 600
|
||||
var/obj/item/radio/radio = null
|
||||
var/hasradio = FALSE
|
||||
|
||||
/obj/structure/bodycontainer/Initialize()
|
||||
. = ..()
|
||||
@@ -128,7 +130,8 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an
|
||||
var/turf/T = get_step(src, dir)
|
||||
connected.setDir(dir)
|
||||
for(var/atom/movable/AM in src)
|
||||
AM.forceMove(T)
|
||||
if(AM != radio)
|
||||
AM.forceMove(T)
|
||||
update_icon()
|
||||
|
||||
/obj/structure/bodycontainer/proc/close()
|
||||
@@ -154,7 +157,41 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an
|
||||
var/beeper = TRUE
|
||||
var/beep_cooldown = 50
|
||||
var/next_beep = 0
|
||||
//Hyperstation edit
|
||||
var/radio_key = /obj/item/encryptionkey/headset_med
|
||||
var/medical_channel = "Medical"
|
||||
var/inuse = FALSE
|
||||
hasradio = TRUE
|
||||
|
||||
/obj/structure/bodycontainer/morgue/Initialize()
|
||||
. = ..()
|
||||
radio = new(src)
|
||||
radio.anchored = TRUE
|
||||
radio.keyslot = new radio_key
|
||||
radio.listening = 0
|
||||
radio.recalculateChannels()
|
||||
|
||||
/obj/structure/bodycontainer/morgue/Destroy()
|
||||
QDEL_NULL(radio)
|
||||
GLOB.bodycontainers -= src
|
||||
open()
|
||||
if(connected)
|
||||
qdel(connected)
|
||||
connected = null
|
||||
return ..()
|
||||
/*
|
||||
/obj/structure/bodycontainer/morgue/proc/open2()
|
||||
recursive_organ_check(src)
|
||||
playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
|
||||
playsound(src, 'sound/effects/roll.ogg', 5, 1)
|
||||
var/turf/T = get_step(src, dir)
|
||||
connected.setDir(dir)
|
||||
for(var/atom/movable/AM in src)
|
||||
if(AM != radio)
|
||||
AM.forceMove(T)
|
||||
update_icon()
|
||||
*/
|
||||
//end of edit
|
||||
/obj/structure/bodycontainer/morgue/New()
|
||||
connected = new/obj/structure/tray/m_tray(src)
|
||||
connected.connected = src
|
||||
@@ -175,7 +212,7 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an
|
||||
if (!connected || connected.loc != src) // Open or tray is gone.
|
||||
icon_state = "morgue0"
|
||||
else
|
||||
if(contents.len == 1) // Empty
|
||||
if(contents.len == 2) // Empty. Was length 1 because of the tray, is now length 2 because it includes a radio.
|
||||
icon_state = "morgue1"
|
||||
else
|
||||
icon_state = "morgue2" // Dead, brainded mob.
|
||||
@@ -381,3 +418,27 @@ GLOBAL_LIST_EMPTY(crematoriums)
|
||||
if(ismovableatom(caller))
|
||||
var/atom/movable/mover = caller
|
||||
. = . || (mover.pass_flags & PASSTABLE)
|
||||
|
||||
//Hyperstation edit starts here
|
||||
/obj/structure/bodycontainer/morgue/attack_ghost(mob/user)
|
||||
. = ..()
|
||||
if(!beeper || inuse)
|
||||
return
|
||||
|
||||
var/list/compiled = recursive_mob_check(src, 0, 0) // Search for mobs in all contents.
|
||||
if(!length(compiled)) // No mobs?
|
||||
return
|
||||
|
||||
for(var/mob/living/M in compiled)
|
||||
var/mob/living/mob_occupant = get_mob_or_brainmob(M)
|
||||
if(!mob_occupant.suiciding && !mob_occupant.hellbound)
|
||||
if(mob_occupant.stat == DEAD && mob_occupant.mind.key == user.client.key)
|
||||
inuse = TRUE
|
||||
visible_message("One of the morgue coffins currently holds a soul that is eager to have its body revived.")
|
||||
radio.talk_into(src, "One of the morgue coffins currently holds a soul that is eager to have its body revived.", medical_channel)
|
||||
playsound(loc, 'sound/machines/ping.ogg', 50)
|
||||
addtimer(CALLBACK(src, .proc/liftcooldown), 500)
|
||||
|
||||
/obj/structure/bodycontainer/morgue/proc/liftcooldown()
|
||||
inuse = FALSE
|
||||
//Hyperstation edit ends here
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
anchored = TRUE
|
||||
layer = TABLE_LAYER
|
||||
climbable = TRUE
|
||||
obj_flags = CAN_BE_HIT|SHOVABLE_ONTO
|
||||
pass_flags = LETPASSTHROW //You can throw objects over this, despite it's density.")
|
||||
var/frame = /obj/structure/table_frame
|
||||
var/framestack = /obj/item/stack/rods
|
||||
@@ -136,6 +137,15 @@
|
||||
var/mob/living/carbon/human/H = pushed_mob
|
||||
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "table", /datum/mood_event/table)
|
||||
|
||||
/obj/structure/table/shove_act(mob/living/target, mob/living/user)
|
||||
if(!target.resting)
|
||||
target.Knockdown(SHOVE_KNOCKDOWN_TABLE)
|
||||
user.visible_message("<span class='danger'>[user.name] shoves [target.name] onto \the [src]!</span>",
|
||||
"<span class='danger'>You shove [target.name] onto \the [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
target.forceMove(src.loc)
|
||||
log_combat(user, target, "shoved", "onto [src] (table)")
|
||||
return TRUE
|
||||
|
||||
/obj/structure/table/attackby(obj/item/I, mob/user, params)
|
||||
if(!(flags_1 & NODECONSTRUCT_1))
|
||||
if(istype(I, /obj/item/screwdriver) && deconstruction_ready)
|
||||
|
||||
@@ -457,6 +457,19 @@
|
||||
if(ismob(A) || .)
|
||||
A.ratvar_act()
|
||||
|
||||
//called on /datum/species/proc/altdisarm()
|
||||
/turf/shove_act(mob/living/target, mob/living/user, pre_act = FALSE)
|
||||
var/list/possibilities
|
||||
for(var/obj/O in contents)
|
||||
if(CHECK_BITFIELD(O.obj_flags, SHOVABLE_ONTO))
|
||||
LAZYADD(possibilities, O)
|
||||
else if(!O.CanPass(target, src))
|
||||
return FALSE
|
||||
if(possibilities)
|
||||
var/obj/O = pick(possibilities)
|
||||
return O.shove_act(target, user)
|
||||
return FALSE
|
||||
|
||||
/turf/proc/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
|
||||
underlay_appearance.icon = icon
|
||||
underlay_appearance.icon_state = icon_state
|
||||
|
||||
@@ -23,7 +23,13 @@
|
||||
name = "Full Tank of Tritium"
|
||||
description = "Station 42 is looking to kickstart their research program. Ship them a tank full of Tritium."
|
||||
gas_type = /datum/gas/tritium
|
||||
|
||||
//Hyperstation edit
|
||||
/datum/bounty/item/engineering/gas/hypernoblium_tank
|
||||
name = "Full Tank of Hyper-Noblium"
|
||||
description = "The 7th Echelon is looking to research the effects of this rare gas in organics. They ask for a full tank of it. Are you up to the task?"
|
||||
gas_type = /datum/gas/hypernoblium
|
||||
reward = 75000 //Very, very difficult to make, requires a fuckton of structural re-design around engineering and can actually royally fuck up the entirety of the station if not done correctly.
|
||||
//Hypersation edit end
|
||||
/datum/bounty/item/engineering/pacman
|
||||
name = "P.A.C.M.A.N.-type portable generator"
|
||||
description = "A neighboring station had a problem with their SMES, and now need something to power their communications console. Can you send them a P.AC.M.A.N.?"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
name = "Trash Bag of Holding"
|
||||
description = "Centcom would make good use of high-capacity trash bags. If you have any, please ship them."
|
||||
reward = 3000
|
||||
wanted_types = list(/obj/item/storage/backpack/holding)
|
||||
wanted_types = list(/obj/item/storage/bag/trash/bluespace)
|
||||
|
||||
/datum/bounty/item/science/bluespace_syringe
|
||||
name = "Bluespace Syringe"
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
/var/list/blacklisted_sentient_animals = typecacheof(list(
|
||||
/mob/living/simple_animal/slime,
|
||||
/mob/living/simple_animal/hostile/megafauna,
|
||||
/mob/living/simple_animal/hostile/blob,
|
||||
/mob/living/simple_animal/jacq,
|
||||
/mob/living/simple_animal/holodeck_monkey,
|
||||
/mob/living/simple_animal/astral))
|
||||
|
||||
/datum/round_event_control/sentience
|
||||
name = "Random Human-level Intelligence"
|
||||
typepath = /datum/round_event/ghost_role/sentience
|
||||
@@ -33,6 +41,8 @@
|
||||
var/turf/T = get_turf(L)
|
||||
if(!T || !is_station_level(T.z))
|
||||
continue
|
||||
if(is_type_in_typecache(L, blacklisted_sentient_animals))
|
||||
continue
|
||||
if(!(L in GLOB.player_list) && !L.mind)
|
||||
potential += L
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
desc = "A plant sculped by extensive genetic engineering. The spaceman's trumpet is said to bear no resemblance to its wild ancestors. Inside NT AgriSci circles it is better known as NTPW-0372."
|
||||
icon_state = "seed-trumpet"
|
||||
species = "spacemanstrumpet"
|
||||
plantname = "Spaceman's Trumpet Plant"
|
||||
plantname = "Spaceman Trumpet"
|
||||
product = /obj/item/reagent_containers/food/snacks/grown/trumpet
|
||||
lifespan = 80
|
||||
production = 5
|
||||
@@ -68,13 +68,14 @@
|
||||
icon_grow = "spacemanstrumpet-grow"
|
||||
icon_dead = "spacemanstrumpet-dead"
|
||||
mutatelist = list()
|
||||
genes = list( "Polypyrylium Oligomers")
|
||||
genes = list(/datum/plant_gene/reagent/polypyr)
|
||||
reagents_add = list("nutriment" = 0.05)
|
||||
rarity = 30
|
||||
|
||||
/obj/item/seeds/poppy/lily/trumpet/Initialize()
|
||||
..()
|
||||
unset_mutability(/datum/plant_gene/reagent/polypyr, PLANT_GENE_EXTRACTABLE)
|
||||
/obj/item/seeds/poppy/lily/trumpet/Initialize(mapload, nogenes = FALSE)
|
||||
. = ..()
|
||||
if(!nogenes)
|
||||
unset_mutability(/datum/plant_gene/reagent/polypyr, PLANT_GENE_EXTRACTABLE)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/trumpet
|
||||
seed = /obj/item/seeds/poppy/lily/trumpet
|
||||
@@ -317,4 +318,4 @@
|
||||
filling_color = "#FF6347"
|
||||
bitesize_mod = 8
|
||||
tastes = list("wax" = 1)
|
||||
foodtype = SUGAR
|
||||
foodtype = SUGAR
|
||||
|
||||
@@ -83,9 +83,10 @@
|
||||
mutatelist = list()
|
||||
reagents_add = list("nutriment" = 0.05, "silibinin" = 0.1)
|
||||
|
||||
/obj/item/seeds/galaxythistle/Initialize()
|
||||
..()
|
||||
unset_mutability(/datum/plant_gene/trait/invasive, PLANT_GENE_REMOVABLE)
|
||||
/obj/item/seeds/galaxythistle/Initialize(mapload, nogenes = FALSE)
|
||||
. = ..()
|
||||
if(!nogenes)
|
||||
unset_mutability(/datum/plant_gene/trait/invasive, PLANT_GENE_REMOVABLE)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/galaxythistle
|
||||
seed = /obj/item/seeds/galaxythistle
|
||||
|
||||
@@ -216,10 +216,11 @@
|
||||
growing_icon = 'icons/obj/hydroponics/growing_mushrooms.dmi'
|
||||
reagents_add = list("nutriment" = 0.1)
|
||||
|
||||
/obj/item/seeds/chanterelle/jupitercup/Initialize()
|
||||
..()
|
||||
unset_mutability(/datum/plant_gene/reagent/teslium, PLANT_GENE_EXTRACTABLE)
|
||||
unset_mutability(/datum/plant_gene/trait/plant_type/carnivory, PLANT_GENE_REMOVABLE)
|
||||
/obj/item/seeds/chanterelle/jupitercup/Initialize(mapload, nogenes = FALSE)
|
||||
. = ..()
|
||||
if(!nogenes)
|
||||
unset_mutability(/datum/plant_gene/reagent/teslium, PLANT_GENE_EXTRACTABLE)
|
||||
unset_mutability(/datum/plant_gene/trait/plant_type/carnivory, PLANT_GENE_REMOVABLE)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/mushroom/jupitercup
|
||||
seed = /obj/item/seeds/chanterelle/jupitercup
|
||||
|
||||
@@ -18,7 +18,9 @@
|
||||
return !istype(S, /obj/item/seeds/sample) // Samples can't accept new genes
|
||||
|
||||
/datum/plant_gene/proc/Copy()
|
||||
return new type
|
||||
var/datum/plant_gene/G = new type
|
||||
G.mutability_flags = mutability_flags
|
||||
return G
|
||||
|
||||
/datum/plant_gene/proc/apply_vars(obj/item/seeds/S) // currently used for fire resist, can prob. be further refactored
|
||||
return
|
||||
@@ -151,9 +153,9 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/plant_gene/reagent/polypyr
|
||||
/datum/plant_gene/reagent/polypyr
|
||||
name = "Polypyrylium Oligomers"
|
||||
reagent_id = "polypyrylium_oligomers"
|
||||
reagent_id = "polypyr"
|
||||
rate = 0.15
|
||||
|
||||
/datum/plant_gene/reagent/teslium
|
||||
@@ -495,4 +497,4 @@ datum/plant_gene/trait/glow/white
|
||||
name ="?????"
|
||||
|
||||
/datum/plant_gene/trait/plant_type/carnivory
|
||||
name = "Obligate Carnivory"
|
||||
name = "Obligate Carnivory"
|
||||
|
||||
@@ -56,6 +56,11 @@
|
||||
for(var/obj/item/stock_parts/manipulator/M in component_parts)
|
||||
seed_multiplier = M.rating
|
||||
|
||||
/obj/machinery/seed_extractor/examine(mob/user)
|
||||
. = ..()
|
||||
if(in_range(user, src) || isobserver(user))
|
||||
. += "<span class='notice'>The status display reads: Extracting <b>[seed_multiplier]</b> seed(s) per piece of produce.<br>Machine can store up to <b>[max_seeds]</b> seeds.</span>"
|
||||
|
||||
/obj/machinery/seed_extractor/attackby(obj/item/O, mob/user, params)
|
||||
|
||||
if(default_deconstruction_screwdriver(user, "sextractor_open", "sextractor", O))
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
var/weed_rate = 1 //If the chance below passes, then this many weeds sprout during growth
|
||||
var/weed_chance = 5 //Percentage chance per tray update to grow weeds
|
||||
|
||||
/obj/item/seeds/Initialize(loc, nogenes = 0)
|
||||
/obj/item/seeds/Initialize(mapload, nogenes = 0)
|
||||
. = ..()
|
||||
pixel_x = rand(-8, 8)
|
||||
pixel_y = rand(-8, 8)
|
||||
|
||||
@@ -1780,6 +1780,130 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
H.forcesay(GLOB.hit_appends) //forcesay checks stat already.
|
||||
return TRUE
|
||||
|
||||
/datum/species/proc/alt_spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style)
|
||||
if(!istype(M))
|
||||
return TRUE
|
||||
CHECK_DNA_AND_SPECIES(M)
|
||||
CHECK_DNA_AND_SPECIES(H)
|
||||
|
||||
if(!istype(M)) //sanity check for drones.
|
||||
return TRUE
|
||||
if(M.mind)
|
||||
attacker_style = M.mind.martial_art
|
||||
if((M != H) && M.a_intent != INTENT_HELP && H.check_shields(M, 0, M.name, attack_type = UNARMED_ATTACK))
|
||||
log_combat(M, H, "attempted to touch")
|
||||
H.visible_message("<span class='warning'>[M] attempted to touch [H]!</span>")
|
||||
return TRUE
|
||||
switch(M.a_intent)
|
||||
if(INTENT_HELP)
|
||||
if(M == H)
|
||||
althelp(M, H, attacker_style)
|
||||
return TRUE
|
||||
return FALSE
|
||||
if(INTENT_DISARM)
|
||||
altdisarm(M, H, attacker_style)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/species/proc/althelp(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
|
||||
if(user == target && istype(user))
|
||||
if(user.getStaminaLoss() >= STAMINA_SOFTCRIT)
|
||||
to_chat(user, "<span class='warning'>You're too exhausted for that.</span>")
|
||||
return
|
||||
if(!user.resting)
|
||||
to_chat(user, "<span class='notice'>You can only force yourself up if you're on the ground.</span>")
|
||||
return
|
||||
user.visible_message("<span class='notice'>[user] forces [p_them()]self up to [p_their()] feet!</span>", "<span class='notice'>You force yourself up to your feet!</span>")
|
||||
user.resting = 0
|
||||
user.update_canmove()
|
||||
user.adjustStaminaLossBuffered(user.stambuffer) //Rewards good stamina management by making it easier to instantly get up from resting
|
||||
playsound(user, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
|
||||
/datum/species/proc/altdisarm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
|
||||
if(user.getStaminaLoss() >= STAMINA_SOFTCRIT)
|
||||
to_chat(user, "<span class='warning'>You're too exhausted.</span>")
|
||||
return FALSE
|
||||
if(target.check_block())
|
||||
target.visible_message("<span class='warning'>[target] blocks [user]'s shoving attempt!</span>")
|
||||
return FALSE
|
||||
if(attacker_style && attacker_style.disarm_act(user,target))
|
||||
return TRUE
|
||||
if(user.resting)
|
||||
return FALSE
|
||||
else
|
||||
if(user == target)
|
||||
return
|
||||
user.do_attack_animation(target, ATTACK_EFFECT_DISARM)
|
||||
user.adjustStaminaLossBuffered(4)
|
||||
playsound(target, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1)
|
||||
|
||||
if(target.w_uniform)
|
||||
target.w_uniform.add_fingerprint(user)
|
||||
SEND_SIGNAL(target, COMSIG_HUMAN_DISARM_HIT, user, user.zone_selected)
|
||||
|
||||
if(!target.resting)
|
||||
target.adjustStaminaLoss(5)
|
||||
|
||||
if(target.is_shove_knockdown_blocked())
|
||||
return
|
||||
|
||||
var/turf/target_oldturf = target.loc
|
||||
var/shove_dir = get_dir(user.loc, target_oldturf)
|
||||
var/turf/target_shove_turf = get_step(target.loc, shove_dir)
|
||||
var/mob/living/carbon/human/target_collateral_human
|
||||
var/shove_blocked = FALSE //Used to check if a shove is blocked so that if it is knockdown logic can be applied
|
||||
|
||||
//Thank you based whoneedsspace
|
||||
target_collateral_human = locate(/mob/living/carbon/human) in target_shove_turf.contents
|
||||
if(target_collateral_human && target_collateral_human.resting)
|
||||
shove_blocked = TRUE
|
||||
else
|
||||
target_collateral_human = null
|
||||
target.Move(target_shove_turf, shove_dir)
|
||||
if(get_turf(target) == target_oldturf)
|
||||
shove_blocked = TRUE
|
||||
|
||||
if(shove_blocked && !target.buckled)
|
||||
var/directional_blocked = !target.Adjacent(target_shove_turf)
|
||||
var/targetatrest = target.resting
|
||||
if((directional_blocked || (!target_collateral_human && !target_shove_turf.shove_act(target, user))) && !targetatrest)
|
||||
target.Knockdown(SHOVE_KNOCKDOWN_SOLID)
|
||||
user.visible_message("<span class='danger'>[user.name] shoves [target.name], knocking them down!</span>",
|
||||
"<span class='danger'>You shove [target.name], knocking them down!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
log_combat(user, target, "shoved", "knocking them down")
|
||||
else if(target_collateral_human && !targetatrest)
|
||||
target.Knockdown(SHOVE_KNOCKDOWN_HUMAN)
|
||||
target_collateral_human.Knockdown(SHOVE_KNOCKDOWN_COLLATERAL)
|
||||
user.visible_message("<span class='danger'>[user.name] shoves [target.name] into [target_collateral_human.name]!</span>",
|
||||
"<span class='danger'>You shove [target.name] into [target_collateral_human.name]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
log_combat(user, target, "shoved", "into [target_collateral_human.name]")
|
||||
|
||||
else
|
||||
user.visible_message("<span class='danger'>[user.name] shoves [target.name]!</span>",
|
||||
"<span class='danger'>You shove [target.name]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
var/target_held_item = target.get_active_held_item()
|
||||
var/knocked_item = FALSE
|
||||
if(!is_type_in_typecache(target_held_item, GLOB.shove_disarming_types))
|
||||
target_held_item = null
|
||||
if(!target.has_movespeed_modifier(SHOVE_SLOWDOWN_ID))
|
||||
target.add_movespeed_modifier(SHOVE_SLOWDOWN_ID, multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH)
|
||||
if(target_held_item)
|
||||
target.visible_message("<span class='danger'>[target.name]'s grip on \the [target_held_item] loosens!</span>",
|
||||
"<span class='danger'>Your grip on \the [target_held_item] loosens!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
addtimer(CALLBACK(target, /mob/living/carbon/human/proc/clear_shove_slowdown), SHOVE_SLOWDOWN_LENGTH)
|
||||
else if(target_held_item)
|
||||
target.dropItemToGround(target_held_item)
|
||||
knocked_item = TRUE
|
||||
target.visible_message("<span class='danger'>[target.name] drops \the [target_held_item]!!</span>",
|
||||
"<span class='danger'>You drop \the [target_held_item]!!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
var/append_message = ""
|
||||
if(target_held_item)
|
||||
if(knocked_item)
|
||||
append_message = "causing them to drop [target_held_item]"
|
||||
else
|
||||
append_message = "loosening their grip on [target_held_item]"
|
||||
log_combat(user, target, "shoved", append_message)
|
||||
|
||||
/datum/species/proc/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H)
|
||||
var/hit_percent = (100-(blocked+armor))/100
|
||||
hit_percent = (hit_percent * (100-H.physiology.damage_resistance))/100
|
||||
|
||||
@@ -113,30 +113,26 @@
|
||||
icon_dead = "original_dead"
|
||||
//Read_Memory()
|
||||
. = ..()
|
||||
|
||||
/*
|
||||
/mob/living/simple_animal/pet/cat/Runtime/Life()
|
||||
/*
|
||||
if(!cats_deployed && SSticker.current_state >= GAME_STATE_SETTING_UP)
|
||||
Deploy_The_Cats()
|
||||
if(!stat && SSticker.current_state == GAME_STATE_FINISHED && !memory_saved)
|
||||
Write_Memory()
|
||||
memory_saved = TRUE
|
||||
*/
|
||||
..()
|
||||
|
||||
*/
|
||||
/mob/living/simple_animal/pet/cat/Runtime/make_babies()
|
||||
var/mob/baby = ..()
|
||||
if(baby)
|
||||
children += baby
|
||||
return baby
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Runtime/death()
|
||||
/*
|
||||
/mob/living/simple_animal/pet/cat/Runtime/death()
|
||||
if(!memory_saved)
|
||||
Write_Memory(TRUE)
|
||||
..()
|
||||
*/
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Runtime/proc/Read_Memory()
|
||||
if(fexists("data/npc_saves/Runtime.sav")) //legacy compatability to convert old format to new
|
||||
var/savefile/S = new /savefile("data/npc_saves/Runtime.sav")
|
||||
|
||||
@@ -130,8 +130,11 @@
|
||||
/mob/living/simple_animal/hostile/proc/ListTargets()//Step 1, find out what we can see
|
||||
if(!search_objects)
|
||||
. = hearers(vision_range, targets_from) - src //Remove self, so we don't suicide
|
||||
|
||||
var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/mecha, /obj/structure/destructible/clockwork/ocular_warden,/obj/item/electronic_assembly))
|
||||
var/static/hostile_machines
|
||||
if(istype(src, /mob/living/simple_animal/hostile/megafauna)) //If we are a megafauna, don't attack turrets as they're hard coded to not shoot us.
|
||||
hostile_machines = typecacheof(list(/obj/mecha, /obj/structure/destructible/clockwork/ocular_warden,/obj/item/electronic_assembly))
|
||||
else
|
||||
hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/mecha, /obj/structure/destructible/clockwork/ocular_warden,/obj/item/electronic_assembly))
|
||||
|
||||
for(var/HM in typecache_filter_list(range(vision_range, targets_from), hostile_machines))
|
||||
if(can_see(targets_from, HM, vision_range))
|
||||
|
||||
@@ -260,7 +260,7 @@
|
||||
visible_message("<span class='danger'>[M] pulls [src] off!</span>")
|
||||
return
|
||||
attacked += 5
|
||||
if(nutrition >= 100) //steal some nutrition. negval handled in life()
|
||||
if(nutrition >= 100 && !istype(src, /mob/living/simple_animal/slime)) //steal some nutrition. negval handled in life()
|
||||
nutrition -= (50 + (40 * M.is_adult))
|
||||
M.add_nutrition(50 + (40 * M.is_adult))
|
||||
if(health > 0)
|
||||
|
||||
@@ -1481,8 +1481,8 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M)
|
||||
|
||||
/datum/reagent/medicine/polypyr //This is intended to be an ingredient in advanced chems.
|
||||
name = "Polypyrylium Oligomers"
|
||||
id = "polypyrylium_oligomers"
|
||||
description = "A?purple mixture of short polyelectrolyte chains not easily synthesized in the laboratory. It is valued as an intermediate in the synthesis of the cutting edge pharmaceuticals."
|
||||
id = "polypyr"
|
||||
description = "A purple mixture of short polyelectrolyte chains not easily synthesized in the laboratory. It is valued as an intermediate in the synthesis of the cutting edge pharmaceuticals."
|
||||
reagent_state = SOLID
|
||||
color = "#9423FF"
|
||||
metabolization_rate = 0.25 * REAGENTS_METABOLISM
|
||||
|
||||
@@ -119,14 +119,7 @@
|
||||
stuff_mob_in(target, user)
|
||||
|
||||
/obj/machinery/disposal/proc/stuff_mob_in(mob/living/target, mob/living/user)
|
||||
if(!iscarbon(user) && !user.ventcrawler) //only carbon and ventcrawlers can climb into disposal by themselves.
|
||||
return
|
||||
if(!isturf(user.loc)) //No magically doing it from inside closets
|
||||
return
|
||||
if(target.buckled || target.has_buckled_mobs())
|
||||
return
|
||||
if(target.mob_size > MOB_SIZE_HUMAN)
|
||||
to_chat(user, "<span class='warning'>[target] doesn't fit inside [src]!</span>")
|
||||
if(!can_stuff_mob_in(target, user))
|
||||
return
|
||||
add_fingerprint(user)
|
||||
if(user == target)
|
||||
@@ -145,6 +138,19 @@
|
||||
target.LAssailant = user
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/disposal/proc/can_stuff_mob_in(mob/living/target, mob/living/user, pushing = FALSE)
|
||||
if(!pushing && !iscarbon(user) && !user.ventcrawler) //only carbon and ventcrawlers can climb into disposal by themselves.
|
||||
return FALSE
|
||||
if(!isturf(user.loc)) //No magically doing it from inside closets
|
||||
return FALSE
|
||||
if(target.buckled || target.has_buckled_mobs())
|
||||
return FALSE
|
||||
if(target.mob_size > MOB_SIZE_HUMAN)
|
||||
if(!pushing)
|
||||
to_chat(user, "<span class='warning'>[target] doesn't fit inside [src]!</span>")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/disposal/relaymove(mob/user)
|
||||
attempt_escape(user)
|
||||
|
||||
@@ -273,6 +279,7 @@
|
||||
desc = "A pneumatic waste disposal unit."
|
||||
icon_state = "disposal"
|
||||
var/datum/oracle_ui/themed/nano/ui
|
||||
obj_flags = CAN_BE_HIT | USES_TGUI | SHOVABLE_ONTO
|
||||
|
||||
/obj/machinery/disposal/bin/Initialize(mapload, obj/structure/disposalconstruct/make_from)
|
||||
. = ..()
|
||||
@@ -313,7 +320,7 @@
|
||||
if(Adjacent(user))
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
|
||||
|
||||
/obj/machinery/disposal/bin/oui_data(mob/user)
|
||||
var/list/data = list()
|
||||
@@ -368,6 +375,17 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/disposal/bin/shove_act(mob/living/target, mob/living/user)
|
||||
if(can_stuff_mob_in(target, user, TRUE))
|
||||
target.Knockdown(SHOVE_KNOCKDOWN_SOLID)
|
||||
target.forceMove(src)
|
||||
user.visible_message("<span class='danger'>[user.name] shoves [target.name] into \the [src]!</span>",
|
||||
"<span class='danger'>You shove [target.name] into \the [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
log_combat(user, target, "shoved", "into [src] (disposal bin)")
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
/obj/machinery/disposal/bin/flush()
|
||||
..()
|
||||
full_pressure = FALSE
|
||||
|
||||
Reference in New Issue
Block a user