mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-30 15:37:36 +01:00
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:
co-authored by
Luc
DGamerL
DGamerL
Burzah
Qwertytoforty
parent
c4521dc955
commit
036b8e0182
+1
-1
@@ -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)
|
||||
|
||||
@@ -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 ..()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
/////////////////////////////////////////////
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>"
|
||||
|
||||
Reference in New Issue
Block a user