mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-29 08:08:49 +01:00
[MIRROR] Removes bug room objective, Reworks primary objective and steal objectives. [MDB IGNORE] (#19819)
* Removes bug room objective, Reworks primary objective and steal objectives. * ??? * fix * Delete bug_room.dm --------- Co-authored-by: Watermelon914 <37270891+Watermelon914@users.noreply.github.com> Co-authored-by: Gandalf <9026500+Gandalf2k15@users.noreply.github.com>
This commit is contained in:
co-authored by
Watermelon914
Gandalf
parent
30bdf00da2
commit
f7e6ea19e1
@@ -252,6 +252,21 @@ GLOBAL_LIST_INIT(human_invader_antagonists, list(
|
||||
|
||||
// Progression traitor defines
|
||||
|
||||
/// Chance that the traitor could roll hijack if the pop limit is met.
|
||||
#define HIJACK_PROB 10
|
||||
/// Hijack is unavailable as a random objective below this player count.
|
||||
#define HIJACK_MIN_PLAYERS 30
|
||||
|
||||
/// Chance the traitor gets a martyr objective instead of having to escape alive, as long as all the objectives are martyr compatible.
|
||||
#define MARTYR_PROB 20
|
||||
|
||||
/// Chance the traitor gets a kill objective. If this prob fails, they will get a steal objective instead.
|
||||
#define KILL_PROB 50
|
||||
/// If a kill objective is rolled, chance that it is to destroy the AI.
|
||||
#define DESTROY_AI_PROB(denominator) (100 / denominator)
|
||||
/// If the destroy AI objective doesn't roll, chance that we'll get a maroon instead. If this prob fails, they will get a generic assassinate objective instead.
|
||||
#define MAROON_PROB 30
|
||||
|
||||
/// How many telecrystals a normal traitor starts with
|
||||
#define TELECRYSTALS_DEFAULT 20
|
||||
/// How many telecrystals mapper/admin only "precharged" uplink implant
|
||||
@@ -280,11 +295,11 @@ GLOBAL_LIST_INIT(human_invader_antagonists, list(
|
||||
#define OBJECTIVE_STATE_INVALID 5
|
||||
|
||||
/// Weights for traitor objective categories
|
||||
#define OBJECTIVE_WEIGHT_TINY 5
|
||||
#define OBJECTIVE_WEIGHT_SMALL 7
|
||||
#define OBJECTIVE_WEIGHT_VERY_UNLIKELY 2
|
||||
#define OBJECTIVE_WEIGHT_UNLIKELY 5
|
||||
#define OBJECTIVE_WEIGHT_DEFAULT 10
|
||||
#define OBJECTIVE_WEIGHT_BIG 15
|
||||
#define OBJECTIVE_WEIGHT_HUGE 20
|
||||
#define OBJECTIVE_WEIGHT_LIKELY 15
|
||||
#define OBJECTIVE_WEIGHT_VERY_LIKELY 20
|
||||
|
||||
#define REVENANT_NAME_FILE "revenant_names.json"
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
#define ADD_STEAL_ITEM(Source, Type) GLOB.steal_item_handler.objectives_by_path[Type] += Source
|
||||
/proc/add_item_to_steal(source, type)
|
||||
GLOB.steal_item_handler.objectives_by_path[type] += source
|
||||
return type
|
||||
|
||||
//Contains the target item datums for Steal objectives.
|
||||
/datum/objective_item
|
||||
@@ -60,11 +62,11 @@
|
||||
return ..()
|
||||
|
||||
// Low risk steal objectives
|
||||
/datum/objective_item/steal/low_risk
|
||||
/datum/objective_item/steal/traitor
|
||||
objective_type = OBJECTIVE_ITEM_TYPE_TRAITOR
|
||||
|
||||
// Unique-ish low risk objectives
|
||||
/datum/objective_item/steal/low_risk/bartender_shotgun
|
||||
/datum/objective_item/steal/traitor/bartender_shotgun
|
||||
name = "the bartender's shotgun"
|
||||
targetitem = /obj/item/gun/ballistic/shotgun/doublebarrel
|
||||
excludefromjob = list(JOB_BARTENDER)
|
||||
@@ -72,10 +74,9 @@
|
||||
exists_on_map = TRUE
|
||||
|
||||
/obj/item/gun/ballistic/shotgun/doublebarrel/add_stealing_item_objective()
|
||||
ADD_STEAL_ITEM(src, /obj/item/gun/ballistic/shotgun/doublebarrel)
|
||||
return add_item_to_steal(src, /obj/item/gun/ballistic/shotgun/doublebarrel)
|
||||
|
||||
// No item owner, list would be so long as to be functionally useless and they're in two very disparate locations on most maps
|
||||
/datum/objective_item/steal/low_risk/fireaxe
|
||||
/datum/objective_item/steal/traitor/fireaxe
|
||||
name = "a fire axe"
|
||||
targetitem = /obj/item/fireaxe
|
||||
excludefromjob = list(
|
||||
@@ -92,9 +93,9 @@
|
||||
exists_on_map = TRUE
|
||||
|
||||
/obj/item/fireaxe/add_stealing_item_objective()
|
||||
ADD_STEAL_ITEM(src, /obj/item/fireaxe)
|
||||
return add_item_to_steal(src, /obj/item/fireaxe)
|
||||
|
||||
/datum/objective_item/steal/low_risk/big_crowbar
|
||||
/datum/objective_item/steal/traitor/big_crowbar
|
||||
name = "a mech removal tool"
|
||||
targetitem = /obj/item/crowbar/mechremoval
|
||||
excludefromjob = list(
|
||||
@@ -106,9 +107,9 @@
|
||||
exists_on_map = TRUE
|
||||
|
||||
/obj/item/crowbar/mechremoval/add_stealing_item_objective()
|
||||
ADD_STEAL_ITEM(src, /obj/item/crowbar/mechremoval)
|
||||
return add_item_to_steal(src, /obj/item/crowbar/mechremoval)
|
||||
|
||||
/datum/objective_item/steal/low_risk/nullrod
|
||||
/datum/objective_item/steal/traitor/nullrod
|
||||
name = "the chaplain's null rod"
|
||||
targetitem = /obj/item/nullrod
|
||||
excludefromjob = list(JOB_CHAPLAIN)
|
||||
@@ -116,15 +117,49 @@
|
||||
exists_on_map = TRUE
|
||||
|
||||
/obj/item/nullrod/add_stealing_item_objective()
|
||||
ADD_STEAL_ITEM(src, /obj/item/nullrod)
|
||||
return add_item_to_steal(src, /obj/item/nullrod)
|
||||
|
||||
/datum/objective_item/steal/low_risk/clown_shoes
|
||||
/datum/objective_item/steal/traitor/clown_shoes
|
||||
name = "the clown's shoes"
|
||||
targetitem = /obj/item/clothing/shoes/clown_shoes
|
||||
excludefromjob = list(JOB_CLOWN, JOB_CARGO_TECHNICIAN, JOB_QUARTERMASTER)
|
||||
item_owner = list(JOB_CLOWN)
|
||||
|
||||
/datum/objective_item/steal/low_risk/cargo_budget
|
||||
/datum/objective_item/steal/traitor/det_revolver
|
||||
name = "detective's revolver"
|
||||
targetitem = /obj/item/gun/ballistic/revolver/c38/detective
|
||||
excludefromjob = list(JOB_DETECTIVE)
|
||||
exists_on_map = TRUE
|
||||
|
||||
/obj/item/gun/ballistic/revolver/c38/detective/add_stealing_item_objective()
|
||||
return add_item_to_steal(src, /obj/item/gun/ballistic/revolver/c38/detective)
|
||||
|
||||
/datum/objective_item/steal/traitor/chief_engineer_belt
|
||||
name = "the chief engineer's belt"
|
||||
targetitem = /obj/item/storage/belt/utility/chief
|
||||
excludefromjob = list(JOB_CHIEF_ENGINEER)
|
||||
exists_on_map = TRUE
|
||||
|
||||
/obj/item/storage/belt/utility/chief/add_stealing_item_objective()
|
||||
return add_item_to_steal(src, /obj/item/storage/belt/utility/chief)
|
||||
|
||||
/datum/objective_item/steal/traitor/telebaton
|
||||
name = "a head of staff's telescopic baton"
|
||||
targetitem = /obj/item/melee/baton/telescopic
|
||||
excludefromjob = list(
|
||||
JOB_RESEARCH_DIRECTOR,
|
||||
JOB_CAPTAIN,
|
||||
JOB_HEAD_OF_SECURITY,
|
||||
JOB_HEAD_OF_PERSONNEL,
|
||||
JOB_CHIEF_ENGINEER,
|
||||
JOB_CHIEF_MEDICAL_OFFICER
|
||||
)
|
||||
exists_on_map = TRUE
|
||||
|
||||
/obj/item/melee/baton/telescopic/add_stealing_item_objective()
|
||||
return add_item_to_steal(src, /obj/item/melee/baton/telescopic)
|
||||
|
||||
/datum/objective_item/steal/traitor/cargo_budget
|
||||
name = "cargo's departmental budget"
|
||||
targetitem = /obj/item/card/id/departmental_budget/car
|
||||
excludefromjob = list(JOB_QUARTERMASTER, JOB_CARGO_TECHNICIAN)
|
||||
@@ -132,7 +167,32 @@
|
||||
exists_on_map = TRUE
|
||||
|
||||
/obj/item/card/id/departmental_budget/car/add_stealing_item_objective()
|
||||
ADD_STEAL_ITEM(src, /obj/item/card/id/departmental_budget/car)
|
||||
return add_item_to_steal(src, /obj/item/card/id/departmental_budget/car)
|
||||
|
||||
/datum/objective_item/steal/traitor/captain_modsuit
|
||||
name = "the captain's magnate MOD control unit"
|
||||
targetitem = /obj/item/mod/control/pre_equipped/magnate
|
||||
excludefromjob = list(JOB_CAPTAIN)
|
||||
exists_on_map = TRUE
|
||||
|
||||
/obj/item/mod/control/pre_equipped/magnate/add_stealing_item_objective()
|
||||
return add_item_to_steal(src, /obj/item/mod/control/pre_equipped/magnate)
|
||||
|
||||
/datum/objective_item/steal/traitor/captain_spare
|
||||
name = "the captain's spare ID"
|
||||
targetitem = /obj/item/card/id/advanced/gold/captains_spare
|
||||
excludefromjob = list(
|
||||
JOB_RESEARCH_DIRECTOR,
|
||||
JOB_CAPTAIN,
|
||||
JOB_HEAD_OF_SECURITY,
|
||||
JOB_HEAD_OF_PERSONNEL,
|
||||
JOB_CHIEF_ENGINEER,
|
||||
JOB_CHIEF_MEDICAL_OFFICER
|
||||
)
|
||||
exists_on_map = TRUE
|
||||
|
||||
/obj/item/card/id/advanced/gold/captains_spare/add_stealing_item_objective()
|
||||
return add_item_to_steal(src, /obj/item/card/id/advanced/gold/captains_spare)
|
||||
|
||||
// High risk steal objectives
|
||||
|
||||
@@ -144,7 +204,7 @@
|
||||
exists_on_map = TRUE
|
||||
|
||||
/obj/item/gun/energy/laser/captain/add_stealing_item_objective()
|
||||
ADD_STEAL_ITEM(src, /obj/item/gun/energy/laser/captain)
|
||||
return add_item_to_steal(src, /obj/item/gun/energy/laser/captain)
|
||||
|
||||
/datum/objective_item/steal/hoslaser
|
||||
name = "the head of security's personal laser gun"
|
||||
@@ -154,7 +214,7 @@
|
||||
exists_on_map = TRUE
|
||||
|
||||
/obj/item/gun/energy/e_gun/hos/add_stealing_item_objective()
|
||||
ADD_STEAL_ITEM(src, /obj/item/gun/energy/e_gun/hos)
|
||||
return add_item_to_steal(src, /obj/item/gun/energy/e_gun/hos)
|
||||
|
||||
/datum/objective_item/steal/handtele
|
||||
name = "a hand teleporter"
|
||||
@@ -164,7 +224,7 @@
|
||||
exists_on_map = TRUE
|
||||
|
||||
/obj/item/hand_tele/add_stealing_item_objective()
|
||||
ADD_STEAL_ITEM(src, /obj/item/hand_tele)
|
||||
return add_item_to_steal(src, /obj/item/hand_tele)
|
||||
|
||||
/datum/objective_item/steal/jetpack
|
||||
name = "the Captain's jetpack"
|
||||
@@ -174,7 +234,7 @@
|
||||
exists_on_map = TRUE
|
||||
|
||||
/obj/item/tank/jetpack/oxygen/captain/add_stealing_item_objective()
|
||||
ADD_STEAL_ITEM(src, /obj/item/tank/jetpack/oxygen/captain)
|
||||
return add_item_to_steal(src, /obj/item/tank/jetpack/oxygen/captain)
|
||||
|
||||
/datum/objective_item/steal/magboots
|
||||
name = "the chief engineer's advanced magnetic boots"
|
||||
@@ -184,7 +244,7 @@
|
||||
exists_on_map = TRUE
|
||||
|
||||
/obj/item/clothing/shoes/magboots/advance/add_stealing_item_objective()
|
||||
ADD_STEAL_ITEM(src, /obj/item/clothing/shoes/magboots/advance)
|
||||
return add_item_to_steal(src, /obj/item/clothing/shoes/magboots/advance)
|
||||
|
||||
/datum/objective_item/steal/capmedal
|
||||
name = "the medal of captaincy"
|
||||
@@ -194,7 +254,7 @@
|
||||
exists_on_map = TRUE
|
||||
|
||||
/obj/item/clothing/accessory/medal/gold/captain/add_stealing_item_objective()
|
||||
ADD_STEAL_ITEM(src, /obj/item/clothing/accessory/medal/gold/captain)
|
||||
return add_item_to_steal(src, /obj/item/clothing/accessory/medal/gold/captain)
|
||||
|
||||
/datum/objective_item/steal/hypo
|
||||
//name = "the hypospray" // ORIGINAL
|
||||
@@ -205,16 +265,17 @@
|
||||
item_owner = list(JOB_CHIEF_MEDICAL_OFFICER)
|
||||
exists_on_map = TRUE
|
||||
|
||||
///obj/item/reagent_containers/hypospray/cmo/add_stealing_item_objective() // ORIGINAL
|
||||
/obj/item/hypospray/mkii/cmo/add_stealing_item_objective() // SKYRAT EDIT CHANGE
|
||||
//ADD_STEAL_ITEM(src, /obj/item/reagent_containers/hypospray/cmo) // ORIGINAL
|
||||
ADD_STEAL_ITEM(src, /obj/item/hypospray/mkii/cmo) // SKYRAT EDIT CHANGE
|
||||
return add_item_to_steal(src, /obj/item/hypospray/mkii/cmo) // SKYRAT EDIT CHANGE
|
||||
|
||||
/datum/objective_item/steal/nukedisc
|
||||
name = "the nuclear authentication disk"
|
||||
targetitem = /obj/item/disk/nuclear
|
||||
excludefromjob = list(JOB_CAPTAIN)
|
||||
|
||||
/obj/item/disk/nuclear/add_stealing_item_objective()
|
||||
return add_item_to_steal(src, /obj/item/disk/nuclear)
|
||||
|
||||
/datum/objective_item/steal/nukedisc/check_special_completion(obj/item/disk/nuclear/N)
|
||||
return !N.fake
|
||||
|
||||
@@ -226,7 +287,7 @@
|
||||
exists_on_map = TRUE
|
||||
|
||||
/obj/item/clothing/suit/hooded/ablative/add_stealing_item_objective()
|
||||
ADD_STEAL_ITEM(src, /obj/item/clothing/suit/hooded/ablative)
|
||||
return add_item_to_steal(src, /obj/item/clothing/suit/hooded/ablative)
|
||||
|
||||
/datum/objective_item/steal/reactive
|
||||
name = "the reactive teleport armor"
|
||||
@@ -236,7 +297,7 @@
|
||||
exists_on_map = TRUE
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/teleport/add_stealing_item_objective()
|
||||
ADD_STEAL_ITEM(src, /obj/item/clothing/suit/armor/reactive/teleport)
|
||||
return add_item_to_steal(src, /obj/item/clothing/suit/armor/reactive/teleport)
|
||||
|
||||
/datum/objective_item/steal/documents
|
||||
name = "any set of secret documents of any organization"
|
||||
@@ -244,7 +305,7 @@
|
||||
exists_on_map = TRUE
|
||||
|
||||
/obj/item/documents/add_stealing_item_objective()
|
||||
ADD_STEAL_ITEM(src, /obj/item/documents) //Any set of secret documents. Doesn't have to be NT's
|
||||
return add_item_to_steal(src, /obj/item/documents) //Any set of secret documents. Doesn't have to be NT's
|
||||
|
||||
/datum/objective_item/steal/nuke_core
|
||||
name = "the heavily radioactive plutonium core from the onboard self-destruct"
|
||||
@@ -253,7 +314,7 @@
|
||||
exists_on_map = TRUE
|
||||
|
||||
/obj/item/nuke_core/add_stealing_item_objective()
|
||||
ADD_STEAL_ITEM(src, /obj/item/nuke_core)
|
||||
return add_item_to_steal(src, /obj/item/nuke_core)
|
||||
|
||||
/datum/objective_item/steal/nuke_core/New()
|
||||
special_equipment += /obj/item/storage/box/syndie_kit/nuke
|
||||
@@ -267,7 +328,7 @@
|
||||
exists_on_map = TRUE
|
||||
|
||||
/obj/item/computer_disk/hdd_theft/add_stealing_item_objective()
|
||||
ADD_STEAL_ITEM(src, /obj/item/computer_disk/hdd_theft)
|
||||
return add_item_to_steal(src, /obj/item/computer_disk/hdd_theft)
|
||||
|
||||
/datum/objective_item/steal/hdd_extraction/New()
|
||||
special_equipment += /obj/item/paper/guides/antag/hdd_extraction
|
||||
@@ -324,7 +385,7 @@
|
||||
exists_on_map = TRUE
|
||||
|
||||
/obj/item/areaeditor/blueprints/add_stealing_item_objective()
|
||||
ADD_STEAL_ITEM(src, /obj/item/areaeditor/blueprints)
|
||||
return add_item_to_steal(src, /obj/item/areaeditor/blueprints)
|
||||
|
||||
/datum/objective_item/steal/blueprints/check_special_completion(obj/item/I)
|
||||
if(istype(I, /obj/item/areaeditor/blueprints))
|
||||
@@ -342,6 +403,4 @@
|
||||
exists_on_map = TRUE
|
||||
|
||||
/obj/item/blackbox/add_stealing_item_objective()
|
||||
ADD_STEAL_ITEM(src, /obj/item/blackbox)
|
||||
|
||||
#undef ADD_STEAL_ITEM
|
||||
return add_item_to_steal(src, /obj/item/blackbox)
|
||||
|
||||
@@ -254,8 +254,6 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_NEW_ITEM, src)
|
||||
if(LAZYLEN(embedding))
|
||||
updateEmbedding()
|
||||
if(mapload && !GLOB.steal_item_handler.generated_items)
|
||||
add_stealing_item_objective()
|
||||
|
||||
/obj/item/Destroy(force)
|
||||
// This var exists as a weird proxy "owner" ref
|
||||
@@ -313,7 +311,7 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
LAZYREMOVE(actions, action)
|
||||
qdel(action)
|
||||
|
||||
/// Called if this item is supposed to be a steal objective item objective. Only done at mapload
|
||||
/// Called if this item is supposed to be a steal objective item objective.
|
||||
/obj/item/proc/add_stealing_item_objective()
|
||||
return
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
|
||||
var/uplink_sale_count = 3
|
||||
|
||||
///the final objective the traitor has to accomplish, be it escaping, hijacking, or just martyrdom.
|
||||
var/datum/objective/ending_objective
|
||||
|
||||
/datum/antagonist/traitor/New(give_objectives = TRUE)
|
||||
. = ..()
|
||||
src.give_objectives = give_objectives
|
||||
@@ -53,10 +56,10 @@
|
||||
else
|
||||
uplink_handler = uplink.uplink_handler
|
||||
uplink_handler.primary_objectives = objectives
|
||||
uplink_handler.has_progression = progression_enabled
|
||||
uplink_handler.has_progression = TRUE
|
||||
SStraitor.register_uplink_handler(uplink_handler)
|
||||
|
||||
uplink_handler.has_objectives = progression_enabled //SKYRAT EDIT
|
||||
uplink_handler.has_objectives = TRUE
|
||||
uplink_handler.generate_objectives()
|
||||
|
||||
if(uplink_handler.progression_points < SStraitor.current_global_progression)
|
||||
@@ -72,8 +75,10 @@
|
||||
uplink_items += item
|
||||
continue
|
||||
uplink_handler.extra_purchasable += create_uplink_sales(uplink_sale_count, /datum/uplink_category/discounts, 1, uplink_items)
|
||||
if(give_objectives && progression_enabled) //SKYRAT EDIT - progression_enabled
|
||||
|
||||
if(give_objectives)
|
||||
forge_traitor_objectives()
|
||||
forge_ending_objective()
|
||||
|
||||
pick_employer()
|
||||
|
||||
@@ -144,6 +149,11 @@
|
||||
|
||||
possible_employers.Add(GLOB.syndicate_employers, GLOB.nanotrasen_employers)
|
||||
|
||||
if(istype(ending_objective, /datum/objective/hijack))
|
||||
possible_employers -= GLOB.normal_employers
|
||||
else //escape or martyrdom
|
||||
possible_employers -= GLOB.hijack_employers
|
||||
|
||||
switch(faction)
|
||||
if(FLAVOR_FACTION_SYNDICATE)
|
||||
possible_employers -= GLOB.nanotrasen_employers
|
||||
@@ -152,33 +162,74 @@
|
||||
employer = pick(possible_employers)
|
||||
traitor_flavor = strings(TRAITOR_FLAVOR_FILE, employer)
|
||||
|
||||
/// Generates a complete set of traitor objectives up to the traitor objective limit, including non-generic objectives such as martyr and hijack.
|
||||
/datum/antagonist/traitor/proc/forge_traitor_objectives()
|
||||
objectives.Cut()
|
||||
var/objective_count = 0
|
||||
|
||||
if((GLOB.joined_player_list.len >= HIJACK_MIN_PLAYERS) && prob(HIJACK_PROB))
|
||||
is_hijacker = TRUE
|
||||
objective_count++
|
||||
|
||||
var/list/kill_targets = list() //for blacklisting already-set targets
|
||||
var/objective_limit = CONFIG_GET(number/traitor_objectives_amount)
|
||||
for(var/i in 1 to objective_limit)
|
||||
var/list/ai_targets = active_ais(z = 2) //For multiZ stations, this proc will include AIs on all station levels if the provided arg is 2.
|
||||
ai_targets -= kill_targets
|
||||
if(ai_targets.len)
|
||||
var/diceroll = rand(1, (living_player_count() - 1)) //AI kill and crew kill objectives are different, but I want a rough equal chance for AIs to be targets. Maybe I'll refractor this someday
|
||||
if(diceroll <= ai_targets.len)
|
||||
var/datum/objective/task = new /datum/objective/destroy()
|
||||
task.owner = owner
|
||||
task.find_target(blacklist = kill_targets)
|
||||
kill_targets += task.target
|
||||
objectives += task
|
||||
continue
|
||||
|
||||
var/datum/objective/task = new /datum/objective/assassinate()
|
||||
task.owner = owner
|
||||
task.find_target(blacklist = kill_targets)
|
||||
kill_targets += task.target
|
||||
objectives += task
|
||||
// for(in...to) loops iterate inclusively, so to reach objective_limit we need to loop to objective_limit - 1
|
||||
// This does not give them 1 fewer objectives than intended.
|
||||
for(var/i in objective_count to objective_limit - 1)
|
||||
objectives += forge_single_generic_objective()
|
||||
|
||||
var/datum/objective/escape/bye = new /datum/objective/escape()
|
||||
objectives += bye
|
||||
bye.owner = owner
|
||||
/**
|
||||
* ## forge_ending_objective
|
||||
*
|
||||
* Forges the endgame objective and adds it to this datum's objective list.
|
||||
*/
|
||||
/datum/antagonist/traitor/proc/forge_ending_objective()
|
||||
if(is_hijacker)
|
||||
ending_objective = new /datum/objective/hijack
|
||||
ending_objective.owner = owner
|
||||
return
|
||||
|
||||
var/martyr_compatibility = TRUE
|
||||
|
||||
for(var/datum/objective/traitor_objective in objectives)
|
||||
if(!traitor_objective.martyr_compatible)
|
||||
martyr_compatibility = FALSE
|
||||
break
|
||||
|
||||
if(martyr_compatibility && prob(MARTYR_PROB))
|
||||
ending_objective = new /datum/objective/martyr
|
||||
ending_objective.owner = owner
|
||||
objectives += ending_objective
|
||||
return
|
||||
|
||||
ending_objective = new /datum/objective/escape
|
||||
ending_objective.owner = owner
|
||||
objectives += ending_objective
|
||||
|
||||
/datum/antagonist/traitor/proc/forge_single_generic_objective()
|
||||
if(prob(KILL_PROB))
|
||||
var/list/active_ais = active_ais()
|
||||
if(active_ais.len && prob(DESTROY_AI_PROB(GLOB.joined_player_list.len)))
|
||||
var/datum/objective/destroy/destroy_objective = new()
|
||||
destroy_objective.owner = owner
|
||||
destroy_objective.find_target()
|
||||
return destroy_objective
|
||||
|
||||
if(prob(MAROON_PROB))
|
||||
var/datum/objective/maroon/maroon_objective = new()
|
||||
maroon_objective.owner = owner
|
||||
maroon_objective.find_target()
|
||||
return maroon_objective
|
||||
|
||||
var/datum/objective/assassinate/kill_objective = new()
|
||||
kill_objective.owner = owner
|
||||
kill_objective.find_target()
|
||||
return kill_objective
|
||||
|
||||
var/datum/objective/steal/steal_objective = new()
|
||||
steal_objective.owner = owner
|
||||
steal_objective.find_target()
|
||||
return steal_objective
|
||||
|
||||
/datum/antagonist/traitor/apply_innate_effects(mob/living/mob_override)
|
||||
. = ..()
|
||||
@@ -240,16 +291,11 @@
|
||||
if(objectives.len) //If the traitor had no objectives, don't need to process this.
|
||||
var/count = 1
|
||||
for(var/datum/objective/objective in objectives)
|
||||
// SKYRAT EDIT START - No greentext
|
||||
/*
|
||||
if(objective.check_completion())
|
||||
objectives_text += "<br><B>Objective #[count]</B>: [objective.explanation_text] [span_greentext("Success!")]"
|
||||
else
|
||||
objectives_text += "<br><B>Objective #[count]</B>: [objective.explanation_text] [span_redtext("Fail.")]"
|
||||
traitor_won = FALSE
|
||||
*/
|
||||
objectives_text += "<br><B>Objective #[count]</B>: [objective.explanation_text]"
|
||||
// SKYRAT EDIT END - No greentext
|
||||
count++
|
||||
if(uplink_handler.final_objective)
|
||||
objectives_text += "<br>[span_greentext("[traitor_won ? "Additionally" : "However"], the final objective \"[uplink_handler.final_objective]\" was completed!")]"
|
||||
@@ -267,15 +313,8 @@
|
||||
result += objectives_text
|
||||
|
||||
if(uplink_handler)
|
||||
var/completed_objectives_text = "Completed Uplink Objectives: "
|
||||
for(var/datum/traitor_objective/objective as anything in uplink_handler.completed_objectives)
|
||||
if(objective.objective_state == OBJECTIVE_STATE_COMPLETED)
|
||||
completed_objectives_text += "<br><B>[objective.name]</B> - ([objective.telecrystal_reward] TC, [DISPLAY_PROGRESSION(objective.progression_reward)] Reputation)"
|
||||
result += completed_objectives_text
|
||||
result += "<br>The traitor had a total of [DISPLAY_PROGRESSION(uplink_handler.progression_points)] Reputation and [uplink_handler.telecrystals] Unused Telecrystals."
|
||||
|
||||
// SKYRAT EDIT REMOVAL
|
||||
/*
|
||||
var/special_role_text = lowertext(name)
|
||||
|
||||
if(traitor_won)
|
||||
@@ -283,7 +322,6 @@
|
||||
else
|
||||
result += span_redtext("The [special_role_text] has failed!")
|
||||
SEND_SOUND(owner.current, 'sound/ambience/ambifailure.ogg')
|
||||
*/
|
||||
|
||||
return result.Join("<br>")
|
||||
|
||||
|
||||
@@ -1,210 +0,0 @@
|
||||
/datum/traitor_objective_category/bug_room
|
||||
name = "Bug Room"
|
||||
objectives = list(
|
||||
/datum/traitor_objective/bug_room = 1,
|
||||
/datum/traitor_objective/bug_room/risky = 1,
|
||||
/datum/traitor_objective/bug_room/super_risky = 1,
|
||||
)
|
||||
|
||||
/datum/traitor_objective/bug_room
|
||||
name = "Bug the %DEPARTMENT HEAD%'s office"
|
||||
description = "Use the button below to materialize the bug within your hand, \
|
||||
where you'll then be able to place it down in the %DEPARTMENT HEAD%'s office. \
|
||||
If it gets destroyed before you are able to plant it, this objective will fail. \
|
||||
Remember, planting the bug may leave behind fibers and fingerprints - \
|
||||
be sure to clean it off with soap (or similar) to be safe!"
|
||||
|
||||
progression_reward = list(2 MINUTES, 8 MINUTES)
|
||||
telecrystal_reward = list(0, 1)
|
||||
|
||||
progression_minimum = 0 MINUTES
|
||||
progression_maximum = 30 MINUTES
|
||||
|
||||
var/list/applicable_heads = list(
|
||||
JOB_RESEARCH_DIRECTOR = /area/station/command/heads_quarters/rd,
|
||||
JOB_CHIEF_MEDICAL_OFFICER = /area/station/command/heads_quarters/cmo,
|
||||
JOB_CHIEF_ENGINEER = /area/station/command/heads_quarters/ce,
|
||||
JOB_HEAD_OF_PERSONNEL = /area/station/command/heads_quarters/hop,
|
||||
JOB_CAPTAIN = /area/station/command/heads_quarters/captain, // For head roles so that they can still get this objective.
|
||||
JOB_QUARTERMASTER = /area/station/command/heads_quarters/qm,
|
||||
)
|
||||
var/datum/job/target_office
|
||||
var/requires_head_as_supervisor = TRUE
|
||||
|
||||
var/obj/item/traitor_bug/bug
|
||||
|
||||
/datum/traitor_objective/bug_room/risky
|
||||
progression_minimum = 10 MINUTES
|
||||
progression_maximum = 40 MINUTES
|
||||
applicable_heads = list(
|
||||
JOB_CAPTAIN = /area/station/command/heads_quarters/captain,
|
||||
)
|
||||
progression_reward = list(5 MINUTES, 10 MINUTES)
|
||||
telecrystal_reward = list(1, 2)
|
||||
requires_head_as_supervisor = FALSE
|
||||
|
||||
/datum/traitor_objective/bug_room/super_risky
|
||||
progression_minimum = 20 MINUTES
|
||||
progression_maximum = 60 MINUTES
|
||||
applicable_heads = list(
|
||||
JOB_HEAD_OF_SECURITY = /area/station/command/heads_quarters/hos,
|
||||
)
|
||||
progression_reward = list(10 MINUTES, 15 MINUTES)
|
||||
telecrystal_reward = list(2, 3)
|
||||
requires_head_as_supervisor = FALSE
|
||||
|
||||
/datum/traitor_objective/bug_room/super_risky/generate_objective(datum/mind/generating_for, list/possible_duplicates)
|
||||
if(!handler.get_completion_count(/datum/traitor_objective/bug_room/risky))
|
||||
// Locked if they don't have any of the risky bug room objective completed
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/traitor_objective/bug_room/generate_ui_buttons(mob/user)
|
||||
var/list/buttons = list()
|
||||
if(!bug)
|
||||
buttons += add_ui_button("", "Pressing this will materialize a bug in your hand, which you can place at the target office", "wifi", "summon_gear")
|
||||
return buttons
|
||||
|
||||
/datum/traitor_objective/bug_room/ui_perform_action(mob/living/user, action)
|
||||
. = ..()
|
||||
switch(action)
|
||||
if("summon_gear")
|
||||
if(bug)
|
||||
return
|
||||
bug = new(user.drop_location())
|
||||
user.put_in_hands(bug)
|
||||
bug.balloon_alert(user, "the bug materializes in your hand")
|
||||
bug.target_area_type = applicable_heads[target_office.title]
|
||||
AddComponent(/datum/component/traitor_objective_register, bug, \
|
||||
succeed_signals = list(COMSIG_TRAITOR_BUG_PLANTED_GROUND), \
|
||||
fail_signals = list(COMSIG_PARENT_QDELETING), \
|
||||
penalty = TRUE)
|
||||
|
||||
/datum/traitor_objective/bug_room/generate_objective(datum/mind/generating_for, list/possible_duplicates)
|
||||
var/datum/job/role = generating_for.assigned_role
|
||||
var/list/possible_heads
|
||||
if(requires_head_as_supervisor)
|
||||
possible_heads = applicable_heads & role.department_head
|
||||
else
|
||||
possible_heads = applicable_heads
|
||||
for(var/datum/traitor_objective/bug_room/room as anything in possible_duplicates)
|
||||
possible_heads -= room.target_office.title
|
||||
if(!length(possible_heads))
|
||||
return FALSE
|
||||
var/target_head = pick(possible_heads)
|
||||
|
||||
target_office = SSjob.name_occupations[target_head]
|
||||
replace_in_name("%DEPARTMENT HEAD%", target_head)
|
||||
return TRUE
|
||||
|
||||
/datum/traitor_objective/bug_room/ungenerate_objective()
|
||||
bug = null
|
||||
|
||||
/obj/item/traitor_bug
|
||||
name = "suspicious device"
|
||||
desc = "It looks dangerous."
|
||||
item_flags = EXAMINE_SKIP
|
||||
|
||||
icon = 'icons/obj/weapons/items_and_weapons.dmi'
|
||||
icon_state = "bug"
|
||||
|
||||
/// The area at which this bug can be planted at. Has to be a type.
|
||||
var/area/target_area_type
|
||||
/// The object on which this bug can be planted on. Has to be a type.
|
||||
var/obj/target_object_type
|
||||
/// The object this bug is currently planted on.
|
||||
var/obj/planted_on
|
||||
/// The time it takes to place this bug.
|
||||
var/deploy_time = 10 SECONDS
|
||||
|
||||
/obj/item/traitor_bug/examine(mob/user)
|
||||
. = ..()
|
||||
if(planted_on)
|
||||
return
|
||||
|
||||
if(user.mind?.has_antag_datum(/datum/antagonist/traitor))
|
||||
if(target_area_type)
|
||||
. += span_notice("This device must be placed by <b>using it in hand</b> inside the <b>[initial(target_area_type.name)]</b>.")
|
||||
else if(target_object_type)
|
||||
. += span_notice("This device must be placed by <b>clicking on the [initial(target_object_type.name)]</b> with it.")
|
||||
. += span_notice("Remember, you may leave behind fingerprints or fibers on the device. Use <b>soap</b> or similar to scrub it clean to be safe!")
|
||||
|
||||
/obj/item/traitor_bug/interact(mob/user)
|
||||
. = ..()
|
||||
if(!target_area_type)
|
||||
return
|
||||
var/turf/location = drop_location()
|
||||
if(!location)
|
||||
return
|
||||
var/area/current_area = get_area(location)
|
||||
if(!istype(current_area, target_area_type))
|
||||
balloon_alert(user, "you can't deploy this here!")
|
||||
return
|
||||
if(!do_after(user, deploy_time, src))
|
||||
return
|
||||
var/obj/structure/traitor_bug/new_bug = new(location)
|
||||
transfer_fingerprints_to(new_bug)
|
||||
transfer_fibers_to(new_bug)
|
||||
SEND_SIGNAL(src, COMSIG_TRAITOR_BUG_PLANTED_GROUND, location)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/traitor_bug/afterattack(atom/movable/target, mob/user, proximity_flag, click_parameters)
|
||||
. = ..()
|
||||
if(!target_object_type)
|
||||
return
|
||||
if(!user.Adjacent(target))
|
||||
return
|
||||
. |= AFTERATTACK_PROCESSED_ITEM
|
||||
var/result = SEND_SIGNAL(src, COMSIG_TRAITOR_BUG_PRE_PLANTED_OBJECT, target)
|
||||
if(!(result & COMPONENT_FORCE_PLACEMENT))
|
||||
if(result & COMPONENT_FORCE_FAIL_PLACEMENT || !istype(target, target_object_type))
|
||||
balloon_alert(user, "you can't attach this onto here!")
|
||||
return
|
||||
if(!do_after(user, deploy_time, src))
|
||||
return
|
||||
if(planted_on)
|
||||
return
|
||||
forceMove(target)
|
||||
target.vis_contents += src
|
||||
vis_flags |= VIS_INHERIT_PLANE
|
||||
planted_on = target
|
||||
RegisterSignal(planted_on, COMSIG_PARENT_QDELETING, PROC_REF(handle_planted_on_deletion))
|
||||
SEND_SIGNAL(src, COMSIG_TRAITOR_BUG_PLANTED_OBJECT, target)
|
||||
|
||||
/obj/item/traitor_bug/proc/handle_planted_on_deletion()
|
||||
planted_on = null
|
||||
|
||||
/obj/item/traitor_bug/Destroy()
|
||||
if(planted_on)
|
||||
vis_flags &= ~VIS_INHERIT_PLANE
|
||||
planted_on.vis_contents -= src
|
||||
return ..()
|
||||
|
||||
/obj/item/traitor_bug/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change = TRUE)
|
||||
. = ..()
|
||||
if(planted_on)
|
||||
vis_flags &= ~VIS_INHERIT_PLANE
|
||||
planted_on.vis_contents -= src
|
||||
anchored = FALSE
|
||||
UnregisterSignal(planted_on, COMSIG_PARENT_QDELETING)
|
||||
planted_on = null
|
||||
|
||||
/obj/structure/traitor_bug
|
||||
name = "suspicious device"
|
||||
desc = "It looks dangerous. Best you leave this alone."
|
||||
|
||||
anchored = TRUE
|
||||
|
||||
icon = 'icons/obj/weapons/items_and_weapons.dmi'
|
||||
icon_state = "bug-animated"
|
||||
|
||||
/obj/structure/traitor_bug/Initialize(mapload)
|
||||
. = ..()
|
||||
addtimer(CALLBACK(src, PROC_REF(fade_out), 10 SECONDS), 3 MINUTES)
|
||||
|
||||
/obj/structure/traitor_bug/proc/fade_out(seconds)
|
||||
animate(src, alpha = 30, time = seconds)
|
||||
|
||||
/obj/structure/traitor_bug/deconstruct(disassembled)
|
||||
explosion(src, light_impact_range = 2, flame_range = 5, explosion_cause = src) // Pretty god damn dangerous
|
||||
return ..()
|
||||
@@ -8,7 +8,7 @@
|
||||
/datum/traitor_objective/demoralise/poster = 2,
|
||||
/datum/traitor_objective/demoralise/graffiti = 1,
|
||||
)
|
||||
weight = OBJECTIVE_WEIGHT_TINY
|
||||
weight = OBJECTIVE_WEIGHT_UNLIKELY
|
||||
|
||||
/datum/traitor_objective/demoralise
|
||||
name = "Debug your code."
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
telecrystal_reward = 1
|
||||
|
||||
possible_items = list(
|
||||
/datum/objective_item/steal/low_risk/bartender_shotgun,
|
||||
/datum/objective_item/steal/low_risk/fireaxe,
|
||||
/datum/objective_item/steal/low_risk/big_crowbar,
|
||||
/datum/objective_item/steal/low_risk/nullrod,
|
||||
/datum/objective_item/steal/traitor/bartender_shotgun,
|
||||
/datum/objective_item/steal/traitor/fireaxe,
|
||||
/datum/objective_item/steal/traitor/nullrod,
|
||||
/datum/objective_item/steal/traitor/big_crowbar,
|
||||
)
|
||||
|
||||
/datum/traitor_objective/destroy_item/very_risky
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/datum/traitor_objective/eyesnatching = 1,
|
||||
/datum/traitor_objective/eyesnatching/heads = 1,
|
||||
)
|
||||
weight = OBJECTIVE_WEIGHT_TINY
|
||||
weight = OBJECTIVE_WEIGHT_UNLIKELY
|
||||
|
||||
/datum/traitor_objective/eyesnatching
|
||||
name = "Steal the eyes of %TARGET% the %JOB TITLE%"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
objectives = list(
|
||||
/datum/traitor_objective/locate_weakpoint = 1,
|
||||
)
|
||||
weight = OBJECTIVE_WEIGHT_TINY
|
||||
weight = OBJECTIVE_WEIGHT_UNLIKELY
|
||||
|
||||
/datum/traitor_objective/locate_weakpoint
|
||||
name = "Triangulate station's structural weakpoint and detonate an explosive charge nearby."
|
||||
|
||||
@@ -8,16 +8,15 @@
|
||||
/datum/traitor_objective/steal_item/somewhat_risky = 1,
|
||||
list(
|
||||
/datum/traitor_objective/destroy_item/very_risky = 1,
|
||||
/datum/traitor_objective/steal_item/risky = 1,
|
||||
/datum/traitor_objective/steal_item/very_risky = 1,
|
||||
) = 1,
|
||||
/datum/traitor_objective/steal_item/very_risky = 1,
|
||||
/datum/traitor_objective/steal_item/most_risky = 1
|
||||
)
|
||||
|
||||
GLOBAL_DATUM_INIT(steal_item_handler, /datum/objective_item_handler, new())
|
||||
|
||||
/datum/objective_item_handler
|
||||
var/list/objectives_by_path
|
||||
var/list/list/objectives_by_path
|
||||
var/generated_items = FALSE
|
||||
|
||||
/datum/objective_item_handler/New()
|
||||
@@ -26,25 +25,42 @@ GLOBAL_DATUM_INIT(steal_item_handler, /datum/objective_item_handler, new())
|
||||
for(var/datum/objective_item/item as anything in subtypesof(/datum/objective_item))
|
||||
objectives_by_path[initial(item.targetitem)] = list()
|
||||
RegisterSignal(SSatoms, COMSIG_SUBSYSTEM_POST_INITIALIZE, PROC_REF(save_items))
|
||||
RegisterSignal(SSdcs, COMSIG_GLOB_NEW_ITEM, PROC_REF(new_item_created))
|
||||
|
||||
/datum/objective_item_handler/proc/new_item_created(datum/source, obj/item/item)
|
||||
SIGNAL_HANDLER
|
||||
if(!generated_items)
|
||||
item.add_stealing_item_objective()
|
||||
return
|
||||
var/typepath = item.add_stealing_item_objective()
|
||||
if(typepath != null)
|
||||
register_item(item, typepath)
|
||||
|
||||
/// Registers all items that are potentially stealable and removes ones that aren't.
|
||||
/// We still need to do things this way because on mapload, items may not be on the station until everything has finished loading.
|
||||
/datum/objective_item_handler/proc/save_items()
|
||||
SIGNAL_HANDLER
|
||||
for(var/obj/item/typepath as anything in objectives_by_path)
|
||||
for(var/obj/item/object as anything in objectives_by_path[typepath])
|
||||
var/turf/place = get_turf(object)
|
||||
if(!place || !is_station_level(place.z))
|
||||
objectives_by_path[typepath] -= object
|
||||
continue
|
||||
RegisterSignal(object, COMSIG_PARENT_QDELETING, PROC_REF(remove_item))
|
||||
var/list/obj_by_path_cache = objectives_by_path[typepath].Copy()
|
||||
for(var/obj/item/object as anything in obj_by_path_cache)
|
||||
register_item(object, typepath)
|
||||
generated_items = TRUE
|
||||
|
||||
/datum/objective_item_handler/proc/register_item(atom/object, typepath)
|
||||
var/turf/place = get_turf(object)
|
||||
if(!place || !is_station_level(place.z))
|
||||
objectives_by_path[typepath] -= object
|
||||
return
|
||||
RegisterSignal(object, COMSIG_PARENT_QDELETING, PROC_REF(remove_item))
|
||||
|
||||
/datum/objective_item_handler/proc/remove_item(atom/source)
|
||||
SIGNAL_HANDLER
|
||||
for(var/typepath in objectives_by_path)
|
||||
objectives_by_path[typepath] -= source
|
||||
|
||||
/datum/traitor_objective/steal_item
|
||||
name = "Steal %ITEM% and place a bug on it."
|
||||
description = "Use the button below to materialize the bug within your hand, where you'll then be able to place it on the item. Additionally, you can keep it near you for %TIME% minutes, and you will be rewarded with %PROGRESSION% reputation and %TC% telecrystals."
|
||||
name = "Steal %ITEM% and place a schematics scanner on it."
|
||||
description = "Use the button below to materialize the schematic scanner within your hand, where you'll then be able to place it on the item. Additionally, you can keep it near you and let it scan for %TIME% minutes, and you will be rewarded with %PROGRESSION% reputation and %TC% telecrystals."
|
||||
|
||||
progression_minimum = 20 MINUTES
|
||||
|
||||
@@ -79,54 +95,37 @@ GLOBAL_DATUM_INIT(steal_item_handler, /datum/objective_item_handler, new())
|
||||
minutes_per_telecrystal = 6
|
||||
|
||||
possible_items = list(
|
||||
/datum/objective_item/steal/low_risk/cargo_budget,
|
||||
/datum/objective_item/steal/low_risk/clown_shoes,
|
||||
/datum/objective_item/steal/traitor/cargo_budget,
|
||||
/datum/objective_item/steal/traitor/clown_shoes,
|
||||
)
|
||||
|
||||
/datum/traitor_objective/steal_item/somewhat_risky
|
||||
progression_minimum = 20 MINUTES
|
||||
progression_reward = 5 MINUTES
|
||||
telecrystal_reward = 1
|
||||
|
||||
possible_items = list(
|
||||
/datum/objective_item/steal/magboots,
|
||||
/datum/objective_item/steal/hypo,
|
||||
/datum/objective_item/steal/reactive,
|
||||
/datum/objective_item/steal/handtele,
|
||||
/datum/objective_item/steal/blueprints,
|
||||
)
|
||||
|
||||
/datum/traitor_objective/steal_item/risky
|
||||
progression_minimum = 30 MINUTES
|
||||
progression_reward = 13 MINUTES
|
||||
progression_maximum = 50 MINUTES
|
||||
progression_reward = 10 MINUTES
|
||||
telecrystal_reward = 2
|
||||
|
||||
possible_items = list(
|
||||
/datum/objective_item/steal/reflector,
|
||||
/datum/objective_item/steal/capmedal,
|
||||
/datum/objective_item/steal/hdd_extraction,
|
||||
/datum/objective_item/steal/documents,
|
||||
/datum/objective_item/steal/traitor/chief_engineer_belt
|
||||
)
|
||||
|
||||
/datum/traitor_objective/steal_item/very_risky
|
||||
progression_minimum = 40 MINUTES
|
||||
progression_reward = 17 MINUTES
|
||||
progression_minimum = 30 MINUTES
|
||||
progression_reward = 15 MINUTES
|
||||
telecrystal_reward = 3
|
||||
|
||||
possible_items = list(
|
||||
/datum/objective_item/steal/hoslaser,
|
||||
/datum/objective_item/steal/caplaser,
|
||||
/datum/objective_item/steal/nuke_core,
|
||||
/datum/objective_item/steal/supermatter,
|
||||
/datum/objective_item/steal/traitor/det_revolver,
|
||||
)
|
||||
|
||||
/datum/traitor_objective/steal_item/most_risky
|
||||
progression_minimum = 50 MINUTES
|
||||
progression_reward = 25 MINUTES
|
||||
progression_reward = 20 MINUTES
|
||||
telecrystal_reward = 5
|
||||
|
||||
possible_items = list(
|
||||
/datum/objective_item/steal/nukedisc,
|
||||
/datum/objective_item/steal/traitor/captain_modsuit,
|
||||
/datum/objective_item/steal/traitor/captain_spare,
|
||||
)
|
||||
|
||||
/datum/traitor_objective/steal_item/most_risky/generate_objective(datum/mind/generating_for, list/possible_duplicates)
|
||||
@@ -169,9 +168,9 @@ GLOBAL_DATUM_INIT(steal_item_handler, /datum/objective_item_handler, new())
|
||||
if(special_equipment)
|
||||
buttons += add_ui_button("", "Pressing this will summon any extra special equipment you may need for the mission.", "tools", "summon_gear")
|
||||
if(!bug)
|
||||
buttons += add_ui_button("", "Pressing this will materialize a bug in your hand, which you can place on the target item", "wifi", "summon_bug")
|
||||
buttons += add_ui_button("", "Pressing this will materialize a scanner in your hand, which you can place on the target item", "wifi", "summon_bug")
|
||||
else if(bug.planted_on)
|
||||
buttons += add_ui_button("[DisplayTimeText(time_fulfilled)]", "This tells you how much time you have spent around the target item after the bug has been planted.", "clock", "none")
|
||||
buttons += add_ui_button("[DisplayTimeText(time_fulfilled)]", "This tells you how much time you have spent around the target item after the scanner has been planted.", "clock", "none")
|
||||
buttons += add_ui_button("Skip Time", "Pressing this will succeed the mission. You will not get the extra TC and progression.", "forward", "cash_out")
|
||||
return buttons
|
||||
|
||||
@@ -183,7 +182,7 @@ GLOBAL_DATUM_INIT(steal_item_handler, /datum/objective_item_handler, new())
|
||||
return
|
||||
bug = new(user.drop_location())
|
||||
user.put_in_hands(bug)
|
||||
bug.balloon_alert(user, "the bug materializes in your hand")
|
||||
bug.balloon_alert(user, "the scanner materializes in your hand")
|
||||
bug.target_object_type = target_item.targetitem
|
||||
AddComponent(/datum/component/traitor_objective_register, bug, \
|
||||
fail_signals = list(COMSIG_PARENT_QDELETING), \
|
||||
@@ -245,3 +244,72 @@ GLOBAL_DATUM_INIT(steal_item_handler, /datum/objective_item_handler, new())
|
||||
SIGNAL_HANDLER
|
||||
if(objective_state == OBJECTIVE_STATE_ACTIVE)
|
||||
START_PROCESSING(SSprocessing, src)
|
||||
|
||||
/obj/item/traitor_bug
|
||||
name = "suspicious device"
|
||||
desc = "It looks dangerous."
|
||||
item_flags = EXAMINE_SKIP
|
||||
|
||||
icon = 'icons/obj/weapons/items_and_weapons.dmi'
|
||||
icon_state = "bug"
|
||||
|
||||
/// The object on which this bug can be planted on. Has to be a type.
|
||||
var/obj/target_object_type
|
||||
/// The object this bug is currently planted on.
|
||||
var/obj/planted_on
|
||||
/// The time it takes to place this bug.
|
||||
var/deploy_time = 10 SECONDS
|
||||
|
||||
/obj/item/traitor_bug/examine(mob/user)
|
||||
. = ..()
|
||||
if(planted_on)
|
||||
return
|
||||
|
||||
if(user.mind?.has_antag_datum(/datum/antagonist/traitor))
|
||||
if(target_object_type)
|
||||
. += span_notice("This device must be placed by <b>clicking on the [initial(target_object_type.name)]</b> with it.")
|
||||
. += span_notice("Remember, you may leave behind fingerprints or fibers on the device. Use <b>soap</b> or similar to scrub it clean to be safe!")
|
||||
|
||||
/obj/item/traitor_bug/afterattack(atom/movable/target, mob/user, proximity_flag, click_parameters)
|
||||
. = ..()
|
||||
if(!target_object_type)
|
||||
return
|
||||
if(!user.Adjacent(target))
|
||||
return
|
||||
. |= AFTERATTACK_PROCESSED_ITEM
|
||||
var/result = SEND_SIGNAL(src, COMSIG_TRAITOR_BUG_PRE_PLANTED_OBJECT, target)
|
||||
if(!(result & COMPONENT_FORCE_PLACEMENT))
|
||||
if(result & COMPONENT_FORCE_FAIL_PLACEMENT || !istype(target, target_object_type))
|
||||
balloon_alert(user, "you can't attach this onto here!")
|
||||
return
|
||||
if(!do_after(user, deploy_time, src))
|
||||
return
|
||||
if(planted_on)
|
||||
return
|
||||
forceMove(target)
|
||||
target.vis_contents += src
|
||||
vis_flags |= VIS_INHERIT_PLANE
|
||||
planted_on = target
|
||||
RegisterSignal(planted_on, COMSIG_PARENT_QDELETING, PROC_REF(handle_planted_on_deletion))
|
||||
SEND_SIGNAL(src, COMSIG_TRAITOR_BUG_PLANTED_OBJECT, target)
|
||||
|
||||
/obj/item/traitor_bug/proc/handle_planted_on_deletion()
|
||||
planted_on = null
|
||||
|
||||
/obj/item/traitor_bug/Destroy()
|
||||
if(planted_on)
|
||||
vis_flags &= ~VIS_INHERIT_PLANE
|
||||
planted_on.vis_contents -= src
|
||||
return ..()
|
||||
|
||||
/obj/item/traitor_bug/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change = TRUE)
|
||||
. = ..()
|
||||
if(planted_on)
|
||||
vis_flags &= ~VIS_INHERIT_PLANE
|
||||
planted_on.vis_contents -= src
|
||||
anchored = FALSE
|
||||
UnregisterSignal(planted_on, COMSIG_PARENT_QDELETING)
|
||||
planted_on = null
|
||||
|
||||
/obj/item/traitor_bug/attackby_storage_insert(datum/storage, atom/storage_holder, mob/user)
|
||||
return !istype(storage_holder, target_object_type)
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
/// Chance that the traitor could roll hijack if the pop limit is met.
|
||||
#define HIJACK_PROB 10
|
||||
/// Hijack is unavailable as a random objective below this player count.
|
||||
#define HIJACK_MIN_PLAYERS 50
|
||||
|
||||
/// Chance the traitor gets a martyr objective instead of having to escape alive, as long as all the objectives are martyr compatible.
|
||||
#define MARTYR_PROB 20
|
||||
|
||||
/// Chance the traitor gets a kill objective. If this prob fails, they will get a steal objective instead.
|
||||
#define KILL_PROB 50
|
||||
/// If a kill objective is rolled, chance that it is to destroy the AI.
|
||||
#define DESTROY_AI_PROB(denominator) (100 / denominator)
|
||||
|
||||
/// Generates a complete set of traitor objectives up to the traitor objective limit, including non-generic objectives such as martyr and hijack.
|
||||
/datum/antagonist/traitor/forge_traitor_objectives()
|
||||
objectives.Cut()
|
||||
|
||||
var/objective_count = 0
|
||||
|
||||
if((length(GLOB.joined_player_list) >= HIJACK_MIN_PLAYERS) && prob(HIJACK_PROB))
|
||||
is_hijacker = TRUE
|
||||
objective_count++
|
||||
|
||||
var/objective_limit = CONFIG_GET(number/traitor_objectives_amount)
|
||||
|
||||
// for(in...to) loops iterate inclusively, so to reach objective_limit we need to loop to objective_limit - 1
|
||||
// This does not give them 1 fewer objectives than intended.
|
||||
for(var/i in objective_count to objective_limit - 1)
|
||||
objectives += forge_single_generic_objective()
|
||||
|
||||
|
||||
/// Adds a generic kill or steal objective to this datum's objective list.
|
||||
/datum/antagonist/traitor/proc/forge_single_generic_objective()
|
||||
if(prob(KILL_PROB))
|
||||
var/list/active_ais = active_ais()
|
||||
if(length(active_ais) && prob(DESTROY_AI_PROB(length(GLOB.joined_player_list))))
|
||||
var/datum/objective/destroy/destroy_objective = new
|
||||
destroy_objective.owner = owner
|
||||
destroy_objective.find_target()
|
||||
return destroy_objective
|
||||
|
||||
var/datum/objective/assassinate/kill_objective = new
|
||||
kill_objective.owner = owner
|
||||
kill_objective.find_target()
|
||||
return kill_objective
|
||||
|
||||
var/datum/objective/steal/steal_objective = new
|
||||
steal_objective.owner = owner
|
||||
steal_objective.find_target()
|
||||
return steal_objective
|
||||
|
||||
/**
|
||||
* ## forge_ending_objective
|
||||
*
|
||||
* Forges the endgame objective and adds it to this datum's objective list.
|
||||
*/
|
||||
/datum/antagonist/traitor/proc/forge_ending_objective()
|
||||
if(is_hijacker)
|
||||
ending_objective = new /datum/objective/hijack
|
||||
ending_objective.owner = owner
|
||||
objectives += ending_objective
|
||||
return
|
||||
|
||||
var/martyr_compatibility = TRUE
|
||||
|
||||
for(var/datum/objective/traitor_objective in objectives)
|
||||
if(!traitor_objective.martyr_compatible)
|
||||
martyr_compatibility = FALSE
|
||||
break
|
||||
|
||||
if(martyr_compatibility && prob(MARTYR_PROB))
|
||||
ending_objective = new /datum/objective/martyr
|
||||
ending_objective.owner = owner
|
||||
objectives += ending_objective
|
||||
return
|
||||
|
||||
ending_objective = new /datum/objective/escape
|
||||
ending_objective.owner = owner
|
||||
objectives += ending_objective
|
||||
|
||||
/// Forges a single escape objective and adds it to this datum's objective list.
|
||||
/datum/antagonist/traitor/proc/forge_escape_objective()
|
||||
var/is_martyr = prob(MARTYR_PROB)
|
||||
var/martyr_compatibility = TRUE
|
||||
|
||||
for(var/datum/objective/traitor_objective in objectives)
|
||||
if(!traitor_objective.martyr_compatible)
|
||||
martyr_compatibility = FALSE
|
||||
break
|
||||
|
||||
if(martyr_compatibility && is_martyr)
|
||||
var/datum/objective/martyr/martyr_objective = new
|
||||
martyr_objective.owner = owner
|
||||
objectives += martyr_objective
|
||||
return
|
||||
|
||||
var/datum/objective/escape/escape_objective = new
|
||||
escape_objective.owner = owner
|
||||
objectives += escape_objective
|
||||
|
||||
|
||||
#undef HIJACK_PROB
|
||||
#undef HIJACK_MIN_PLAYERS
|
||||
#undef MARTYR_PROB
|
||||
#undef KILL_PROB
|
||||
#undef DESTROY_AI_PROB
|
||||
@@ -1,12 +0,0 @@
|
||||
/// Progresionless traitor
|
||||
/datum/antagonist/traitor
|
||||
/// If the traitor should have progression enabled or not on their uplink
|
||||
var/progression_enabled = FALSE
|
||||
/// The final objective the traitor has to accomplish, be it escaping, hijacking, or just martyrdom.
|
||||
var/datum/objective/ending_objective
|
||||
|
||||
/datum/antagonist/traitor/on_gain()
|
||||
if(give_objectives)
|
||||
forge_traitor_objectives()
|
||||
forge_ending_objective()
|
||||
return ..()
|
||||
@@ -2686,7 +2686,6 @@
|
||||
#include "code\modules\antagonists\traitor\components\traitor_objective_limit_per_time.dm"
|
||||
#include "code\modules\antagonists\traitor\components\traitor_objective_mind_tracker.dm"
|
||||
#include "code\modules\antagonists\traitor\objectives\assassination.dm"
|
||||
#include "code\modules\antagonists\traitor\objectives\bug_room.dm"
|
||||
#include "code\modules\antagonists\traitor\objectives\demoralise_crew.dm"
|
||||
#include "code\modules\antagonists\traitor\objectives\demoralise_graffiti.dm"
|
||||
#include "code\modules\antagonists\traitor\objectives\demoralise_poster.dm"
|
||||
@@ -5252,10 +5251,8 @@
|
||||
#include "modular_skyrat\master_files\code\game\turfs\open\space\space.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\admin\admin.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\antagonists\_common\antag_datum.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\antagonists\_common\objectives.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\antagonists\ashwalker\ashwalker.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\antagonists\ert\ert.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\antagonists\traitor\datums\datum_traitor.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\antagonists\traitor\objectives\kill_pet.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\antagonists\traitor\objectives\smuggling.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\bandana\bandanafix.dm"
|
||||
|
||||
Reference in New Issue
Block a user