diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index 0dc50b7dc4c..ac2e2b33a68 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -406,6 +406,13 @@ return ishuman(target) && target.dna.species.is_monkeybasic // we deserve a runtime if a human has no DNA +/proc/is_evolvedslime(mob/living/carbon/human/target) + if(!ishuman(target) || !istype(target.dna.species, /datum/species/slime)) + return FALSE + var/datum/species/slime/species = target.dna.species + return species.evolved_slime + + /proc/spawn_atom_to_turf(spawn_type, target, amount, admin_spawn=FALSE, list/extra_args) var/turf/T = get_turf(target) if(!T) diff --git a/code/game/gamemodes/antag_paradise/antag_paradise.dm b/code/game/gamemodes/antag_paradise/antag_paradise.dm index 1d2c015694b..0f0a8896ce6 100644 --- a/code/game/gamemodes/antag_paradise/antag_paradise.dm +++ b/code/game/gamemodes/antag_paradise/antag_paradise.dm @@ -1,3 +1,6 @@ +#define AUTOTRAITOR_LOW_BOUND (5 MINUTES) +#define AUTOTRAITOR_HIGH_BOUND (15 MINUTES) + /** * This is a game mode which has a chance to spawn any minor antagonist. */ @@ -16,9 +19,6 @@ var/list/datum/mind/pre_antags = list() var/list/datum/mind/pre_double_antags = list() - var/antag_making_cooldown = 5 MINUTES - var/next_antag_making_time = 0 - var/list/antag_required_players = list( ROLE_TRAITOR = 10, ROLE_THIEF = 10, @@ -32,25 +32,29 @@ var/list/antags_weights /// Chosen speciaal antag type. var/special_antag_type = ROLE_NONE + /// Timestamp for autotraitor + COOLDOWN_DECLARE(antag_making_cooldown) /datum/game_mode/antag_paradise/announce() to_chat(world, "The current game mode is - Antag Paradise") to_chat(world, "Traitors, thieves, vampires and changelings, oh my! Stay safe as these forces work to bring down the station.") + /datum/game_mode/antag_paradise/process() if(SSshuttle.emergency.mode >= SHUTTLE_ESCAPE) return PROCESS_KILL - if(world.time < next_antag_making_time) - return FALSE + if(!COOLDOWN_STARTED(src, antag_making_cooldown) || !COOLDOWN_FINISHED(src, antag_making_cooldown)) + return - next_antag_making_time = world.time + antag_making_cooldown + COOLDOWN_START(src, antag_making_cooldown, rand(AUTOTRAITOR_LOW_BOUND, AUTOTRAITOR_HIGH_BOUND)) var/list/antag_possibilities = list() antag_possibilities[ROLE_VAMPIRE] = get_alive_players_for_role(ROLE_VAMPIRE) antag_possibilities[ROLE_CHANGELING] = get_alive_players_for_role(ROLE_CHANGELING) antag_possibilities[ROLE_TRAITOR] = get_alive_players_for_role(ROLE_TRAITOR) antag_possibilities[ROLE_THIEF] = get_alive_players_for_role(ROLE_THIEF, list(SPECIES_VOX = 4)) + antag_possibilities[ROLE_MALF_AI] = get_alive_AIs_for_role(ROLE_MALF_AI) roll_antagonists(antag_possibilities) initiate_antags() @@ -65,15 +69,17 @@ var/special_antag_amount antags_amount = 1 + round(players / scale) - //Special antag spawning not on roundstart is currently disabled for testing purposes. - special_antag_amount = roundstart ? 1 + round(players / 50) : 0 + special_antag_amount = roundstart ? 1 + round(players / 50) : round(players / 50) antags_amount = antags_amount - length(GLOB.antagonists) if(antags_amount <= 0) return - if(special_antag_type == ROLE_NINJA && !roundstart) - special_antag_type = pick(ROLE_HIJACKER, ROLE_THIEF, ROLE_MALF_AI) + if(!roundstart) + if(length(antag_possibilities[ROLE_MALF_AI])) + special_antag_type = pick(ROLE_HIJACKER, ROLE_THIEF, ROLE_MALF_AI) + else + special_antag_type = pick(ROLE_HIJACKER, ROLE_THIEF) switch(special_antag_type) if(ROLE_HIJACKER) @@ -97,7 +103,7 @@ if(ROLE_MALF_AI) if(special_antag_amount) - var/datum/mind/special_antag = roundstart ? safepick(get_players_for_role(ROLE_MALF_AI, req_job_rank = JOB_TITLE_AI)) : safepick(get_alive_players_for_role(ROLE_MALF_AI, req_job_rank = JOB_TITLE_AI)) + var/datum/mind/special_antag = roundstart ? safepick(get_players_for_role(ROLE_MALF_AI, req_job_rank = JOB_TITLE_AI)) : safepick(antag_possibilities[ROLE_MALF_AI]) if(special_antag) special_antag.restricted_roles = (restricted_jobs|protected_jobs|protected_jobs_AI) special_antag.restricted_roles -= JOB_TITLE_AI @@ -199,6 +205,7 @@ pre_double_antags[antag] = ROLE_CHANGELING break + /datum/game_mode/antag_paradise/pre_setup() if(CONFIG_GET(flag/protect_roles_from_antagonist)) restricted_jobs += protected_jobs @@ -211,7 +218,8 @@ calculate_antags() - return roll_antagonists(antag_possibilities, TRUE) + return roll_antagonists(antag_possibilities, roundstart = TRUE) + /datum/game_mode/antag_paradise/proc/calculate_antags() var/players = num_players() @@ -288,7 +296,7 @@ antag.add_antag_datum(ninja_datum) addtimer(CALLBACK(src, PROC_REF(initiate_antags)), rand(1 SECONDS, 10 SECONDS)) - next_antag_making_time = world.time + antag_making_cooldown + COOLDOWN_START(src, antag_making_cooldown, AUTOTRAITOR_LOW_BOUND) // first auto-traitor tick checks all players in 5 minutes ..() @@ -347,3 +355,7 @@ new_list[index] = check_list[index] return new_list + +#undef AUTOTRAITOR_LOW_BOUND +#undef AUTOTRAITOR_HIGH_BOUND + diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index ac8a287a857..13d6f7d0feb 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -326,10 +326,7 @@ if(!player.client \ || jobban_isbanned(player, "Syndicate") || jobban_isbanned(player, role) \ || !player_old_enough_antag(player.client, role, req_job_rank) || player.client.prefs?.skip_antag \ - || !(role in player.client.prefs.be_special)) - continue - - if(player.mind.has_antag_datum(/datum/antagonist) || player.mind.offstation_role || player.mind.special_role) + || !(role in player.client.prefs.be_special) || !is_player_station_relevant(player)) continue players += player @@ -356,34 +353,67 @@ return candidates + +/datum/game_mode/proc/get_alive_AIs_for_role(role) + . = list() + for(var/mob/living/silicon/ai/AI in GLOB.alive_mob_list) + if(!AI.client || !AI.mind \ + || jobban_isbanned(AI, "Syndicate") || jobban_isbanned(AI, role) \ + || !player_old_enough_antag(AI.client, role, JOB_TITLE_AI) || AI.client.prefs?.skip_antag \ + || !(role in AI.client.prefs.be_special) || AI.stat == DEAD || AI.control_disabled \ + || AI.mind.offstation_role || AI.mind.special_role) + continue + . += AI.mind + + +/// All the checks required to find baseline human being +/proc/is_player_station_relevant(mob/living/carbon/human/player) + if(QDELING(player)) + return FALSE + if(!player.client) + return FALSE + if(!player.mind) + return FALSE + if(player.mind.special_role) // already "special" + return FALSE + if(player.mind.offstation_role) // spawned mobs + return FALSE + if(player.stat == DEAD) // no zombies + return FALSE + var/turf/player_turf = get_turf(player) + if(!player_turf) // nullspace, eh? + return FALSE + if(!is_level_reachable(player_turf.z) && !is_away_level(player_turf.z)) // taipan is not available, mkay? + return FALSE + if(is_monkeybasic(player)) // no monkas + return FALSE + if(isgolem(player)) // get out of here + return FALSE + if(is_evolvedslime(player)) // no evolved slimes please + return FALSE + return TRUE // congratulations, you are normal! + + /datum/game_mode/proc/latespawn(mob/player) /datum/game_mode/proc/num_players() . = 0 - for(var/mob/new_player/player in GLOB.player_list) - if(player.client && player.ready) .++ + /proc/num_station_players() . = 0 for(var/mob/living/carbon/human/player in GLOB.player_list) - if(!player) - continue - - if(player.client && player.mind && !player.mind.offstation_role && !player.mind.special_role) + if(is_player_station_relevant(player)) .++ /datum/game_mode/proc/num_players_started() . = 0 - for(var/mob/living/carbon/human/player in GLOB.player_list) - if(!player) - continue - if(player.client) .++ diff --git a/code/modules/mob/living/carbon/human/species/slime.dm b/code/modules/mob/living/carbon/human/species/slime.dm index a590987e95a..622a3fdebc9 100644 --- a/code/modules/mob/living/carbon/human/species/slime.dm +++ b/code/modules/mob/living/carbon/human/species/slime.dm @@ -72,6 +72,8 @@ disliked_food = SUGAR | FRIED liked_food = MEAT | TOXIC | RAW + /// Special flag used for slimeperson evolved from the slime. + var/evolved_slime = FALSE /datum/species/slime/on_species_gain(mob/living/carbon/human/H) ..() diff --git a/code/modules/mob/living/simple_animal/slime/powers.dm b/code/modules/mob/living/simple_animal/slime/powers.dm index b2394fa6190..8bc3dd9be1e 100644 --- a/code/modules/mob/living/simple_animal/slime/powers.dm +++ b/code/modules/mob/living/simple_animal/slime/powers.dm @@ -165,7 +165,9 @@ new_slime.update_hair() new_slime.update_body() new_slime.blood_color = new_colour - new_slime.dna.species.blood_color = new_slime.blood_color + new_slime.dna.species.blood_color = new_slime.dna.species + var/datum/species/slime/species = new_slime.dna.species + species.evolved_slime = TRUE else to_chat(src, "I am not ready to evolve yet...")