mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-24 13:38:41 +01:00
[MIRROR] Remove all gamemodes except Dynamic (#5173)
* Remove all gamemodes except Dynamic * qaaaaaaaa Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com> Co-authored-by: Gandalf <jzo123@hotmail.com>
This commit is contained in:
co-authored by
Mothblocks
Gandalf
parent
9c68fa922a
commit
2ab15aecb5
@@ -61,10 +61,6 @@
|
||||
#define CONTRACT_UPLINK_PAGE_CONTRACTS "CONTRACTS"
|
||||
#define CONTRACT_UPLINK_PAGE_HUB "HUB"
|
||||
|
||||
///It is faster as a macro than a proc
|
||||
#define IS_HERETIC(mob) (mob.mind?.has_antag_datum(/datum/antagonist/heretic))
|
||||
#define IS_HERETIC_MONSTER(mob) (mob.mind?.has_antag_datum(/datum/antagonist/heretic_monster))
|
||||
|
||||
GLOBAL_LIST_INIT(heretic_start_knowledge,list(/datum/eldritch_knowledge/spell/basic,/datum/eldritch_knowledge/living_heart,/datum/eldritch_knowledge/codex_cicatrix))
|
||||
|
||||
|
||||
@@ -85,3 +81,28 @@ GLOBAL_LIST_INIT(heretic_start_knowledge,list(/datum/eldritch_knowledge/spell/ba
|
||||
/// TC to charge someone if they get a free implant through choice or
|
||||
/// because they have nothing else that supports an implant.
|
||||
#define UPLINK_IMPLANT_TELECRYSTAL_COST 4
|
||||
|
||||
/// Checks if the given mob is a blood cultist
|
||||
#define IS_CULTIST(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/cult))
|
||||
|
||||
/// Checks if the given mind is a leader of the monkey antagonists
|
||||
#define IS_MONKEY_LEADER(mind) mind?.has_antag_datum(/datum/antagonist/monkey/leader)
|
||||
|
||||
/// Checks if the given mind is a monkey antagonist
|
||||
#define IS_INFECTED_MONKEY(mind) mind?.has_antag_datum(/datum/antagonist/monkey)
|
||||
|
||||
/// Checks if the given mob is a nuclear operative
|
||||
#define IS_NUKE_OP(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/nukeop))
|
||||
|
||||
#define IS_HERETIC(mob) (mob.mind?.has_antag_datum(/datum/antagonist/heretic))
|
||||
|
||||
#define IS_HERETIC_MONSTER(mob) (mob.mind?.has_antag_datum(/datum/antagonist/heretic_monster))
|
||||
|
||||
/// Checks if the given mob is a wizard
|
||||
#define IS_WIZARD(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/wizard))
|
||||
|
||||
/// Checks if the given mob is a revolutionary. Will return TRUE for rev heads as well.
|
||||
#define IS_REVOLUTIONARY(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/rev))
|
||||
|
||||
/// Checks if the given mob is a head revolutionary.
|
||||
#define IS_HEAD_REVOLUTIONARY(mob) (mob?.mind?.has_antag_datum(/datum/antagonist/rev/head))
|
||||
|
||||
@@ -43,31 +43,31 @@
|
||||
#define ROLE_SYNDICATE_CYBERSUN "Cybersun Space Syndicate" //Ghost role syndi from Forgottenship ruin
|
||||
#define ROLE_SYNDICATE_CYBERSUN_CAPTAIN "Cybersun Space Syndicate Captain" //Forgottenship captain syndie
|
||||
|
||||
//Missing assignment means it's not a gamemode specific role, IT'S NOT A BUG OR ERROR.
|
||||
//The gamemode specific ones are just so the gamemodes can query whether a player is old enough
|
||||
//(in game days played) to play that role
|
||||
/// This defines the antagonists you can operate with in the settings.
|
||||
/// Keys are the antagonist, values are the number of days since the player's
|
||||
/// first connection in order to play.
|
||||
GLOBAL_LIST_INIT(special_roles, list(
|
||||
ROLE_TRAITOR = /datum/game_mode/traitor,
|
||||
ROLE_BROTHER = /datum/game_mode/traitor/bros,
|
||||
ROLE_OPERATIVE = /datum/game_mode/nuclear,
|
||||
ROLE_CHANGELING = /datum/game_mode/changeling,
|
||||
ROLE_WIZARD = /datum/game_mode/wizard,
|
||||
ROLE_MALF,
|
||||
ROLE_REV = /datum/game_mode/revolution,
|
||||
ROLE_ALIEN,
|
||||
ROLE_PAI,
|
||||
ROLE_CULTIST = /datum/game_mode/cult,
|
||||
ROLE_BLOB,
|
||||
ROLE_NINJA,
|
||||
ROLE_OBSESSED,
|
||||
ROLE_SPACE_DRAGON,
|
||||
ROLE_MONKEY = /datum/game_mode/monkey,
|
||||
ROLE_REVENANT,
|
||||
ROLE_ABDUCTOR,
|
||||
ROLE_INTERNAL_AFFAIRS = /datum/game_mode/traitor/internal_affairs,
|
||||
ROLE_SENTIENCE,
|
||||
ROLE_FAMILIES = /datum/game_mode/gang,
|
||||
ROLE_HERETIC = /datum/game_mode/heretics
|
||||
ROLE_TRAITOR = 0,
|
||||
ROLE_BROTHER = 0,
|
||||
ROLE_OPERATIVE = 14,
|
||||
ROLE_CHANGELING = 0,
|
||||
ROLE_WIZARD = 14,
|
||||
ROLE_MALF = 0,
|
||||
ROLE_REV = 14,
|
||||
ROLE_ALIEN = 0,
|
||||
ROLE_PAI = 0,
|
||||
ROLE_CULTIST = 14,
|
||||
ROLE_BLOB = 0,
|
||||
ROLE_NINJA = 0,
|
||||
ROLE_OBSESSED = 0,
|
||||
ROLE_SPACE_DRAGON = 0,
|
||||
ROLE_MONKEY = 0,
|
||||
ROLE_REVENANT = 0,
|
||||
ROLE_ABDUCTOR = 0,
|
||||
ROLE_INTERNAL_AFFAIRS = 0,
|
||||
ROLE_SENTIENCE = 0,
|
||||
ROLE_FAMILIES = 0,
|
||||
ROLE_HERETIC = 0,
|
||||
))
|
||||
|
||||
//Job defines for what happens when you fail to qualify for any job during job selection
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
// These are used in uplink_devices.dm to determine whether or not an item is purchasable.
|
||||
|
||||
/// This item is purchasable to traitors
|
||||
#define UPLINK_TRAITORS (1 << 0)
|
||||
|
||||
/// This item is purchasable to nuke ops
|
||||
#define UPLINK_NUKE_OPS (1 << 1)
|
||||
|
||||
/// This item is purchasable to clown ops
|
||||
#define UPLINK_CLOWN_OPS (1 << 2)
|
||||
+10
-9
@@ -410,7 +410,7 @@
|
||||
else
|
||||
candidates -= M
|
||||
|
||||
/proc/pollGhostCandidates(Question, jobbanType, datum/game_mode/gametypeCheck, be_special_flag = 0, poll_time = 300, ignore_category = null, flashwindow = TRUE)
|
||||
/proc/pollGhostCandidates(Question, jobbanType, be_special_flag = 0, poll_time = 300, ignore_category = null, flashwindow = TRUE)
|
||||
var/list/candidates = list()
|
||||
if(!(GLOB.ghost_role_flags & GHOSTROLE_STATION_SENTIENCE))
|
||||
return candidates
|
||||
@@ -418,9 +418,9 @@
|
||||
for(var/mob/dead/observer/G in GLOB.player_list)
|
||||
candidates += G
|
||||
|
||||
return pollCandidates(Question, jobbanType, gametypeCheck, be_special_flag, poll_time, ignore_category, flashwindow, candidates)
|
||||
return pollCandidates(Question, jobbanType, be_special_flag, poll_time, ignore_category, flashwindow, candidates)
|
||||
|
||||
/proc/pollCandidates(Question, jobbanType, datum/game_mode/gametypeCheck, be_special_flag = 0, poll_time = 300, ignore_category = null, flashwindow = TRUE, list/group = null)
|
||||
/proc/pollCandidates(Question, jobbanType, be_special_flag = 0, poll_time = 300, ignore_category = null, flashwindow = TRUE, list/group = null)
|
||||
var/time_passed = world.time
|
||||
if (!Question)
|
||||
Question = "Would you like to be a special role?"
|
||||
@@ -432,8 +432,9 @@
|
||||
if(be_special_flag)
|
||||
if(!(M.client.prefs) || !(be_special_flag in M.client.prefs.be_special))
|
||||
continue
|
||||
if(gametypeCheck)
|
||||
if(!gametypeCheck.age_check(M.client))
|
||||
|
||||
var/required_time = GLOB.special_roles[be_special_flag] || 0
|
||||
if (M.client && M.client.get_remaining_days(required_time) > 0)
|
||||
continue
|
||||
if(jobbanType)
|
||||
if(is_banned_from(M.ckey, list(jobbanType, ROLE_SYNDICATE)) || QDELETED(M))
|
||||
@@ -451,14 +452,14 @@
|
||||
|
||||
return result
|
||||
|
||||
/proc/pollCandidatesForMob(Question, jobbanType, datum/game_mode/gametypeCheck, be_special_flag = 0, poll_time = 300, mob/M, ignore_category = null)
|
||||
var/list/L = pollGhostCandidates(Question, jobbanType, gametypeCheck, be_special_flag, poll_time, ignore_category)
|
||||
/proc/pollCandidatesForMob(Question, jobbanType, be_special_flag = 0, poll_time = 300, mob/M, ignore_category = null)
|
||||
var/list/L = pollGhostCandidates(Question, jobbanType, be_special_flag, poll_time, ignore_category)
|
||||
if(!M || QDELETED(M) || !M.loc)
|
||||
return list()
|
||||
return L
|
||||
|
||||
/proc/pollCandidatesForMobs(Question, jobbanType, datum/game_mode/gametypeCheck, be_special_flag = 0, poll_time = 300, list/mobs, ignore_category = null)
|
||||
var/list/L = pollGhostCandidates(Question, jobbanType, gametypeCheck, be_special_flag, poll_time, ignore_category)
|
||||
/proc/pollCandidatesForMobs(Question, jobbanType, be_special_flag = 0, poll_time = 300, list/mobs, ignore_category = null)
|
||||
var/list/L = pollGhostCandidates(Question, jobbanType, be_special_flag, poll_time, ignore_category)
|
||||
var/i=1
|
||||
for(var/v in mobs)
|
||||
var/atom/A = v
|
||||
|
||||
@@ -349,7 +349,7 @@ Example config:
|
||||
var/ct = initial(M.config_tag)
|
||||
if(ct && ct == mode_name)
|
||||
return new T
|
||||
return new /datum/game_mode/extended()
|
||||
return new /datum/game_mode/dynamic
|
||||
|
||||
/datum/controller/configuration/proc/get_runnable_modes()
|
||||
var/list/datum/game_mode/runnable_modes = new
|
||||
|
||||
@@ -108,8 +108,6 @@
|
||||
|
||||
/datum/config_entry/flag/allow_vote_restart // allow votes to restart
|
||||
|
||||
/datum/config_entry/flag/allow_vote_mode // allow votes to change mode
|
||||
|
||||
/datum/config_entry/flag/allow_vote_map // allow votes to change map
|
||||
|
||||
/datum/config_entry/number/vote_delay // minimum time between voting sessions (deciseconds, 10 minute default)
|
||||
|
||||
@@ -695,11 +695,6 @@ SUBSYSTEM_DEF(ticker)
|
||||
GLOB.master_mode = "extended"
|
||||
log_game("Saved mode is '[GLOB.master_mode]'")
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/save_mode(the_mode)
|
||||
var/F = file("data/mode.txt")
|
||||
fdel(F)
|
||||
WRITE_FILE(F, the_mode)
|
||||
|
||||
/// Returns if either the master mode or the forced secret ruleset matches the mode name.
|
||||
/datum/controller/subsystem/ticker/proc/is_mode(mode_name)
|
||||
return GLOB.master_mode == mode_name || GLOB.secret_force_mode == mode_name
|
||||
|
||||
@@ -61,11 +61,6 @@ SUBSYSTEM_DEF(vote)
|
||||
choices["Continue Playing"] += non_voters.len
|
||||
if(choices["Continue Playing"] >= greatest_votes)
|
||||
greatest_votes = choices["Continue Playing"]
|
||||
else if(mode == "gamemode")
|
||||
if(GLOB.master_mode in choices)
|
||||
choices[GLOB.master_mode] += non_voters.len
|
||||
if(choices[GLOB.master_mode] >= greatest_votes)
|
||||
greatest_votes = choices[GLOB.master_mode]
|
||||
else if(mode == "map")
|
||||
for (var/non_voter_ckey in non_voters)
|
||||
var/client/C = non_voters[non_voter_ckey]
|
||||
@@ -120,13 +115,6 @@ SUBSYSTEM_DEF(vote)
|
||||
if("restart")
|
||||
if(. == "Restart Round")
|
||||
restart = TRUE
|
||||
if("gamemode")
|
||||
if(GLOB.master_mode != .)
|
||||
SSticker.save_mode(.)
|
||||
if(SSticker.HasRoundStarted())
|
||||
restart = TRUE
|
||||
else
|
||||
GLOB.master_mode = .
|
||||
if("map")
|
||||
SSmapping.changemap(global.config.maplist[.])
|
||||
SSmapping.map_voted = TRUE
|
||||
@@ -199,8 +187,6 @@ SUBSYSTEM_DEF(vote)
|
||||
switch(vote_type)
|
||||
if("restart")
|
||||
choices.Add("Restart Round","Continue Playing")
|
||||
if("gamemode")
|
||||
choices.Add(config.votable_modes)
|
||||
if("map")
|
||||
if(!lower_admin && SSmapping.map_voted)
|
||||
to_chat(usr, "<span class='warning'>The next map has already been selected.</span>")
|
||||
@@ -291,7 +277,6 @@ SUBSYSTEM_DEF(vote)
|
||||
/datum/controller/subsystem/vote/ui_data(mob/user)
|
||||
var/list/data = list(
|
||||
"allow_vote_map" = CONFIG_GET(flag/allow_vote_map),
|
||||
"allow_vote_mode" = CONFIG_GET(flag/allow_vote_mode),
|
||||
"allow_vote_restart" = CONFIG_GET(flag/allow_vote_restart),
|
||||
"choices" = list(),
|
||||
"lower_admin" = !!user.client?.holder,
|
||||
@@ -333,18 +318,12 @@ SUBSYSTEM_DEF(vote)
|
||||
if("toggle_restart")
|
||||
if(usr.client.holder && upper_admin)
|
||||
CONFIG_SET(flag/allow_vote_restart, !CONFIG_GET(flag/allow_vote_restart))
|
||||
if("toggle_gamemode")
|
||||
if(usr.client.holder && upper_admin)
|
||||
CONFIG_SET(flag/allow_vote_mode, !CONFIG_GET(flag/allow_vote_mode))
|
||||
if("toggle_map")
|
||||
if(usr.client.holder && upper_admin)
|
||||
CONFIG_SET(flag/allow_vote_map, !CONFIG_GET(flag/allow_vote_map))
|
||||
if("restart")
|
||||
if(CONFIG_GET(flag/allow_vote_restart) || usr.client.holder)
|
||||
initiate_vote("restart",usr.key)
|
||||
if("gamemode")
|
||||
if(CONFIG_GET(flag/allow_vote_mode) || usr.client.holder)
|
||||
initiate_vote("gamemode",usr.key)
|
||||
if("map")
|
||||
if(CONFIG_GET(flag/allow_vote_map) || usr.client.holder)
|
||||
initiate_vote("map",usr.key)
|
||||
|
||||
@@ -481,7 +481,7 @@
|
||||
background_icon_state = "bg_demon"
|
||||
|
||||
/datum/action/item_action/cult_dagger/Grant(mob/M)
|
||||
if(iscultist(M))
|
||||
if(IS_CULTIST(M))
|
||||
..()
|
||||
button.screen_loc = "6:157,4:-2"
|
||||
button.moved = "6:157,4:-2"
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
/datum/brain_trauma/special/imaginary_friend/proc/get_ghost()
|
||||
set waitfor = FALSE
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner.real_name]'s imaginary friend?", ROLE_PAI, null, null, 75, friend, POLL_IGNORE_IMAGINARYFRIEND)
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner.real_name]'s imaginary friend?", ROLE_PAI, null, 75, friend, POLL_IGNORE_IMAGINARYFRIEND)
|
||||
if(LAZYLEN(candidates))
|
||||
var/mob/dead/observer/C = pick(candidates)
|
||||
friend.key = C.key
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
/datum/brain_trauma/severe/split_personality/proc/get_ghost()
|
||||
set waitfor = FALSE
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner.real_name]'s split personality?", ROLE_PAI, null, null, 75, stranger_backseat, POLL_IGNORE_SPLITPERSONALITY)
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner.real_name]'s split personality?", ROLE_PAI, null, 75, stranger_backseat, POLL_IGNORE_SPLITPERSONALITY)
|
||||
if(LAZYLEN(candidates))
|
||||
var/mob/dead/observer/C = pick(candidates)
|
||||
stranger_backseat.key = C.key
|
||||
@@ -196,7 +196,7 @@
|
||||
|
||||
/datum/brain_trauma/severe/split_personality/brainwashing/get_ghost()
|
||||
set waitfor = FALSE
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner.real_name]'s brainwashed mind?", null, null, null, 75, stranger_backseat)
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [owner.real_name]'s brainwashed mind?", null, null, 75, stranger_backseat)
|
||||
if(LAZYLEN(candidates))
|
||||
var/mob/dead/observer/C = pick(candidates)
|
||||
stranger_backseat.key = C.key
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
target.apply_status_effect(STATUS_EFFECT_HELDUP, shooter)
|
||||
|
||||
if(istype(weapon, /obj/item/gun/ballistic/rocketlauncher) && weapon.chambered)
|
||||
if(target.stat == CONSCIOUS && is_nuclear_operative(shooter) && !is_nuclear_operative(target) && (locate(/obj/item/disk/nuclear) in target.get_contents()) && shooter.client)
|
||||
if(target.stat == CONSCIOUS && IS_NUKE_OP(shooter) && !IS_NUKE_OP(target) && (locate(/obj/item/disk/nuclear) in target.get_contents()) && shooter.client)
|
||||
shooter.client.give_award(/datum/award/achievement/misc/rocket_holdup, shooter)
|
||||
|
||||
target.do_alert_animation()
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
var/telecrystals
|
||||
var/selected_cat
|
||||
var/owner = null
|
||||
var/datum/game_mode/gamemode
|
||||
var/uplink_flag
|
||||
var/datum/uplink_purchase_log/purchase_log
|
||||
var/list/uplink_items
|
||||
var/hidden_crystals = 0
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
var/list/previous_attempts
|
||||
|
||||
/datum/component/uplink/Initialize(_owner, _lockable = TRUE, _enabled = FALSE, datum/game_mode/_gamemode, starting_tc = TELECRYSTALS_DEFAULT)
|
||||
/datum/component/uplink/Initialize(_owner, _lockable = TRUE, _enabled = FALSE, uplink_flag = UPLINK_TRAITORS, starting_tc = TELECRYSTALS_DEFAULT)
|
||||
if(!isitem(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
@@ -49,8 +49,6 @@
|
||||
else if(istype(parent, /obj/item/pen))
|
||||
RegisterSignal(parent, COMSIG_PEN_ROTATED, .proc/pen_rotation)
|
||||
|
||||
update_items()
|
||||
|
||||
if(_owner)
|
||||
owner = _owner
|
||||
LAZYINITLIST(GLOB.uplink_purchase_logs_by_key)
|
||||
@@ -60,7 +58,8 @@
|
||||
purchase_log = new(owner, src)
|
||||
lockable = _lockable
|
||||
active = _enabled
|
||||
gamemode = _gamemode
|
||||
src.uplink_flag = uplink_flag
|
||||
update_items()
|
||||
telecrystals = starting_tc
|
||||
if(!lockable)
|
||||
active = TRUE
|
||||
@@ -71,20 +70,18 @@
|
||||
/datum/component/uplink/InheritComponent(datum/component/uplink/U)
|
||||
lockable |= U.lockable
|
||||
active |= U.active
|
||||
if(!gamemode)
|
||||
gamemode = U.gamemode
|
||||
uplink_flag |= U.uplink_flag
|
||||
telecrystals += U.telecrystals
|
||||
if(purchase_log && U.purchase_log)
|
||||
purchase_log.MergeWithAndDel(U.purchase_log)
|
||||
|
||||
/datum/component/uplink/Destroy()
|
||||
gamemode = null
|
||||
purchase_log = null
|
||||
return ..()
|
||||
|
||||
/datum/component/uplink/proc/update_items()
|
||||
var/updated_items
|
||||
updated_items = get_uplink_items(gamemode, TRUE, allow_restricted)
|
||||
updated_items = get_uplink_items(uplink_flag, TRUE, allow_restricted)
|
||||
update_sales(updated_items)
|
||||
uplink_items = updated_items
|
||||
|
||||
@@ -104,10 +101,6 @@
|
||||
TC.use(amt)
|
||||
log_uplink("[key_name(user)] loaded [amt] telecrystals into [parent]'s uplink")
|
||||
|
||||
/datum/component/uplink/proc/set_gamemode(_gamemode)
|
||||
gamemode = _gamemode
|
||||
update_items()
|
||||
|
||||
/datum/component/uplink/proc/OnAttackBy(datum/source, obj/item/I, mob/user)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
/datum/disease/transformation/proc/replace_banned_player(mob/living/new_mob) // This can run well after the mob has been transferred, so need a handle on the new mob to kill it if needed.
|
||||
set waitfor = FALSE
|
||||
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [affected_mob.real_name]?", bantype, null, bantype, 50, affected_mob)
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [affected_mob.real_name]?", bantype, bantype, 50, affected_mob)
|
||||
if(LAZYLEN(candidates))
|
||||
var/mob/dead/observer/C = pick(candidates)
|
||||
to_chat(affected_mob, "<span class='userdanger'>Your mob has been taken over by a ghost! Appeal your job ban if you want to avoid this in the future!</span>")
|
||||
@@ -124,8 +124,8 @@
|
||||
stage5 = list("<span class='warning'>You feel like monkeying around.</span>")
|
||||
|
||||
/datum/disease/transformation/jungle_fever/do_disease_transformation(mob/living/carbon/affected_mob)
|
||||
if(affected_mob.mind && !is_monkey(affected_mob.mind))
|
||||
add_monkey(affected_mob.mind)
|
||||
if(affected_mob.mind && !IS_INFECTED_MONKEY(affected_mob.mind))
|
||||
affected_mob.mind.add_antag_datum(/datum/antagonist/monkey)
|
||||
affected_mob.monkeyize()
|
||||
ADD_TRAIT(affected_mob, TRAIT_VENTCRAWLER_ALWAYS, type)
|
||||
|
||||
@@ -149,7 +149,7 @@
|
||||
|
||||
|
||||
/datum/disease/transformation/jungle_fever/cure()
|
||||
remove_monkey(affected_mob.mind)
|
||||
affected_mob.mind.remove_antag_datum(/datum/antagonist/monkey)
|
||||
..()
|
||||
|
||||
/datum/disease/transformation/jungle_fever/monkeymode
|
||||
@@ -157,7 +157,7 @@
|
||||
disease_flags = CAN_CARRY //no vaccines! no cure!
|
||||
|
||||
/datum/disease/transformation/jungle_fever/monkeymode/after_add()
|
||||
if(affected_mob && !is_monkey_leader(affected_mob.mind))
|
||||
if(affected_mob && !IS_MONKEY_LEADER(affected_mob.mind))
|
||||
visibility_flags = NONE
|
||||
|
||||
|
||||
|
||||
+4
-30
@@ -325,10 +325,6 @@
|
||||
/datum/mind/proc/remove_traitor()
|
||||
remove_antag_datum(/datum/antagonist/traitor)
|
||||
|
||||
/datum/mind/proc/remove_brother()
|
||||
if(src in SSticker.mode.brothers)
|
||||
remove_antag_datum(/datum/antagonist/brother)
|
||||
|
||||
/datum/mind/proc/remove_nukeop()
|
||||
var/datum/antagonist/nukeop/nuke = has_antag_datum(/datum/antagonist/nukeop,TRUE)
|
||||
if(nuke)
|
||||
@@ -339,12 +335,6 @@
|
||||
remove_antag_datum(/datum/antagonist/wizard)
|
||||
special_role = null
|
||||
|
||||
/datum/mind/proc/remove_cultist()
|
||||
if(src in SSticker.mode.cult)
|
||||
SSticker.mode.remove_cultist(src, 0, 0)
|
||||
special_role = null
|
||||
remove_antag_equip()
|
||||
|
||||
/datum/mind/proc/remove_rev()
|
||||
var/datum/antagonist/rev/rev = has_antag_datum(/datum/antagonist/rev)
|
||||
if(rev)
|
||||
@@ -359,14 +349,6 @@
|
||||
if(O)
|
||||
O.unlock_code = null
|
||||
|
||||
/datum/mind/proc/remove_all_antag() //For the Lazy amongst us.
|
||||
remove_changeling()
|
||||
remove_traitor()
|
||||
remove_nukeop()
|
||||
remove_wizard()
|
||||
remove_cultist()
|
||||
remove_rev()
|
||||
|
||||
/datum/mind/proc/equip_traitor(employer = "The Syndicate", silent = FALSE, datum/antagonist/uplink_owner)
|
||||
if(!current)
|
||||
return
|
||||
@@ -443,14 +425,14 @@
|
||||
//Link a new mobs mind to the creator of said mob. They will join any team they are currently on, and will only switch teams when their creator does.
|
||||
|
||||
/datum/mind/proc/enslave_mind_to_creator(mob/living/creator)
|
||||
if(iscultist(creator))
|
||||
SSticker.mode.add_cultist(src)
|
||||
if(IS_CULTIST(creator))
|
||||
add_antag_datum(/datum/antagonist/cult)
|
||||
|
||||
else if(is_revolutionary(creator))
|
||||
else if(IS_REVOLUTIONARY(creator))
|
||||
var/datum/antagonist/rev/converter = creator.mind.has_antag_datum(/datum/antagonist/rev,TRUE)
|
||||
converter.add_revolutionary(src,FALSE)
|
||||
|
||||
else if(is_nuclear_operative(creator))
|
||||
else if(IS_NUKE_OP(creator))
|
||||
var/datum/antagonist/nukeop/converter = creator.mind.has_antag_datum(/datum/antagonist/nukeop,TRUE)
|
||||
var/datum/antagonist/nukeop/N = new()
|
||||
N.send_to_spawnpoint = FALSE
|
||||
@@ -724,14 +706,6 @@
|
||||
assigned_role = ROLE_WIZARD
|
||||
add_antag_datum(/datum/antagonist/wizard)
|
||||
|
||||
|
||||
/datum/mind/proc/make_Cultist()
|
||||
if(!has_antag_datum(/datum/antagonist/cult,TRUE))
|
||||
SSticker.mode.add_cultist(src,FALSE,equip=TRUE)
|
||||
special_role = ROLE_CULTIST
|
||||
to_chat(current, "<font color=\"purple\"><b><i>You catch a glimpse of the Realm of Nar'Sie, The Geometer of Blood. You now see how flimsy your world is, you see that it should be open to the knowledge of Nar'Sie.</b></i></font>")
|
||||
to_chat(current, "<font color=\"purple\"><b><i>Assist your new brethren in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back.</b></i></font>")
|
||||
|
||||
/datum/mind/proc/make_Rev()
|
||||
var/datum/antagonist/rev/head/head = new()
|
||||
head.give_flash = TRUE
|
||||
|
||||
@@ -68,20 +68,20 @@
|
||||
mode = MODE_MONKEY
|
||||
|
||||
/datum/saymode/monkey/handle_message(mob/living/user, message, datum/language/language)
|
||||
var/datum/mind = user.mind
|
||||
var/datum/mind/mind = user.mind
|
||||
if(!mind)
|
||||
return TRUE
|
||||
if(is_monkey_leader(mind) || (ismonkey(user) && is_monkey(mind)))
|
||||
if(IS_MONKEY_LEADER(mind) || (ismonkey(user) && IS_INFECTED_MONKEY(mind)))
|
||||
user.log_talk(message, LOG_SAY, tag="monkey")
|
||||
if(prob(75) && ismonkey(user))
|
||||
user.visible_message("<span class='notice'>\The [user] chimpers.</span>")
|
||||
var/msg = "<span class='[is_monkey_leader(mind) ? "monkeylead" : "monkeyhive"]'><b><font size=2>\[[is_monkey_leader(mind) ? "Monkey Leader" : "Monkey"]\]</font> [user]</b>: [message]</span>"
|
||||
var/msg = "<span class='[IS_MONKEY_LEADER(mind) ? "monkeylead" : "monkeyhive"]'><b><font size=2>\[[IS_MONKEY_LEADER(mind) ? "Monkey Leader" : "Monkey"]\]</font> [user]</b>: [message]</span>"
|
||||
for(var/_M in GLOB.mob_list)
|
||||
var/mob/M = _M
|
||||
if(M in GLOB.dead_mob_list)
|
||||
var/link = FOLLOW_LINK(M, user)
|
||||
to_chat(M, "[link] [msg]")
|
||||
if((is_monkey_leader(M.mind) || ismonkey(M)) && (M.mind in SSticker.mode.ape_infectees))
|
||||
if((IS_MONKEY_LEADER(M.mind) || ismonkey(M)) && IS_INFECTED_MONKEY(M.mind))
|
||||
to_chat(M, msg)
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
if(!QDELETED(GLOB.cult_narsie))
|
||||
return //if Nar'Sie is alive, don't even worry about it
|
||||
var/area/A = get_area(owner)
|
||||
for(var/datum/mind/B in SSticker.mode.cult)
|
||||
for(var/datum/mind/B as anything in get_antag_minds(/datum/antagonist/cult))
|
||||
if(isliving(B.current))
|
||||
var/mob/living/M = B.current
|
||||
SEND_SOUND(M, sound('sound/hallucinations/veryfar_noise.ogg'))
|
||||
|
||||
@@ -32,7 +32,7 @@ GLOBAL_LIST_INIT(voice_of_god_commands, init_voice_of_god_commands())
|
||||
*/
|
||||
/proc/voice_of_god(message, mob/living/user, list/span_list, base_multiplier = 1, include_speaker = FALSE, message_admins = TRUE)
|
||||
var/log_message = uppertext(message)
|
||||
var/is_cultie = iscultist(user)
|
||||
var/is_cultie = IS_CULTIST(user)
|
||||
if(LAZYLEN(span_list))
|
||||
if(is_cultie)
|
||||
span_list = list("narsiesmall")
|
||||
|
||||
@@ -144,7 +144,6 @@
|
||||
.["mode"] = GLOB.master_mode
|
||||
.["respawn"] = config ? !CONFIG_GET(flag/norespawn) : FALSE
|
||||
.["enter"] = GLOB.enter_allowed
|
||||
.["vote"] = CONFIG_GET(flag/allow_vote_mode)
|
||||
.["ai"] = CONFIG_GET(flag/allow_ai)
|
||||
.["host"] = world.host ? world.host : null
|
||||
.["round_id"] = GLOB.round_id
|
||||
|
||||
@@ -140,7 +140,7 @@ GLOBAL_LIST_EMPTY(active_alternate_appearances)
|
||||
add_hud_to(mob)
|
||||
|
||||
/datum/atom_hud/alternate_appearance/basic/noncult/mobShouldSee(mob/M)
|
||||
if(!iscultist(M))
|
||||
if(!IS_CULTIST(M))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -153,7 +153,7 @@ GLOBAL_LIST_EMPTY(active_alternate_appearances)
|
||||
add_hud_to(mob)
|
||||
|
||||
/datum/atom_hud/alternate_appearance/basic/cult/mobShouldSee(mob/M)
|
||||
if(iscultist(M))
|
||||
if(IS_CULTIST(M))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -170,7 +170,7 @@ GLOBAL_LIST_EMPTY(active_alternate_appearances)
|
||||
return TRUE
|
||||
if (istype(M, /mob/living/simple_animal/hostile/construct/wraith))
|
||||
return TRUE
|
||||
if(isrevenant(M) || iswizard(M))
|
||||
if(isrevenant(M) || IS_WIZARD(M))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
/datum/game_mode
|
||||
var/list/datum/mind/brothers = list()
|
||||
var/list/datum/team/brother_team/brother_teams = list()
|
||||
|
||||
/datum/game_mode/traitor/bros
|
||||
name = "traitor+brothers"
|
||||
config_tag = "traitorbro"
|
||||
restricted_jobs = list("Prisoner","AI", "Cyborg")
|
||||
|
||||
announce_span = "danger"
|
||||
announce_text = "There are Syndicate agents and Blood Brothers on the station!\n\
|
||||
<span class='danger'>Traitors</span>: Accomplish your objectives.\n\
|
||||
<span class='danger'>Blood Brothers</span>: Accomplish your objectives.\n\
|
||||
<span class='notice'>Crew</span>: Do not let the traitors or brothers succeed!"
|
||||
|
||||
var/list/datum/team/brother_team/pre_brother_teams = list()
|
||||
var/const/team_amount = 2 //hard limit on brother teams if scaling is turned off
|
||||
var/const/min_team_size = 2
|
||||
traitors_required = FALSE //Only teams are possible
|
||||
|
||||
/datum/game_mode/traitor/bros/pre_setup()
|
||||
if(CONFIG_GET(flag/protect_roles_from_antagonist))
|
||||
restricted_jobs += protected_jobs
|
||||
if(CONFIG_GET(flag/protect_assistant_from_antagonist))
|
||||
restricted_jobs += "Assistant"
|
||||
|
||||
var/list/datum/mind/possible_brothers = get_players_for_role(ROLE_BROTHER)
|
||||
|
||||
var/num_teams = team_amount
|
||||
var/bsc = CONFIG_GET(number/brother_scaling_coeff)
|
||||
if(bsc)
|
||||
num_teams = max(1, round(num_players() / bsc))
|
||||
|
||||
for(var/j = 1 to num_teams)
|
||||
if(possible_brothers.len < min_team_size || antag_candidates.len <= required_enemies)
|
||||
break
|
||||
var/datum/team/brother_team/team = new
|
||||
var/team_size = prob(10) ? min(3, possible_brothers.len) : 2
|
||||
for(var/k = 1 to team_size)
|
||||
var/datum/mind/bro = antag_pick(possible_brothers)
|
||||
possible_brothers -= bro
|
||||
antag_candidates -= bro
|
||||
team.add_member(bro)
|
||||
bro.special_role = "brother"
|
||||
bro.restricted_roles = restricted_jobs
|
||||
log_game("[key_name(bro)] has been selected as a Brother")
|
||||
pre_brother_teams += team
|
||||
. = ..()
|
||||
if(.) //To ensure the game mode is going ahead
|
||||
for(var/teams in pre_brother_teams)
|
||||
for(var/antag in teams)
|
||||
GLOB.pre_setup_antags += antag
|
||||
return
|
||||
|
||||
/datum/game_mode/traitor/bros/post_setup()
|
||||
for(var/datum/team/brother_team/team in pre_brother_teams)
|
||||
team.pick_meeting_area()
|
||||
team.forge_brother_objectives()
|
||||
for(var/datum/mind/M in team.members)
|
||||
M.add_antag_datum(/datum/antagonist/brother, team)
|
||||
GLOB.pre_setup_antags -= M
|
||||
team.update_name()
|
||||
brother_teams += pre_brother_teams
|
||||
return ..()
|
||||
|
||||
/datum/game_mode/traitor/bros/generate_report()
|
||||
return "It's Syndicate recruiting season. Be alert for potential Syndicate infiltrators, but also watch out for disgruntled employees trying to defect. Unlike Nanotrasen, the Syndicate prides itself in teamwork and will only recruit pairs that share a brotherly trust."
|
||||
@@ -403,7 +403,8 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
|
||||
var/mob/dead/new_player/player = i
|
||||
if(player.ready == PLAYER_READY_TO_PLAY && player.mind)
|
||||
roundstart_pop_ready++
|
||||
candidates.Add(player)
|
||||
if(player.client.prefs.be_antag) //SKYRAT EDIT CHANGE
|
||||
candidates.Add(player)
|
||||
log_game("DYNAMIC: Listing [roundstart_rules.len] round start rulesets, and [candidates.len] players ready.")
|
||||
if (candidates.len <= 0)
|
||||
log_game("DYNAMIC: [candidates.len] candidates.")
|
||||
@@ -686,15 +687,6 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/// Checks if client age is age or older.
|
||||
/datum/game_mode/dynamic/proc/check_age(client/C, age)
|
||||
enemy_minimum_age = age
|
||||
if(get_remaining_days(C) == 0)
|
||||
enemy_minimum_age = initial(enemy_minimum_age)
|
||||
return TRUE // Available in 0 days = available right now = player is old enough to play.
|
||||
enemy_minimum_age = initial(enemy_minimum_age)
|
||||
return FALSE
|
||||
|
||||
/datum/game_mode/dynamic/make_antag_chance(mob/living/carbon/human/newPlayer)
|
||||
if (GLOB.dynamic_forced_extended)
|
||||
return
|
||||
|
||||
@@ -194,7 +194,7 @@
|
||||
var/client/client = GET_CLIENT(P)
|
||||
if (!client || !P.mind) // Are they connected?
|
||||
candidates.Remove(P)
|
||||
else if(!mode.check_age(client, minimum_required_age))
|
||||
else if(client.get_remaining_days(minimum_required_age) > 0)
|
||||
candidates.Remove(P)
|
||||
else if(P.mind.special_role) // We really don't want to give antag to an antag.
|
||||
candidates.Remove(P)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
for(var/mob/P in candidates)
|
||||
if(!P.client || !P.mind || !P.mind.assigned_role) // Are they connected?
|
||||
candidates.Remove(P)
|
||||
else if(!mode.check_age(P.client, minimum_required_age))
|
||||
else if (P.client.get_remaining_days(minimum_required_age) > 0)
|
||||
candidates.Remove(P)
|
||||
else if(P.mind.assigned_role in restricted_roles) // Does their job allow for it?
|
||||
candidates.Remove(P)
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
if (!M.client) // Are they connected?
|
||||
trimmed_list.Remove(M)
|
||||
continue
|
||||
if(!mode.check_age(M.client, minimum_required_age))
|
||||
if(M.client.get_remaining_days(minimum_required_age) > 0)
|
||||
trimmed_list.Remove(M)
|
||||
continue
|
||||
if(antag_flag_override)
|
||||
|
||||
@@ -87,7 +87,6 @@
|
||||
M.add_antag_datum(/datum/antagonist/brother, team)
|
||||
GLOB.pre_setup_antags -= M
|
||||
team.update_name()
|
||||
mode.brother_teams += pre_brother_teams
|
||||
return TRUE
|
||||
|
||||
//////////////////////////////////////////////
|
||||
@@ -574,7 +573,7 @@
|
||||
|
||||
/datum/dynamic_ruleset/roundstart/monkey/execute()
|
||||
for(var/datum/mind/carrier in assigned)
|
||||
var/datum/antagonist/monkey/M = add_monkey_leader(carrier)
|
||||
var/datum/antagonist/monkey/M = carrier.add_antag_datum(/datum/antagonist/monkey/leader)
|
||||
if(M)
|
||||
monkey_team = M.monkey_team
|
||||
return TRUE
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
/datum/game_mode/extended
|
||||
name = "secret extended"
|
||||
config_tag = "secret_extended"
|
||||
report_type = "extended"
|
||||
false_report_weight = 5
|
||||
required_players = 0
|
||||
|
||||
announce_span = "notice"
|
||||
announce_text = "Just have fun and enjoy the game!"
|
||||
|
||||
/datum/game_mode/extended/pre_setup()
|
||||
return 1
|
||||
|
||||
/datum/game_mode/extended/generate_report()
|
||||
return "The transmission mostly failed to mention your sector. It is possible that there is nothing in the Syndicate that could threaten your station during this shift."
|
||||
|
||||
/datum/game_mode/extended/announced
|
||||
name = "extended"
|
||||
config_tag = "extended"
|
||||
false_report_weight = 0
|
||||
|
||||
/datum/game_mode/extended/announced/generate_station_goals()
|
||||
for(var/T in subtypesof(/datum/station_goal))
|
||||
var/datum/station_goal/G = new T
|
||||
station_goals += G
|
||||
G.on_report()
|
||||
|
||||
/datum/game_mode/extended/announced/send_intercept()
|
||||
var/greenshift_message = "Thanks to the tireless efforts of our security and intelligence divisions, there are currently no credible threats to [station_name()]. All station construction projects have been authorized. Have a secure shift!"
|
||||
. += "<b><i>Central Command Status Summary</i></b><hr>"
|
||||
. += greenshift_message
|
||||
. += generate_station_trait_report()
|
||||
|
||||
print_command_report(., "Central Command Status Summary", announce = FALSE)
|
||||
priority_announce(greenshift_message, "Security Report", SSstation.announcer.get_rand_report_sound())
|
||||
@@ -99,7 +99,6 @@
|
||||
if(!GLOB.Debug2)
|
||||
if(playerC < required_players || (maximum_players >= 0 && playerC > maximum_players))
|
||||
return FALSE
|
||||
antag_candidates = get_players_for_role(antag_flag)
|
||||
if(!GLOB.Debug2)
|
||||
if(antag_candidates.len < required_enemies)
|
||||
return FALSE
|
||||
@@ -414,66 +413,6 @@
|
||||
WARNING("Something has gone terribly wrong. /datum/game_mode/proc/antag_pick failed to select a candidate. Falling back to pick()")
|
||||
return pick(candidates)
|
||||
|
||||
/datum/game_mode/proc/get_players_for_role(role)
|
||||
var/list/players = list()
|
||||
var/list/candidates = list()
|
||||
var/list/drafted = list()
|
||||
var/datum/mind/applicant = null
|
||||
|
||||
// Ultimate randomizing code right here
|
||||
for(var/i in GLOB.new_player_list)
|
||||
var/mob/dead/new_player/player = i
|
||||
if(player.ready == PLAYER_READY_TO_PLAY && player.check_preferences())
|
||||
players += player
|
||||
|
||||
// Shuffling, the players list is now ping-independent!!!
|
||||
// Goodbye antag dante
|
||||
players = shuffle(players)
|
||||
|
||||
for(var/mob/dead/new_player/player in players)
|
||||
if(player.client && player.ready == PLAYER_READY_TO_PLAY && player.client.prefs.be_antag) //SKYRAT EDIT CHANGE
|
||||
if(role in player.client.prefs.be_special)
|
||||
if(!is_banned_from(player.ckey, list(role, ROLE_SYNDICATE)) && !QDELETED(player))
|
||||
if(age_check(player.client)) //Must be older than the minimum age
|
||||
candidates += player.mind // Get a list of all the people who want to be the antagonist for this round
|
||||
|
||||
if(restricted_jobs)
|
||||
for(var/datum/mind/player in candidates)
|
||||
for(var/job in restricted_jobs) // Remove people who want to be antagonist but have a job already that precludes it
|
||||
if(player.assigned_role == job)
|
||||
candidates -= player
|
||||
|
||||
if(candidates.len < recommended_enemies)
|
||||
for(var/mob/dead/new_player/player in players)
|
||||
if(player.client && player.ready == PLAYER_READY_TO_PLAY && player.client.prefs.be_antag) //SKYRAT EDIT CHANGE
|
||||
if(!(role in player.client.prefs.be_special)) // We don't have enough people who want to be antagonist, make a separate list of people who don't want to be one
|
||||
if(!is_banned_from(player.ckey, list(role, ROLE_SYNDICATE)) && !QDELETED(player))
|
||||
drafted += player.mind
|
||||
|
||||
if(restricted_jobs)
|
||||
for(var/datum/mind/player in drafted) // Remove people who can't be an antagonist
|
||||
for(var/job in restricted_jobs)
|
||||
if(player.assigned_role == job)
|
||||
drafted -= player
|
||||
|
||||
drafted = shuffle(drafted) // Will hopefully increase randomness, Donkie
|
||||
|
||||
while(candidates.len < recommended_enemies) // Pick randomlly just the number of people we need and add them to our list of candidates
|
||||
if(drafted.len > 0)
|
||||
applicant = pick(drafted)
|
||||
if(applicant)
|
||||
candidates += applicant
|
||||
drafted.Remove(applicant)
|
||||
|
||||
else // Not enough scrubs, ABORT ABORT ABORT
|
||||
break
|
||||
|
||||
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
|
||||
// recommended_enemies if the number of people with that role set to yes is less than recomended_enemies,
|
||||
// Less if there are not enough valid players in the game entirely to make recommended_enemies.
|
||||
|
||||
|
||||
|
||||
/datum/game_mode/proc/num_players()
|
||||
. = 0
|
||||
for(var/i in GLOB.new_player_list)
|
||||
@@ -589,27 +528,8 @@
|
||||
for (var/C in GLOB.admins)
|
||||
to_chat(C, msg.Join())
|
||||
|
||||
//If the configuration option is set to require players to be logged as old enough to play certain jobs, then this proc checks that they are, otherwise it just returns 1
|
||||
/datum/game_mode/proc/age_check(client/C)
|
||||
if(get_remaining_days(C) == 0)
|
||||
return 1 //Available in 0 days = available right now = player is old enough to play.
|
||||
return 0
|
||||
|
||||
|
||||
/datum/game_mode/proc/get_remaining_days(client/C)
|
||||
if(!C)
|
||||
return 0
|
||||
if(!CONFIG_GET(flag/use_age_restriction_for_jobs))
|
||||
return 0
|
||||
if(!isnum(C.player_age))
|
||||
return 0 //This is only a number if the db connection is established, otherwise it is text: "Requires database", meaning these restrictions cannot be enforced
|
||||
if(!isnum(enemy_minimum_age))
|
||||
return 0
|
||||
|
||||
return max(0, enemy_minimum_age - C.player_age)
|
||||
|
||||
/datum/game_mode/proc/remove_antag_for_borging(datum/mind/newborgie)
|
||||
SSticker.mode.remove_cultist(newborgie, 0, 0)
|
||||
newborgie.remove_antag_datum(/datum/antagonist/cult)
|
||||
var/datum/antagonist/rev/rev = newborgie.has_antag_datum(/datum/antagonist/rev)
|
||||
if(rev)
|
||||
rev.remove_revolutionary(TRUE)
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
/datum/game_mode/meteor
|
||||
name = "meteor"
|
||||
config_tag = "meteor"
|
||||
report_type = "meteor"
|
||||
false_report_weight = 1
|
||||
var/meteordelay = 2000
|
||||
var/nometeors = 0
|
||||
var/rampupdelta = 5
|
||||
required_players = 0
|
||||
|
||||
announce_span = "danger"
|
||||
announce_text = "A major meteor shower is bombarding the station! The crew needs to evacuate or survive the onslaught."
|
||||
|
||||
|
||||
/datum/game_mode/meteor/process()
|
||||
if(nometeors || meteordelay > world.time - SSticker.round_start_time)
|
||||
return
|
||||
|
||||
var/list/wavetype = GLOB.meteors_normal
|
||||
var/meteorminutes = (world.time - SSticker.round_start_time - meteordelay) / 10 / 60
|
||||
|
||||
|
||||
if (prob(meteorminutes))
|
||||
wavetype = GLOB.meteors_threatening
|
||||
|
||||
if (prob(meteorminutes/2))
|
||||
wavetype = GLOB.meteors_catastrophic
|
||||
|
||||
var/ramp_up_final = clamp(round(meteorminutes/rampupdelta), 1, 10)
|
||||
|
||||
spawn_meteors(ramp_up_final, wavetype)
|
||||
|
||||
|
||||
/datum/game_mode/meteor/special_report()
|
||||
var/survivors = 0
|
||||
var/list/survivor_list = list()
|
||||
|
||||
for(var/mob/living/player in GLOB.player_list)
|
||||
if(player.stat != DEAD)
|
||||
++survivors
|
||||
|
||||
if(player.onCentCom())
|
||||
survivor_list += "<span class='greentext'>[player.real_name] escaped to the safety of CentCom.</span>"
|
||||
else if(player.onSyndieBase())
|
||||
survivor_list += "<span class='greentext'>[player.real_name] escaped to the (relative) safety of Syndicate Space.</span>"
|
||||
else
|
||||
survivor_list += "<span class='neutraltext'>[player.real_name] survived but is stranded without any hope of rescue.</span>"
|
||||
|
||||
if(survivors)
|
||||
return "<div class='panel greenborder'><span class='header'>The following survived the meteor storm:</span><br>[survivor_list.Join("<br>")]</div>"
|
||||
else
|
||||
return "<div class='panel redborder'><span class='redtext big'>Nobody survived the meteor storm!</span></div>"
|
||||
|
||||
/datum/game_mode/meteor/set_round_result()
|
||||
..()
|
||||
SSticker.mode_result = "end - evacuation"
|
||||
|
||||
/datum/game_mode/meteor/generate_report()
|
||||
return "[pick("Asteroids have", "Meteors have", "Large rocks have", "Stellar minerals have", "Space hail has", "Debris has")] been detected near your station, and a collision is possible, \
|
||||
though unlikely. Be prepared for largescale impacts and destruction. Please note that the debris will prevent the escape shuttle from arriving quickly."
|
||||
@@ -1,134 +0,0 @@
|
||||
/datum/game_mode
|
||||
var/list/ape_infectees = list()
|
||||
var/list/ape_leaders = list()
|
||||
|
||||
/datum/game_mode/monkey
|
||||
name = "monkey"
|
||||
config_tag = "monkey"
|
||||
report_type = "monkey"
|
||||
antag_flag = ROLE_MONKEY
|
||||
false_report_weight = 1
|
||||
|
||||
required_players = 20
|
||||
required_enemies = 1
|
||||
recommended_enemies = 1
|
||||
|
||||
restricted_jobs = list("Prisoner", "Cyborg", "AI")
|
||||
|
||||
announce_span = "Monkey"
|
||||
announce_text = "One or more crewmembers have been infected with Jungle Fever! Crew: Contain the outbreak. None of the infected monkeys may escape alive to CentCom. Monkeys: Ensure that your kind lives on! Rise up against your captors!"
|
||||
|
||||
var/carriers_to_make = 1
|
||||
var/list/carriers = list()
|
||||
|
||||
var/monkeys_to_win = 1
|
||||
var/escaped_monkeys = 0
|
||||
|
||||
var/players_per_carrier = 30
|
||||
|
||||
var/datum/team/monkey/monkey_team
|
||||
|
||||
|
||||
|
||||
/datum/game_mode/monkey/pre_setup()
|
||||
carriers_to_make = max(round(num_players()/players_per_carrier, 1), 1)
|
||||
|
||||
for(var/j = 0, j < carriers_to_make, j++)
|
||||
if (!antag_candidates.len)
|
||||
break
|
||||
var/datum/mind/carrier = pick(antag_candidates)
|
||||
carriers += carrier
|
||||
carrier.special_role = "Monkey Leader"
|
||||
carrier.restricted_roles = restricted_jobs
|
||||
log_game("[key_name(carrier)] has been selected as a Jungle Fever carrier")
|
||||
antag_candidates -= carrier
|
||||
|
||||
if(!carriers.len)
|
||||
setup_error = "No monkey candidates"
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/game_mode/monkey/post_setup()
|
||||
for(var/datum/mind/carriermind in carriers)
|
||||
var/datum/antagonist/monkey/M = add_monkey_leader(carriermind, monkey_team)
|
||||
if(M)
|
||||
monkey_team = M.monkey_team
|
||||
return ..()
|
||||
|
||||
/datum/game_mode/monkey/check_finished()
|
||||
if((SSshuttle.emergency.mode == SHUTTLE_ENDGAME) || station_was_nuked)
|
||||
return TRUE
|
||||
|
||||
if(!round_converted)
|
||||
for(var/datum/mind/monkey_mind in ape_infectees)
|
||||
continuous_sanity_checked = TRUE
|
||||
if(monkey_mind.current && monkey_mind.current.stat != DEAD)
|
||||
return FALSE
|
||||
|
||||
var/datum/disease/D = new /datum/disease/transformation/jungle_fever() //ugly but unfortunately needed
|
||||
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
|
||||
if(!is_station_level(H.z))
|
||||
continue
|
||||
if(H.mind && H.client && H.stat != DEAD)
|
||||
if(H.HasDisease(D))
|
||||
return FALSE
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/game_mode/monkey/proc/check_monkey_victory()
|
||||
if(SSshuttle.emergency.mode != SHUTTLE_ENDGAME)
|
||||
return FALSE
|
||||
var/datum/disease/D = new /datum/disease/transformation/jungle_fever()
|
||||
for(var/mob/living/carbon/human/M in GLOB.alive_mob_list)
|
||||
if(!ismonkey(M))
|
||||
return
|
||||
if (M.HasDisease(D))
|
||||
if(M.onCentCom() || M.onSyndieBase())
|
||||
escaped_monkeys++
|
||||
if(escaped_monkeys >= monkeys_to_win)
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
|
||||
|
||||
/datum/game_mode/monkey/set_round_result()
|
||||
..()
|
||||
if(check_monkey_victory())
|
||||
SSticker.mode_result = "win - monkey win"
|
||||
else
|
||||
SSticker.mode_result = "loss - staff stopped the monkeys"
|
||||
|
||||
/datum/game_mode/monkey/special_report()
|
||||
if(check_monkey_victory())
|
||||
return "<div class='panel redborder'><span class='redtext big'>The monkeys have overthrown their captors! Eeek eeeek!!</span></div>"
|
||||
else
|
||||
return "<div class='panel redborder'><span class='redtext big'>The staff managed to contain the monkey infestation!</span></div>"
|
||||
|
||||
/datum/game_mode/monkey/generate_report()
|
||||
return "Reports of an ancient [pick("retrovirus", "flesh eating bacteria", "disease", "magical curse blamed on viruses", "banana blight")] outbreak that turn humans into monkeys has been reported in your quadrant. Due to strain mutation, such infections are no longer curable by any known means. If an outbreak occurs, ensure the station is quarantined to prevent a largescale outbreak at CentCom."
|
||||
|
||||
/proc/add_monkey_leader(datum/mind/monkey_mind)
|
||||
if(is_monkey_leader(monkey_mind))
|
||||
return FALSE
|
||||
var/datum/antagonist/monkey/leader/M = monkey_mind.add_antag_datum(/datum/antagonist/monkey/leader)
|
||||
return M
|
||||
|
||||
/proc/add_monkey(datum/mind/monkey_mind)
|
||||
if(is_monkey(monkey_mind))
|
||||
return FALSE
|
||||
var/datum/antagonist/monkey/M = monkey_mind.add_antag_datum(/datum/antagonist/monkey)
|
||||
return M
|
||||
|
||||
/proc/remove_monkey(datum/mind/monkey_mind)
|
||||
if(!is_monkey(monkey_mind))
|
||||
return FALSE
|
||||
var/datum/antagonist/monkey/M = monkey_mind.has_antag_datum(/datum/antagonist/monkey)
|
||||
M.on_removal()
|
||||
return TRUE
|
||||
|
||||
/proc/is_monkey_leader(datum/mind/monkey_mind)
|
||||
return monkey_mind?.has_antag_datum(/datum/antagonist/monkey/leader)
|
||||
|
||||
/proc/is_monkey(datum/mind/monkey_mind)
|
||||
return monkey_mind && (monkey_mind.has_antag_datum(/datum/antagonist/monkey) || is_monkey_leader(monkey_mind))
|
||||
|
||||
@@ -1,172 +0,0 @@
|
||||
/datum/game_mode/nuclear
|
||||
name = "nuclear emergency"
|
||||
config_tag = "nuclear"
|
||||
report_type = "nuclear"
|
||||
false_report_weight = 10
|
||||
required_players = 30 // 30 players - 3 players to be the nuke ops = 27 players remaining
|
||||
required_enemies = 2
|
||||
recommended_enemies = 5
|
||||
antag_flag = ROLE_OPERATIVE
|
||||
enemy_minimum_age = 14
|
||||
|
||||
announce_span = "danger"
|
||||
announce_text = "Syndicate forces are approaching the station in an attempt to destroy it!\n\
|
||||
<span class='danger'>Operatives</span>: Secure the nuclear authentication disk and use your nuke to destroy the station.\n\
|
||||
<span class='notice'>Crew</span>: Defend the nuclear authentication disk and ensure that it leaves with you on the emergency shuttle."
|
||||
|
||||
var/const/agents_possible = 5 //If we ever need more syndicate agents.
|
||||
var/nukes_left = 1 // Call 3714-PRAY right now and order more nukes! Limited offer!
|
||||
var/list/pre_nukeops = list()
|
||||
|
||||
var/datum/team/nuclear/nuke_team
|
||||
|
||||
var/operative_antag_datum_type = /datum/antagonist/nukeop
|
||||
var/leader_antag_datum_type = /datum/antagonist/nukeop/leader
|
||||
|
||||
/datum/game_mode/nuclear/pre_setup()
|
||||
var/n_agents = min(round(num_players() / 10), antag_candidates.len, agents_possible)
|
||||
if(n_agents >= required_enemies)
|
||||
for(var/i = 0, i < n_agents, ++i)
|
||||
var/datum/mind/new_op = pick_n_take(antag_candidates)
|
||||
pre_nukeops += new_op
|
||||
new_op.assigned_role = "Nuclear Operative"
|
||||
new_op.special_role = "Nuclear Operative"
|
||||
log_game("[key_name(new_op)] has been selected as a nuclear operative")
|
||||
return TRUE
|
||||
else
|
||||
setup_error = "Not enough nuke op candidates"
|
||||
return FALSE
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/datum/game_mode/nuclear/post_setup()
|
||||
//Assign leader
|
||||
var/datum/mind/leader_mind = pre_nukeops[1]
|
||||
var/datum/antagonist/nukeop/L = leader_mind.add_antag_datum(leader_antag_datum_type)
|
||||
nuke_team = L.nuke_team
|
||||
//Assign the remaining operatives
|
||||
for(var/i = 2 to pre_nukeops.len)
|
||||
var/datum/mind/nuke_mind = pre_nukeops[i]
|
||||
nuke_mind.add_antag_datum(operative_antag_datum_type)
|
||||
return ..()
|
||||
|
||||
/datum/game_mode/nuclear/OnNukeExplosion(off_station)
|
||||
..()
|
||||
nukes_left--
|
||||
|
||||
/datum/game_mode/nuclear/check_finished()
|
||||
//Keep the round going if ops are dead but bomb is ticking.
|
||||
if(nuke_team.operatives_dead())
|
||||
for(var/obj/machinery/nuclearbomb/N in GLOB.nuke_list)
|
||||
if(N.proper_bomb && (N.timing || N.exploding))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/game_mode/nuclear/set_round_result()
|
||||
..()
|
||||
var/result = nuke_team.get_result()
|
||||
switch(result)
|
||||
if(NUKE_RESULT_FLUKE)
|
||||
SSticker.mode_result = "loss - syndicate nuked - disk secured"
|
||||
SSticker.news_report = NUKE_SYNDICATE_BASE
|
||||
if(NUKE_RESULT_NUKE_WIN)
|
||||
SSticker.mode_result = "win - syndicate nuke"
|
||||
SSticker.news_report = STATION_NUKED
|
||||
if(NUKE_RESULT_NOSURVIVORS)
|
||||
SSticker.mode_result = "halfwin - syndicate nuke - did not evacuate in time"
|
||||
SSticker.news_report = STATION_NUKED
|
||||
if(NUKE_RESULT_WRONG_STATION)
|
||||
SSticker.mode_result = "halfwin - blew wrong station"
|
||||
SSticker.news_report = NUKE_MISS
|
||||
if(NUKE_RESULT_WRONG_STATION_DEAD)
|
||||
SSticker.mode_result = "halfwin - blew wrong station - did not evacuate in time"
|
||||
SSticker.news_report = NUKE_MISS
|
||||
if(NUKE_RESULT_CREW_WIN_SYNDIES_DEAD)
|
||||
SSticker.mode_result = "loss - evacuation - disk secured - syndi team dead"
|
||||
SSticker.news_report = OPERATIVES_KILLED
|
||||
if(NUKE_RESULT_CREW_WIN)
|
||||
SSticker.mode_result = "loss - evacuation - disk secured"
|
||||
SSticker.news_report = OPERATIVES_KILLED
|
||||
if(NUKE_RESULT_DISK_LOST)
|
||||
SSticker.mode_result = "halfwin - evacuation - disk not secured"
|
||||
SSticker.news_report = OPERATIVE_SKIRMISH
|
||||
if(NUKE_RESULT_DISK_STOLEN)
|
||||
SSticker.mode_result = "halfwin - detonation averted"
|
||||
SSticker.news_report = OPERATIVE_SKIRMISH
|
||||
else
|
||||
SSticker.mode_result = "halfwin - interrupted"
|
||||
SSticker.news_report = OPERATIVE_SKIRMISH
|
||||
|
||||
/datum/game_mode/nuclear/generate_report()
|
||||
return "One of Central Command's trading routes was recently disrupted by a raid carried out by the Gorlex Marauders. They seemed to only be after one ship - a highly-sensitive \
|
||||
transport containing a nuclear fission explosive, although it is useless without the proper code and authorization disk. While the code was likely found in minutes, the only disk that \
|
||||
can activate this explosive is on your station. Ensure that it is protected at all times, and remain alert for possible intruders."
|
||||
|
||||
/proc/is_nuclear_operative(mob/M)
|
||||
return M && istype(M) && M.mind && M.mind.has_antag_datum(/datum/antagonist/nukeop)
|
||||
|
||||
/datum/outfit/syndicate
|
||||
name = "Syndicate Operative - Basic"
|
||||
|
||||
uniform = /obj/item/clothing/under/syndicate
|
||||
shoes = /obj/item/clothing/shoes/combat
|
||||
gloves = /obj/item/clothing/gloves/combat
|
||||
back = /obj/item/storage/backpack/fireproof
|
||||
ears = /obj/item/radio/headset/syndicate/alt
|
||||
l_pocket = /obj/item/modular_computer/tablet/nukeops
|
||||
id = /obj/item/card/id/advanced/chameleon
|
||||
belt = /obj/item/gun/ballistic/automatic/pistol
|
||||
backpack_contents = list(/obj/item/storage/box/survival/syndie=1,\
|
||||
/obj/item/kitchen/knife/combat/survival)
|
||||
|
||||
skillchips = list(/obj/item/skillchip/disk_verifier)
|
||||
|
||||
var/tc = 25
|
||||
var/command_radio = FALSE
|
||||
var/uplink_type = /obj/item/uplink/nuclear
|
||||
|
||||
id_trim = /datum/id_trim/chameleon/operative
|
||||
|
||||
/datum/outfit/syndicate/leader
|
||||
name = "Syndicate Leader - Basic"
|
||||
gloves = /obj/item/clothing/gloves/krav_maga/combatglovesplus
|
||||
command_radio = TRUE
|
||||
|
||||
id_trim = /datum/id_trim/chameleon/operative/nuke_leader
|
||||
|
||||
/datum/outfit/syndicate/no_crystals
|
||||
name = "Syndicate Operative - Reinforcement"
|
||||
tc = 0
|
||||
|
||||
/datum/outfit/syndicate/post_equip(mob/living/carbon/human/H)
|
||||
var/obj/item/radio/R = H.ears
|
||||
R.set_frequency(FREQ_SYNDICATE)
|
||||
R.freqlock = TRUE
|
||||
if(command_radio)
|
||||
R.command = TRUE
|
||||
|
||||
if(ispath(uplink_type, /obj/item/uplink/nuclear) || tc) // /obj/item/uplink/nuclear understands 0 tc
|
||||
var/obj/item/U = new uplink_type(H, H.key, tc)
|
||||
H.equip_to_slot_or_del(U, ITEM_SLOT_BACKPACK)
|
||||
|
||||
var/obj/item/implant/weapons_auth/W = new/obj/item/implant/weapons_auth(H)
|
||||
W.implant(H)
|
||||
var/obj/item/implant/explosive/E = new/obj/item/implant/explosive(H)
|
||||
E.implant(H)
|
||||
H.faction |= ROLE_SYNDICATE
|
||||
H.update_icons()
|
||||
|
||||
/datum/outfit/syndicate/full
|
||||
name = "Syndicate Operative - Full Kit"
|
||||
|
||||
glasses = /obj/item/clothing/glasses/night
|
||||
mask = /obj/item/clothing/mask/gas/syndicate
|
||||
suit = /obj/item/clothing/suit/space/hardsuit/syndi
|
||||
r_pocket = /obj/item/tank/internals/emergency_oxygen/engi
|
||||
internals_slot = ITEM_SLOT_RPOCKET
|
||||
belt = /obj/item/storage/belt/military
|
||||
r_hand = /obj/item/gun/ballistic/shotgun/bulldog
|
||||
backpack_contents = list(/obj/item/storage/box/survival/syndie=1,\
|
||||
/obj/item/tank/jetpack/oxygen/harness=1,\
|
||||
/obj/item/gun/ballistic/automatic/pistol=1,\
|
||||
/obj/item/kitchen/knife/combat/survival)
|
||||
@@ -1,142 +0,0 @@
|
||||
/*
|
||||
This is for the sandbox for now,
|
||||
maybe useful later for an actual thing?
|
||||
-Sayu
|
||||
*/
|
||||
|
||||
/obj/structure/door_assembly
|
||||
var/datum/airlock_maker/maker = null
|
||||
|
||||
/obj/structure/door_assembly/attack_hand(mob/user, list/modifiers)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(maker)
|
||||
maker.interact()
|
||||
|
||||
/datum/airlock_maker
|
||||
var/obj/structure/door_assembly/linked = null
|
||||
|
||||
var/list/access_used = null
|
||||
var/require_all = 1
|
||||
|
||||
var/paintjob = "none"
|
||||
var/glassdoor = FALSE
|
||||
|
||||
var/doorname = "airlock"
|
||||
|
||||
/datum/airlock_maker/New(atom/target_loc)
|
||||
linked = new(target_loc)
|
||||
linked.maker = src
|
||||
linked.set_anchored(FALSE)
|
||||
access_used = list()
|
||||
|
||||
interact()
|
||||
|
||||
/datum/airlock_maker/proc/linkpretty(href,desc,active)
|
||||
if(!desc)
|
||||
var/static/list/defaults = list("No","Yes")
|
||||
desc = defaults[active+1]
|
||||
if(active)
|
||||
return "<a href='?src=[REF(src)];[href]'><b>[desc]</b></a>"
|
||||
return "<a href='?src=[REF(src)];[href]'><i>[desc]</i></a>"
|
||||
|
||||
/datum/airlock_maker/proc/interact()
|
||||
var/list/leftcolumn = list()
|
||||
var/list/rightcolumn = list()
|
||||
leftcolumn += "<u><b>Required Access</b></u>"
|
||||
var/list/all_station_access = SSid_access.get_region_access_list(list(REGION_ALL_STATION))
|
||||
for(var/access in all_station_access)
|
||||
leftcolumn += linkpretty("access=[access]",SSid_access.get_access_desc(access),access in access_used)
|
||||
leftcolumn += "Require all listed accesses: [linkpretty("reqall",null,require_all)]"
|
||||
|
||||
rightcolumn += "<u><b>Paintjob</b></u>"
|
||||
for(var/option in list("none","engineering","atmos","security","command","medical","research","mining","maintenance","external","highsecurity"))
|
||||
rightcolumn += linkpretty("paint=[option]",option,option == paintjob)
|
||||
rightcolumn += "Glass door: " + linkpretty("glass",null,glassdoor) + "<br><br>"
|
||||
var/length = max(leftcolumn.len,rightcolumn.len)
|
||||
|
||||
var/dat = "You may move the model airlock around. A new airlock will be built in its space when you click done, below.<hr><br>"
|
||||
dat += "<a href='?src=[REF(src)];rename'>Door name</a>: \"[doorname]\""
|
||||
dat += "<table>"
|
||||
for(var/i=1; i<=length; i++)
|
||||
dat += "<tr><td>"
|
||||
if(i<=leftcolumn.len)
|
||||
dat += leftcolumn[i]
|
||||
dat += "</td><td>"
|
||||
if(i<=rightcolumn.len)
|
||||
dat += rightcolumn[i]
|
||||
dat += "</td></tr>"
|
||||
|
||||
dat += "</table><hr><a href='?src=[REF(src)];done'>Finalize Airlock Construction</a> | <a href='?src=[REF(src)];cancel'>Cancel and Destroy Airlock</a>"
|
||||
usr << browse(dat,"window=airlockmaker")
|
||||
|
||||
/datum/airlock_maker/Topic(href,list/href_list)
|
||||
if(!usr)
|
||||
return
|
||||
if(!src || !linked || !linked.loc)
|
||||
usr << browse(null,"window=airlockmaker")
|
||||
return
|
||||
|
||||
if("rename" in href_list)
|
||||
var/newname = stripped_input(usr,"New airlock name:","Name the airlock",doorname)
|
||||
if(newname)
|
||||
doorname = newname
|
||||
if("access" in href_list)
|
||||
var/value = text2num(href_list["access"])
|
||||
access_used ^= value
|
||||
if("reqall" in href_list)
|
||||
require_all = !require_all
|
||||
if("paint" in href_list)
|
||||
paintjob = href_list["paint"]
|
||||
if("glass" in href_list)
|
||||
glassdoor = !glassdoor
|
||||
|
||||
if("cancel" in href_list)
|
||||
usr << browse(null,"window=airlockmaker")
|
||||
qdel(linked)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
if("done" in href_list)
|
||||
usr << browse(null,"window=airlockmaker")
|
||||
var/turf/t_loc = linked.loc
|
||||
qdel(linked)
|
||||
if(!istype(t_loc))
|
||||
return
|
||||
|
||||
var/target_type = "/obj/machinery/door/airlock"
|
||||
if(glassdoor)
|
||||
if(paintjob != "none")
|
||||
if(paintjob in list("external","highsecurity","maintenance")) // no glass version
|
||||
target_type += "/[paintjob]"
|
||||
else
|
||||
target_type += "/glass_[paintjob]"
|
||||
else
|
||||
target_type += "/glass"
|
||||
else if(paintjob != "none")
|
||||
target_type += "/[paintjob]"
|
||||
var/final = target_type
|
||||
target_type = text2path(final)
|
||||
if(!target_type)
|
||||
to_chat(usr, "Didn't work, contact Sayu with this: [final]")
|
||||
usr << browse(null,"window=airlockmaker")
|
||||
return
|
||||
|
||||
var/obj/machinery/door/D = new target_type(t_loc)
|
||||
|
||||
D.name = doorname
|
||||
|
||||
if(access_used.len == 0)
|
||||
D.req_access = null
|
||||
D.req_one_access = null
|
||||
else if(require_all)
|
||||
D.req_access = access_used.Copy()
|
||||
D.req_one_access = null
|
||||
else
|
||||
D.req_access = null
|
||||
D.req_one_access = access_used.Copy()
|
||||
|
||||
return
|
||||
|
||||
interact()
|
||||
@@ -1,307 +0,0 @@
|
||||
GLOBAL_VAR_INIT(hsboxspawn, TRUE)
|
||||
|
||||
/mob/proc/CanBuild()
|
||||
sandbox = new/datum/h_sandbox
|
||||
sandbox.owner = src.ckey
|
||||
if(src.client.holder)
|
||||
sandbox.admin = TRUE
|
||||
add_verb(src, /mob/proc/sandbox_panel)
|
||||
|
||||
/mob/proc/sandbox_panel()
|
||||
set name = "Sandbox Panel"
|
||||
if(sandbox)
|
||||
sandbox.update()
|
||||
|
||||
/datum/h_sandbox
|
||||
var/owner = null
|
||||
var/admin = FALSE
|
||||
|
||||
var/static/clothinfo = null
|
||||
var/static/reaginfo = null
|
||||
var/static/objinfo = null
|
||||
var/canisterinfo = null
|
||||
var/hsbinfo = null
|
||||
//items that shouldn't spawn on the floor because they would bug or act weird
|
||||
var/static/list/spawn_forbidden = list(
|
||||
/obj/item/tk_grab, /obj/item/implant, // not implanter, the actual thing that is inside you
|
||||
/obj/item/assembly, /obj/item/onetankbomb, /obj/item/pda/ai,
|
||||
/obj/item/small_delivery, /obj/projectile,
|
||||
/obj/item/borg/sight, /obj/item/borg/stun, /obj/item/robot_model)
|
||||
|
||||
/datum/h_sandbox/proc/update()
|
||||
var/static/list/hrefs = list(
|
||||
"Space Gear",
|
||||
"Suit Up (Space Travel Gear)" = "hsbsuit",
|
||||
"Spawn Gas Mask" = "hsbspawn&path=[/obj/item/clothing/mask/gas]",
|
||||
"Spawn Emergency Air Tank" = "hsbspawn&path=[/obj/item/tank/internals/emergency_oxygen/double]",
|
||||
|
||||
"Standard Tools",
|
||||
"Spawn Flashlight" = "hsbspawn&path=[/obj/item/flashlight]",
|
||||
"Spawn Toolbox" = "hsbspawn&path=[/obj/item/storage/toolbox/mechanical]",
|
||||
"Spawn Experimental Welding tool" = "hsbspawn&path=[/obj/item/weldingtool/experimental]",
|
||||
"Spawn Light Replacer" = "hsbspawn&path=[/obj/item/lightreplacer]",
|
||||
"Spawn Medical Kit" = "hsbspawn&path=[/obj/item/storage/firstaid/regular]",
|
||||
"Spawn All-Access ID" = "hsbaaid",
|
||||
|
||||
"Building Supplies",
|
||||
"Spawn 50 Wood" = "hsbwood",
|
||||
"Spawn 50 Metal" = "hsbmetal",
|
||||
"Spawn 50 Plasteel" = "hsbplasteel",
|
||||
"Spawn 50 Reinforced Glass" = "hsbrglass",
|
||||
"Spawn 50 Glass" = "hsbglass",
|
||||
"Spawn Box of Materials" = "hsbspawn&path=[/obj/item/storage/box/material]",
|
||||
"Spawn Full Cable Coil" = "hsbspawn&path=[/obj/item/stack/cable_coil]",
|
||||
"Spawn Hyper Capacity Power Cell" = "hsbspawn&path=[/obj/item/stock_parts/cell/hyper]",
|
||||
"Spawn Inf. Capacity Power Cell" = "hsbspawn&path=[/obj/item/stock_parts/cell/infinite]",
|
||||
"Spawn Rapid Construction Device" = "hsbrcd",
|
||||
"Spawn RCD Ammo" = "hsb_safespawn&path=[/obj/item/rcd_ammo]",
|
||||
"Spawn Airlock" = "hsbairlock",
|
||||
|
||||
"Miscellaneous",
|
||||
"Spawn Air Scrubber" = "hsbscrubber",
|
||||
"Spawn CentCom Technology Disk" = "hsbspawn&path=[/obj/item/disk/tech_disk/debug]",
|
||||
"Spawn Adminordrazine" = "hsbspawn&path=[/obj/item/reagent_containers/pill/adminordrazine]",
|
||||
"Spawn Water Tank" = "hsbspawn&path=[/obj/structure/reagent_dispensers/watertank]",
|
||||
|
||||
"Bots",
|
||||
"Spawn Cleanbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/cleanbot]",
|
||||
"Spawn Floorbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/floorbot]",
|
||||
"Spawn Medbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/medbot]",
|
||||
|
||||
"Canisters",
|
||||
"Spawn O2 Canister" = "hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/oxygen]",
|
||||
"Spawn Air Canister" = "hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/air]")
|
||||
|
||||
|
||||
if(!hsbinfo)
|
||||
hsbinfo = "<center><b>Sandbox Panel</b></center><hr>"
|
||||
if(admin)
|
||||
hsbinfo += "<b>Administration</b><br>"
|
||||
hsbinfo += "- <a href='?src=[REF(src)];hsb=hsbtobj'>Toggle Object Spawning</a><br>"
|
||||
hsbinfo += "- <a href='?src=[REF(src)];hsb=hsbtac'>Toggle Item Spawn Panel Auto-close</a><br>"
|
||||
hsbinfo += "<b>Canister Spawning</b><br>"
|
||||
hsbinfo += "- <a href='?src=[REF(src)];hsb=hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/toxins]'>Spawn Plasma Canister</a><br>"
|
||||
hsbinfo += "- <a href='?src=[REF(src)];hsb=hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/carbon_dioxide]'>Spawn CO2 Canister</a><br>"
|
||||
hsbinfo += "- <a href='?src=[REF(src)];hsb=hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/nitrogen]'>Spawn Nitrogen Canister</a><br>"
|
||||
hsbinfo += "- <a href='?src=[REF(src)];hsb=hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/nitrous_oxide]'>Spawn N2O Canister</a><hr>"
|
||||
else
|
||||
hsbinfo += "<i>Some item spawning may be disabled by the administrators.</i><br>"
|
||||
hsbinfo += "<i>Only administrators may spawn dangerous canisters.</i><br>"
|
||||
for(var/T in hrefs)
|
||||
var/href = hrefs[T]
|
||||
if(href)
|
||||
hsbinfo += "- <a href='?[REF(src)];hsb=[hrefs[T]]'>[T]</a><br>"
|
||||
else
|
||||
hsbinfo += "<br><b>[T]</b><br>"
|
||||
hsbinfo += "<hr>"
|
||||
hsbinfo += "- <a href='?[REF(src)];hsb=hsbcloth'>Spawn Clothing...</a><br>"
|
||||
hsbinfo += "- <a href='?[REF(src)];hsb=hsbreag'>Spawn Reagent Container...</a><br>"
|
||||
hsbinfo += "- <a href='?[REF(src)];hsb=hsbobj'>Spawn Other Item...</a><br><br>"
|
||||
|
||||
usr << browse(hsbinfo, "window=hsbpanel")
|
||||
|
||||
/datum/h_sandbox/Topic(href, href_list)
|
||||
if(!usr || !src || !(src.owner == usr.ckey))
|
||||
if(usr)
|
||||
usr << browse(null,"window=sandbox")
|
||||
return
|
||||
|
||||
if(href_list["hsb"])
|
||||
switch(href_list["hsb"])
|
||||
//
|
||||
// Admin: toggle spawning
|
||||
//
|
||||
if("hsbtobj")
|
||||
if(!admin) return
|
||||
if(GLOB.hsboxspawn)
|
||||
to_chat(world, "<span class='boldannounce'>Sandbox:</span> <b>\black[usr.key] has disabled object spawning!</b>")
|
||||
GLOB.hsboxspawn = FALSE
|
||||
return
|
||||
else
|
||||
to_chat(world, "<span class='boldnotice'>Sandbox:</span> <b>\black[usr.key] has enabled object spawning!</b>")
|
||||
GLOB.hsboxspawn = TRUE
|
||||
return
|
||||
//
|
||||
// Admin: Toggle auto-close
|
||||
//
|
||||
if("hsbtac")
|
||||
if(!admin) return
|
||||
var/sbac = CONFIG_GET(flag/sandbox_autoclose)
|
||||
if(sbac)
|
||||
to_chat(world, "<span class='boldnotice'>Sandbox:</span> <b>\black [usr.key] has removed the object spawn limiter.</b>")
|
||||
else
|
||||
to_chat(world, "<span class='danger'>Sandbox:</span> <b>\black [usr.key] has added a limiter to object spawning. The window will now auto-close after use.</b>")
|
||||
CONFIG_SET(flag/sandbox_autoclose, !sbac)
|
||||
return
|
||||
//
|
||||
// Spacesuit with full air jetpack set as internals
|
||||
//
|
||||
if("hsbsuit")
|
||||
var/mob/living/carbon/human/P = usr
|
||||
if(!istype(P)) return
|
||||
if(P.wear_suit)
|
||||
P.wear_suit.forceMove(P.drop_location())
|
||||
P.wear_suit.layer = initial(P.wear_suit.layer)
|
||||
P.wear_suit.plane = initial(P.wear_suit.plane)
|
||||
P.wear_suit = null
|
||||
P.wear_suit = new/obj/item/clothing/suit/space(P)
|
||||
P.wear_suit.plane = ABOVE_HUD_PLANE
|
||||
P.update_inv_wear_suit()
|
||||
if(P.head)
|
||||
P.head.forceMove(P.drop_location())
|
||||
P.head.layer = initial(P.head.layer)
|
||||
P.head.plane = initial(P.head.plane)
|
||||
P.head = null
|
||||
P.head = new/obj/item/clothing/head/helmet/space(P)
|
||||
P.head.plane = ABOVE_HUD_PLANE
|
||||
P.update_inv_head()
|
||||
if(P.wear_mask)
|
||||
P.wear_mask.forceMove(P.drop_location())
|
||||
P.wear_mask.layer = initial(P.wear_mask.layer)
|
||||
P.wear_mask.plane = initial(P.wear_mask.plane)
|
||||
P.wear_mask = null
|
||||
P.wear_mask = new/obj/item/clothing/mask/gas(P)
|
||||
P.wear_mask.plane = ABOVE_HUD_PLANE
|
||||
P.update_inv_wear_mask()
|
||||
if(P.back)
|
||||
P.back.forceMove(P.drop_location())
|
||||
P.back.layer = initial(P.back.layer)
|
||||
P.back.plane = initial(P.back.plane)
|
||||
P.back = null
|
||||
P.back = new/obj/item/tank/jetpack/oxygen(P)
|
||||
P.back.plane = ABOVE_HUD_PLANE
|
||||
P.update_inv_back()
|
||||
P.internal = P.back
|
||||
P.update_internals_hud_icon(1)
|
||||
|
||||
if("hsbscrubber") // This is beyond its normal capability but this is sandbox and you spawned one, I assume you need it
|
||||
var/obj/hsb = new/obj/machinery/portable_atmospherics/scrubber{volume_rate=50*ONE_ATMOSPHERE;on=1}(usr.loc)
|
||||
hsb.update_appearance() // hackish but it wasn't meant to be spawned I guess?
|
||||
|
||||
//
|
||||
// Stacked Materials
|
||||
//
|
||||
|
||||
if("hsbrglass")
|
||||
new/obj/item/stack/sheet/rglass{amount=50}(usr.loc)
|
||||
|
||||
if("hsbmetal")
|
||||
new/obj/item/stack/sheet/iron/fifty(usr.loc)
|
||||
|
||||
if("hsbplasteel")
|
||||
new/obj/item/stack/sheet/plasteel{amount=50}(usr.loc)
|
||||
|
||||
if("hsbglass")
|
||||
new/obj/item/stack/sheet/glass{amount=50}(usr.loc)
|
||||
|
||||
if("hsbwood")
|
||||
new/obj/item/stack/sheet/mineral/wood{amount=50}(usr.loc)
|
||||
|
||||
//
|
||||
// All access ID
|
||||
//
|
||||
if("hsbaaid")
|
||||
var/obj/item/card/id/advanced/debug/ID = new(usr.loc)
|
||||
ID.registered_name = usr.real_name
|
||||
ID.update_label()
|
||||
ID.update_icon()
|
||||
|
||||
//
|
||||
// RCD - starts with full clip
|
||||
// Spawn check due to grief potential (destroying floors, walls, etc)
|
||||
//
|
||||
if("hsbrcd")
|
||||
if(!GLOB.hsboxspawn) return
|
||||
|
||||
new/obj/item/construction/rcd/combat(usr.loc)
|
||||
|
||||
//
|
||||
// New sandbox airlock maker
|
||||
//
|
||||
if("hsbairlock")
|
||||
new /datum/airlock_maker(usr.loc)
|
||||
|
||||
//
|
||||
// Object spawn window
|
||||
//
|
||||
|
||||
// Clothing
|
||||
if("hsbcloth")
|
||||
if(!GLOB.hsboxspawn) return
|
||||
|
||||
if(!clothinfo)
|
||||
clothinfo = "<b>Clothing</b> <a href='?[REF(src)];hsb=hsbreag'>(Reagent Containers)</a> <a href='?[REF(src)];hsb=hsbobj'>(Other Items)</a><hr><br>"
|
||||
var/list/all_items = subtypesof(/obj/item/clothing)
|
||||
for(var/typekey in spawn_forbidden)
|
||||
all_items -= typesof(typekey)
|
||||
for(var/O in reverseRange(all_items))
|
||||
clothinfo += "<a href='?src=[REF(src)];hsb=hsb_safespawn&path=[O]'>[O]</a><br>"
|
||||
|
||||
usr << browse(clothinfo,"window=sandbox")
|
||||
|
||||
// Reagent containers
|
||||
if("hsbreag")
|
||||
if(!GLOB.hsboxspawn) return
|
||||
|
||||
if(!reaginfo)
|
||||
reaginfo = "<b>Reagent Containers</b> <a href='?[REF(src)];hsb=hsbcloth'>(Clothing)</a> <a href='?[REF(src)];hsb=hsbobj'>(Other Items)</a><hr><br>"
|
||||
var/list/all_items = subtypesof(/obj/item/reagent_containers)
|
||||
for(var/typekey in spawn_forbidden)
|
||||
all_items -= typesof(typekey)
|
||||
for(var/O in reverseRange(all_items))
|
||||
reaginfo += "<a href='?src=[REF(src)];hsb=hsb_safespawn&path=[O]'>[O]</a><br>"
|
||||
|
||||
usr << browse(reaginfo,"window=sandbox")
|
||||
|
||||
// Other items
|
||||
if("hsbobj")
|
||||
if(!GLOB.hsboxspawn) return
|
||||
|
||||
if(!objinfo)
|
||||
objinfo = "<b>Other Items</b> <a href='?[REF(src)];hsb=hsbcloth'>(Clothing)</a> <a href='?[REF(src)];hsb=hsbreag'>(Reagent Containers)</a><hr><br>"
|
||||
var/list/all_items = subtypesof(/obj/item/) - typesof(/obj/item/clothing) - typesof(/obj/item/reagent_containers)
|
||||
for(var/typekey in spawn_forbidden)
|
||||
all_items -= typesof(typekey)
|
||||
|
||||
for(var/O in reverseRange(all_items))
|
||||
objinfo += "<a href='?src=[REF(src)];hsb=hsb_safespawn&path=[O]'>[O]</a><br>"
|
||||
|
||||
usr << browse(objinfo,"window=sandbox")
|
||||
|
||||
//
|
||||
// Safespawn checks to see if spawning is disabled.
|
||||
//
|
||||
if("hsb_safespawn")
|
||||
if(!GLOB.hsboxspawn)
|
||||
usr << browse(null,"window=sandbox")
|
||||
return
|
||||
|
||||
var/typepath = text2path(href_list["path"])
|
||||
if(!typepath)
|
||||
to_chat(usr, "Bad path: \"[href_list["path"]]\"")
|
||||
return
|
||||
new typepath(usr.loc)
|
||||
|
||||
if(CONFIG_GET(flag/sandbox_autoclose))
|
||||
usr << browse(null,"window=sandbox")
|
||||
//
|
||||
// For everything else in the href list
|
||||
//
|
||||
if("hsbspawn")
|
||||
var/typepath = text2path(href_list["path"])
|
||||
if(!typepath)
|
||||
to_chat(usr, "Bad path: \"[href_list["path"]]\"")
|
||||
return
|
||||
new typepath(usr.loc)
|
||||
|
||||
if(CONFIG_GET(flag/sandbox_autoclose))
|
||||
usr << browse(null,"window=sandbox")
|
||||
|
||||
/// Simple helper trim for sandbox mode's ID cards. Comes with station AA.
|
||||
/datum/id_trim/sandbox
|
||||
assignment = "Sandbox"
|
||||
trim_state = "trim_captain"
|
||||
|
||||
/datum/id_trim/sandbox/New()
|
||||
. = ..()
|
||||
access = SSid_access.get_region_access_list(list(REGION_ALL_STATION))
|
||||
@@ -1,22 +0,0 @@
|
||||
/datum/game_mode/sandbox
|
||||
name = "sandbox"
|
||||
config_tag = "sandbox"
|
||||
report_type = "sandbox"
|
||||
required_players = 0
|
||||
|
||||
announce_span = "info"
|
||||
announce_text = "Build your own station... or just shoot each other!"
|
||||
|
||||
allow_persistence_save = FALSE
|
||||
|
||||
/datum/game_mode/sandbox/pre_setup()
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
M.CanBuild()
|
||||
return 1
|
||||
|
||||
/datum/game_mode/sandbox/post_setup()
|
||||
..()
|
||||
SSshuttle.registerHostileEnvironment(src)
|
||||
|
||||
/datum/game_mode/sandbox/generate_report()
|
||||
return "Sensors indicate that crewmembers have been all given psychic powers from which they can manifest various objects.<br><br>This can only end poorly."
|
||||
@@ -1,83 +0,0 @@
|
||||
/datum/game_mode
|
||||
var/list/target_list = list()
|
||||
var/list/late_joining_list = list()
|
||||
|
||||
/datum/game_mode/traitor/internal_affairs
|
||||
name = "Internal Affairs"
|
||||
config_tag = "internal_affairs"
|
||||
report_type = "internal_affairs"
|
||||
false_report_weight = 10
|
||||
required_players = 25
|
||||
required_enemies = 5
|
||||
recommended_enemies = 8
|
||||
reroll_friendly = 0
|
||||
traitor_name = "Nanotrasen Internal Affairs Agent"
|
||||
antag_flag = ROLE_INTERNAL_AFFAIRS
|
||||
|
||||
traitors_possible = 10 //hard limit on traitors if scaling is turned off
|
||||
num_modifier = 4 // Four additional traitors
|
||||
antag_datum = /datum/antagonist/traitor/internal_affairs
|
||||
|
||||
announce_text = "There are Nanotrasen Internal Affairs Agents trying to kill each other!\n\
|
||||
<span class='danger'>IAA</span>: Eliminate your targets and protect yourself!\n\
|
||||
<span class='notice'>Crew</span>: Stop the IAA agents before they can cause too much mayhem."
|
||||
|
||||
|
||||
|
||||
/datum/game_mode/traitor/internal_affairs/post_setup()
|
||||
var/i = 0
|
||||
for(var/datum/mind/traitor in pre_traitors)
|
||||
i++
|
||||
if(i + 1 > pre_traitors.len)
|
||||
i = 0
|
||||
target_list[traitor] = pre_traitors[i+1]
|
||||
..()
|
||||
|
||||
|
||||
/datum/game_mode/traitor/internal_affairs/add_latejoin_traitor(datum/mind/character)
|
||||
|
||||
check_potential_agents()
|
||||
|
||||
// As soon as we get 3 or 4 extra latejoin traitors, make them traitors and kill each other.
|
||||
if(late_joining_list.len >= rand(3, 4))
|
||||
// True randomness
|
||||
shuffle_inplace(late_joining_list)
|
||||
// Reset the target_list, it'll be used again in force_traitor_objectives
|
||||
target_list = list()
|
||||
|
||||
// Basically setting the target_list for who is killing who
|
||||
var/i = 0
|
||||
for(var/datum/mind/traitor in late_joining_list)
|
||||
i++
|
||||
if(i + 1 > late_joining_list.len)
|
||||
i = 0
|
||||
target_list[traitor] = late_joining_list[i + 1]
|
||||
traitor.special_role = traitor_name
|
||||
|
||||
// Now, give them their targets
|
||||
for(var/datum/mind/traitor in target_list)
|
||||
..(traitor)
|
||||
|
||||
late_joining_list = list()
|
||||
else
|
||||
late_joining_list += character
|
||||
return
|
||||
|
||||
/datum/game_mode/traitor/internal_affairs/proc/check_potential_agents()
|
||||
|
||||
for(var/M in late_joining_list)
|
||||
if(istype(M, /datum/mind))
|
||||
var/datum/mind/agent_mind = M
|
||||
if(ishuman(agent_mind.current))
|
||||
var/mob/living/carbon/human/H = agent_mind.current
|
||||
if(H.stat != DEAD)
|
||||
if(H.client)
|
||||
continue // It all checks out.
|
||||
|
||||
// If any check fails, remove them from our list
|
||||
late_joining_list -= M
|
||||
|
||||
|
||||
/datum/game_mode/traitor/internal_affairs/generate_report()
|
||||
return "Nanotrasen denies any accusations of placing internal affairs agents onboard your station to eliminate inconvenient employees. Any further accusations against CentCom for such \
|
||||
actions will be met with a conversation with an official internal affairs agent."
|
||||
@@ -1,82 +0,0 @@
|
||||
/datum/game_mode
|
||||
var/list/datum/mind/wizards = list()
|
||||
var/list/datum/mind/apprentices = list()
|
||||
|
||||
/datum/game_mode/wizard
|
||||
name = "wizard"
|
||||
config_tag = "wizard"
|
||||
report_type = "wizard"
|
||||
antag_flag = ROLE_WIZARD
|
||||
false_report_weight = 10
|
||||
required_players = 20
|
||||
required_enemies = 1
|
||||
recommended_enemies = 1
|
||||
enemy_minimum_age = 14
|
||||
round_ends_with_antag_death = 1
|
||||
announce_span = "danger"
|
||||
announce_text = "There is a space wizard attacking the station!\n\
|
||||
<span class='danger'>Wizard</span>: Accomplish your objectives and cause mayhem on the station.\n\
|
||||
<span class='notice'>Crew</span>: Eliminate the wizard before they can succeed!"
|
||||
var/finished = 0
|
||||
|
||||
/datum/game_mode/wizard/pre_setup()
|
||||
var/datum/mind/wizard = antag_pick(antag_candidates)
|
||||
wizards += wizard
|
||||
wizard.assigned_role = ROLE_WIZARD
|
||||
wizard.special_role = ROLE_WIZARD
|
||||
log_game("[key_name(wizard)] has been selected as a Wizard") //TODO: Move these to base antag datum
|
||||
if(GLOB.wizardstart.len == 0)
|
||||
setup_error = "No wizard starting location found"
|
||||
return FALSE
|
||||
for(var/datum/mind/wiz in wizards)
|
||||
wiz.current.forceMove(pick(GLOB.wizardstart))
|
||||
return TRUE
|
||||
|
||||
|
||||
/datum/game_mode/wizard/post_setup()
|
||||
for(var/datum/mind/wizard in wizards)
|
||||
wizard.add_antag_datum(/datum/antagonist/wizard)
|
||||
return ..()
|
||||
|
||||
/datum/game_mode/wizard/generate_report()
|
||||
return "A dangerous Wizards' Federation individual by the name of [pick(GLOB.wizard_first)] [pick(GLOB.wizard_second)] has recently escaped confinement from an unlisted prison facility. This \
|
||||
man is a dangerous mutant with the ability to alter himself and the world around him by what he and his leaders believe to be magic. If this man attempts an attack on your station, \
|
||||
his execution is highly encouraged, as is the preservation of his body for later study."
|
||||
|
||||
|
||||
/datum/game_mode/wizard/are_special_antags_dead()
|
||||
for(var/datum/mind/wizard in wizards | apprentices)
|
||||
if(isliving(wizard.current) && wizard.current.stat!=DEAD)
|
||||
return FALSE
|
||||
|
||||
for(var/obj/item/phylactery/P in GLOB.poi_list) //TODO : IsProperlyDead()
|
||||
if(P.mind && P.mind.has_antag_datum(/datum/antagonist/wizard))
|
||||
return FALSE
|
||||
|
||||
if(SSevents.wizardmode) //If summon events was active, turn it off
|
||||
SSevents.toggleWizardmode()
|
||||
SSevents.resetFrequency()
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/game_mode/wizard/check_finished()
|
||||
. = ..()
|
||||
if(.)
|
||||
finished = TRUE
|
||||
else if(gamemode_ready && are_special_antags_dead() && !CONFIG_GET(keyed_list/continuous)[config_tag])
|
||||
finished = TRUE
|
||||
. = TRUE
|
||||
|
||||
/datum/game_mode/wizard/set_round_result()
|
||||
..()
|
||||
if(finished)
|
||||
SSticker.mode_result = "loss - wizard killed"
|
||||
SSticker.news_report = WIZARD_KILLED
|
||||
|
||||
/datum/game_mode/wizard/special_report()
|
||||
if(finished)
|
||||
return "<div class='panel redborder'><span class='redtext big'>The wizard[(wizards.len>1)?"s":""] has been killed by the crew! The Space Wizards Federation has been taught a lesson they will not soon forget!</span></div>"
|
||||
|
||||
//returns whether the mob is a wizard (or apprentice)
|
||||
/proc/iswizard(mob/living/M)
|
||||
return M.mind && M.mind.has_antag_datum(/datum/antagonist/wizard,TRUE)
|
||||
@@ -465,7 +465,7 @@
|
||||
new openingoverlaytype(loc)
|
||||
|
||||
/obj/machinery/door/airlock/cult/canAIControl(mob/user)
|
||||
return (iscultist(user) && !isAllPowerCut())
|
||||
return (IS_CULTIST(user) && !isAllPowerCut())
|
||||
|
||||
/obj/machinery/door/airlock/cult/on_break()
|
||||
if(!panel_open)
|
||||
@@ -480,7 +480,7 @@
|
||||
/obj/machinery/door/airlock/cult/allowed(mob/living/L)
|
||||
if(!density)
|
||||
return TRUE
|
||||
if(friendly || iscultist(L) || istype(L, /mob/living/simple_animal/shade) || isconstruct(L))
|
||||
if(friendly || IS_CULTIST(L) || istype(L, /mob/living/simple_animal/shade) || isconstruct(L))
|
||||
if(!stealthy)
|
||||
new openingoverlaytype(loc)
|
||||
return TRUE
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
parent_rune.attack_hand(user, modifiers)
|
||||
|
||||
/obj/structure/emergency_shield/cult/barrier/attack_animal(mob/living/simple_animal/user, list/modifiers)
|
||||
if(iscultist(user))
|
||||
if(IS_CULTIST(user))
|
||||
parent_rune.attack_animal(user)
|
||||
else
|
||||
..()
|
||||
|
||||
@@ -307,7 +307,7 @@
|
||||
var/datum/action/innate/slime/reproduce/A = new
|
||||
A.Grant(S)
|
||||
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as a pyroclastic anomaly slime?", ROLE_SENTIENCE, null, null, 100, S, POLL_IGNORE_PYROSLIME)
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as a pyroclastic anomaly slime?", ROLE_SENTIENCE, null, 100, S, POLL_IGNORE_PYROSLIME)
|
||||
if(LAZYLEN(candidates))
|
||||
var/mob/dead/observer/chosen = pick(candidates)
|
||||
S.key = chosen.key
|
||||
|
||||
@@ -125,7 +125,7 @@
|
||||
for(var/obj/effect/proc_holder/spell/knownspell in user.mind.spell_list)
|
||||
if(knownspell.type == spell)
|
||||
if(user.mind)
|
||||
if(iswizard(user))
|
||||
if(IS_WIZARD(user))
|
||||
to_chat(user,"<span class='warning'>You're already far more versed in this spell than this flimsy how-to book can provide!</span>")
|
||||
else
|
||||
to_chat(user,"<span class='warning'>You've already read this one!</span>")
|
||||
|
||||
@@ -520,7 +520,7 @@
|
||||
|
||||
possessed = TRUE
|
||||
|
||||
var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as the spirit of [user.real_name]'s blade?", ROLE_PAI, null, FALSE, 100, POLL_IGNORE_POSSESSED_BLADE)
|
||||
var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as the spirit of [user.real_name]'s blade?", ROLE_PAI, FALSE, 100, POLL_IGNORE_POSSESSED_BLADE)
|
||||
|
||||
if(LAZYLEN(candidates))
|
||||
var/mob/dead/observer/C = pick(candidates)
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
deconverted = TRUE
|
||||
rev.remove_revolutionary(FALSE, user)
|
||||
if(!silent)
|
||||
if(target.mind in SSticker.mode.cult)
|
||||
if(target.mind.has_antag_datum(/datum/antagonist/cult))
|
||||
to_chat(target, "<span class='warning'>You feel something interfering with your mental conditioning, but you resist it!</span>")
|
||||
else
|
||||
to_chat(target, "<span class='notice'>You feel a sense of peace and security. You are now protected from brainwashing.</span>")
|
||||
|
||||
@@ -542,7 +542,7 @@ GLOBAL_LIST_INIT(runed_metal_recipes, list ( \
|
||||
has_unique_girder = TRUE
|
||||
|
||||
/obj/item/stack/sheet/runed_metal/attack_self(mob/living/user)
|
||||
if(!iscultist(user))
|
||||
if(!IS_CULTIST(user))
|
||||
to_chat(user, "<span class='warning'>Only one with forbidden knowledge could hope to work this metal...</span>")
|
||||
return
|
||||
var/turf/T = get_turf(user) //we may have moved. adjust as needed...
|
||||
|
||||
@@ -210,7 +210,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "burning",
|
||||
B.name = name
|
||||
B.icon_state = icon_state
|
||||
B.inhand_icon_state = inhand_icon_state
|
||||
if(istype(A, /obj/item/cult_bastard) && !iscultist(user))
|
||||
if(istype(A, /obj/item/cult_bastard) && !IS_CULTIST(user))
|
||||
var/obj/item/cult_bastard/sword = A
|
||||
to_chat(user, "<span class='notice'>You begin to exorcise [sword].</span>")
|
||||
playsound(src,'sound/hallucinations/veryfar_noise.ogg',40,TRUE)
|
||||
@@ -219,7 +219,11 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "burning",
|
||||
for(var/obj/item/soulstone/SS in sword.contents)
|
||||
SS.required_role = null
|
||||
for(var/mob/living/simple_animal/shade/EX in SS)
|
||||
SSticker.mode.remove_cultist(EX.mind, 1, 0)
|
||||
var/datum/antagonist/cult/cultist = EX.mind.has_antag_datum(/datum/antagonist/cult)
|
||||
if (cultist)
|
||||
cultist.silent = TRUE
|
||||
cultist.on_removal()
|
||||
|
||||
EX.icon_state = "shade_holy"
|
||||
EX.name = "Purified [EX.name]"
|
||||
SS.release_shades(user)
|
||||
@@ -227,7 +231,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "burning",
|
||||
new /obj/item/nullrod/claymore(get_turf(sword))
|
||||
user.visible_message("<span class='notice'>[user] purifies [sword]!</span>")
|
||||
qdel(sword)
|
||||
else if(istype(A, /obj/item/soulstone) && !iscultist(user))
|
||||
else if(istype(A, /obj/item/soulstone) && !IS_CULTIST(user))
|
||||
var/obj/item/soulstone/SS = A
|
||||
if(SS.theme == THEME_HOLY)
|
||||
return
|
||||
@@ -241,8 +245,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "burning",
|
||||
for(var/mob/M in SS.contents)
|
||||
if(M.mind)
|
||||
SS.icon_state = "purified_soulstone2"
|
||||
if(iscultist(M))
|
||||
SSticker.mode.remove_cultist(M.mind, FALSE, FALSE)
|
||||
M.mind?.remove_antag_datum(/datum/antagonist/cult)
|
||||
for(var/mob/living/simple_animal/shade/EX in SS)
|
||||
EX.icon_state = "ghost1"
|
||||
EX.name = "Purified [initial(EX.name)]"
|
||||
|
||||
@@ -340,7 +340,7 @@
|
||||
|
||||
/obj/structure/girder/cult/attackby(obj/item/W, mob/user, params)
|
||||
add_fingerprint(user)
|
||||
if(istype(W, /obj/item/melee/cultblade/dagger) && iscultist(user)) //Cultists can demolish cult girders instantly with their tomes
|
||||
if(istype(W, /obj/item/melee/cultblade/dagger) && IS_CULTIST(user)) //Cultists can demolish cult girders instantly with their tomes
|
||||
user.visible_message("<span class='warning'>[user] strikes [src] with [W]!</span>", "<span class='notice'>You demolish [src].</span>")
|
||||
new /obj/item/stack/sheet/runed_metal(drop_location(), 1)
|
||||
qdel(src)
|
||||
|
||||
@@ -293,8 +293,6 @@ GLOBAL_VAR(restart_counter)
|
||||
if (server_name)
|
||||
s += "<b>[server_name]</b> — "
|
||||
features += "[CONFIG_GET(flag/norespawn) ? "no " : ""]respawn"
|
||||
if(CONFIG_GET(flag/allow_vote_mode))
|
||||
features += "vote"
|
||||
if(CONFIG_GET(flag/allow_ai))
|
||||
features += "AI allowed"
|
||||
hostedby = CONFIG_GET(string/hostedby)
|
||||
|
||||
@@ -416,10 +416,7 @@
|
||||
if(!check_rights(0))
|
||||
return
|
||||
|
||||
var/dat = {"
|
||||
<center><B>Game Panel</B></center><hr>\n
|
||||
<A href='?src=[REF(src)];[HrefToken()];c_mode=1'>Change Game Mode</A><br>
|
||||
"}
|
||||
var/dat = "<center><B>Game Panel</B></center><hr>"
|
||||
if(GLOB.master_mode == "secret")
|
||||
dat += "<A href='?src=[REF(src)];[HrefToken()];f_secret=1'>(Force Secret Mode)</A><br>"
|
||||
if(SSticker.is_mode("dynamic"))
|
||||
|
||||
@@ -101,7 +101,7 @@ GLOBAL_LIST_INIT(admin_verbs_fun, list(
|
||||
/client/proc/set_dynex_scale,
|
||||
/client/proc/drop_dynex_bomb,
|
||||
/client/proc/cinematic,
|
||||
/client/proc/one_click_antag,
|
||||
/client/proc/summon_ert,
|
||||
/client/proc/cmd_admin_add_freeform_ai_law,
|
||||
/client/proc/object_say,
|
||||
/client/proc/toggle_random_events,
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
bodies += possessable
|
||||
|
||||
var/question = "Would you like to be [group_name]?"
|
||||
var/list/candidates = pollCandidatesForMobs(question, ROLE_PAI, null, FALSE, 100, bodies)
|
||||
var/list/candidates = pollCandidatesForMobs(question, ROLE_PAI, FALSE, 100, bodies)
|
||||
while(LAZYLEN(candidates) && LAZYLEN(bodies))
|
||||
var/mob/dead/observer/C = pick_n_take(candidates)
|
||||
var/mob/living/body = pick_n_take(bodies)
|
||||
|
||||
@@ -47,116 +47,6 @@
|
||||
to_chat(usr, "<span class='danger'>ERROR: Mob not found.</span>", confidential = TRUE)
|
||||
return
|
||||
cmd_show_exp_panel(M.client)
|
||||
else if(href_list["makeAntag"])
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
if (!SSticker.mode)
|
||||
to_chat(usr, "<span class='danger'>Not until the round starts!</span>", confidential = TRUE)
|
||||
return
|
||||
switch(href_list["makeAntag"])
|
||||
if("traitors")
|
||||
var/maxCount = input("Set number of Traitors","Set Traitor Count (max)",1) as num|null
|
||||
if(src.makeTraitors(maxCount))
|
||||
message_admins("[key_name_admin(usr)] created [maxCount] traitor(s).")
|
||||
log_admin("[key_name(usr)] created [maxCount] traitor(s).")
|
||||
else
|
||||
message_admins("[key_name_admin(usr)] tried to create [maxCount] traitor(s). Unfortunately, there were no candidates available.")
|
||||
log_admin("[key_name(usr)] failed to create [maxCount] traitor(s).")
|
||||
if("changelings")
|
||||
var/maxCount = input("Set number of Changelings","Set Changeling Count (max)",1) as num|null
|
||||
if(src.makeChangelings(maxCount))
|
||||
message_admins("[key_name(usr)] created [maxCount] changelings.")
|
||||
log_admin("[key_name(usr)] created [maxCount] changelings.")
|
||||
else
|
||||
message_admins("[key_name_admin(usr)] tried to create [maxCount] changelings. Unfortunately, there were no candidates available.")
|
||||
log_admin("[key_name(usr)] failed to create [maxCount] changelings.")
|
||||
if("revs")
|
||||
var/maxCount = input("Set number of Revolutionaries","Set Revolutionaries Count (max)",1) as num|null
|
||||
if(src.makeRevs(maxCount))
|
||||
message_admins("[key_name(usr)] started a revolution with [maxCount] freedom fighters.")
|
||||
log_admin("[key_name(usr)] started a [maxCount] freedom fighters.")
|
||||
else
|
||||
message_admins("[key_name_admin(usr)] tried to start a revolution with [maxCount] freedom fighters. Unfortunately, there were no candidates available.")
|
||||
log_admin("[key_name(usr)] failed to start a revolution with [maxCount] freedom fighters.")
|
||||
if("cult")
|
||||
var/maxCount = input("Set number of Cultists","Set Cultist Count (max)",1) as num|null
|
||||
if(src.makeCult(maxCount))
|
||||
message_admins("[key_name(usr)] started a cult with [maxCount] cultists.")
|
||||
log_admin("[key_name(usr)] started a cult with [maxCount] cultists.")
|
||||
else
|
||||
message_admins("[key_name_admin(usr)] tried to start a cult with [maxCount] cultists. Unfortunately, there were no candidates available.")
|
||||
log_admin("[key_name(usr)] failed to start a cult with [maxCount] cultists.")
|
||||
if("wizard")
|
||||
message_admins("[key_name(usr)] is creating a wizard...")
|
||||
if(src.makeWizard())
|
||||
message_admins("[key_name(usr)] created a wizard.")
|
||||
log_admin("[key_name(usr)] created a wizard.")
|
||||
else
|
||||
message_admins("[key_name_admin(usr)] tried to create a wizard. Unfortunately, there were no candidates available.")
|
||||
log_admin("[key_name(usr)] failed to create a wizard.")
|
||||
if("nukeops")
|
||||
message_admins("[key_name(usr)] is creating a nuke team...")
|
||||
var/maxCount = input("Set number of Nuke OPs","Set Nuke OP Count (max)",5) as num|null
|
||||
if(src.makeNukeTeam(maxCount))
|
||||
message_admins("[key_name(usr)] created a nuke team with [maxCount] operatives")
|
||||
log_admin("[key_name(usr)] created a nuke team with [maxCount] operatives")
|
||||
else
|
||||
message_admins("[key_name_admin(usr)] tried to create a nuke team with [maxCount] operatives Unfortunately, there were not enough candidates available.")
|
||||
log_admin("[key_name(usr)] failed to create a nuke team with [maxCount] operatives.")
|
||||
if("ninja")
|
||||
message_admins("[key_name(usr)] spawned a ninja.")
|
||||
log_admin("[key_name(usr)] spawned a ninja.")
|
||||
src.makeSpaceNinja()
|
||||
if("aliens")
|
||||
message_admins("[key_name(usr)] started an alien infestation.")
|
||||
log_admin("[key_name(usr)] started an alien infestation.")
|
||||
src.makeAliens()
|
||||
if("deathsquad")
|
||||
message_admins("[key_name(usr)] is creating a death squad...")
|
||||
if(src.makeDeathsquad())
|
||||
message_admins("[key_name(usr)] created a death squad.")
|
||||
log_admin("[key_name(usr)] created a death squad.")
|
||||
else
|
||||
message_admins("[key_name_admin(usr)] tried to create a death squad. Unfortunately, there were not enough candidates available.")
|
||||
log_admin("[key_name(usr)] failed to create a death squad.")
|
||||
if("blob")
|
||||
var/strength = input("Set Blob Resource Gain Rate","Set Resource Rate",1) as num|null
|
||||
if(!strength)
|
||||
return
|
||||
message_admins("[key_name(usr)] spawned a blob with base resource gain [strength].")
|
||||
log_admin("[key_name(usr)] spawned a blob with base resource gain [strength].")
|
||||
new/datum/round_event/ghost_role/blob(TRUE, strength)
|
||||
if("centcom")
|
||||
message_admins("[key_name(usr)] is creating a CentCom response team...")
|
||||
if(src.makeEmergencyresponseteam())
|
||||
message_admins("[key_name(usr)] created a CentCom response team.")
|
||||
log_admin("[key_name(usr)] created a CentCom response team.")
|
||||
else
|
||||
message_admins("[key_name_admin(usr)] tried to create a CentCom response team. Unfortunately, there were not enough candidates available.")
|
||||
log_admin("[key_name(usr)] failed to create a CentCom response team.")
|
||||
if("abductors")
|
||||
message_admins("[key_name(usr)] is creating an abductor team...")
|
||||
if(src.makeAbductorTeam())
|
||||
message_admins("[key_name(usr)] created an abductor team.")
|
||||
log_admin("[key_name(usr)] created an abductor team.")
|
||||
else
|
||||
message_admins("[key_name_admin(usr)] tried to create an abductor team. Unfortunately there were not enough candidates available.")
|
||||
log_admin("[key_name(usr)] failed to create an abductor team.")
|
||||
if("revenant")
|
||||
if(src.makeRevenant())
|
||||
message_admins("[key_name(usr)] created a revenant.")
|
||||
log_admin("[key_name(usr)] created a revenant.")
|
||||
else
|
||||
message_admins("[key_name_admin(usr)] tried to create a revenant. Unfortunately, there were no candidates available.")
|
||||
log_admin("[key_name(usr)] failed to create a revenant.")
|
||||
if("nerd")
|
||||
if(src.makeNerd())
|
||||
message_admins("[key_name(usr)] created a nanotrasen emergency response drone.")
|
||||
log_admin("[key_name(usr)] created a nanotrasen emergency response drone.")
|
||||
else
|
||||
message_admins("[key_name_admin(usr)] tried to create a nanotrasen emergency response drone. Unfortunately, there were no candidates available.")
|
||||
log_admin("[key_name(usr)] failed to create a nanotrasen emergency response drone.")
|
||||
|
||||
else if(href_list["forceevent"])
|
||||
if(!check_rights(R_FUN))
|
||||
return
|
||||
@@ -626,12 +516,6 @@
|
||||
return
|
||||
cmd_admin_mute(href_list["mute"], text2num(href_list["mute_type"]))
|
||||
|
||||
else if(href_list["c_mode"])
|
||||
return HandleCMode()
|
||||
|
||||
else if(href_list["f_secret"])
|
||||
return HandleFSecret()
|
||||
|
||||
else if(href_list["f_dynamic_roundstart"])
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
@@ -731,38 +615,6 @@
|
||||
message_admins("[key_name(usr)] set 'forced_threat_level' to [GLOB.dynamic_forced_threat_level].")
|
||||
dynamic_mode_options(usr)
|
||||
|
||||
else if(href_list["c_mode2"])
|
||||
if(!check_rights(R_ADMIN|R_SERVER))
|
||||
return
|
||||
|
||||
if (SSticker.HasRoundStarted())
|
||||
if (tgui_alert(usr, "The game has already started. Would you like to save this as the default mode effective next round?", "Save mode", list("Yes", "Cancel"), timeout = 0) == "Yes")
|
||||
SSticker.save_mode(href_list["c_mode2"])
|
||||
HandleCMode()
|
||||
return
|
||||
GLOB.master_mode = href_list["c_mode2"]
|
||||
log_admin("[key_name(usr)] set the mode as [GLOB.master_mode].")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] set the mode as [GLOB.master_mode].</span>")
|
||||
to_chat(world, "<span class='adminnotice'><b>The mode is now: [GLOB.master_mode]</b></span>", confidential = TRUE)
|
||||
Game() // updates the main game menu
|
||||
if (tgui_alert(usr, "Would you like to save this as the default mode for the server?", "Save mode", list("Yes", "No"), timeout = 0) == "Yes")
|
||||
SSticker.save_mode(GLOB.master_mode)
|
||||
HandleCMode()
|
||||
|
||||
else if(href_list["f_secret2"])
|
||||
if(!check_rights(R_ADMIN|R_SERVER))
|
||||
return
|
||||
|
||||
if(SSticker.HasRoundStarted())
|
||||
return alert(usr, "The game has already started.", null, null, null, null)
|
||||
if(GLOB.master_mode != "secret")
|
||||
return alert(usr, "The game mode has to be secret!", null, null, null, null)
|
||||
GLOB.secret_force_mode = href_list["f_secret2"]
|
||||
log_admin("[key_name(usr)] set the forced secret mode as [GLOB.secret_force_mode].")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] set the forced secret mode as [GLOB.secret_force_mode].</span>")
|
||||
Game() // updates the main game menu
|
||||
HandleFSecret()
|
||||
|
||||
else if(href_list["monkeyone"])
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
@@ -2203,30 +2055,3 @@
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
GLOB.interviews.ui_interact(usr)
|
||||
|
||||
/datum/admins/proc/HandleCMode()
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
var/dat = {"<B>What mode do you wish to play?</B><HR>"}
|
||||
for(var/mode in config.modes)
|
||||
dat += {"<A href='?src=[REF(src)];[HrefToken()];c_mode2=[mode]'>[config.mode_names[mode]]</A><br>"}
|
||||
dat += {"<A href='?src=[REF(src)];[HrefToken()];c_mode2=secret'>Secret</A><br>"}
|
||||
dat += {"<A href='?src=[REF(src)];[HrefToken()];c_mode2=random'>Random</A><br>"}
|
||||
dat += {"Now: [GLOB.master_mode]"}
|
||||
usr << browse(dat, "window=c_mode")
|
||||
|
||||
/datum/admins/proc/HandleFSecret()
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
if(SSticker.HasRoundStarted())
|
||||
return alert(usr, "The game has already started.", null, null, null, null)
|
||||
if(GLOB.master_mode != "secret")
|
||||
return alert(usr, "The game mode has to be secret!", null, null, null, null)
|
||||
var/dat = {"<B>What game mode do you want to force secret to be? Use this if you want to change the game mode, but want the players to believe it's secret. This will only work if the current game mode is secret.</B><HR>"}
|
||||
for(var/mode in config.modes)
|
||||
dat += {"<A href='?src=[REF(src)];[HrefToken()];f_secret2=[mode]'>[config.mode_names[mode]]</A><br>"}
|
||||
dat += {"<A href='?src=[REF(src)];[HrefToken()];f_secret2=secret'>Random (default)</A><br>"}
|
||||
dat += {"Now: [GLOB.secret_force_mode]"}
|
||||
usr << browse(dat, "window=f_secret")
|
||||
|
||||
@@ -1,244 +1,6 @@
|
||||
/// If we spawn an ERT with the "choose experienced leader" option, select the leader from the top X playtimes
|
||||
#define ERT_EXPERIENCED_LEADER_CHOOSE_TOP 3
|
||||
|
||||
/client/proc/one_click_antag()
|
||||
set name = "Create Antagonist"
|
||||
set desc = "Auto-create an antagonist of your choice"
|
||||
set category = "Admin.Events"
|
||||
|
||||
if(holder)
|
||||
holder.one_click_antag()
|
||||
return
|
||||
|
||||
|
||||
/datum/admins/proc/one_click_antag()
|
||||
var/dat = {"
|
||||
<a href='?src=[REF(src)];[HrefToken()];makeAntag=traitors'>Make Traitors</a><br>
|
||||
<a href='?src=[REF(src)];[HrefToken()];makeAntag=changelings'>Make Changelings</a><br>
|
||||
<a href='?src=[REF(src)];[HrefToken()];makeAntag=revs'>Make Revs</a><br>
|
||||
<a href='?src=[REF(src)];[HrefToken()];makeAntag=cult'>Make Cult</a><br>
|
||||
<a href='?src=[REF(src)];[HrefToken()];makeAntag=blob'>Make Blob</a><br>
|
||||
<a href='?src=[REF(src)];[HrefToken()];makeAntag=wizard'>Make Wizard (Requires Ghosts)</a><br>
|
||||
<a href='?src=[REF(src)];[HrefToken()];makeAntag=nukeops'>Make Nuke Team (Requires Ghosts)</a><br>
|
||||
<a href='?src=[REF(src)];[HrefToken()];makeAntag=centcom'>Make CentCom Response Team (Requires Ghosts)</a><br>
|
||||
<a href='?src=[REF(src)];[HrefToken()];makeAntag=abductors'>Make Abductor Team (Requires Ghosts)</a><br>
|
||||
<a href='?src=[REF(src)];[HrefToken()];makeAntag=revenant'>Make Revenant (Requires Ghost)</a><br>
|
||||
<a href='?src=[REF(src)];[HrefToken()];makeAntag=nerd'>Make N.E.R.D. (Requires Ghost)</a><br>
|
||||
"}
|
||||
var/datum/browser/popup = new(usr, "oneclickantag", "Quick-Create Antagonist", 400, 400)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
/datum/admins/proc/isReadytoRumble(mob/living/carbon/human/applicant, targetrole, onstation = TRUE, conscious = TRUE)
|
||||
if(applicant.mind.special_role)
|
||||
return FALSE
|
||||
if(!(targetrole in applicant.client.prefs.be_special))
|
||||
return FALSE
|
||||
if(onstation)
|
||||
var/turf/T = get_turf(applicant)
|
||||
if(!is_station_level(T.z))
|
||||
return FALSE
|
||||
if(conscious && applicant.stat) //incase you don't care about a certain antag being unconcious when made, ie if they have selfhealing abilities.
|
||||
return FALSE
|
||||
if(!considered_alive(applicant.mind) || considered_afk(applicant.mind)) //makes sure the player isn't a zombie, brain, or just afk all together
|
||||
return FALSE
|
||||
return !is_banned_from(applicant.ckey, list(targetrole, ROLE_SYNDICATE))
|
||||
|
||||
|
||||
/datum/admins/proc/makeTraitors(maxCount = 3)
|
||||
var/datum/game_mode/traitor/temp = new
|
||||
|
||||
if(CONFIG_GET(flag/protect_roles_from_antagonist))
|
||||
temp.restricted_jobs += temp.protected_jobs
|
||||
|
||||
if(CONFIG_GET(flag/protect_assistant_from_antagonist))
|
||||
temp.restricted_jobs += "Assistant"
|
||||
|
||||
var/list/mob/living/carbon/human/candidates = list()
|
||||
var/mob/living/carbon/human/H = null
|
||||
|
||||
for(var/mob/living/carbon/human/applicant in GLOB.player_list)
|
||||
if(isReadytoRumble(applicant, ROLE_TRAITOR))
|
||||
if(temp.age_check(applicant.client))
|
||||
if(!(applicant.job in temp.restricted_jobs))
|
||||
candidates += applicant
|
||||
|
||||
if(candidates.len)
|
||||
var/numTraitors = min(candidates.len, maxCount)
|
||||
|
||||
for(var/i = 0, i<numTraitors, i++)
|
||||
H = pick(candidates)
|
||||
H.mind.make_Traitor()
|
||||
candidates.Remove(H)
|
||||
|
||||
return TRUE
|
||||
|
||||
|
||||
return FALSE
|
||||
|
||||
|
||||
/datum/admins/proc/makeChangelings(maxCount = 3)
|
||||
|
||||
var/datum/game_mode/changeling/temp = new
|
||||
if(CONFIG_GET(flag/protect_roles_from_antagonist))
|
||||
temp.restricted_jobs += temp.protected_jobs
|
||||
|
||||
if(CONFIG_GET(flag/protect_assistant_from_antagonist))
|
||||
temp.restricted_jobs += "Assistant"
|
||||
|
||||
var/list/mob/living/carbon/human/candidates = list()
|
||||
var/mob/living/carbon/human/H = null
|
||||
|
||||
for(var/mob/living/carbon/human/applicant in GLOB.player_list)
|
||||
if(isReadytoRumble(applicant, ROLE_CHANGELING))
|
||||
if(temp.age_check(applicant.client))
|
||||
if(!(applicant.job in temp.restricted_jobs))
|
||||
candidates += applicant
|
||||
|
||||
if(candidates.len)
|
||||
var/numChangelings = min(candidates.len, maxCount)
|
||||
|
||||
for(var/i = 0, i<numChangelings, i++)
|
||||
H = pick(candidates)
|
||||
H.mind.make_Changeling()
|
||||
candidates.Remove(H)
|
||||
|
||||
return TRUE
|
||||
|
||||
return FALSE
|
||||
|
||||
/datum/admins/proc/makeRevs(maxCount = 3)
|
||||
|
||||
var/datum/game_mode/revolution/temp = new
|
||||
if(CONFIG_GET(flag/protect_roles_from_antagonist))
|
||||
temp.restricted_jobs += temp.protected_jobs
|
||||
|
||||
if(CONFIG_GET(flag/protect_assistant_from_antagonist))
|
||||
temp.restricted_jobs += "Assistant"
|
||||
|
||||
var/list/mob/living/carbon/human/candidates = list()
|
||||
var/mob/living/carbon/human/H = null
|
||||
|
||||
for(var/mob/living/carbon/human/applicant in GLOB.player_list)
|
||||
if(isReadytoRumble(applicant, ROLE_REV))
|
||||
if(temp.age_check(applicant.client))
|
||||
if(!(applicant.job in temp.restricted_jobs))
|
||||
candidates += applicant
|
||||
|
||||
if(candidates.len)
|
||||
var/numRevs = min(candidates.len, maxCount)
|
||||
|
||||
for(var/i = 0, i<numRevs, i++)
|
||||
H = pick(candidates)
|
||||
H.mind.make_Rev()
|
||||
candidates.Remove(H)
|
||||
return TRUE
|
||||
|
||||
return FALSE
|
||||
|
||||
/datum/admins/proc/makeWizard()
|
||||
|
||||
var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you wish to be considered for the position of a Wizard Foundation 'diplomat'?", ROLE_WIZARD, null)
|
||||
|
||||
var/mob/dead/observer/selected = pick_n_take(candidates)
|
||||
|
||||
var/mob/living/carbon/human/new_character = makeBody(selected)
|
||||
new_character.mind.make_Wizard()
|
||||
return TRUE
|
||||
|
||||
|
||||
/datum/admins/proc/makeCult(maxCount = 4)
|
||||
var/datum/game_mode/cult/temp = new
|
||||
if(CONFIG_GET(flag/protect_roles_from_antagonist))
|
||||
temp.restricted_jobs += temp.protected_jobs
|
||||
|
||||
if(CONFIG_GET(flag/protect_assistant_from_antagonist))
|
||||
temp.restricted_jobs += "Assistant"
|
||||
|
||||
var/list/mob/living/carbon/human/candidates = list()
|
||||
var/mob/living/carbon/human/H = null
|
||||
|
||||
for(var/mob/living/carbon/human/applicant in GLOB.player_list)
|
||||
if(isReadytoRumble(applicant, ROLE_CULTIST))
|
||||
if(temp.age_check(applicant.client))
|
||||
if(!(applicant.job in temp.restricted_jobs))
|
||||
candidates += applicant
|
||||
|
||||
if(candidates.len)
|
||||
var/numCultists = min(candidates.len, maxCount)
|
||||
|
||||
for(var/i = 0, i<numCultists, i++)
|
||||
H = pick(candidates)
|
||||
H.mind.make_Cultist()
|
||||
candidates.Remove(H)
|
||||
|
||||
return TRUE
|
||||
|
||||
return FALSE
|
||||
|
||||
|
||||
|
||||
/datum/admins/proc/makeNukeTeam(maxCount = 5)
|
||||
var/datum/game_mode/nuclear/temp = new
|
||||
var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you wish to be considered for a nuke team being sent in?", ROLE_OPERATIVE, temp)
|
||||
var/list/mob/dead/observer/chosen = list()
|
||||
var/mob/dead/observer/theghost = null
|
||||
|
||||
if(candidates.len)
|
||||
var/numagents = maxCount
|
||||
var/agentcount = 0
|
||||
|
||||
for(var/i = 0, i<numagents,i++)
|
||||
shuffle_inplace(candidates) //More shuffles means more randoms
|
||||
for(var/mob/j in candidates)
|
||||
if(!j || !j.client)
|
||||
candidates.Remove(j)
|
||||
continue
|
||||
|
||||
theghost = j
|
||||
candidates.Remove(theghost)
|
||||
chosen += theghost
|
||||
agentcount++
|
||||
break
|
||||
//Making sure we have atleast 3 Nuke agents, because less than that is kinda bad
|
||||
if(agentcount < 3)
|
||||
return FALSE
|
||||
|
||||
//Let's find the spawn locations
|
||||
var/leader_chosen = FALSE
|
||||
var/datum/team/nuclear/nuke_team
|
||||
for(var/mob/c in chosen)
|
||||
var/mob/living/carbon/human/new_character=makeBody(c)
|
||||
if(!leader_chosen)
|
||||
leader_chosen = TRUE
|
||||
var/datum/antagonist/nukeop/N = new_character.mind.add_antag_datum(/datum/antagonist/nukeop/leader)
|
||||
nuke_team = N.nuke_team
|
||||
else
|
||||
new_character.mind.add_antag_datum(/datum/antagonist/nukeop,nuke_team)
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/datum/admins/proc/makeAliens()
|
||||
var/datum/round_event/ghost_role/alien_infestation/E = new(FALSE)
|
||||
E.spawncount = 3
|
||||
// TODO The fact we have to do this rather than just have events start
|
||||
// when we ask them to, is bad.
|
||||
E.processing = TRUE
|
||||
return TRUE
|
||||
|
||||
/datum/admins/proc/makeSpaceNinja()
|
||||
new /datum/round_event/ghost_role/space_ninja()
|
||||
return TRUE
|
||||
|
||||
// DEATH SQUADS
|
||||
/datum/admins/proc/makeDeathsquad()
|
||||
return makeEmergencyresponseteam(/datum/ert/deathsquad)
|
||||
|
||||
// CENTCOM RESPONSE TEAM
|
||||
|
||||
/datum/admins/proc/makeERTTemplateModified(list/settings)
|
||||
@@ -456,40 +218,17 @@
|
||||
|
||||
return
|
||||
|
||||
//Abductors
|
||||
/datum/admins/proc/makeAbductorTeam()
|
||||
new /datum/round_event/ghost_role/abductor
|
||||
return TRUE
|
||||
/client/proc/summon_ert()
|
||||
set category = "Admin.Fun"
|
||||
set name = "Summon ERT"
|
||||
set desc = "Summons an emergency response team"
|
||||
|
||||
/datum/admins/proc/makeRevenant()
|
||||
new /datum/round_event/ghost_role/revenant(TRUE, TRUE)
|
||||
return TRUE
|
||||
|
||||
/datum/admins/proc/makeNerd()
|
||||
var/spawnpoint = pick(GLOB.blobstart)
|
||||
var/list/mob/dead/observer/candidates
|
||||
var/mob/dead/observer/chosen_candidate
|
||||
var/mob/living/simple_animal/drone/nerd
|
||||
var/teamsize
|
||||
|
||||
teamsize = input(usr, "How many drones?", "N.E.R.D. team size", 2) as num|null
|
||||
|
||||
if(teamsize <= 0)
|
||||
return FALSE
|
||||
|
||||
candidates = pollGhostCandidates("Do you wish to be considered for a Nanotrasen emergency response drone?", "Drone")
|
||||
|
||||
if(length(candidates) == 0)
|
||||
return FALSE
|
||||
|
||||
while(length(candidates) && teamsize)
|
||||
chosen_candidate = pick(candidates)
|
||||
candidates -= chosen_candidate
|
||||
nerd = new /mob/living/simple_animal/drone/classic(spawnpoint)
|
||||
nerd.key = chosen_candidate.key
|
||||
log_game("[key_name(nerd)] has been selected as a Nanotrasen emergency response drone")
|
||||
teamsize--
|
||||
|
||||
return TRUE
|
||||
message_admins("[key_name(usr)] is creating a CentCom response team...")
|
||||
if(holder?.makeEmergencyresponseteam())
|
||||
message_admins("[key_name(usr)] created a CentCom response team.")
|
||||
log_admin("[key_name(usr)] created a CentCom response team.")
|
||||
else
|
||||
message_admins("[key_name_admin(usr)] tried to create a CentCom response team. Unfortunately, there were not enough candidates available.")
|
||||
log_admin("[key_name(usr)] failed to create a CentCom response team.")
|
||||
|
||||
#undef ERT_EXPERIENCED_LEADER_CHOOSE_TOP
|
||||
@@ -27,7 +27,7 @@
|
||||
prayer_type = "CHAPLAIN PRAYER"
|
||||
if(GLOB.deity)
|
||||
deity = GLOB.deity
|
||||
else if(iscultist(usr))
|
||||
else if(IS_CULTIST(usr))
|
||||
cross.icon_state = "tome"
|
||||
font_color = "red"
|
||||
prayer_type = "CULTIST PRAYER"
|
||||
|
||||
@@ -555,6 +555,32 @@
|
||||
message_admins("[key_name_admin(holder)] has Un-Fully Immersed \
|
||||
everyone!")
|
||||
log_admin("[key_name(holder)] has Un-Fully Immersed everyone.")
|
||||
if("makeNerd")
|
||||
var/spawnpoint = pick(GLOB.blobstart)
|
||||
var/list/mob/dead/observer/candidates
|
||||
var/mob/dead/observer/chosen_candidate
|
||||
var/mob/living/simple_animal/drone/nerd
|
||||
var/teamsize
|
||||
|
||||
teamsize = input(usr, "How many drones?", "N.E.R.D. team size", 2) as num|null
|
||||
|
||||
if(teamsize <= 0)
|
||||
return FALSE
|
||||
|
||||
candidates = pollGhostCandidates("Do you wish to be considered for a Nanotrasen emergency response drone?", "Drone")
|
||||
|
||||
if(length(candidates) == 0)
|
||||
return FALSE
|
||||
|
||||
while(length(candidates) && teamsize)
|
||||
chosen_candidate = pick(candidates)
|
||||
candidates -= chosen_candidate
|
||||
nerd = new /mob/living/simple_animal/drone/classic(spawnpoint)
|
||||
nerd.key = chosen_candidate.key
|
||||
log_game("[key_name(nerd)] has been selected as a Nanotrasen emergency response drone")
|
||||
teamsize--
|
||||
|
||||
return TRUE
|
||||
if(E)
|
||||
E.processing = FALSE
|
||||
if(E.announceWhen>0)
|
||||
|
||||
@@ -128,7 +128,7 @@ GLOBAL_LIST_EMPTY(antagonists)
|
||||
/datum/antagonist/proc/replace_banned_player()
|
||||
set waitfor = FALSE
|
||||
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as a [name]?", "[name]", null, job_rank, 50, owner.current)
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as a [name]?", "[name]", job_rank, 50, owner.current)
|
||||
if(LAZYLEN(candidates))
|
||||
var/mob/dead/observer/C = pick(candidates)
|
||||
to_chat(owner, "Your mob has been taken over by a ghost! Appeal your job ban if you want to avoid this in the future!")
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
//Returns MINDS of the assigned antags of given type/subtypes
|
||||
/proc/get_antag_minds(antag_type,specific = FALSE)
|
||||
RETURN_TYPE(/list/datum/mind)
|
||||
. = list()
|
||||
for(var/datum/antagonist/A in GLOB.antagonists)
|
||||
if(!A.owner)
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
if(used)
|
||||
to_chat(H, "<span class='warning'>You already used this contract!</span>")
|
||||
return
|
||||
var/list/candidates = pollCandidatesForMob("Do you want to play as a wizard's [href_list["school"]] apprentice?", ROLE_WIZARD, null, ROLE_WIZARD, 150, src)
|
||||
var/list/candidates = pollCandidatesForMob("Do you want to play as a wizard's [href_list["school"]] apprentice?", ROLE_WIZARD, ROLE_WIZARD, 150, src)
|
||||
if(LAZYLEN(candidates))
|
||||
if(QDELETED(src))
|
||||
return
|
||||
@@ -132,7 +132,7 @@
|
||||
return
|
||||
|
||||
to_chat(user, "<span class='notice'>You activate [src] and wait for confirmation.</span>")
|
||||
var/list/nuke_candidates = pollGhostCandidates("Do you want to play as a syndicate [borg_to_spawn ? "[lowertext(borg_to_spawn)] cyborg":"operative"]?", ROLE_OPERATIVE, null, ROLE_OPERATIVE, 150, POLL_IGNORE_SYNDICATE)
|
||||
var/list/nuke_candidates = pollGhostCandidates("Do you want to play as a syndicate [borg_to_spawn ? "[lowertext(borg_to_spawn)] cyborg":"operative"]?", ROLE_OPERATIVE, ROLE_OPERATIVE, 150, POLL_IGNORE_SYNDICATE)
|
||||
if(LAZYLEN(nuke_candidates))
|
||||
if(QDELETED(src) || !check_usability(user))
|
||||
return
|
||||
@@ -246,7 +246,7 @@
|
||||
return
|
||||
if(used)
|
||||
return
|
||||
var/list/candidates = pollCandidatesForMob("Do you want to play as a [initial(demon_type.name)]?", ROLE_ALIEN, null, ROLE_ALIEN, 50, src)
|
||||
var/list/candidates = pollCandidatesForMob("Do you want to play as a [initial(demon_type.name)]?", ROLE_ALIEN, ROLE_ALIEN, 50, src)
|
||||
if(LAZYLEN(candidates))
|
||||
if(used || QDELETED(src))
|
||||
return
|
||||
|
||||
@@ -142,7 +142,7 @@
|
||||
|
||||
B.naut = TRUE //temporary placeholder to prevent creation of more than one per factory.
|
||||
to_chat(src, "<span class='notice'>You attempt to produce a blobbernaut.</span>")
|
||||
var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as a [blobstrain.name] blobbernaut?", ROLE_BLOB, null, ROLE_BLOB, 50) //players must answer rapidly
|
||||
var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as a [blobstrain.name] blobbernaut?", ROLE_BLOB, ROLE_BLOB, 50) //players must answer rapidly
|
||||
if(LAZYLEN(candidates)) //if we got at least one candidate, they're a blobbernaut now.
|
||||
B.max_integrity = initial(B.max_integrity) * 0.25 //factories that produced a blobbernaut have much lower health
|
||||
B.obj_integrity = min(B.obj_integrity, B.max_integrity)
|
||||
|
||||
@@ -20,14 +20,12 @@
|
||||
return team
|
||||
|
||||
/datum/antagonist/brother/on_gain()
|
||||
SSticker.mode.brothers += owner
|
||||
objectives += team.objectives
|
||||
owner.special_role = special_role
|
||||
finalize_brother()
|
||||
return ..()
|
||||
|
||||
/datum/antagonist/brother/on_removal()
|
||||
SSticker.mode.brothers -= owner
|
||||
if(owner.current)
|
||||
to_chat(owner.current,"<span class='userdanger'>You are no longer the [special_role]!</span>")
|
||||
owner.special_role = null
|
||||
|
||||
@@ -48,6 +48,21 @@
|
||||
|
||||
var/static/list/all_powers = typecacheof(/datum/action/changeling,TRUE)
|
||||
|
||||
var/static/list/slot2type = list(
|
||||
"head" = /obj/item/clothing/head/changeling,
|
||||
"wear_mask" = /obj/item/clothing/mask/changeling,
|
||||
"back" = /obj/item/changeling,
|
||||
"wear_suit" = /obj/item/clothing/suit/changeling,
|
||||
"w_uniform" = /obj/item/clothing/under/changeling,
|
||||
"shoes" = /obj/item/clothing/shoes/changeling,
|
||||
"belt" = /obj/item/changeling,
|
||||
"gloves" = /obj/item/clothing/gloves/changeling,
|
||||
"glasses" = /obj/item/clothing/glasses/changeling,
|
||||
"ears" = /obj/item/changeling,
|
||||
"wear_id" = /obj/item/changeling/id,
|
||||
"s_store" = /obj/item/changeling,
|
||||
)
|
||||
|
||||
/datum/antagonist/changeling/New()
|
||||
. = ..()
|
||||
for(var/datum/antagonist/changeling/C in GLOB.antagonists)
|
||||
@@ -496,6 +511,120 @@
|
||||
C.updateappearance(mutcolor_update=1)
|
||||
C.domutcheck()
|
||||
|
||||
/datum/antagonist/changeling/proc/transform(mob/living/carbon/human/user, datum/changelingprofile/chosen_prof)
|
||||
var/static/list/slot2slot = list(
|
||||
"head" = ITEM_SLOT_HEAD,
|
||||
"wear_mask" = ITEM_SLOT_MASK,
|
||||
"neck" = ITEM_SLOT_NECK,
|
||||
"back" = ITEM_SLOT_BACK,
|
||||
"wear_suit" = ITEM_SLOT_OCLOTHING,
|
||||
"w_uniform" = ITEM_SLOT_ICLOTHING,
|
||||
"shoes" = ITEM_SLOT_FEET,
|
||||
"belt" = ITEM_SLOT_BELT,
|
||||
"gloves" = ITEM_SLOT_GLOVES,
|
||||
"glasses" = ITEM_SLOT_EYES,
|
||||
"ears" = ITEM_SLOT_EARS,
|
||||
"wear_id" = ITEM_SLOT_ID,
|
||||
"s_store" = ITEM_SLOT_SUITSTORE,
|
||||
)
|
||||
|
||||
var/datum/dna/chosen_dna = chosen_prof.dna
|
||||
user.real_name = chosen_prof.name
|
||||
user.underwear = chosen_prof.underwear
|
||||
user.undershirt = chosen_prof.undershirt
|
||||
user.socks = chosen_prof.socks
|
||||
|
||||
chosen_dna.transfer_identity(user, 1)
|
||||
user.updateappearance(mutcolor_update=1)
|
||||
user.update_body()
|
||||
user.domutcheck()
|
||||
|
||||
// get rid of any scars from previous changeling-ing
|
||||
for(var/i in user.all_scars)
|
||||
var/datum/scar/iter_scar = i
|
||||
if(iter_scar.fake)
|
||||
qdel(iter_scar)
|
||||
|
||||
// Do skillchip code after DNA code.
|
||||
// There's a mutation that increases max chip complexity available, even though we force-implant skillchips.
|
||||
|
||||
// Remove existing skillchips.
|
||||
user.destroy_all_skillchips(silent = FALSE)
|
||||
|
||||
// Add new set of skillchips.
|
||||
for(var/chip in chosen_prof.skillchips)
|
||||
var/chip_type = chip["type"]
|
||||
var/obj/item/skillchip/skillchip = new chip_type(user)
|
||||
|
||||
if(!istype(skillchip))
|
||||
stack_trace("Failure to implant changeling from [chosen_prof] with skillchip [skillchip]. Tried to implant with non-skillchip type [chip_type]")
|
||||
qdel(skillchip)
|
||||
continue
|
||||
|
||||
// Try force-implanting and activating. If it doesn't work, there's nothing much we can do. There may be some
|
||||
// incompatibility out of our hands
|
||||
var/implant_msg = user.implant_skillchip(skillchip, TRUE)
|
||||
if(implant_msg)
|
||||
// Hopefully recording the error message will help debug it.
|
||||
stack_trace("Failure to implant changeling from [chosen_prof] with skillchip [skillchip]. Error msg: [implant_msg]")
|
||||
qdel(skillchip)
|
||||
continue
|
||||
|
||||
// Time to set the metadata. This includes trying to activate the chip.
|
||||
var/set_meta_msg = skillchip.set_metadata(chip)
|
||||
|
||||
if(set_meta_msg)
|
||||
// Hopefully recording the error message will help debug it.
|
||||
stack_trace("Failure to activate changeling skillchip from [chosen_prof] with skillchip [skillchip] using [chip] metadata. Error msg: [set_meta_msg]")
|
||||
continue
|
||||
|
||||
//vars hackery. not pretty, but better than the alternative.
|
||||
for(var/slot in slot2type)
|
||||
if(istype(user.vars[slot], slot2type[slot]) && !(chosen_prof.exists_list[slot])) //remove unnecessary flesh items
|
||||
qdel(user.vars[slot])
|
||||
continue
|
||||
|
||||
if((user.vars[slot] && !istype(user.vars[slot], slot2type[slot])) || !(chosen_prof.exists_list[slot]))
|
||||
continue
|
||||
|
||||
if(istype(user.vars[slot], slot2type[slot]) && slot == "wear_id") //always remove old flesh IDs, so they get properly updated
|
||||
qdel(user.vars[slot])
|
||||
|
||||
var/obj/item/C
|
||||
var/equip = 0
|
||||
if(!user.vars[slot])
|
||||
var/thetype = slot2type[slot]
|
||||
equip = 1
|
||||
C = new thetype(user)
|
||||
|
||||
else if(istype(user.vars[slot], slot2type[slot]))
|
||||
C = user.vars[slot]
|
||||
|
||||
C.appearance = chosen_prof.appearance_list[slot]
|
||||
C.name = chosen_prof.name_list[slot]
|
||||
C.flags_cover = chosen_prof.flags_cover_list[slot]
|
||||
C.lefthand_file = chosen_prof.lefthand_file_list[slot]
|
||||
C.righthand_file = chosen_prof.righthand_file_list[slot]
|
||||
C.inhand_icon_state = chosen_prof.inhand_icon_state_list[slot]
|
||||
C.worn_icon = chosen_prof.worn_icon_list[slot]
|
||||
C.worn_icon_state = chosen_prof.worn_icon_state_list[slot]
|
||||
|
||||
if(istype(C, /obj/item/changeling/id) && chosen_prof.id_icon)
|
||||
var/obj/item/changeling/id/flesh_id = C
|
||||
flesh_id.hud_icon = chosen_prof.id_icon
|
||||
|
||||
if(equip)
|
||||
user.equip_to_slot_or_del(C, slot2slot[slot])
|
||||
if(!QDELETED(C))
|
||||
ADD_TRAIT(C, TRAIT_NODROP, CHANGELING_TRAIT)
|
||||
|
||||
for(var/stored_scar_line in chosen_prof.stored_scars)
|
||||
var/datum/scar/attempted_fake_scar = user.load_scar(stored_scar_line)
|
||||
if(attempted_fake_scar)
|
||||
attempted_fake_scar.fake = TRUE
|
||||
|
||||
user.regenerate_icons()
|
||||
|
||||
// Profile
|
||||
|
||||
/datum/changelingprofile
|
||||
|
||||
@@ -30,5 +30,5 @@
|
||||
|
||||
var/newmob = user.humanize()
|
||||
|
||||
changeling_transform(newmob, chosen_prof)
|
||||
changeling.transform(newmob, chosen_prof)
|
||||
return TRUE
|
||||
|
||||
@@ -165,7 +165,7 @@
|
||||
if(!chosen_prof)
|
||||
return
|
||||
..()
|
||||
changeling_transform(user, chosen_prof)
|
||||
changeling.transform(user, chosen_prof)
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
@@ -188,8 +188,8 @@
|
||||
return
|
||||
|
||||
if(chosen_name == "Drop Flesh Disguise")
|
||||
for(var/slot in GLOB.slots)
|
||||
if(istype(user.vars[slot], GLOB.slot2type[slot]))
|
||||
for(var/slot in slot2type)
|
||||
if(istype(user.vars[slot], slot2type[slot]))
|
||||
qdel(user.vars[slot])
|
||||
for(var/i in user.all_scars)
|
||||
var/datum/scar/iter_scar = i
|
||||
|
||||
-28
@@ -1,31 +1,3 @@
|
||||
/datum/game_mode/nuclear/clown_ops
|
||||
name = "clown ops"
|
||||
config_tag = "clownops"
|
||||
|
||||
announce_span = "danger"
|
||||
announce_text = "Clown empire forces are approaching the station in an attempt to HONK it!\n\
|
||||
<span class='danger'>Operatives</span>: Secure the nuclear authentication disk and use your bananium fission explosive to HONK the station.\n\
|
||||
<span class='notice'>Crew</span>: Defend the nuclear authentication disk and ensure that it leaves with you on the emergency shuttle."
|
||||
|
||||
operative_antag_datum_type = /datum/antagonist/nukeop/clownop
|
||||
leader_antag_datum_type = /datum/antagonist/nukeop/leader/clownop
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/datum/game_mode/nuclear/clown_ops/pre_setup()
|
||||
. = ..()
|
||||
if(.)
|
||||
for(var/obj/machinery/nuclearbomb/syndicate/S in GLOB.nuke_list)
|
||||
var/turf/T = get_turf(S)
|
||||
if(T)
|
||||
qdel(S)
|
||||
new /obj/machinery/nuclearbomb/syndicate/bananium(T)
|
||||
for(var/V in pre_nukeops)
|
||||
var/datum/mind/the_op = V
|
||||
the_op.assigned_role = "Clown Operative"
|
||||
the_op.special_role = "Clown Operative"
|
||||
|
||||
/datum/outfit/syndicate/clownop
|
||||
name = "Clown Operative - Basic"
|
||||
uniform = /obj/item/clothing/under/syndicate
|
||||
@@ -17,7 +17,7 @@
|
||||
..()
|
||||
|
||||
/datum/action/innate/cult/blood_magic/IsAvailable()
|
||||
if(!iscultist(owner))
|
||||
if(!IS_CULTIST(owner))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
..()
|
||||
|
||||
/datum/action/innate/cult/blood_spell/IsAvailable()
|
||||
if(!iscultist(owner) || owner.incapacitated() || !charges)
|
||||
if(!IS_CULTIST(owner) || owner.incapacitated() || !charges)
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
@@ -251,14 +251,15 @@
|
||||
/obj/effect/proc_holder/horror/InterceptClickOn(mob/living/caller, params, atom/target)
|
||||
if(..())
|
||||
return
|
||||
if(ranged_ability_user.incapacitated() || !iscultist(caller))
|
||||
if(ranged_ability_user.incapacitated() || !IS_CULTIST(caller))
|
||||
remove_ranged_ability()
|
||||
return
|
||||
var/turf/T = get_turf(ranged_ability_user)
|
||||
if(!isturf(T))
|
||||
return FALSE
|
||||
if(target in view(7, get_turf(ranged_ability_user)))
|
||||
if(!ishuman(target) || iscultist(target))
|
||||
var/mob/living/carbon/human/human_target = target
|
||||
if(!istype(human_target) || IS_CULTIST(human_target))
|
||||
return
|
||||
var/mob/living/carbon/human/H = target
|
||||
H.hallucination = max(H.hallucination, 120)
|
||||
@@ -381,7 +382,7 @@
|
||||
afterattack(user, user, TRUE)
|
||||
|
||||
/obj/item/melee/blood_magic/attack(mob/living/M, mob/living/carbon/user)
|
||||
if(!iscarbon(user) || !iscultist(user))
|
||||
if(!iscarbon(user) || !IS_CULTIST(user))
|
||||
uses = 0
|
||||
qdel(src)
|
||||
return
|
||||
@@ -416,9 +417,9 @@
|
||||
if(!isliving(target) || !proximity)
|
||||
return
|
||||
var/mob/living/L = target
|
||||
if(iscultist(target))
|
||||
if(IS_CULTIST(L))
|
||||
return
|
||||
if(iscultist(user))
|
||||
if(IS_CULTIST(user))
|
||||
user.visible_message("<span class='warning'>[user] holds up [user.p_their()] hand, which explodes in a flash of red light!</span>", \
|
||||
"<span class='cultitalic'>You attempt to stun [L] with the spell!</span>")
|
||||
|
||||
@@ -464,10 +465,11 @@
|
||||
invocation = "Sas'so c'arta forbici!"
|
||||
|
||||
/obj/item/melee/blood_magic/teleport/afterattack(atom/target, mob/living/carbon/user, proximity)
|
||||
if(!iscultist(target) || !proximity)
|
||||
var/mob/mob_target = target
|
||||
if(istype(mob_target) && !IS_CULTIST(mob_target) || !proximity)
|
||||
to_chat(user, "<span class='warning'>You can only teleport adjacent cultists with this spell!</span>")
|
||||
return
|
||||
if(iscultist(user))
|
||||
if(IS_CULTIST(user))
|
||||
var/list/potential_runes = list()
|
||||
var/list/teleportnames = list()
|
||||
for(var/R in GLOB.teleport_runes)
|
||||
@@ -510,7 +512,7 @@
|
||||
color = "#000000" // black
|
||||
|
||||
/obj/item/melee/blood_magic/shackles/afterattack(atom/target, mob/living/carbon/user, proximity)
|
||||
if(iscultist(user) && iscarbon(target) && proximity)
|
||||
if(IS_CULTIST(user) && iscarbon(target) && proximity)
|
||||
var/mob/living/carbon/C = target
|
||||
if(C.canBeHandcuffed())
|
||||
CuffAttack(C, user)
|
||||
@@ -570,7 +572,7 @@
|
||||
Airlocks into brittle runed airlocks after a delay (harm intent)"}
|
||||
|
||||
/obj/item/melee/blood_magic/construction/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
if(proximity_flag && iscultist(user))
|
||||
if(proximity_flag && IS_CULTIST(user))
|
||||
if(channeling)
|
||||
to_chat(user, "<span class='cultitalic'>You are already invoking twisted construction!</span>")
|
||||
return
|
||||
@@ -674,7 +676,8 @@
|
||||
color = "#33cc33" // green
|
||||
|
||||
/obj/item/melee/blood_magic/armor/afterattack(atom/target, mob/living/carbon/user, proximity)
|
||||
if(iscarbon(target) && iscultist(target) && proximity)
|
||||
var/mob/living/carbon/carbon_target = target
|
||||
if(istype(carbon_target) && IS_CULTIST(carbon_target) && proximity)
|
||||
uses--
|
||||
var/mob/living/carbon/C = target
|
||||
C.visible_message("<span class='warning'>Otherworldly armor suddenly appears on [C]!</span>")
|
||||
@@ -704,7 +707,7 @@
|
||||
if(NOBLOOD in H.dna.species.species_traits)
|
||||
to_chat(user,"<span class='warning'>Blood rites do not work on species with no blood!</span>")
|
||||
return
|
||||
if(iscultist(H))
|
||||
if(IS_CULTIST(H))
|
||||
if(H.stat == DEAD)
|
||||
to_chat(user,"<span class='warning'>Only a revive rune can bring back the dead!</span>")
|
||||
return
|
||||
@@ -802,7 +805,7 @@
|
||||
uses += max(1, round(temp))
|
||||
|
||||
/obj/item/melee/blood_magic/manipulator/attack_self(mob/living/user)
|
||||
if(iscultist(user))
|
||||
if(IS_CULTIST(user))
|
||||
var/static/list/spells = list(
|
||||
"Bloody Halberd (150)" = image(icon = 'icons/obj/items_and_weapons.dmi', icon_state = "occultpoleaxe0"),
|
||||
"Blood Bolt Barrage (300)" = image(icon = 'icons/obj/guns/ballistic.dmi', icon_state = "arcane_barrage"),
|
||||
|
||||
@@ -62,7 +62,6 @@
|
||||
add_objectives()
|
||||
if(give_equipment)
|
||||
equip_cultist(TRUE)
|
||||
SSticker.mode.cult += owner // Only add after they've been given objectives
|
||||
current.log_message("has been converted to the cult of Nar'Sie!", LOG_ATTACK, color="#960000")
|
||||
|
||||
if(cult_team.blood_target && cult_team.blood_target_image && current.client)
|
||||
@@ -140,7 +139,6 @@
|
||||
H.update_body()
|
||||
|
||||
/datum/antagonist/cult/on_removal()
|
||||
SSticker.mode.cult -= owner
|
||||
if(!silent)
|
||||
owner.current.visible_message("<span class='deconversion_message'>[owner.current] looks like [owner.current.p_theyve()] just reverted to [owner.current.p_their()] old faith!</span>", null, null, null, owner.current)
|
||||
to_chat(owner.current, "<span class='userdanger'>An unfamiliar white light flashes through your mind, cleansing the taint of the Geometer and all your memories as her servant.</span>")
|
||||
@@ -156,9 +154,8 @@
|
||||
log_admin("[key_name(admin)] has cult-ed [key_name(new_owner)].")
|
||||
|
||||
/datum/antagonist/cult/admin_remove(mob/user)
|
||||
message_admins("[key_name_admin(user)] has decult-ed [key_name_admin(owner)].")
|
||||
log_admin("[key_name(user)] has decult-ed [key_name(owner)].")
|
||||
SSticker.mode.remove_cultist(owner,silent=TRUE) //disgusting
|
||||
silent = TRUE
|
||||
return ..()
|
||||
|
||||
/datum/antagonist/cult/get_admin_commands()
|
||||
. = ..()
|
||||
@@ -251,7 +248,7 @@
|
||||
for(var/I in GLOB.player_list)
|
||||
var/mob/M = I
|
||||
if(M.stat != DEAD)
|
||||
if(iscultist(M))
|
||||
if(IS_CULTIST(M))
|
||||
++cultplayers
|
||||
else
|
||||
++alive
|
||||
@@ -408,3 +405,28 @@
|
||||
|
||||
/datum/team/cult/is_gamemode_hero()
|
||||
return SSticker.mode.name == "cult"
|
||||
|
||||
/datum/team/cult/proc/is_sacrifice_target(datum/mind/mind)
|
||||
for(var/datum/objective/sacrifice/sac_objective in objectives)
|
||||
if(mind == sac_objective.target)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/// Returns whether the given mob is convertable to the blood cult
|
||||
/proc/is_convertable_to_cult(mob/living/M, datum/team/cult/specific_cult)
|
||||
if(!istype(M))
|
||||
return FALSE
|
||||
if(M.mind)
|
||||
if(ishuman(M) && (M.mind.holy_role))
|
||||
return FALSE
|
||||
if(specific_cult?.is_sacrifice_target(M.mind))
|
||||
return FALSE
|
||||
if(M.mind.enslaved_to && !IS_CULTIST(M.mind.enslaved_to))
|
||||
return FALSE
|
||||
if(M.mind.unconvertable)
|
||||
return FALSE
|
||||
else
|
||||
return FALSE
|
||||
if(HAS_TRAIT(M, TRAIT_MINDSHIELD) || issilicon(M) || isbot(M) || isdrone(M) || !M.client)
|
||||
return FALSE //can't convert machines, shielded, or braindead
|
||||
return TRUE
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
check_flags = AB_CHECK_HANDS_BLOCKED|AB_CHECK_IMMOBILE|AB_CHECK_CONSCIOUS
|
||||
|
||||
/datum/action/innate/cult/IsAvailable()
|
||||
if(!iscultist(owner))
|
||||
if(!IS_CULTIST(owner))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
my_message = "<span class='[span]'><b>[title] [findtextEx(user.name, user.real_name) ? user.name : "[user.real_name] (as [user.name])"]:</b> [message]</span>"
|
||||
for(var/i in GLOB.player_list)
|
||||
var/mob/M = i
|
||||
if(iscultist(M))
|
||||
if(IS_CULTIST(M))
|
||||
to_chat(M, my_message)
|
||||
else if(M in GLOB.dead_mob_list)
|
||||
var/link = FOLLOW_LINK(M, user)
|
||||
@@ -54,7 +54,7 @@
|
||||
desc = "Conveys a message from the spirit realm that all cultists can hear."
|
||||
|
||||
/datum/action/innate/cult/comm/spirit/IsAvailable()
|
||||
if(iscultist(owner.mind.current))
|
||||
if(IS_CULTIST(owner.mind.current))
|
||||
return TRUE
|
||||
|
||||
/datum/action/innate/cult/comm/spirit/cultist_commune(mob/living/user, message)
|
||||
@@ -64,7 +64,7 @@
|
||||
my_message = "<span class='cultboldtalic'>The [user.name]: [message]</span>"
|
||||
for(var/i in GLOB.player_list)
|
||||
var/mob/M = i
|
||||
if(iscultist(M))
|
||||
if(IS_CULTIST(M))
|
||||
to_chat(M, my_message)
|
||||
else if(M in GLOB.dead_mob_list)
|
||||
var/link = FOLLOW_LINK(M, user)
|
||||
@@ -129,7 +129,10 @@
|
||||
to_chat(B.current, "<span class='cultlarge'>[Nominee] could not win the cult's support and shall continue to serve as an acolyte.</span>")
|
||||
return FALSE
|
||||
team.cult_master = Nominee
|
||||
SSticker.mode.remove_cultist(Nominee.mind, TRUE)
|
||||
var/datum/antagonist/cult/cultist = Nominee.mind.has_antag_datum(/datum/antagonist/cult)
|
||||
if (cultist)
|
||||
cultist.silent = TRUE
|
||||
cultist.on_removal()
|
||||
Nominee.mind.add_antag_datum(/datum/antagonist/cult/master)
|
||||
for(var/datum/mind/B in team.members)
|
||||
if(B.current)
|
||||
@@ -281,7 +284,7 @@
|
||||
C.cult_team.blood_target_image.appearance_flags = RESET_COLOR
|
||||
C.cult_team.blood_target_image.pixel_x = -target.pixel_x
|
||||
C.cult_team.blood_target_image.pixel_y = -target.pixel_y
|
||||
for(var/datum/mind/B in SSticker.mode.cult)
|
||||
for(var/datum/mind/B as anything in get_antag_minds(/datum/antagonist/cult))
|
||||
if(B.current && B.current.stat != DEAD && B.current.client)
|
||||
to_chat(B.current, "<span class='cultlarge'><b>[ranged_ability_user] has marked [C.cult_team.blood_target] in the [A.name] as the cult's top priority, get there immediately!</b></span>")
|
||||
SEND_SOUND(B.current, sound(pick('sound/hallucinations/over_here2.ogg','sound/hallucinations/over_here3.ogg'),0,1,75))
|
||||
@@ -307,7 +310,7 @@
|
||||
desc = "Marks a target for the entire cult to track."
|
||||
|
||||
/datum/action/innate/cult/master/cultmark/ghost/IsAvailable()
|
||||
if(istype(owner, /mob/dead/observer) && iscultist(owner.mind.current))
|
||||
if(istype(owner, /mob/dead/observer) && IS_CULTIST(owner.mind.current))
|
||||
return TRUE
|
||||
else
|
||||
qdel(src)
|
||||
@@ -321,7 +324,7 @@
|
||||
var/base_cooldown = 600
|
||||
|
||||
/datum/action/innate/cult/ghostmark/IsAvailable()
|
||||
if(istype(owner, /mob/dead/observer) && iscultist(owner.mind.current))
|
||||
if(istype(owner, /mob/dead/observer) && IS_CULTIST(owner.mind.current))
|
||||
return TRUE
|
||||
else
|
||||
qdel(src)
|
||||
@@ -362,7 +365,7 @@
|
||||
C.cult_team.blood_target_image.pixel_y = -target.pixel_y
|
||||
SEND_SOUND(owner, sound(pick('sound/hallucinations/over_here2.ogg','sound/hallucinations/over_here3.ogg'),0,1,75))
|
||||
owner.client.images += C.cult_team.blood_target_image
|
||||
for(var/datum/mind/B in SSticker.mode.cult)
|
||||
for(var/datum/mind/B as anything in get_antag_minds(/datum/antagonist/cult))
|
||||
if(B.current && B.current.stat != DEAD && B.current.client)
|
||||
to_chat(B.current, "<span class='cultlarge'><b>[owner] has marked [C.cult_team.blood_target] in the [A.name] as the cult's top priority, get there immediately!</b></span>")
|
||||
SEND_SOUND(B.current, sound(pick('sound/hallucinations/over_here2.ogg','sound/hallucinations/over_here3.ogg'),0,1,75))
|
||||
@@ -442,7 +445,9 @@
|
||||
if(!isturf(T))
|
||||
return FALSE
|
||||
if(target in view(7, get_turf(ranged_ability_user)))
|
||||
if((!(iscultist(target) || istype(target, /obj/structure/destructible/cult)) || target == caller) && !(attached_action.throwing))
|
||||
var/mob/mob_target = target
|
||||
var/is_cultist = istype(mob_target) && IS_CULTIST(mob_target)
|
||||
if((!(is_cultist || istype(target, /obj/structure/destructible/cult)) || target == caller) && !(attached_action.throwing))
|
||||
return
|
||||
if(!attached_action.throwing)
|
||||
attached_action.throwing = TRUE
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
if(owner.get_active_held_item() != src)
|
||||
block_message = "[owner] parries [attack_text] with [src] in their offhand"
|
||||
|
||||
if(iscultist(owner) && prob(final_block_chance) && attack_type != PROJECTILE_ATTACK)
|
||||
if(IS_CULTIST(owner) && prob(final_block_chance) && attack_type != PROJECTILE_ATTACK)
|
||||
new /obj/effect/temp_visual/cult/sparks(get_turf(owner))
|
||||
playsound(src, 'sound/weapons/parry.ogg', 100, TRUE)
|
||||
owner.visible_message("<span class='danger'>[block_message]</span>")
|
||||
@@ -73,7 +73,7 @@
|
||||
AddComponent(/datum/component/butchering, 40, 100)
|
||||
|
||||
/obj/item/melee/cultblade/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
if(iscultist(owner) && prob(final_block_chance))
|
||||
if(IS_CULTIST(owner) && prob(final_block_chance))
|
||||
new /obj/effect/temp_visual/cult/sparks(get_turf(owner))
|
||||
playsound(src, 'sound/weapons/parry.ogg', 100, TRUE)
|
||||
owner.visible_message("<span class='danger'>[owner] parries [attack_text] with [src]!</span>")
|
||||
@@ -82,7 +82,7 @@
|
||||
return FALSE
|
||||
|
||||
/obj/item/melee/cultblade/attack(mob/living/target, mob/living/carbon/human/user)
|
||||
if(!iscultist(user))
|
||||
if(!IS_CULTIST(user))
|
||||
user.Paralyze(100)
|
||||
user.dropItemToGround(src, TRUE)
|
||||
user.visible_message("<span class='warning'>A powerful force shoves [user] away from [target]!</span>", \
|
||||
@@ -108,7 +108,7 @@
|
||||
|
||||
/obj/item/melee/cultblade/pickup(mob/living/user)
|
||||
..()
|
||||
if(!iscultist(user))
|
||||
if(!IS_CULTIST(user))
|
||||
to_chat(user, "<span class='cultlarge'>\"I wouldn't advise that.\"</span>")
|
||||
|
||||
/obj/item/cult_bastard
|
||||
@@ -169,7 +169,7 @@
|
||||
|
||||
/obj/item/cult_bastard/pickup(mob/living/user)
|
||||
. = ..()
|
||||
if(!iscultist(user))
|
||||
if(!IS_CULTIST(user))
|
||||
to_chat(user, "<span class='cultlarge'>\"I wouldn't advise that.\"</span>")
|
||||
force = 5
|
||||
return
|
||||
@@ -234,7 +234,7 @@
|
||||
phaseout = /obj/effect/temp_visual/dir_setting/cult/phase/out
|
||||
|
||||
/datum/action/innate/dash/cult/IsAvailable()
|
||||
if(iscultist(holder) && current_charges)
|
||||
if(IS_CULTIST(holder) && current_charges)
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
@@ -256,7 +256,7 @@
|
||||
holder = user
|
||||
|
||||
/datum/action/innate/cult/spin2win/IsAvailable()
|
||||
if(iscultist(holder) && cooldown <= world.time)
|
||||
if(IS_CULTIST(holder) && cooldown <= world.time)
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
@@ -290,7 +290,7 @@
|
||||
/obj/item/restraints/legcuffs/bola/cult/attack_hand(mob/living/carbon/user, list/modifiers)
|
||||
. = ..()
|
||||
|
||||
if(iscultist(user) || !iscarbon(user))
|
||||
if(IS_CULTIST(user) || !iscarbon(user))
|
||||
return
|
||||
var/mob/living/carbon/carbon_user = user
|
||||
if(user.num_legs < 2 || carbon_user.legcuffed) //if they can't be ensnared, stun for the same time as it takes to breakout of bola
|
||||
@@ -304,7 +304,8 @@
|
||||
|
||||
|
||||
/obj/item/restraints/legcuffs/bola/cult/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
if(iscultist(hit_atom))
|
||||
var/mob/hit_mob = hit_atom
|
||||
if (istype(hit_mob) && IS_CULTIST(hit_mob))
|
||||
return
|
||||
. = ..()
|
||||
|
||||
@@ -442,7 +443,7 @@
|
||||
|
||||
/obj/item/clothing/suit/hooded/cultrobes/cult_shield/equipped(mob/living/user, slot)
|
||||
..()
|
||||
if(!iscultist(user))
|
||||
if(!IS_CULTIST(user))
|
||||
to_chat(user, "<span class='cultlarge'>\"I wouldn't advise that.\"</span>")
|
||||
to_chat(user, "<span class='warning'>An overwhelming sense of nausea overpowers you!</span>")
|
||||
user.dropItemToGround(src, TRUE)
|
||||
@@ -464,7 +465,7 @@
|
||||
|
||||
/obj/item/clothing/suit/hooded/cultrobes/berserker/equipped(mob/living/user, slot)
|
||||
..()
|
||||
if(!iscultist(user))
|
||||
if(!IS_CULTIST(user))
|
||||
to_chat(user, "<span class='cultlarge'>\"I wouldn't advise that.\"</span>")
|
||||
to_chat(user, "<span class='warning'>An overwhelming sense of nausea overpowers you!</span>")
|
||||
user.dropItemToGround(src, TRUE)
|
||||
@@ -480,7 +481,7 @@
|
||||
|
||||
/obj/item/clothing/glasses/hud/health/night/cultblind/equipped(mob/living/user, slot)
|
||||
..()
|
||||
if(!iscultist(user) && slot == ITEM_SLOT_EYES)
|
||||
if(!IS_CULTIST(user) && slot == ITEM_SLOT_EYES)
|
||||
to_chat(user, "<span class='cultlarge'>\"You want to be blind, do you?\"</span>")
|
||||
user.dropItemToGround(src, TRUE)
|
||||
user.Dizzy(30)
|
||||
@@ -507,7 +508,7 @@
|
||||
var/static/totalcurses = 0
|
||||
|
||||
/obj/item/shuttle_curse/attack_self(mob/living/user)
|
||||
if(!iscultist(user))
|
||||
if(!IS_CULTIST(user))
|
||||
user.dropItemToGround(src, TRUE)
|
||||
user.Paralyze(100)
|
||||
to_chat(user, "<span class='warning'>A powerful force shoves you away from [src]!</span>")
|
||||
@@ -586,7 +587,7 @@
|
||||
if(!uses || !iscarbon(user))
|
||||
to_chat(user, "<span class='warning'>\The [src] is dull and unmoving in your hands.</span>")
|
||||
return
|
||||
if(!iscultist(user))
|
||||
if(!IS_CULTIST(user))
|
||||
user.dropItemToGround(src, TRUE)
|
||||
step(src, pick(GLOB.alldirs))
|
||||
to_chat(user, "<span class='warning'>\The [src] flickers out of your hands, your connection to this dimension is too strong!</span>")
|
||||
@@ -630,14 +631,14 @@
|
||||
/obj/item/flashlight/flare/culttorch/afterattack(atom/movable/A, mob/user, proximity)
|
||||
if(!proximity)
|
||||
return
|
||||
if(!iscultist(user))
|
||||
if(!IS_CULTIST(user))
|
||||
to_chat(user, "That doesn't seem to do anything useful.")
|
||||
return
|
||||
|
||||
if(istype(A, /obj/item))
|
||||
|
||||
var/list/cultists = list()
|
||||
for(var/datum/mind/M in SSticker.mode.cult)
|
||||
for(var/datum/mind/M as anything in get_antag_minds(/datum/antagonist/cult))
|
||||
if(M.current && M.current.stat != DEAD)
|
||||
cultists |= M.current
|
||||
var/mob/living/cultist_to_receive = input(user, "Who do you wish to call to [src]?", "Followers of the Geometer") as null|anything in (cultists - user)
|
||||
@@ -651,7 +652,7 @@
|
||||
to_chat(user, "<span class='cult italic'>[cultist_to_receive] has died!</span>")
|
||||
log_game("Void torch failed - target died")
|
||||
return
|
||||
if(!iscultist(cultist_to_receive))
|
||||
if(!IS_CULTIST(cultist_to_receive))
|
||||
to_chat(user, "<span class='cult italic'>[cultist_to_receive] is not a follower of the Geometer!</span>")
|
||||
log_game("Void torch failed - target was deconverted")
|
||||
return
|
||||
@@ -726,7 +727,7 @@
|
||||
var/turf/T = get_turf(hit_atom)
|
||||
if(isliving(hit_atom))
|
||||
var/mob/living/L = hit_atom
|
||||
if(iscultist(L))
|
||||
if(IS_CULTIST(L))
|
||||
playsound(src, 'sound/weapons/throwtap.ogg', 50)
|
||||
if(L.put_in_active_hand(src))
|
||||
L.visible_message("<span class='warning'>[L] catches [src] out of the air!</span>")
|
||||
@@ -753,7 +754,7 @@
|
||||
/obj/item/melee/cultblade/halberd/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
if(wielded)
|
||||
final_block_chance *= 2
|
||||
if(iscultist(owner) && prob(final_block_chance))
|
||||
if(IS_CULTIST(owner) && prob(final_block_chance))
|
||||
if(attack_type == PROJECTILE_ATTACK)
|
||||
owner.visible_message("<span class='danger'>[owner] deflects [attack_text] with [src]!</span>")
|
||||
playsound(get_turf(owner), pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, TRUE)
|
||||
@@ -807,7 +808,7 @@
|
||||
|
||||
/obj/item/gun/ballistic/rifle/enchanted/arcane_barrage/blood/can_trigger_gun(mob/living/user)
|
||||
. = ..()
|
||||
if(!iscultist(user))
|
||||
if(!IS_CULTIST(user))
|
||||
to_chat(user, "<span class='cultlarge'>\"Did you truly think that you could channel MY blood without my approval? Amusing, but futile.\"</span>")
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
@@ -836,7 +837,9 @@
|
||||
/obj/projectile/magic/arcane_barrage/blood/Bump(atom/target)
|
||||
var/turf/T = get_turf(target)
|
||||
playsound(T, 'sound/effects/splat.ogg', 50, TRUE)
|
||||
if(iscultist(target))
|
||||
var/mob/mob_target = target
|
||||
|
||||
if(mob_target && IS_CULTIST(mob_target))
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(H.stat != DEAD)
|
||||
@@ -940,7 +943,7 @@
|
||||
break
|
||||
T.narsie_act(TRUE, TRUE)
|
||||
for(var/mob/living/target in T.contents)
|
||||
if(iscultist(target))
|
||||
if(IS_CULTIST(target))
|
||||
new /obj/effect/temp_visual/cult/sparks(T)
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
@@ -982,7 +985,7 @@
|
||||
var/illusions = 2
|
||||
|
||||
/obj/item/shield/mirror/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
if(iscultist(owner))
|
||||
if(IS_CULTIST(owner))
|
||||
if(istype(hitby, /obj/projectile))
|
||||
var/obj/projectile/P = hitby
|
||||
if(P.damage_type == BRUTE || P.damage_type == BURN)
|
||||
@@ -1039,7 +1042,7 @@
|
||||
var/datum/thrownthing/D = throwingdatum
|
||||
if(isliving(hit_atom))
|
||||
var/mob/living/L = hit_atom
|
||||
if(iscultist(L))
|
||||
if(IS_CULTIST(L))
|
||||
playsound(src, 'sound/weapons/throwtap.ogg', 50)
|
||||
if(L.put_in_active_hand(src))
|
||||
L.visible_message("<span class='warning'>[L] catches [src] out of the air!</span>")
|
||||
@@ -1050,7 +1053,7 @@
|
||||
L.Paralyze(30)
|
||||
if(D?.thrower)
|
||||
for(var/mob/living/Next in orange(2, T))
|
||||
if(!Next.density || iscultist(Next))
|
||||
if(!Next.density || IS_CULTIST(Next))
|
||||
continue
|
||||
throw_at(Next, 3, 1, D.thrower)
|
||||
return
|
||||
|
||||
@@ -33,14 +33,14 @@
|
||||
/obj/structure/destructible/cult/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>\The [src] is [anchored ? "":"not "]secured to the floor.</span>"
|
||||
if(iscultist(user) || isobserver(user))
|
||||
if(IS_CULTIST(user) || isobserver(user))
|
||||
if(cultist_examine_message)
|
||||
. += "<span class='cult'>[cultist_examine_message]</span>"
|
||||
if(cooldowntime > world.time)
|
||||
. += "<span class='cult italic'>The magic in [src] is too weak, [p_they()] will be ready to use again in [DisplayTimeText(cooldowntime - world.time)].</span>"
|
||||
|
||||
/obj/structure/destructible/cult/examine_status(mob/user)
|
||||
if(iscultist(user) || isobserver(user))
|
||||
if(IS_CULTIST(user) || isobserver(user))
|
||||
var/t_It = p_they(TRUE)
|
||||
var/t_is = p_are()
|
||||
return "<span class='cult'>[t_It] [t_is] at <b>[round(obj_integrity * 100 / max_integrity)]%</b> stability.</span>"
|
||||
@@ -70,7 +70,7 @@
|
||||
return ..()
|
||||
|
||||
/obj/structure/destructible/cult/attackby(obj/I, mob/user, params)
|
||||
if(istype(I, /obj/item/melee/cultblade/dagger) && iscultist(user))
|
||||
if(istype(I, /obj/item/melee/cultblade/dagger) && IS_CULTIST(user))
|
||||
set_anchored(!anchored)
|
||||
to_chat(user, "<span class='notice'>You [anchored ? "":"un"]secure \the [src] [anchored ? "to":"from"] the floor.</span>")
|
||||
else
|
||||
@@ -94,7 +94,7 @@
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(!iscultist(user))
|
||||
if(!IS_CULTIST(user))
|
||||
to_chat(user, "<span class='warning'>You're pretty sure you know exactly what this is used for and you can't seem to touch it.</span>")
|
||||
return
|
||||
if(!anchored)
|
||||
@@ -119,7 +119,7 @@
|
||||
pickedtype += /obj/item/reagent_containers/glass/beaker/unholywater
|
||||
else
|
||||
return
|
||||
if(src && !QDELETED(src) && anchored && pickedtype && Adjacent(user) && !user.incapacitated() && iscultist(user) && cooldowntime <= world.time)
|
||||
if(src && !QDELETED(src) && anchored && pickedtype && Adjacent(user) && !user.incapacitated() && IS_CULTIST(user) && cooldowntime <= world.time)
|
||||
cooldowntime = world.time + 2400
|
||||
for(var/N in pickedtype)
|
||||
new N(get_turf(src))
|
||||
@@ -138,7 +138,7 @@
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(!iscultist(user))
|
||||
if(!IS_CULTIST(user))
|
||||
to_chat(user, "<span class='warning'>The heat radiating from [src] pushes you back.</span>")
|
||||
return
|
||||
if(!anchored)
|
||||
@@ -163,7 +163,7 @@
|
||||
pickedtype += /obj/item/melee/cultblade
|
||||
else
|
||||
return
|
||||
if(src && !QDELETED(src) && anchored && pickedtype && Adjacent(user) && !user.incapacitated() && iscultist(user) && cooldowntime <= world.time)
|
||||
if(src && !QDELETED(src) && anchored && pickedtype && Adjacent(user) && !user.incapacitated() && IS_CULTIST(user) && cooldowntime <= world.time)
|
||||
cooldowntime = world.time + 2400
|
||||
for(var/N in pickedtype)
|
||||
new N(get_turf(src))
|
||||
@@ -198,7 +198,7 @@
|
||||
if(last_heal <= world.time)
|
||||
last_heal = world.time + heal_delay
|
||||
for(var/mob/living/L in range(5, src))
|
||||
if(iscultist(L) || isshade(L) || isconstruct(L))
|
||||
if(IS_CULTIST(L) || isshade(L) || isconstruct(L))
|
||||
if(L.health != L.maxHealth)
|
||||
new /obj/effect/temp_visual/heal(get_turf(src), "#960000")
|
||||
if(ishuman(L))
|
||||
@@ -259,7 +259,7 @@
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(!iscultist(user))
|
||||
if(!IS_CULTIST(user))
|
||||
to_chat(user, "<span class='warning'>These books won't open and it hurts to even try and read the covers.</span>")
|
||||
return
|
||||
if(!anchored)
|
||||
@@ -285,7 +285,7 @@
|
||||
pickedtype += /obj/item/flashlight/flare/culttorch
|
||||
else
|
||||
return
|
||||
if(src && !QDELETED(src) && anchored && pickedtype.len && Adjacent(user) && !user.incapacitated() && iscultist(user) && cooldowntime <= world.time)
|
||||
if(src && !QDELETED(src) && anchored && pickedtype.len && Adjacent(user) && !user.incapacitated() && IS_CULTIST(user) && cooldowntime <= world.time)
|
||||
cooldowntime = world.time + 2400
|
||||
for(var/N in pickedtype)
|
||||
new N(get_turf(src))
|
||||
|
||||
@@ -16,14 +16,14 @@ This file contains the cult dagger and rune list code
|
||||
|
||||
/obj/item/melee/cultblade/dagger/examine(mob/user)
|
||||
. = ..()
|
||||
if(iscultist(user) || isobserver(user))
|
||||
if(IS_CULTIST(user) || isobserver(user))
|
||||
. += {"<span class='cult'>The scriptures of the Geometer. Allows the scribing of runes and access to the knowledge archives of the cult of Nar'Sie.\n
|
||||
Striking a cult structure will unanchor or reanchor it.\n
|
||||
Striking another cultist with it will purge holy water from them.\n
|
||||
Striking a noncultist, however, will tear their flesh.</span>"}
|
||||
|
||||
/obj/item/melee/cultblade/dagger/attack(mob/living/M, mob/living/user)
|
||||
if(iscultist(M))
|
||||
if(IS_CULTIST(M))
|
||||
if(M.has_reagent(/datum/reagent/water/holywater)) //allows cultists to be rescued from the clutches of ordained religion
|
||||
to_chat(user, "<span class='cult'>You remove the taint from [M].</span>" )
|
||||
var/holy2unholy = M.reagents.get_reagent_amount(/datum/reagent/water/holywater)
|
||||
@@ -41,7 +41,7 @@ This file contains the cult dagger and rune list code
|
||||
. = ..()
|
||||
|
||||
/obj/item/melee/cultblade/dagger/attack_self(mob/user)
|
||||
if(!iscultist(user))
|
||||
if(!IS_CULTIST(user))
|
||||
to_chat(user, "<span class='warning'>[src] is covered in unintelligible shapes and markings.</span>")
|
||||
return
|
||||
scribe_rune(user)
|
||||
|
||||
@@ -50,7 +50,7 @@ Runes can either be invoked by one's self or with many different cultists. Each
|
||||
|
||||
/obj/effect/rune/examine(mob/user)
|
||||
. = ..()
|
||||
if(iscultist(user) || user.stat == DEAD) //If they're a cultist or a ghost, tell them the effects
|
||||
if(IS_CULTIST(user) || user.stat == DEAD) //If they're a cultist or a ghost, tell them the effects
|
||||
. += "<b>Name:</b> [cultist_name]\n"+\
|
||||
"<b>Effects:</b> [capitalize(cultist_desc)]\n"+\
|
||||
"<b>Required Acolytes:</b> [req_cultists_text ? "[req_cultists_text]":"[req_cultists]"]"
|
||||
@@ -58,7 +58,7 @@ Runes can either be invoked by one's self or with many different cultists. Each
|
||||
. += "<b>Keyword:</b> [keyword]"
|
||||
|
||||
/obj/effect/rune/attackby(obj/I, mob/user, params)
|
||||
if(istype(I, /obj/item/melee/cultblade/dagger) && iscultist(user))
|
||||
if(istype(I, /obj/item/melee/cultblade/dagger) && IS_CULTIST(user))
|
||||
if(log_when_erased)
|
||||
var/confirm = alert(user, "Erasing this [cultist_name] rune might be against your goal to summon Nar'Sie.", "Begin to erase the [cultist_name] rune?", "Proceed", "Abort")
|
||||
if(confirm != "Proceed")
|
||||
@@ -85,7 +85,7 @@ Runes can either be invoked by one's self or with many different cultists. Each
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(!iscultist(user))
|
||||
if(!IS_CULTIST(user))
|
||||
to_chat(user, "<span class='warning'>You aren't able to understand the words of [src].</span>")
|
||||
return
|
||||
var/list/invokers = can_invoke(user)
|
||||
@@ -100,7 +100,7 @@ Runes can either be invoked by one's self or with many different cultists. Each
|
||||
if(istype(user, /mob/living/simple_animal/hostile/construct/wraith/angelic) || istype(user, /mob/living/simple_animal/hostile/construct/juggernaut/angelic) || istype(user, /mob/living/simple_animal/hostile/construct/artificer/angelic))
|
||||
to_chat(user, "<span class='warning'>You purge the rune!</span>")
|
||||
qdel(src)
|
||||
else if(construct_invoke || !iscultist(user)) //if you're not a cult construct we want the normal fail message
|
||||
else if(construct_invoke || !IS_CULTIST(user)) //if you're not a cult construct we want the normal fail message
|
||||
attack_hand(user)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You are unable to invoke the rune!</span>")
|
||||
@@ -133,7 +133,7 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
if(req_cultists > 1 || istype(src, /obj/effect/rune/convert))
|
||||
var/list/things_in_range = range(1, src)
|
||||
for(var/mob/living/L in things_in_range)
|
||||
if(iscultist(L))
|
||||
if(IS_CULTIST(L))
|
||||
if(L == user)
|
||||
continue
|
||||
if(ishuman(L))
|
||||
@@ -210,7 +210,7 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
var/list/myriad_targets = list()
|
||||
var/turf/T = get_turf(src)
|
||||
for(var/mob/living/M in T)
|
||||
if(!iscultist(M))
|
||||
if(!IS_CULTIST(M))
|
||||
myriad_targets |= M
|
||||
if(!myriad_targets.len)
|
||||
fail_invoke()
|
||||
@@ -259,7 +259,8 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
convertee.visible_message("<span class='warning'>[convertee] writhes in pain \
|
||||
[brutedamage || burndamage ? "even as [convertee.p_their()] wounds heal and close" : "as the markings below [convertee.p_them()] glow a bloody red"]!</span>", \
|
||||
"<span class='cultlarge'><i>AAAAAAAAAAAAAA-</i></span>")
|
||||
SSticker.mode.add_cultist(convertee.mind, 1)
|
||||
convertee.mind?.add_antag_datum(/datum/antagonist/cult)
|
||||
convertee.Unconscious(100)
|
||||
new /obj/item/melee/cultblade/dagger(get_turf(src))
|
||||
convertee.mind.special_role = ROLE_CULTIST
|
||||
to_chat(convertee, "<span class='cult italic'><b>Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible, truth. The veil of reality has been ripped away \
|
||||
@@ -525,7 +526,7 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
|
||||
/obj/effect/rune/raise_dead/examine(mob/user)
|
||||
. = ..()
|
||||
if(iscultist(user) || user.stat == DEAD)
|
||||
if(IS_CULTIST(user) || user.stat == DEAD)
|
||||
. += "<b>Sacrifices unrewarded:</b> [LAZYLEN(GLOB.sacrificed) - sacrifices_used]"
|
||||
|
||||
/obj/effect/rune/raise_dead/invoke(list/invokers)
|
||||
@@ -537,7 +538,7 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
return
|
||||
rune_in_use = TRUE
|
||||
for(var/mob/living/M in T.contents)
|
||||
if(iscultist(M) && (M.stat == DEAD || !M.client || M.client.is_afk()))
|
||||
if(IS_CULTIST(M) && (M.stat == DEAD || !M.client || M.client.is_afk()))
|
||||
potential_revive_mobs |= M
|
||||
if(!potential_revive_mobs.len)
|
||||
to_chat(user, "<span class='cult italic'>There are no dead cultists on the rune!</span>")
|
||||
@@ -567,7 +568,7 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
mob_to_revive.grab_ghost()
|
||||
if(!mob_to_revive.client || mob_to_revive.client.is_afk())
|
||||
set waitfor = FALSE
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as a [mob_to_revive.real_name], an inactive blood cultist?", ROLE_CULTIST, null, ROLE_CULTIST, 50, mob_to_revive)
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as a [mob_to_revive.real_name], an inactive blood cultist?", ROLE_CULTIST, ROLE_CULTIST, 50, mob_to_revive)
|
||||
if(LAZYLEN(candidates))
|
||||
var/mob/dead/observer/C = pick(candidates)
|
||||
to_chat(mob_to_revive.mind, "Your physical form has been taken over by another soul due to your inactivity! Ahelp if you wish to regain your form.")
|
||||
@@ -601,7 +602,7 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
..()
|
||||
rune_in_use = FALSE
|
||||
for(var/mob/living/M in range(1,src))
|
||||
if(iscultist(M) && M.stat == DEAD)
|
||||
if(IS_CULTIST(M) && M.stat == DEAD)
|
||||
M.visible_message("<span class='warning'>[M] twitches.</span>")
|
||||
|
||||
//Rite of the Corporeal Shield: When invoked, becomes solid and cannot be passed. Invoke again to undo.
|
||||
@@ -648,7 +649,7 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
/obj/effect/rune/summon/invoke(list/invokers)
|
||||
var/mob/living/user = invokers[1]
|
||||
var/list/cultists = list()
|
||||
for(var/datum/mind/M in SSticker.mode.cult)
|
||||
for(var/datum/mind/M as anything in get_antag_minds(/datum/antagonist/cult))
|
||||
if(!(M.current in invokers) && M.current && M.current.stat != DEAD)
|
||||
cultists |= M.current
|
||||
var/mob/living/cultist_to_summon = input(user, "Who do you wish to call to [src]?", "Followers of the Geometer") as null|anything in cultists
|
||||
@@ -669,7 +670,7 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
fail_invoke()
|
||||
log_game("Summon Cultist rune failed - target restrained")
|
||||
return
|
||||
if(!iscultist(cultist_to_summon))
|
||||
if(!IS_CULTIST(cultist_to_summon))
|
||||
to_chat(user, "<span class='cult italic'>[cultist_to_summon] is not a follower of the Geometer!</span>")
|
||||
fail_invoke()
|
||||
log_game("Summon Cultist rune failed - target was deconverted")
|
||||
@@ -713,7 +714,7 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
color = "#FC9B54"
|
||||
set_light(6, 1, color)
|
||||
for(var/mob/living/L in viewers(T))
|
||||
if(!iscultist(L) && L.blood_volume)
|
||||
if(!IS_CULTIST(L) && L.blood_volume)
|
||||
var/atom/I = L.anti_magic_check(chargecost = 0)
|
||||
if(I)
|
||||
if(isitem(I))
|
||||
@@ -741,7 +742,7 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
/obj/effect/rune/blood_boil/proc/do_area_burn(turf/T, multiplier)
|
||||
set_light(6, 1, color)
|
||||
for(var/mob/living/L in viewers(T))
|
||||
if(!iscultist(L) && L.blood_volume)
|
||||
if(!IS_CULTIST(L) && L.blood_volume)
|
||||
if(L.anti_magic_check(chargecost = 0))
|
||||
continue
|
||||
L.take_overall_damage(tick_damage*multiplier, tick_damage*multiplier)
|
||||
@@ -813,7 +814,7 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
to_chat(user, "<span class='cultitalic'>Your blood begins flowing into [src]. You must remain in place and conscious to maintain the forms of those summoned. This will hurt you slowly but surely...</span>")
|
||||
var/obj/structure/emergency_shield/cult/weak/N = new(T)
|
||||
new_human.key = ghost_to_spawn.key
|
||||
SSticker.mode.add_cultist(new_human.mind, 0)
|
||||
new_human.mind?.add_antag_datum(/datum/antagonist/cult)
|
||||
to_chat(new_human, "<span class='cultitalic'><b>You are a servant of the Geometer. You have been made semi-corporeal by the cult of Nar'Sie, and you are to serve them at all costs.</b></span>")
|
||||
|
||||
while(!QDELETED(src) && !QDELETED(user) && !QDELETED(new_human) && (user in T))
|
||||
@@ -905,7 +906,7 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
new /obj/effect/temp_visual/dir_setting/curse/grasp_portal/fading(T)
|
||||
var/intensity = 0
|
||||
for(var/mob/living/M in GLOB.player_list)
|
||||
if(iscultist(M))
|
||||
if(IS_CULTIST(M))
|
||||
intensity++
|
||||
intensity = max(60, 360 - (360*(intensity/GLOB.player_list.len + 0.3)**2)) //significantly lower intensity for "winning" cults
|
||||
var/duration = intensity*10
|
||||
@@ -921,7 +922,7 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
if(M.z != zmatch)
|
||||
continue
|
||||
if(ishuman(M))
|
||||
if(!iscultist(M))
|
||||
if(!IS_CULTIST(M))
|
||||
AH.remove_hud_from(M)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, .proc/hudFix, M), duration)
|
||||
var/image/A = image('icons/mob/cult.dmi',M,"cultist", ABOVE_MOB_LAYER)
|
||||
@@ -937,7 +938,7 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/noncult, "mob_apoc", B, NONE)
|
||||
addtimer(CALLBACK(M,/atom/.proc/remove_alt_appearance,"mob_apoc",TRUE), duration)
|
||||
images += B
|
||||
if(!iscultist(M))
|
||||
if(!IS_CULTIST(M))
|
||||
if(M.client)
|
||||
var/image/C = image('icons/effects/cult_effects.dmi',M,"bloodsparkles", ABOVE_MOB_LAYER)
|
||||
add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/cult, "cult_apoc", C, NONE)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
role_name = "sentient disease"
|
||||
|
||||
/datum/round_event/ghost_role/sentient_disease/spawn_role()
|
||||
var/list/candidates = get_candidates(ROLE_ALIEN, null, ROLE_ALIEN)
|
||||
var/list/candidates = get_candidates(ROLE_ALIEN, ROLE_ALIEN)
|
||||
if(!candidates.len)
|
||||
return NOT_ENOUGH_PLAYERS
|
||||
|
||||
|
||||
@@ -185,7 +185,7 @@
|
||||
//we need to spawn the mob first so that we can use it in pollCandidatesForMob, we will move it from nullspace down the code
|
||||
var/mob/living/summoned = new mob_to_summon(loc)
|
||||
message_admins("[summoned.name] is being summoned by [user.real_name] in [loc]")
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [summoned.real_name]", ROLE_HERETIC, null, FALSE, 100, summoned)
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [summoned.real_name]", ROLE_HERETIC, FALSE, 100, summoned)
|
||||
if(!LAZYLEN(candidates))
|
||||
to_chat(user,"<span class='warning'>No ghost could be found...</span>")
|
||||
qdel(summoned)
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
humie.grab_ghost()
|
||||
|
||||
if(!humie.mind || !humie.client)
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as a [humie.real_name], a voiceless dead", ROLE_HERETIC, null, ROLE_HERETIC, 50,humie)
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as a [humie.real_name], a voiceless dead", ROLE_HERETIC, ROLE_HERETIC, 50,humie)
|
||||
if(!LAZYLEN(candidates))
|
||||
return
|
||||
var/mob/dead/observer/chosen_candidate = pick(candidates)
|
||||
|
||||
@@ -460,7 +460,7 @@ GLOBAL_VAR_INIT(deaths_during_shift, 0)
|
||||
announcer = "Spinward Stellar Coalition National Guard"
|
||||
|
||||
priority_announce(announcement_message, announcer, 'sound/effects/families_police.ogg')
|
||||
var/list/candidates = pollGhostCandidates("Do you want to help clean up crime on this station?", "deathsquad", null)
|
||||
var/list/candidates = pollGhostCandidates("Do you want to help clean up crime on this station?", "deathsquad")
|
||||
|
||||
|
||||
if(candidates.len)
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
/datum/antagonist/monkey/on_gain()
|
||||
. = ..()
|
||||
SSticker.mode.ape_infectees += owner
|
||||
owner.special_role = "Infected Monkey"
|
||||
|
||||
var/datum/disease/D = new /datum/disease/transformation/jungle_fever/monkeymode
|
||||
@@ -39,7 +38,6 @@
|
||||
|
||||
/datum/antagonist/monkey/on_removal()
|
||||
owner.special_role = null
|
||||
SSticker.mode.ape_infectees -= owner
|
||||
|
||||
var/datum/disease/transformation/jungle_fever/D = locate() in owner.current.diseases
|
||||
if(D)
|
||||
@@ -116,11 +114,9 @@
|
||||
. = ..()
|
||||
var/obj/item/organ/heart/freedom/F = new
|
||||
F.Insert(owner.current, drop_if_replaced = FALSE)
|
||||
SSticker.mode.ape_leaders += owner
|
||||
owner.special_role = "Monkey Leader"
|
||||
|
||||
/datum/antagonist/monkey/leader/on_removal()
|
||||
SSticker.mode.ape_leaders -= owner
|
||||
var/obj/item/organ/heart/H = new
|
||||
H.Insert(owner.current, drop_if_replaced = FALSE) //replace freedom heart with normal heart
|
||||
|
||||
@@ -223,8 +219,8 @@
|
||||
|
||||
if(LAZYLEN(leaders))
|
||||
parts += "<span class='header'>The monkey leaders were:</span>"
|
||||
parts += printplayerlist(SSticker.mode.ape_leaders)
|
||||
parts += printplayerlist(leaders)
|
||||
if(LAZYLEN(monkeys))
|
||||
parts += "<span class='header'>The monkeys were:</span>"
|
||||
parts += printplayerlist(SSticker.mode.ape_infectees)
|
||||
parts += printplayerlist(monkeys)
|
||||
return "<div class='panel redborder'>[parts.Join("<br>")]</div>"
|
||||
|
||||
@@ -214,7 +214,7 @@
|
||||
role_name = "morphling"
|
||||
|
||||
/datum/round_event/ghost_role/morph/spawn_role()
|
||||
var/list/candidates = get_candidates(ROLE_ALIEN, null, ROLE_ALIEN)
|
||||
var/list/candidates = get_candidates(ROLE_ALIEN, ROLE_ALIEN)
|
||||
if(!candidates.len)
|
||||
return NOT_ENOUGH_PLAYERS
|
||||
|
||||
|
||||
@@ -69,10 +69,9 @@
|
||||
//ui_style = "syndicate" // actually the nuke op bomb is a stole nt bomb
|
||||
|
||||
/obj/machinery/nuclearbomb/syndicate/get_cinematic_type(off_station)
|
||||
var/datum/game_mode/nuclear/NM = SSticker.mode
|
||||
switch(off_station)
|
||||
if(0)
|
||||
if(istype(NM) && !NM.nuke_team.syndies_escaped())
|
||||
if(get_antag_minds(/datum/antagonist/nukeop).len && syndies_escaped())
|
||||
return CINEMATIC_ANNIHILATION
|
||||
else
|
||||
return CINEMATIC_NUKE_WIN
|
||||
|
||||
@@ -286,11 +286,6 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/team/nuclear/proc/syndies_escaped()
|
||||
var/obj/docking_port/mobile/S = SSshuttle.getShuttle("syndicate")
|
||||
var/obj/docking_port/stationary/transit/T = locate() in S.loc
|
||||
return S && (is_centcom_level(S.z) || T)
|
||||
|
||||
/datum/team/nuclear/proc/get_result()
|
||||
var/evacuation = EMERGENCY_ESCAPED_OR_ENDGAMED
|
||||
var/disk_rescued = disk_rescued()
|
||||
@@ -405,3 +400,9 @@
|
||||
|
||||
/datum/team/nuclear/is_gamemode_hero()
|
||||
return SSticker.mode.name == "nuclear emergency"
|
||||
|
||||
/// Returns whether or not syndicate operatives escaped.
|
||||
/proc/syndies_escaped()
|
||||
var/obj/docking_port/mobile/S = SSshuttle.getShuttle("syndicate")
|
||||
var/obj/docking_port/stationary/transit/T = locate() in S.loc
|
||||
return S && (is_centcom_level(S.z) || T)
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/datum/outfit/syndicate
|
||||
name = "Syndicate Operative - Basic"
|
||||
|
||||
uniform = /obj/item/clothing/under/syndicate
|
||||
shoes = /obj/item/clothing/shoes/combat
|
||||
gloves = /obj/item/clothing/gloves/combat
|
||||
back = /obj/item/storage/backpack/fireproof
|
||||
ears = /obj/item/radio/headset/syndicate/alt
|
||||
l_pocket = /obj/item/modular_computer/tablet/nukeops
|
||||
id = /obj/item/card/id/advanced/chameleon
|
||||
belt = /obj/item/gun/ballistic/automatic/pistol
|
||||
backpack_contents = list(/obj/item/storage/box/survival/syndie=1,\
|
||||
/obj/item/kitchen/knife/combat/survival)
|
||||
|
||||
skillchips = list(/obj/item/skillchip/disk_verifier)
|
||||
|
||||
var/tc = 25
|
||||
var/command_radio = FALSE
|
||||
var/uplink_type = /obj/item/uplink/nuclear
|
||||
|
||||
id_trim = /datum/id_trim/chameleon/operative
|
||||
|
||||
/datum/outfit/syndicate/leader
|
||||
name = "Syndicate Leader - Basic"
|
||||
gloves = /obj/item/clothing/gloves/krav_maga/combatglovesplus
|
||||
command_radio = TRUE
|
||||
|
||||
id_trim = /datum/id_trim/chameleon/operative/nuke_leader
|
||||
|
||||
/datum/outfit/syndicate/no_crystals
|
||||
name = "Syndicate Operative - Reinforcement"
|
||||
tc = 0
|
||||
|
||||
/datum/outfit/syndicate/post_equip(mob/living/carbon/human/H)
|
||||
var/obj/item/radio/R = H.ears
|
||||
R.set_frequency(FREQ_SYNDICATE)
|
||||
R.freqlock = TRUE
|
||||
if(command_radio)
|
||||
R.command = TRUE
|
||||
|
||||
if(ispath(uplink_type, /obj/item/uplink/nuclear) || tc) // /obj/item/uplink/nuclear understands 0 tc
|
||||
var/obj/item/U = new uplink_type(H, H.key, tc)
|
||||
H.equip_to_slot_or_del(U, ITEM_SLOT_BACKPACK)
|
||||
|
||||
var/obj/item/implant/weapons_auth/W = new/obj/item/implant/weapons_auth(H)
|
||||
W.implant(H)
|
||||
var/obj/item/implant/explosive/E = new/obj/item/implant/explosive(H)
|
||||
E.implant(H)
|
||||
H.faction |= ROLE_SYNDICATE
|
||||
H.update_icons()
|
||||
|
||||
/datum/outfit/syndicate/full
|
||||
name = "Syndicate Operative - Full Kit"
|
||||
|
||||
glasses = /obj/item/clothing/glasses/night
|
||||
mask = /obj/item/clothing/mask/gas/syndicate
|
||||
suit = /obj/item/clothing/suit/space/hardsuit/syndi
|
||||
r_pocket = /obj/item/tank/internals/emergency_oxygen/engi
|
||||
internals_slot = ITEM_SLOT_RPOCKET
|
||||
belt = /obj/item/storage/belt/military
|
||||
r_hand = /obj/item/gun/ballistic/shotgun/bulldog
|
||||
backpack_contents = list(/obj/item/storage/box/survival/syndie=1,\
|
||||
/obj/item/tank/jetpack/oxygen/harness=1,\
|
||||
/obj/item/gun/ballistic/automatic/pistol=1,\
|
||||
/obj/item/kitchen/knife/combat/survival)
|
||||
@@ -410,7 +410,7 @@
|
||||
break
|
||||
if(!key_of_revenant)
|
||||
message_admins("The new revenant's old client either could not be found or is in a new, living mob - grabbing a random candidate instead...")
|
||||
var/list/candidates = pollCandidatesForMob("Do you want to be [revenant.name] (reforming)?", ROLE_REVENANT, null, ROLE_REVENANT, 50, revenant)
|
||||
var/list/candidates = pollCandidatesForMob("Do you want to be [revenant.name] (reforming)?", ROLE_REVENANT, ROLE_REVENANT, 50, revenant)
|
||||
if(!LAZYLEN(candidates))
|
||||
qdel(revenant)
|
||||
message_admins("No candidates were found for the new revenant. Oh well!")
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
message_admins("Event attempted to spawn a revenant, but there were only [deadMobs]/[REVENANT_SPAWN_THRESHOLD] dead mobs.")
|
||||
return WAITING_FOR_SOMETHING
|
||||
|
||||
var/list/candidates = get_candidates(ROLE_REVENANT, null, ROLE_REVENANT)
|
||||
var/list/candidates = get_candidates(ROLE_REVENANT, ROLE_REVENANT)
|
||||
if(!candidates.len)
|
||||
return NOT_ENOUGH_PLAYERS
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
role_name = "slaughter demon"
|
||||
|
||||
/datum/round_event/ghost_role/slaughter/spawn_role()
|
||||
var/list/candidates = get_candidates(ROLE_ALIEN, null, ROLE_ALIEN)
|
||||
var/list/candidates = get_candidates(ROLE_ALIEN, ROLE_ALIEN)
|
||||
if(!candidates.len)
|
||||
return NOT_ENOUGH_PLAYERS
|
||||
|
||||
|
||||
@@ -219,34 +219,7 @@
|
||||
to_chat(owner.current, fail_msg)
|
||||
objective.stolen = FALSE
|
||||
|
||||
/datum/antagonist/traitor/internal_affairs/proc/forge_iaa_objectives()
|
||||
if(SSticker.mode.target_list.len && SSticker.mode.target_list[owner]) // Is a double agent
|
||||
// Assassinate
|
||||
var/datum/mind/target_mind = SSticker.mode.target_list[owner]
|
||||
if(issilicon(target_mind.current))
|
||||
var/datum/objective/destroy/internal/destroy_objective = new
|
||||
destroy_objective.owner = owner
|
||||
destroy_objective.target = target_mind
|
||||
destroy_objective.update_explanation_text()
|
||||
add_objective(destroy_objective)
|
||||
else
|
||||
var/datum/objective/assassinate/internal/kill_objective = new
|
||||
kill_objective.owner = owner
|
||||
kill_objective.target = target_mind
|
||||
kill_objective.update_explanation_text()
|
||||
add_objective(kill_objective)
|
||||
|
||||
//Optional traitor objective
|
||||
if(prob(PROB_ACTUAL_TRAITOR))
|
||||
employer = "The Syndicate"
|
||||
owner.special_role = TRAITOR_AGENT_ROLE
|
||||
special_role = TRAITOR_AGENT_ROLE
|
||||
syndicate = TRUE
|
||||
forge_single_objective()
|
||||
|
||||
/datum/antagonist/traitor/internal_affairs/forge_traitor_objectives()
|
||||
forge_iaa_objectives()
|
||||
|
||||
var/objtype = traitor_kind == TRAITOR_HUMAN ? /datum/objective/escape : /datum/objective/survive/malf
|
||||
var/datum/objective/escape_objective = new objtype
|
||||
escape_objective.owner = owner
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
if(owner.current && isAI(owner.current))
|
||||
traitor_kind = TRAITOR_AI
|
||||
|
||||
SSticker.mode.traitors += owner
|
||||
owner.special_role = special_role
|
||||
if(give_objectives)
|
||||
forge_traitor_objectives()
|
||||
@@ -36,7 +35,6 @@
|
||||
A.set_zeroth_law("")
|
||||
A.remove_malf_abilities()
|
||||
QDEL_NULL(A.malf_picker)
|
||||
SSticker.mode.traitors -= owner
|
||||
if(!silent && owner.current)
|
||||
to_chat(owner.current,"<span class='userdanger'>You are no longer the [special_role]!</span>")
|
||||
owner.special_role = null
|
||||
|
||||
@@ -165,7 +165,7 @@
|
||||
if (.)
|
||||
to_chat(user, "<span class='notice'>The uplink vibrates quietly, connecting to nearby agents...</span>")
|
||||
|
||||
var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as the Contractor Support Unit for [user.real_name]?", ROLE_PAI, null, FALSE, 100, POLL_IGNORE_CONTRACTOR_SUPPORT)
|
||||
var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as the Contractor Support Unit for [user.real_name]?", ROLE_PAI, FALSE, 100, POLL_IGNORE_CONTRACTOR_SUPPORT)
|
||||
|
||||
if(LAZYLEN(candidates))
|
||||
var/mob/dead/observer/C = pick(candidates)
|
||||
|
||||
@@ -87,10 +87,10 @@
|
||||
return
|
||||
if(!ishuman(M))//If target is not a human.
|
||||
return ..()
|
||||
if(iscultist(M) && iscultist(user))
|
||||
if(IS_CULTIST(M) && IS_CULTIST(user))
|
||||
to_chat(user, "<span class='cultlarge'>\"Come now, do not capture your bretheren's soul.\"</span>")
|
||||
return
|
||||
if(theme == THEME_HOLY && iscultist(user))
|
||||
if(theme == THEME_HOLY && IS_CULTIST(user))
|
||||
hot_potato(user)
|
||||
return
|
||||
log_combat(user, M, "captured [M.name]'s soul", src)
|
||||
@@ -105,7 +105,7 @@
|
||||
user.Unconscious(100)
|
||||
to_chat(user, "<span class='userdanger'>Your body is wracked with debilitating pain!</span>")
|
||||
return
|
||||
if(theme == THEME_HOLY && iscultist(user))
|
||||
if(theme == THEME_HOLY && IS_CULTIST(user))
|
||||
hot_potato(user)
|
||||
return
|
||||
release_shades(user)
|
||||
@@ -128,7 +128,7 @@
|
||||
icon_state = "soulstone"
|
||||
name = initial(name)
|
||||
if(!silent)
|
||||
if(iscultist(user))
|
||||
if(IS_CULTIST(user))
|
||||
to_chat(A, "<b>You have been released from your prison, but you are still bound to the cult's will. Help them succeed in their goals at all costs.</b>")
|
||||
else if(role_check(user))
|
||||
to_chat(A, "<b>You have been released from your prison, but you are still bound to [user.real_name]'s will. Help [user.p_them()] succeed in [user.p_their()] goals at all costs.</b>")
|
||||
@@ -140,7 +140,7 @@
|
||||
if(!occupant || !istype(target_toolbox) || target_toolbox.has_soul)
|
||||
return ..()
|
||||
|
||||
if(theme == THEME_HOLY && iscultist(user))
|
||||
if(theme == THEME_HOLY && IS_CULTIST(user))
|
||||
hot_potato(user)
|
||||
return
|
||||
if(!role_check(user))
|
||||
@@ -172,7 +172,7 @@
|
||||
|
||||
/obj/structure/constructshell/examine(mob/user)
|
||||
. = ..()
|
||||
if(iscultist(user) || iswizard(user) || user.stat == DEAD)
|
||||
if(IS_CULTIST(user) || IS_WIZARD(user) || user.stat == DEAD)
|
||||
. += {"<span class='cult'>A construct shell, used to house bound souls from a soulstone.\n
|
||||
Placing a soulstone with a soul into this shell allows you to produce your choice of the following:\n
|
||||
An <b>Artificer</b>, which can produce <b>more shells and soulstones</b>, as well as fortifications.\n
|
||||
@@ -182,11 +182,11 @@
|
||||
/obj/structure/constructshell/attackby(obj/item/O, mob/user, params)
|
||||
if(istype(O, /obj/item/soulstone))
|
||||
var/obj/item/soulstone/SS = O
|
||||
if(!iscultist(user) && !iswizard(user) && !SS.theme == THEME_HOLY)
|
||||
if(!IS_CULTIST(user) && !IS_WIZARD(user) && !SS.theme == THEME_HOLY)
|
||||
to_chat(user, "<span class='danger'>An overwhelming feeling of dread comes over you as you attempt to place [SS] into the shell. It would be wise to be rid of this quickly.</span>")
|
||||
user.Dizzy(30)
|
||||
return
|
||||
if(SS.theme == THEME_HOLY && iscultist(user))
|
||||
if(SS.theme == THEME_HOLY && IS_CULTIST(user))
|
||||
SS.hot_potato(user)
|
||||
return
|
||||
SS.transfer_soul("CONSTRUCT",src,user)
|
||||
@@ -243,8 +243,7 @@
|
||||
T.AddComponent(/datum/component/soulstoned, src)
|
||||
if(theme == THEME_HOLY)
|
||||
icon_state = "purified_soulstone2"
|
||||
if(iscultist(T))
|
||||
SSticker.mode.remove_cultist(T.mind, FALSE, FALSE)
|
||||
T.mind?.remove_antag_datum(/datum/antagonist/cult)
|
||||
if(theme == THEME_WIZARD)
|
||||
icon_state = "mystic_soulstone2"
|
||||
if(theme == THEME_CULT)
|
||||
@@ -268,7 +267,7 @@
|
||||
return
|
||||
switch(construct_class)
|
||||
if("Juggernaut")
|
||||
if(iscultist(user))
|
||||
if(IS_CULTIST(user))
|
||||
makeNewConstruct(/mob/living/simple_animal/hostile/construct/juggernaut, A, user, FALSE, T.loc)
|
||||
else
|
||||
switch(theme)
|
||||
@@ -279,7 +278,7 @@
|
||||
if(THEME_CULT)
|
||||
makeNewConstruct(/mob/living/simple_animal/hostile/construct/juggernaut/noncult, A, user, FALSE, T.loc)
|
||||
if("Wraith")
|
||||
if(iscultist(user))
|
||||
if(IS_CULTIST(user))
|
||||
makeNewConstruct(/mob/living/simple_animal/hostile/construct/wraith, A, user, FALSE, T.loc)
|
||||
else
|
||||
switch(theme)
|
||||
@@ -290,7 +289,7 @@
|
||||
if(THEME_CULT)
|
||||
makeNewConstruct(/mob/living/simple_animal/hostile/construct/wraith/noncult, A, user, FALSE, T.loc)
|
||||
if("Artificer")
|
||||
if(iscultist(user))
|
||||
if(IS_CULTIST(user))
|
||||
makeNewConstruct(/mob/living/simple_animal/hostile/construct/artificer, A, user, FALSE, T.loc)
|
||||
else
|
||||
switch(theme)
|
||||
@@ -302,9 +301,7 @@
|
||||
makeNewConstruct(/mob/living/simple_animal/hostile/construct/artificer/noncult, A, user, FALSE, T.loc)
|
||||
else
|
||||
return
|
||||
for(var/datum/mind/B in SSticker.mode.cult)
|
||||
if(B == A.mind)
|
||||
SSticker.mode.remove_cultist(A.mind)
|
||||
A.mind?.remove_antag_datum(/datum/antagonist/cult)
|
||||
qdel(T)
|
||||
qdel(src)
|
||||
else
|
||||
@@ -332,9 +329,9 @@
|
||||
SM.Grant(newstruct)
|
||||
newstruct.key = target.key
|
||||
var/atom/movable/screen/alert/bloodsense/BS
|
||||
if(newstruct.mind && ((stoner && iscultist(stoner)) || cultoverride) && SSticker?.mode)
|
||||
SSticker.mode.add_cultist(newstruct.mind, 0)
|
||||
if(iscultist(stoner) || cultoverride)
|
||||
if(newstruct.mind && ((stoner && IS_CULTIST(stoner)) || cultoverride) && SSticker?.mode)
|
||||
newstruct.mind.add_antag_datum(/datum/antagonist/cult)
|
||||
if(IS_CULTIST(stoner) || cultoverride)
|
||||
to_chat(newstruct, "<b>You are still bound to serve the cult[stoner ? " and [stoner]":""], follow [stoner ? stoner.p_their() : "their"] orders and help [stoner ? stoner.p_them() : "them"] complete [stoner ? stoner.p_their() : "their"] goals at all costs.</b>")
|
||||
else if(stoner)
|
||||
to_chat(newstruct, "<b>You are still bound to serve your creator, [stoner], follow [stoner.p_their()] orders and help [stoner.p_them()] complete [stoner.p_their()] goals at all costs.</b>")
|
||||
@@ -364,8 +361,8 @@
|
||||
grant_all_languages(FALSE, FALSE, TRUE) //Grants omnitongue
|
||||
if(user)
|
||||
S.faction |= "[REF(user)]" //Add the master as a faction, allowing inter-mob cooperation
|
||||
if(user && iscultist(user))
|
||||
SSticker.mode.add_cultist(S.mind, 0)
|
||||
if(user && IS_CULTIST(user))
|
||||
S.mind.add_antag_datum(/datum/antagonist/cult)
|
||||
S.cancel_camera()
|
||||
name = "soulstone: Shade of [T.real_name]"
|
||||
switch(theme)
|
||||
@@ -376,7 +373,7 @@
|
||||
if(THEME_CULT)
|
||||
icon_state = "soulstone2"
|
||||
if(user)
|
||||
if(iscultist(user))
|
||||
if(IS_CULTIST(user))
|
||||
to_chat(S, "Your soul has been captured! You are now bound to the cult's will. Help them succeed in their goals at all costs.")
|
||||
else if(role_check(user))
|
||||
to_chat(S, "Your soul has been captured! You are now bound to [user.real_name]'s will. Help [user.p_them()] succeed in [user.p_their()] goals at all costs.")
|
||||
@@ -390,7 +387,7 @@
|
||||
chosen_ghost = T.get_ghost(TRUE,TRUE) //Try to grab original owner's ghost first
|
||||
|
||||
if(!chosen_ghost || !chosen_ghost.client) //Failing that, we grab a ghosts
|
||||
var/list/consenting_candidates = pollGhostCandidates("Would you like to play as a Shade?", "Cultist", null, ROLE_CULTIST, 50, POLL_IGNORE_SHADE)
|
||||
var/list/consenting_candidates = pollGhostCandidates("Would you like to play as a Shade?", "Cultist", ROLE_CULTIST, 50, POLL_IGNORE_SHADE)
|
||||
if(consenting_candidates.len)
|
||||
chosen_ghost = pick(consenting_candidates)
|
||||
if(!T)
|
||||
|
||||
@@ -31,12 +31,6 @@
|
||||
if(allow_rename)
|
||||
rename_wizard()
|
||||
|
||||
/datum/antagonist/wizard/proc/register()
|
||||
SSticker.mode.wizards |= owner
|
||||
|
||||
/datum/antagonist/wizard/proc/unregister()
|
||||
SSticker.mode.wizards -= src
|
||||
|
||||
/datum/antagonist/wizard/create_team(datum/team/wizard/new_team)
|
||||
if(!new_team)
|
||||
return
|
||||
@@ -122,9 +116,9 @@
|
||||
//SKYRAT EDIT REMOVAL BEGIN - WIZARD CHANGES
|
||||
/*
|
||||
unregister()
|
||||
owner.RemoveAllSpells() // TODO keep track which spells are wizard spells which innate stuff
|
||||
*/
|
||||
//SKYRAT EDIT REMOVAL END
|
||||
owner.RemoveAllSpells() // TODO keep track which spells are wizard spells which innate stuff
|
||||
return ..()
|
||||
|
||||
/datum/antagonist/wizard/proc/equip_wizard()
|
||||
@@ -203,12 +197,6 @@
|
||||
to_chat(owner, "<B>You are [master.current.real_name]'s apprentice! You are bound by magic contract to follow [master.p_their()] orders and help [master.p_them()] in accomplishing [master.p_their()] goals.")
|
||||
owner.announce_objectives()
|
||||
|
||||
/datum/antagonist/wizard/apprentice/register()
|
||||
SSticker.mode.apprentices |= owner
|
||||
|
||||
/datum/antagonist/wizard/apprentice/unregister()
|
||||
SSticker.mode.apprentices -= owner
|
||||
|
||||
/datum/antagonist/wizard/apprentice/equip_wizard()
|
||||
. = ..()
|
||||
if(!owner)
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
|
||||
if(!current_wizard)
|
||||
return
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as Wizard Academy Defender?", ROLE_WIZARD, null, ROLE_WIZARD, 50, current_wizard, POLL_IGNORE_ACADEMY_WIZARD)
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as Wizard Academy Defender?", ROLE_WIZARD, ROLE_WIZARD, 50, current_wizard, POLL_IGNORE_ACADEMY_WIZARD)
|
||||
|
||||
if(LAZYLEN(candidates))
|
||||
var/mob/dead/observer/C = pick(candidates)
|
||||
@@ -209,7 +209,7 @@
|
||||
if(used)
|
||||
return
|
||||
|
||||
if(!ishuman(user) || !user.mind || (user.mind in SSticker.mode.wizards))
|
||||
if(!ishuman(user) || !user.mind || IS_WIZARD(user))
|
||||
to_chat(user, "<span class='warning'>You feel the magic of the dice is restricted to ordinary humans!</span>")
|
||||
return
|
||||
|
||||
@@ -224,7 +224,7 @@
|
||||
|
||||
/obj/item/dice/d20/fate/equipped(mob/user, slot)
|
||||
. = ..()
|
||||
if(!ishuman(user) || !user.mind || (user.mind in SSticker.mode.wizards))
|
||||
if(!ishuman(user) || !user.mind || IS_WIZARD(user))
|
||||
to_chat(user, "<span class='warning'>You feel the magic of the dice is restricted to ordinary humans! You should leave it alone.</span>")
|
||||
user.dropItemToGround(src)
|
||||
|
||||
@@ -325,7 +325,7 @@
|
||||
A.setup_master(user)
|
||||
servant_mind.transfer_to(H)
|
||||
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [user.real_name] Servant?", ROLE_WIZARD, null, ROLE_WIZARD, 50, H)
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [user.real_name] Servant?", ROLE_WIZARD, ROLE_WIZARD, 50, H)
|
||||
if(LAZYLEN(candidates))
|
||||
var/mob/dead/observer/C = pick(candidates)
|
||||
message_admins("[ADMIN_LOOKUPFLW(C)] was spawned as Dice Servant")
|
||||
@@ -405,5 +405,5 @@
|
||||
user.visible_message("<span class='notice'>[user] activates \the [src].</span>", "<span class='notice'>You activate \the [src].</span>")
|
||||
|
||||
/obj/structure/ladder/unbreakable/rune/use(mob/user, is_ghost=FALSE)
|
||||
if(is_ghost || !(user.mind in SSticker.mode.wizards))
|
||||
if(is_ghost || !IS_WIZARD(user))
|
||||
..()
|
||||
|
||||
@@ -2640,7 +2640,7 @@
|
||||
|
||||
///Generate assorted uplink items, taking into account the same surplus modifiers used for surplus crates
|
||||
/datum/supply_pack/misc/syndicate/fill(obj/structure/closet/crate/C)
|
||||
var/list/uplink_items = get_uplink_items(SSticker.mode)
|
||||
var/list/uplink_items = get_uplink_items(UPLINK_TRAITORS)
|
||||
while(crate_value)
|
||||
var/category = pick(uplink_items)
|
||||
var/item = pick(uplink_items[category])
|
||||
|
||||
@@ -1146,3 +1146,18 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
|
||||
SSambience.ambience_listening_clients[src] = world.time + 10 SECONDS //Just wait 10 seconds before the next one aight mate? cheers.
|
||||
else
|
||||
SSambience.ambience_listening_clients -= src
|
||||
|
||||
/// Checks if this client has met the days requirement passed in, or if
|
||||
/// they are exempt from it.
|
||||
/// Returns the number of days left, or 0.
|
||||
/client/proc/get_remaining_days(days_needed)
|
||||
if(!CONFIG_GET(flag/use_age_restriction_for_jobs))
|
||||
return 0
|
||||
|
||||
if(!isnum(player_age))
|
||||
return 0 //This is only a number if the db connection is established, otherwise it is text: "Requires database", meaning these restrictions cannot be enforced
|
||||
|
||||
if(!isnum(days_needed))
|
||||
return 0
|
||||
|
||||
return max(0, days_needed - player_age)
|
||||
|
||||
@@ -695,20 +695,19 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
src.be_special = list()
|
||||
|
||||
|
||||
for (var/i in GLOB.special_roles)
|
||||
if(is_banned_from(user.ckey, i))
|
||||
dat += "<b>Be [capitalize(i)]:</b> <a href='?_src_=prefs;bancheck=[i]'>BANNED</a><br>"
|
||||
for (var/special_role in GLOB.special_roles)
|
||||
if(is_banned_from(user.ckey, special_role))
|
||||
dat += "<b>Be [capitalize(special_role)]:</b> <a href='?_src_=prefs;bancheck=[special_role]'>BANNED</a><br>"
|
||||
else
|
||||
var/days_remaining = null
|
||||
if(ispath(GLOB.special_roles[i]) && CONFIG_GET(flag/use_age_restriction_for_jobs)) //If it's a game mode antag, check if the player meets the minimum age
|
||||
var/mode_path = GLOB.special_roles[i]
|
||||
var/datum/game_mode/temp_mode = new mode_path
|
||||
days_remaining = temp_mode.get_remaining_days(user.client)
|
||||
if(CONFIG_GET(flag/use_age_restriction_for_jobs)) //If it's a game mode antag, check if the player meets the minimum age
|
||||
var/days_needed = GLOB.special_roles[special_role]
|
||||
days_remaining = user.client?.get_remaining_days(days_needed)
|
||||
|
||||
if(days_remaining)
|
||||
dat += "<b>Be [capitalize(i)]:</b> <font color=red> \[IN [days_remaining] DAYS]</font><br>"
|
||||
dat += "<b>Be [capitalize(special_role)]:</b> <font color=red> \[IN [days_remaining] DAYS]</font><br>"
|
||||
else
|
||||
dat += "<b>Be [capitalize(i)]:</b> <a href='?_src_=prefs;preference=be_special;be_special_type=[i]'>[(i in be_special) ? "Enabled" : "Disabled"]</a><br>"
|
||||
dat += "<b>Be [capitalize(special_role)]:</b> <a href='?_src_=prefs;preference=be_special;be_special_type=[special_role]'>[(special_role in be_special) ? "Enabled" : "Disabled"]</a><br>"
|
||||
dat += "<br>"
|
||||
dat += "<b>Midround Antagonist:</b> <a href='?_src_=prefs;preference=allow_midround_antag'>[(toggles & MIDROUND_ANTAG) ? "Enabled" : "Disabled"]</a><br>"
|
||||
dat += "</td></tr></table>"
|
||||
|
||||
@@ -434,7 +434,7 @@
|
||||
playsound(src, 'sound/machines/ping.ogg', 30, TRUE)
|
||||
RegisterSignal(magnification, COMSIG_SPECIES_LOSS, .proc/make_fall_off)
|
||||
polling = TRUE
|
||||
var/list/candidates = pollCandidatesForMob("Do you want to play as a mind magnified monkey?", ROLE_SENTIENCE, null, ROLE_SENTIENCE, 50, magnification, POLL_IGNORE_SENTIENCE_POTION)
|
||||
var/list/candidates = pollCandidatesForMob("Do you want to play as a mind magnified monkey?", ROLE_SENTIENCE, ROLE_SENTIENCE, 50, magnification, POLL_IGNORE_SENTIENCE_POTION)
|
||||
polling = FALSE
|
||||
if(!magnification)
|
||||
return
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
fakeable = FALSE //Nothing to fake here
|
||||
|
||||
/datum/round_event/ghost_role/abductor/spawn_role()
|
||||
var/list/mob/dead/observer/candidates = get_candidates(ROLE_ABDUCTOR, null, ROLE_ABDUCTOR)
|
||||
var/list/mob/dead/observer/candidates = get_candidates(ROLE_ABDUCTOR, ROLE_ABDUCTOR)
|
||||
|
||||
if(candidates.len < 2)
|
||||
return NOT_ENOUGH_PLAYERS
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
message_admins("An event attempted to spawn an alien but no suitable vents were found. Shutting down.")
|
||||
return MAP_ERROR
|
||||
|
||||
var/list/candidates = get_candidates(ROLE_ALIEN, null, ROLE_ALIEN)
|
||||
var/list/candidates = get_candidates(ROLE_ALIEN, ROLE_ALIEN)
|
||||
|
||||
if(!candidates.len)
|
||||
return NOT_ENOUGH_PLAYERS
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
/datum/round_event/ghost_role/blob/spawn_role()
|
||||
if(!GLOB.blobstart.len)
|
||||
return MAP_ERROR
|
||||
var/list/candidates = get_candidates(ROLE_BLOB, null, ROLE_BLOB)
|
||||
var/list/candidates = get_candidates(ROLE_BLOB, ROLE_BLOB)
|
||||
if(!candidates.len)
|
||||
return NOT_ENOUGH_PLAYERS
|
||||
var/mob/dead/observer/new_blob = pick(candidates)
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
return MAP_ERROR
|
||||
var/turf/landing_turf = pick(possible_spawns)
|
||||
var/list/possible_backstories = list()
|
||||
var/list/candidates = get_candidates(ROLE_TRAITOR, null, ROLE_TRAITOR)
|
||||
var/list/candidates = get_candidates(ROLE_TRAITOR, ROLE_TRAITOR)
|
||||
if(candidates.len >= 1) //solo refugees
|
||||
if(prob(30))
|
||||
possible_backstories.Add("waldo") //less common as it comes with magicks and is kind of immershun shattering
|
||||
|
||||
@@ -56,14 +56,14 @@
|
||||
// players could be found, and just runtime if anything else happens
|
||||
return TRUE
|
||||
|
||||
/datum/round_event/ghost_role/proc/get_candidates(jobban, gametypecheck, be_special)
|
||||
/datum/round_event/ghost_role/proc/get_candidates(jobban, be_special)
|
||||
// Returns a list of candidates in priority order, with candidates from
|
||||
// `priority_candidates` first, and ghost roles randomly shuffled and
|
||||
// appended after
|
||||
var/list/mob/dead/observer/regular_candidates
|
||||
// don't get their hopes up
|
||||
if(priority_candidates.len < minimum_required)
|
||||
regular_candidates = pollGhostCandidates("Do you wish to be considered for the special role of '[role_name]'?", jobban, gametypecheck, be_special)
|
||||
regular_candidates = pollGhostCandidates("Do you wish to be considered for the special role of '[role_name]'?", jobban, be_special)
|
||||
else
|
||||
regular_candidates = list()
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
fakeable = FALSE
|
||||
|
||||
/datum/round_event/ghost_role/nightmare/spawn_role()
|
||||
var/list/candidates = get_candidates(ROLE_ALIEN, null, ROLE_ALIEN)
|
||||
var/list/candidates = get_candidates(ROLE_ALIEN, ROLE_ALIEN)
|
||||
if(!candidates.len)
|
||||
return NOT_ENOUGH_PLAYERS
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user