Mindflayers v0.9, Playable Edition! (#26596)

* adds antaghud icon

* TGUI bundle build dont push changes i didnt stage challenge 2025 (IMPOSSIBLE)

* Adds organ repair passive

* Description fix

* Runs prettier

* Fixes desc 2

* Fix revert

* Remove vamp text

* Fix some CI + Partial refactor

* Fixes CI

* Fixes gamemodes I messed with

* Moves these procs over

* Description fix again

* Add back limit requiring drainees to have ckeys

* Adds terminator icon

* Update code/datums/status_effects/buffs.dm

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: DGamerL <108773801+DGamerL@users.noreply.github.com>

* Update code/modules/surgery/organs/augments_internal.dm

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com>

* Update code/modules/antagonists/mind_flayer/powers/flayer_stealth_powers.dm

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com>

* More lewv review

* Clamps the EMP severity

* Fixes "surveilance" typos

* The TODO is gone and can't hurt me anymore

* Update code/modules/antagonists/mind_flayer/flayer_datum.dm

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com>

* Update code/game/objects/items/weapons/pneumaticCannon.dm

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com>

* Update code/game/objects/items/weapons/stunbaton.dm

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com>

* More lewc reviews

* Update code/modules/antagonists/_common/antag_datum.dm

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com>

* Update code/modules/antagonists/_common/antag_datum.dm

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com>

* Update code/modules/antagonists/mind_flayer/flayer_datum.dm

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com>

* Update code/modules/antagonists/mind_flayer/flayer_datum.dm

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com>

* Update code/modules/antagonists/mind_flayer/flayer_datum.dm

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com>

* Update code/modules/antagonists/mind_flayer/flayer_datum.dm

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com>

* Update code/modules/antagonists/mind_flayer/flayer_power.dm

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com>

* Fixes some camera bug issues + lewc reviews

* Update code/modules/antagonists/mind_flayer/powers/flayer_passives.dm

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com>

* Update code/modules/antagonists/mind_flayer/flayer_power.dm

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com>

* Updates a comment and fixes whitespace

* Autodocs flayerprod

* Update code/modules/antagonists/mind_flayer/powers/flayer_mobility_powers.dm

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com>

* qdel things we dont need anymore + typing an argument of add_abillity

* Remove debug log

* Update code/modules/antagonists/mind_flayer/flayer_power.dm

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com>

* Slightly buffs, and fixes GC issues of tether

* I no longer feel i am a mindflayer

* Fixes formatting of greeting

* Better greeting

* Worlds shittiest sprite

* Don't need this TODO anymore

* Fixes double description

* Changes the wording on the borg laws

* and bundle too

* The cannon uses shrapnel now

* Initial style changes

* Ratios for brain damage

* Adds a chemical to test for flayerism

* Fixes the brain damage ratios

* Abilities are purchasable again

* Updates TGUI properly

* im sorry linter

* Steam smoke

* Hi bundle

* Re-abstracts this proc post syndi orgs

* Fixes gamemode logic post cling round removal

* I WONT FORGET IT THIS TIME

* Fix name of steam ability

* I'm a fool

* Fixes processed passives + removes debug message

* Fixes updating abilities inside UI

* Better description for quicksilver form

* First part lewc review

* Remove debug thingy

* Apply suggestions from code review

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: DGamerL <108773801+DGamerL@users.noreply.github.com>

* Fixes defines + GCs weapon spells

* We don't need this

* Eyes GC properly

* Update code/modules/antagonists/mind_flayer/powers/flayer_mobility_powers.dm

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com>

* adds better logging to the assimilate

* Adds parenthesis

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com>

* TGUI Bundle Rebuild

* Fixes and Reworks TGUI

* Cleaner JS and Fixes

* adds anti-snitching clause to borg laws

* changes the span for the borg messages

* No holoparasites

* Puts baton silence in line with glare

* Fixes total_swarms_gathered

* Nuke old trait

* Gun no longer not stuck

* Rejuv clears delayed knockdown

* Some weapon ability fixes

* Makes radio enable timers not counterintuitive

* Fixes beepsky runtimes

* Makes naming more consistent

* Adds one-click-antag

* Adds the mind flayer toggle (doesn't technically work)

* Adds flayers to check_antagonist

* Gives IDs to the status effects

* Also this one

* Makes retracting work again if it's in your offhand

* Fixes pacification tech levels

* Grapple is a weapon ability now, nullifcation retracts implants

* Fixed descriptions

* Adds some pizzaz to torque enhancer

* This actually needs to be like this

* Moves a helper proc over to a helper proc file

* Extra admin visibility

* Nukes the wacky flayer mob

* Makes silicon administrative access more sane

* Terminator form better description

* Makes rejuv set stamina to 0

* Various price increases

* AAAAAAAAAAAAA

* Better feedback + logging on cyborg subversion

* Swarm purchase display (temp fix)

* Makes mindflayer sounds more silent

* UI improvements

* Various mindflayer fixes

* Typo

* More fixes

* Fixes innates from being stupid

* Forgot to add this check earlier

* Oh this is how you add things to the protolathe

* Changes some description and upgrade messages

* Allows you to drain people beyond your limit

* Fixes some weapon upgrade issues

* Fix CI

* Fixes some draining issues

* More UI Tweaks and QoL

* Fixes most of the issues

* text

* Fixes

* Adds a radio jamming option to intruder

* Gives obfusciation to jammer ability

* Small passive cleanup

* Fixes Search and Adds Ability Stages to UI

* Adds freebie abilities

* Restructuring chain and adding blackbox

* Tgui polish

* Small fix for traceroute

* Fixes one click antag

* Increases EMP resistance cost

* Changes the pneumatic cannon into a shotgun

* Slightly lower static

* Fixed innate building rendering in upgrades

* Fixes icon and description

* Consistency

* Punctuation fix.

* Quick reboot + terminator form synergy

* Adds safety deleting

* Fix level for torque

* Fixes a bad bug

* Update code/game/gamemodes/objective.dm

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: DGamerL <108773801+DGamerL@users.noreply.github.com>

* Aaaaaaaaaaa

* Makes torque a martial art and some martial arts safeties

* Replaces vortex arm with barrier

* Fix paths

* Adds torque knockdown

* Part 1 lewc review

* HIIIII SQUIDWARD I'M IN YOUR BRANCH NOW

* Removes flak cannon

* Flayer respects mindshielding now on vamp+cling

* Fixes EMP resist

* More fixes

* DGL review

* Contra review

* Clean up weapon powers

* Various tweaks

* Borg hand slight improvements

* Parent call needs to be after this

* Fixes stuff

* Adds a new proc that is called when a spell is purchased

* NEW SPRITES WOOOO

* Traceroute update

* Slightly lower traceroute cost

* Formatting

* Oops

* Wow this could've been bad

* Overclock small buff

* Reduces cost of 1st level EMP immunity

* Lewc review

* TGUI Bundle Rebuild

* Fix barricades

* Lewc review

* Okay FINE qwerty I'll change this

* Traceroute thingy

* I am an idiot

* First part

* Lewc review

* Forgor  this one

* Last bits

* Update code/game/objects/items/control_wand.dm

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: DGamerL <108773801+DGamerL@users.noreply.github.com>

* Update code/modules/antagonists/mind_flayer/powers/flayer_mobility_powers.dm

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: DGamerL <108773801+DGamerL@users.noreply.github.com>

* Null

* Static-ness

* Update code/game/gamemodes/changeling/traitor_chan.dm

Signed-off-by: DGamerL <108773801+DGamerL@users.noreply.github.com>

* Update code/__DEFINES/mindflayer_defines.dm

Signed-off-by: DGamerL <108773801+DGamerL@users.noreply.github.com>

* Last bits

---------

Signed-off-by: DGamerL <108773801+DGamerL@users.noreply.github.com>
Signed-off-by: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com>
Co-authored-by: DGamerL <daan.lyklema@gmail.com>
Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com>
Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com>
Co-authored-by: Qwertytoforty <52090703+Qwertytoforty@users.noreply.github.com>
This commit is contained in:
BiancaWilkson
2024-10-30 18:35:29 +00:00
committed by GitHub
co-authored by Luc DGamerL DGamerL Burzah Qwertytoforty
parent c4521dc955
commit 036b8e0182
100 changed files with 3063 additions and 193 deletions
+1 -1
View File
@@ -340,7 +340,7 @@
* Proc which will make the atom act accordingly to an EMP.
* This proc can sleep depending on the implementation. So assume it sleeps!
*
* severity - The severity of the EMP. Either EMP_HEAVY or EMP_LIGHT
* severity - The severity of the EMP. Either EMP_HEAVY, EMP_LIGHT, or EMP_WEAKENED
*/
/atom/proc/emp_act(severity)
SEND_SIGNAL(src, COMSIG_ATOM_EMP_ACT, severity)
+8 -5
View File
@@ -7,17 +7,16 @@ GLOBAL_LIST_INIT(possible_changeling_IDs, list("Alpha","Beta","Gamma","Delta","E
config_tag = "changeling"
restricted_jobs = list("AI", "Cyborg")
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Blueshield", "Nanotrasen Representative", "Magistrate", "Internal Affairs Agent", "Nanotrasen Navy Officer", "Special Operations Officer", "Syndicate Officer", "Trans-Solar Federation General")
protected_species = list("Machine")
species_to_mindflayer = list("Machine")
required_players = 15
required_enemies = 1
recommended_enemies = 4
/// The total number of changelings allowed to be picked.
var/changeling_amount = 4
/// A list containing references to the minds of soon-to-be changelings. This is seperate to avoid duplicate entries in the `changelings` list.
var/list/datum/mind/pre_changelings = list()
/datum/game_mode/changeling/Destroy(force, ...)
pre_changelings.Cut()
pre_mindflayers.Cut()
return ..()
/datum/game_mode/changeling/announce()
@@ -36,11 +35,15 @@ GLOBAL_LIST_INIT(possible_changeling_IDs, list("Alpha","Beta","Gamma","Delta","E
if(!length(possible_changelings))
break
var/datum/mind/changeling = pick_n_take(possible_changelings)
pre_changelings += changeling
changeling.restricted_roles = restricted_jobs
if(changeling.current?.client?.prefs.active_character.species in species_to_mindflayer)
pre_mindflayers += changeling
changeling.special_role = SPECIAL_ROLE_MIND_FLAYER
continue
pre_changelings += changeling
changeling.special_role = SPECIAL_ROLE_CHANGELING
if(!length(pre_changelings))
if(!(length(pre_changelings) + length(pre_mindflayers)))
return FALSE
return TRUE
@@ -8,9 +8,7 @@
required_enemies = 1 // how many of each type are required
recommended_enemies = 3
secondary_enemies_scaling = 0.025
secondary_protected_species = list("Machine")
/// A list containing references to the minds of soon-to-be changelings. This is seperate to avoid duplicate entries in the `changelings` list.
var/list/datum/mind/pre_changelings = list()
species_to_mindflayer = list("Machine")
/datum/game_mode/traitor/changeling/announce()
to_chat(world, "<B>The current game mode is - Traitor+Changeling!</B>")
@@ -24,19 +22,19 @@
var/list/datum/mind/possible_changelings = get_players_for_role(ROLE_CHANGELING)
secondary_enemies = CEILING((secondary_enemies_scaling * num_players()), 1)
for(var/mob/new_player/player in GLOB.player_list)
if((player.mind in possible_changelings) && (player.client.prefs.active_character.species in secondary_protected_species))
possible_changelings -= player.mind
if(!length(possible_changelings))
return ..()
for(var/I in possible_changelings)
if(length(pre_changelings) >= secondary_enemies)
if((length(pre_changelings) + length(pre_mindflayers)) >= secondary_enemies)
break
var/datum/mind/changeling = pick_n_take(possible_changelings)
pre_changelings += changeling
changeling.restricted_roles = (restricted_jobs + secondary_restricted_jobs)
if(changeling.current?.client?.prefs.active_character.species in species_to_mindflayer)
pre_mindflayers += changeling
changeling.special_role = SPECIAL_ROLE_MIND_FLAYER
continue
pre_changelings += changeling
changeling.special_role = SPECIAL_ROLE_CHANGELING
return ..()
+38 -15
View File
@@ -23,8 +23,8 @@
var/list/restricted_jobs = list() // Jobs it doesn't make sense to be. I.E chaplain or AI cultist
var/list/secondary_restricted_jobs = list() // Same as above, but for secondary antagonists
var/list/protected_jobs = list() // Jobs that can't be traitors
var/list/protected_species = list() // Species that can't be traitors
var/list/secondary_protected_species = list() // Same as above, but for secondary antagonists
/// Species that will become mindflayers if they're picked, instead of the regular antagonist
var/list/species_to_mindflayer = list()
var/required_players = 0
var/required_enemies = 0
var/recommended_enemies = 0
@@ -56,6 +56,17 @@
var/list/datum/mind/vampires = list()
/// A list of all minds which are thralled by a vampire
var/list/datum/mind/vampire_enthralled = list()
/// A list of all minds which have the mindflayer antag datum
var/list/datum/mind/mindflayers = list()
/// A list containing references to the minds of soon-to-be traitors. This is seperate to avoid duplicate entries in the `traitors` list.
var/list/datum/mind/pre_traitors = list()
/// A list containing references to the minds of soon-to-be changelings. This is seperate to avoid duplicate entries in the `changelings` list.
var/list/datum/mind/pre_changelings = list()
///list of minds of soon to be vampires
var/list/datum/mind/pre_vampires = list()
/// A list containing references to the minds of soon-to-be mindflayers.
var/list/datum/mind/pre_mindflayers = list()
/// A list of all minds which have the wizard special role
var/list/datum/mind/wizards = list()
/// A list of all minds that are wizard apprentices
@@ -132,6 +143,10 @@
GLOB.start_state = new /datum/station_state()
GLOB.start_state.count()
for(var/datum/mind/flayer as anything in pre_mindflayers) //Mindflayers need to be all the way out here since they could come from most gamemodes
flayer.make_mind_flayer()
return TRUE
///process()
@@ -259,7 +274,7 @@
if(rev_team)
rev_team.check_all_victory()
/datum/game_mode/proc/get_players_for_role(role, override_jobbans = FALSE)
/datum/game_mode/proc/get_players_for_role(role, override_jobbans = FALSE, species_exclusive = null)
var/list/players = list()
var/list/candidates = list()
@@ -272,22 +287,29 @@
if(player_old_enough_antag(player.client,role))
players += player
for(var/mob/living/carbon/human/player in GLOB.player_list)
if(jobban_isbanned(player, ROLE_SYNDICATE) || jobban_isbanned(player, roletext))
continue
if(player_old_enough_antag(player.client, role))
players += player
// Shuffle the players list so that it becomes ping-independent.
players = shuffle(players)
// Get a list of all the people who want to be the antagonist for this round, except those with incompatible species
for(var/mob/new_player/player in players)
if(!player.client.skip_antag)
if((role in player.client.prefs.be_special) && !(player.client.prefs.active_character.species in protected_species))
player_draft_log += "[player.key] had [roletext] enabled, so we are drafting them."
candidates += player.mind
players -= player
// Get a list of all the people who want to be the antagonist for this round
for(var/mob/eligible_player in players)
if(!eligible_player.client.skip_antag)
if(species_exclusive && (eligible_player.client.prefs.active_character.species != species_exclusive))
continue
if(role in eligible_player.client.prefs.be_special)
player_draft_log += "[eligible_player.key] had [roletext] enabled, so we are drafting them."
candidates += eligible_player.mind
players -= eligible_player
// Remove candidates who want to be antagonist but have a job (or other antag datum) that precludes it
if(restricted_jobs)
for(var/datum/mind/player in candidates)
if((player.assigned_role in restricted_jobs) || player.special_role)
candidates -= player
for(var/datum/mind/player_mind in candidates)
if((player_mind.assigned_role in restricted_jobs) || player_mind.special_role)
candidates -= player_mind
return candidates // Returns: The number of people who had the antagonist role set to yes, regardless of recomended_enemies, if that number is greater than recommended_enemies
@@ -317,7 +339,7 @@
if(player.client.skip_antag || !(allow_offstation_roles || !player.mind?.offstation_role) || player.mind?.special_role)
continue
if(!(role in player.client.prefs.be_special) || (player.client.prefs.active_character.species in protected_species))
if(!(role in player.client.prefs.be_special) || (player.client.prefs.active_character.species in species_to_mindflayer))
continue
player_draft_log += "[player.key] had [roletext] enabled, so we are drafting them."
@@ -620,6 +642,7 @@
. += auto_declare_completion_traitor()
. += auto_declare_completion_vampire()
. += auto_declare_completion_enthralled()
. += auto_declare_completion_mindflayer()
. += auto_declare_completion_changeling()
. += auto_declare_completion_nuclear()
. += auto_declare_completion_wizard()
+1 -1
View File
@@ -116,7 +116,7 @@
if((man.mind.assigned_role in SSticker.mode.protected_jobs) || (man.mind.assigned_role in SSticker.mode.restricted_jobs))
return
//don't include suspects who can't possibly be the antag based on their species (no suspecting the machines of being sneaky changelings)
if(man.dna.species.name in SSticker.mode.protected_species)
if(man.dna.species.name in SSticker.mode.species_to_mindflayer)
return
dudes += man
for(var/i = 0, i < max(length(GLOB.player_list)/10,2), i++)
@@ -283,7 +283,7 @@
if(has_guardian(user))
to_chat(user, "You already have a [mob_name]!")
return
if(user.mind && (IS_CHANGELING(user) || user.mind.has_antag_datum(/datum/antagonist/vampire)))
if(user.mind && (IS_CHANGELING(user) || user.mind.has_antag_datum(/datum/antagonist/vampire) || IS_MINDFLAYER(user)))
to_chat(user, "[ling_failure]")
return
if(used)
+26
View File
@@ -857,6 +857,32 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective)
else
return FALSE
#define SWARM_GOAL_LOWER_BOUND 130
#define SWARM_GOAL_UPPER_BOUND 400
/datum/objective/swarms
name = "Gain swarms"
needs_target = FALSE
/datum/objective/swarms/New()
gen_amount_goal()
return ..()
/datum/objective/swarms/proc/gen_amount_goal(low = SWARM_GOAL_LOWER_BOUND, high = SWARM_GOAL_UPPER_BOUND)
target_amount = round(rand(low, high), 5)
update_explanation_text()
return target_amount
/datum/objective/swarms/update_explanation_text()
explanation_text = "Accumulate at least [target_amount] worth of swarms."
/datum/objective/swarms/check_completion()
for(var/datum/mind/M in get_owners())
var/datum/antagonist/mindflayer/flayer = M.has_antag_datum(/datum/antagonist/mindflayer)
return flayer?.total_swarms_gathered >= target_amount
#undef SWARM_GOAL_LOWER_BOUND
#undef SWARM_GOAL_UPPER_BOUND
// Traders
// These objectives have no check_completion, they exist only to tell Sol Traders what to aim for.
+1 -3
View File
@@ -6,8 +6,6 @@
required_players = 0
required_enemies = 1
recommended_enemies = 4
/// A list containing references to the minds of soon-to-be traitors. This is seperate to avoid duplicate entries in the `traitors` list.
var/list/datum/mind/pre_traitors = list()
/// Hard limit on traitors if scaling is turned off.
var/traitors_possible = 4
/// How much the amount of players get divided by to determine the number of traitors.
@@ -25,7 +23,7 @@
var/list/possible_traitors = get_players_for_role(ROLE_TRAITOR)
for(var/datum/mind/candidate in possible_traitors)
if(candidate.special_role == SPECIAL_ROLE_VAMPIRE || candidate.special_role == SPECIAL_ROLE_CHANGELING) // no traitor vampires or changelings
if(candidate.special_role == SPECIAL_ROLE_VAMPIRE || candidate.special_role == SPECIAL_ROLE_CHANGELING || candidate.special_role == SPECIAL_ROLE_MIND_FLAYER) // no traitor vampires, changelings, or mindflayers
possible_traitors.Remove(candidate)
// stop setup if no possible traitors
+14 -9
View File
@@ -12,11 +12,8 @@
required_players = 25
required_enemies = 1 // how many of each type are required
recommended_enemies = 3
secondary_protected_species = list("Machine")
species_to_mindflayer = list("Machine")
var/vampire_restricted_jobs = list("Chaplain")
var/list/datum/mind/pre_traitors = list()
var/list/datum/mind/pre_changelings = list()
var/list/datum/mind/pre_vampires = list()
var/amount_vamp = 1
var/amount_cling = 1
var/amount_tot = 1
@@ -40,11 +37,14 @@
for(var/datum/mind/vampire as anything in shuffle(possible_vampires))
if(length(pre_vampires) >= amount_vamp)
break
if(vampire.current.client.prefs.active_character.species in secondary_protected_species)
vampire.restricted_roles = restricted_jobs + secondary_restricted_jobs + vampire_restricted_jobs
if(vampire.current.client.prefs.active_character.species in species_to_mindflayer)
pre_mindflayers += vampire
amount_vamp -= 1 //It's basically the same thing as incrementing pre_vampires
vampire.special_role = SPECIAL_ROLE_MIND_FLAYER
continue
pre_vampires += vampire
vampire.special_role = SPECIAL_ROLE_VAMPIRE
vampire.restricted_roles = (restricted_jobs + secondary_restricted_jobs + vampire_restricted_jobs)
//Vampires made, off to changelings
var/list/datum/mind/possible_changelings = get_players_for_role(ROLE_CHANGELING)
@@ -55,10 +55,15 @@
for(var/datum/mind/changeling as anything in shuffle(possible_changelings))
if(length(pre_changelings) >= amount_cling)
break
if((changeling.current.client.prefs.active_character.species in secondary_protected_species) || changeling.special_role == SPECIAL_ROLE_VAMPIRE)
if(changeling.special_role == SPECIAL_ROLE_VAMPIRE || changeling.special_role == SPECIAL_ROLE_MIND_FLAYER)
continue
changeling.restricted_roles = (restricted_jobs + secondary_restricted_jobs)
if(changeling.current?.client?.prefs.active_character.species in species_to_mindflayer)
pre_mindflayers += changeling
amount_cling -= 1
changeling.special_role = SPECIAL_ROLE_MIND_FLAYER
continue
pre_changelings += changeling
changeling.restricted_roles = (restricted_jobs + secondary_restricted_jobs)
changeling.special_role = SPECIAL_ROLE_CHANGELING
//And now traitors
@@ -71,7 +76,7 @@
for(var/datum/mind/traitor as anything in shuffle(possible_traitors))
if(length(pre_traitors) >= amount_tot)
break
if(traitor.special_role == SPECIAL_ROLE_VAMPIRE || traitor.special_role == SPECIAL_ROLE_CHANGELING) // no traitor vampires or changelings
if(traitor.special_role == SPECIAL_ROLE_VAMPIRE || traitor.special_role == SPECIAL_ROLE_CHANGELING || traitor.special_role == SPECIAL_ROLE_MIND_FLAYER) // no traitor vampires or changelings
continue
pre_traitors += traitor
traitor.special_role = SPECIAL_ROLE_TRAITOR
+16 -17
View File
@@ -9,8 +9,7 @@
required_enemies = 1 // how many of each type are required
recommended_enemies = 3
secondary_enemies_scaling = 0.025
secondary_protected_species = list("Machine")
var/list/datum/mind/pre_vampires = list()
species_to_mindflayer = list("Machine")
/datum/game_mode/traitor/vampire/announce()
to_chat(world, "<B>The current game mode is - Traitor+Vampire!</B>")
@@ -24,22 +23,22 @@
var/list/datum/mind/possible_vampires = get_players_for_role(ROLE_VAMPIRE)
secondary_enemies = CEILING((secondary_enemies_scaling * num_players()), 1)
for(var/mob/new_player/player in GLOB.player_list)
if((player.mind in possible_vampires) && (player.client.prefs.active_character.species in secondary_protected_species))
possible_vampires -= player.mind
if(length(possible_vampires) <= 0)
return FALSE
if(length(possible_vampires) > 0)
for(var/I in possible_vampires)
if(length(pre_vampires) >= secondary_enemies)
break
var/datum/mind/vampire = pick_n_take(possible_vampires)
pre_vampires += vampire
vampire.special_role = SPECIAL_ROLE_VAMPIRE
vampire.restricted_roles = (restricted_jobs + secondary_restricted_jobs)
..()
return 1
else
return 0
for(var/I in possible_vampires)
if((length(pre_vampires) + length(pre_mindflayers)) >= secondary_enemies)
break
var/datum/mind/vampire = pick_n_take(possible_vampires)
vampire.restricted_roles = (restricted_jobs + secondary_restricted_jobs)
if(vampire.current?.client?.prefs.active_character.species in species_to_mindflayer)
pre_mindflayers += vampire
vampire.special_role = SPECIAL_ROLE_MIND_FLAYER
continue
pre_vampires += vampire
vampire.special_role = SPECIAL_ROLE_VAMPIRE
..()
return TRUE
/datum/game_mode/traitor/vampire/post_setup()
for(var/datum/mind/vampire in pre_vampires)
+7 -8
View File
@@ -3,14 +3,12 @@
config_tag = "vampchan"
restricted_jobs = list("AI", "Cyborg")
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Blueshield", "Nanotrasen Representative", "Magistrate", "Chaplain", "Internal Affairs Agent", "Nanotrasen Navy Officer", "Special Operations Officer", "Syndicate Officer", "Solar Federation General")
protected_species = list("Machine")
species_to_mindflayer = list("Machine")
required_players = 15
required_enemies = 1
recommended_enemies = 3
secondary_enemies_scaling = 0.025
vampire_penalty = 0.4 // Cut out 40% of the vampires since we'll replace some with changelings
/// A list of all soon-to-be changelings
var/list/datum/mind/pre_changelings = list()
/datum/game_mode/vampire/changeling/pre_setup()
if(GLOB.configuration.gamemode.prevent_mindshield_antags)
@@ -19,10 +17,6 @@
var/list/datum/mind/possible_changelings = get_players_for_role(ROLE_CHANGELING)
secondary_enemies = CEILING((secondary_enemies_scaling * num_players()), 1)
for(var/mob/new_player/player in GLOB.player_list)
if((player.mind in possible_changelings) && (player.client.prefs.active_character.species in secondary_protected_species))
possible_changelings -= player.mind
if(!length(possible_changelings))
return ..()
@@ -30,8 +24,13 @@
if(length(pre_changelings) >= secondary_enemies)
break
var/datum/mind/changeling = pick_n_take(possible_changelings)
pre_changelings += changeling
changeling.restricted_roles = (restricted_jobs + secondary_restricted_jobs)
if(changeling.current?.client?.prefs.active_character.species in species_to_mindflayer)
pre_mindflayers += changeling
secondary_enemies -= 1 // Again, since we aren't increasing pre_changeling we'll just decrement what it's compared to.
changeling.special_role = SPECIAL_ROLE_MIND_FLAYER
continue
pre_changelings += changeling
changeling.special_role = SPECIAL_ROLE_CHANGELING
return ..()
@@ -3,16 +3,13 @@
config_tag = "vampire"
restricted_jobs = list("AI", "Cyborg")
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Blueshield", "Nanotrasen Representative", "Magistrate", "Chaplain", "Internal Affairs Agent", "Nanotrasen Navy Officer", "Special Operations Officer", "Syndicate Officer", "Trans-Solar Federation General")
protected_species = list("Machine")
species_to_mindflayer = list("Machine")
required_players = 15
required_enemies = 1
recommended_enemies = 4
/// If this gamemode should spawn less vampires than a usual vampire round, as a percentage of how many you want relative to the regular amount
var/vampire_penalty = 0
///list of minds of soon to be vampires
var/list/datum/mind/pre_vampires = list()
/datum/game_mode/vampire/announce()
to_chat(world, "<B>The current game mode is - Vampires!</B>")
to_chat(world, "<B>There are Bluespace Vampires infesting your fellow crewmates, keep your blood close and neck safe!</B>")
@@ -31,9 +28,13 @@
if(!length(possible_vampires))
break
var/datum/mind/vampire = pick_n_take(possible_vampires)
vampire.restricted_roles = (restricted_jobs + secondary_restricted_jobs)
if(vampire.current?.client?.prefs.active_character.species in species_to_mindflayer)
pre_mindflayers += vampire
vampire.special_role = SPECIAL_ROLE_MIND_FLAYER
continue
pre_vampires += vampire
vampire.special_role = SPECIAL_ROLE_VAMPIRE
vampire.restricted_roles = restricted_jobs
..()
return TRUE
@@ -13,7 +13,7 @@
#define RECRUITER_STATUS_GAMEOVER 3
/obj/machinery/computer/arcade/recruiter
name = "NT Recruiter Simulator"
name = "\improper NT Recruiter Simulator"
desc = "Weed out the good from bad employees and build the perfect manifest to work aboard the station."
icon_state = "arcade_recruiter"
icon_screen = "nanotrasen"
@@ -311,7 +311,7 @@
to_chat(user, "<span class='notice'>You override the menu and revert the game to its previous version.</span>")
add_hiddenprint(user)
game_status = RECRUITER_STATUS_START
name = "NT Recruiter Simulator HARDCORE EDITION"
name = "\improper NT Recruiter Simulator HARDCORE EDITION"
desc = "The advanced version of Nanotrasen's recruiting simulator, used to train the highest echelon of Nanotrasen recruiters. Has double the application count, and supposedly includes some routines to weed out the less skilled."
total_curriculums = 14
emagged = TRUE
+2
View File
@@ -60,6 +60,8 @@
/obj/structure/barricade/CanPass(atom/movable/mover, turf/target)//So bullets will fly over and stuff.
if(locate(/obj/structure/barricade) in get_turf(mover))
return TRUE
else if(istype(mover) && mover.checkpass(PASSBARRICADE))
return TRUE
else if(isprojectile(mover))
if(!anchored)
return TRUE
@@ -134,6 +134,35 @@
/datum/effect_system/smoke_spread/bad
effect_type = /obj/effect/particle_effect/smoke/bad
/// Steam smoke
/datum/effect_system/smoke_spread/steam
effect_type = /obj/effect/particle_effect/smoke/steam
/obj/effect/particle_effect/smoke/steam
color = COLOR_OFF_WHITE
lifetime = 10 SECONDS_TO_LIFE_CYCLES
causes_coughing = TRUE
/obj/effect/particle_effect/smoke/steam/Crossed(atom/movable/AM, oldloc)
. = ..()
if(!isliving(AM))
return
var/mob/living/crosser = AM
if(IS_MINDFLAYER(crosser))
return // Mindflayers are fully immune to steam
if(!ishuman(crosser))
crosser.adjustFireLoss(8)
return
var/mob/living/carbon/human/human_crosser = AM
var/fire_armour = human_crosser.get_thermal_protection()
if(fire_armour >= FIRE_SUIT_MAX_TEMP_PROTECT || HAS_TRAIT(human_crosser, TRAIT_RESISTHEAT))
return
crosser.adjustFireLoss(5)
if(prob(20))
to_chat(crosser, "<span class='warning'>You are being scalded by the hot steam!</span>")
/////////////////////////////////////////////
// Nanofrost smoke
/////////////////////////////////////////////
+10
View File
@@ -181,10 +181,15 @@
item_state = "hacktool"
var/hack_speed = 1.5 SECONDS
var/busy = FALSE
/// How far can we use this. Leave `null` for infinite range
var/range
/obj/item/door_remote/omni/access_tuner/afterattack(obj/machinery/door/D, mob/user)
if(!istype(D, /obj/machinery/door/airlock) && !istype(D, /obj/machinery/door/window))
return
if(!isnull(range) && get_dist(src, D) > range)
return
if(busy)
to_chat(user, "<span class='warning'>[src] is alreading interfacing with a door!</span>")
return
@@ -196,6 +201,11 @@
busy = FALSE
icon_state = "hacktool"
/obj/item/door_remote/omni/access_tuner/flayer
name = "integrated access tuner"
hack_speed = 5 SECONDS
range = 10
/// How long before you can "jangle" your keyring again (to prevent spam)
#define JANGLE_COOLDOWN 10 SECONDS
+28 -4
View File
@@ -42,7 +42,7 @@
/obj/item/camera_bug/ert
name = "ERT Camera Monitor"
name = "\improper ERT Camera Monitor"
desc = "A small handheld device used by ERT commanders to view camera feeds remotely."
/obj/item/camera_bug/ert/Initialize(mapload)
@@ -57,11 +57,16 @@
w_class = WEIGHT_CLASS_TINY
var/obj/machinery/camera/portable/camera_bug/camera
var/index = "REPORT THIS TO CODERS"
/// What name shows up on the camera bug list
var/camera_tag = "Hidden Camera"
/// If it sticks to whatever you throw at it
var/is_sticky = TRUE
/obj/item/wall_bug/Initialize(mapload, obj/item/camera_bug/the_bug)
. = ..()
link_to_camera(the_bug)
AddComponent(/datum/component/sticky)
if(is_sticky)
AddComponent(/datum/component/sticky)
ADD_TRAIT(src, TRAIT_NO_THROWN_MESSAGE, ROUNDSTART_TRAIT)
/obj/item/wall_bug/Destroy()
@@ -83,13 +88,32 @@
camera = new /obj/machinery/camera/portable/camera_bug(src)
camera.network = list("camera_bug[camera_bug.UID()]")
camera.c_tag = "Hidden Camera [index]"
camera.c_tag = "[camera_tag] [index]"
/// Created by a mindflayer ability
/obj/item/wall_bug/computer_bug
name = "nanobot"
desc = "A small droplet of a shimmering metallic slurry."
camera_tag = "Surveillance Unit"
is_sticky = FALSE
/// Reference to the creator's antag datum
var/datum/antagonist/mindflayer/flayer
COOLDOWN_DECLARE(alert_cooldown)
/obj/item/wall_bug/computer_bug/Destroy()
flayer = null
return ..()
/obj/item/wall_bug/computer_bug/link_to_camera(obj/item/camera_bug/camera_bug, datum/antagonist/mindflayer/flayer_datum)
..()
if(flayer_datum)
flayer = flayer_datum
/obj/machinery/camera/portable/camera_bug
non_chunking_camera = TRUE
/obj/item/paper/camera_bug
name = "Camera Bug Guide"
name = "\improper Camera Bug Guide"
icon_state = "paper"
info = {"<b>Instructions on your new invasive camera utility</b><br>
<br>
+5 -4
View File
@@ -241,12 +241,13 @@ SLIME SCANNER
msgs += "<span class='warning'>Subject appears to have [H.getCloneLoss() > 30 ? "severe" : "minor"] cellular damage.</span>"
// Brain.
if(H.get_int_organ(/obj/item/organ/internal/brain))
if(H.getBrainLoss() >= 100)
var/obj/item/organ/internal/brain = H.get_int_organ(/obj/item/organ/internal/brain)
if(brain)
if(H.check_brain_threshold(BRAIN_DAMAGE_RATIO_CRITICAL)) // 100
msgs += "<span class='warning'>Subject is brain dead.</span>"
else if(H.getBrainLoss() >= 60)
else if(H.check_brain_threshold(BRAIN_DAMAGE_RATIO_MODERATE)) // 60
msgs += "<span class='warning'>Severe brain damage detected. Subject likely to have dementia.</span>"
else if(H.getBrainLoss() >= 10)
else if(H.check_brain_threshold(BRAIN_DAMAGE_RATIO_MINOR)) // 10
msgs += "<span class='warning'>Significant brain damage detected. Subject may have had a concussion.</span>"
else
msgs += "<span class='warning'>Subject has no brain.</span>"
@@ -46,7 +46,7 @@
* Arguments:
* * I - item to load into the cannon
* * user - the person loading the item in
* Returns:
* * Returns:
* * True if item was loaded, false if it failed
*/
/obj/item/pneumatic_cannon/proc/load_item(obj/item/I, mob/user)
@@ -59,7 +59,6 @@
if(!user.unEquip(I) || I.flags & (ABSTRACT | NODROP | DROPDEL))
to_chat(user, "<span class='warning'>You can't put [I] into [src]!</span>")
return FALSE
to_chat(user, "<span class='notice'>You load [I] into [src].</span>")
loaded_items.Add(I)
loaded_weight_class += I.w_class
I.forceMove(src)
+12
View File
@@ -91,3 +91,15 @@
materials = list(MAT_PLASMA = MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS = MINERAL_MATERIAL_AMOUNT)
icon_prefix = "plasma"
welded_type = /obj/item/stack/sheet/plasmaglass
/obj/item/shard/scrap
name = "sharpened scrap"
desc = "Some discarded scrap metal. It has sharp, jagged edges."
icon_state = "scrap"
materials = list(MAT_METAL = MINERAL_MATERIAL_AMOUNT)
welded_type = /obj/item/stack/sheet/metal
force = 9
throwforce = 15 //owie
/obj/item/shard/scrap/set_initial_icon_state()
return
+82 -4
View File
@@ -20,7 +20,7 @@
var/turned_on = FALSE
/// How much power does it cost to stun someone
var/hitcost = 1000
var/obj/item/stock_parts/cell/high/cell = null
var/obj/item/stock_parts/cell/cell = null // Adminbus tip: make this something that isn't a cell :)
/// the initial cooldown tracks the time between swings. tracks the world.time when the baton is usable again.
var/cooldown = 3.5 SECONDS
/// the time it takes before the target falls over
@@ -50,11 +50,16 @@
/obj/item/melee/baton/proc/link_new_cell(unlink = FALSE)
if(unlink)
cell = null
else if(isrobot(loc.loc)) // First loc is the module
return
if(isrobot(loc?.loc)) // First loc is the module
var/mob/living/silicon/robot/R = loc.loc
cell = R.cell
return
if(!cell)
var/powercell = /obj/item/stock_parts/cell/high
cell = new powercell(src)
else
cell = new(src)
cell = new cell(src)
/obj/item/melee/baton/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is putting the live [name] in [user.p_their()] mouth! It looks like [user.p_theyre()] trying to commit suicide!</span>")
@@ -207,6 +212,10 @@
if(HAS_TRAIT_FROM(L, TRAIT_WAS_BATONNED, user_UID)) // prevents double baton cheese.
return FALSE
if(hitcost > 0 && cell?.charge < hitcost)
to_chat(user, "<span class='warning'>[src] fizzles weakly as it makes contact. It needs more power!</span>")
return FALSE
cooldown = world.time + initial(cooldown) // tracks the world.time when hitting will be next available.
if(ishuman(L))
var/mob/living/carbon/human/H = L
@@ -230,10 +239,13 @@
L.visible_message("<span class='danger'>[user] has stunned [L] with [src]!</span>",
"<span class='userdanger'>[L == user ? "You stun yourself" : "[user] has stunned you"] with [src]!</span>")
add_attack_logs(user, L, "stunned")
playsound(src, 'sound/weapons/egloves.ogg', 50, TRUE, -1)
play_hit_sound()
deductcharge(hitcost)
return TRUE
/obj/item/melee/baton/proc/play_hit_sound()
playsound(src, 'sound/weapons/egloves.ogg', 50, TRUE, -1)
/obj/item/melee/baton/proc/thrown_baton_stun(mob/living/carbon/human/L)
if(cooldown > world.time)
return FALSE
@@ -321,3 +333,69 @@
name = "electrically-charged arm"
desc = "A piece of scrap metal wired directly to your power cell."
hitcost = 100
/obj/item/melee/baton/flayerprod
name = "stunprod"
desc = "A mechanical mass which you can use to incapacitate someone with."
icon_state = "swarmprod"
base_icon = "swarmprod"
item_state = "swarmprod"
force = 10
throwforce = 0 // Just in case
knockdown_duration = 6 SECONDS
knockdown_delay = 0 SECONDS
w_class = WEIGHT_CLASS_BULKY
flags = ABSTRACT | NODROP
turned_on = TRUE
cell = /obj/item/stock_parts/cell/flayerprod
/// The duration that stunning someone will disable their radio for
var/radio_disable_time = 8 SECONDS
/obj/item/melee/baton/flayerprod/Initialize(mapload) // We are not making a flayerprod without a cell
link_new_cell()
return ..()
/obj/item/melee/baton/flayerprod/update_icon_state()
return
/obj/item/melee/baton/flayerprod/attackby(obj/item/I, mob/user, params)
return
/obj/item/melee/baton/flayerprod/screwdriver_act(mob/living/user, obj/item/I)
return
/obj/item/melee/baton/flayerprod/attack_self(mob/user)
return
/obj/item/melee/baton/flayerprod/play_hit_sound()
playsound(src, 'sound/weapons/egloves.ogg', 25, TRUE, -1, ignore_walls = FALSE)
/obj/item/melee/baton/flayerprod/baton_stun(mob/living/L, mob/user, skip_cooldown, ignore_shield_check = FALSE)
if(..())
disable_radio(L)
L.radio_enable_timer = addtimer(CALLBACK(src, PROC_REF(enable_radio), L), radio_disable_time, TIMER_UNIQUE | TIMER_OVERRIDE | TIMER_STOPPABLE | TIMER_DELETE_ME)
return TRUE
return FALSE
/obj/item/melee/baton/flayerprod/proc/disable_radio(mob/living/L)
var/list/all_items = L.GetAllContents()
for(var/obj/item/radio/R in all_items)
R.on = FALSE
R.listening = FALSE
R.broadcasting = FALSE
L.visible_message("<span class='warning'>[R] buzzes loudly as it short circuits!</span>", blind_message = "<span class='notice'>You hear a loud, electronic buzzing.</span>")
/obj/item/melee/baton/flayerprod/proc/enable_radio(mob/living/L)
var/list/all_items = L.GetAllContents()
for(var/obj/item/radio/R in all_items)
R.on = TRUE
R.listening = TRUE
/obj/item/melee/baton/flayerprod/deductcharge(amount)
if(cell.charge < hitcost)
return
cell.use(amount)
/obj/item/melee/baton/flayerprod/examine(mob/user)
. = ..()
. += "<span class='notice'>This one seems to be able to interfere with radio headsets.</span>"