Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/Fluffy-Frontier/FluffySTG
Browse files Browse the repository at this point in the history
…into upstream-mirror-1251
  • Loading branch information
Iajret committed Mar 5, 2024
2 parents 1dbdcbe + 14f98d5 commit 4a335bc
Show file tree
Hide file tree
Showing 66 changed files with 1,858 additions and 200 deletions.
13 changes: 13 additions & 0 deletions code/__DEFINES/antagonists.dm
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@
/// JSON string file for all of our heretic influence flavors
#define HERETIC_INFLUENCE_FILE "antagonist_flavor/heretic_influences.json"

/// JSON file containing spy objectives
#define SPY_OBJECTIVE_FILE "antagonist_flavor/spy_objective.json"

///employers that are from the syndicate
GLOBAL_LIST_INIT(syndicate_employers, list(
"Animal Rights Consortium",
Expand Down Expand Up @@ -265,6 +268,8 @@ GLOBAL_LIST_INIT(human_invader_antagonists, list(
#define OBJECTIVE_ITEM_TYPE_NORMAL "normal"
/// Only appears in traitor objectives
#define OBJECTIVE_ITEM_TYPE_TRAITOR "traitor"
/// Only appears for spy bounties
#define OBJECTIVE_ITEM_TYPE_SPY "spy"

// Progression traitor defines

Expand Down Expand Up @@ -378,3 +383,11 @@ GLOBAL_LIST_INIT(human_invader_antagonists, list(
#define BATON_MODES 4

#define FREEDOM_IMPLANT_CHARGES 4

// Spy bounty difficulties
/// Can easily be accomplished by any job without any specialized tools, people won't really miss these things
#define SPY_DIFFICULTY_EASY "Easy"
/// Requires some specialized tools, knowledge, or access to accomplish, may require getting into conflict with the crew
#define SPY_DIFFICULTY_MEDIUM "Medium"
/// Very difficult to accomplish, almost guaranteed to require crew conflict
#define SPY_DIFFICULTY_HARD "Hard"
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,6 @@
#define COMSIG_MOVABLE_EDIT_UNIQUE_IMMERSE_OVERLAY "movable_edit_unique_submerge_overlay"
/// From base of area/Exited(): (area/left, direction)
#define COMSIG_MOVABLE_EXITED_AREA "movable_exited_area"

/// Sent to movables when they are being stolen by a spy: (mob/living/spy, datum/spy_bounty/bounty)
#define COMSIG_MOVABLE_SPY_STEALING "movable_spy_stealing"
1 change: 1 addition & 0 deletions code/__DEFINES/is_helpers.dm
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ GLOBAL_LIST_INIT(book_types, typecacheof(list(
#define is_captain_job(job_type) (istype(job_type, /datum/job/captain))
#define is_chaplain_job(job_type) (istype(job_type, /datum/job/chaplain))
#define is_clown_job(job_type) (istype(job_type, /datum/job/clown))
#define is_mime_job(job_type) (istype(job_type, /datum/job/mime))
#define is_detective_job(job_type) (istype(job_type, /datum/job/detective))
#define is_scientist_job(job_type) (istype(job_type, /datum/job/scientist))
#define is_security_officer_job(job_type) (istype(job_type, /datum/job/security_officer))
Expand Down
1 change: 1 addition & 0 deletions code/__DEFINES/logging.dm
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@
#define LOG_CATEGORY_UPLINK_HERETIC "uplink-heretic"
#define LOG_CATEGORY_UPLINK_MALF "uplink-malf"
#define LOG_CATEGORY_UPLINK_SPELL "uplink-spell"
#define LOG_CATEGORY_UPLINK_SPY "uplink-spy"

// PDA categories
#define LOG_CATEGORY_PDA "pda"
Expand Down
18 changes: 9 additions & 9 deletions code/__DEFINES/role_preferences.dm
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@
#define ROLE_OPERATIVE "Operative"
#define ROLE_TRAITOR "Traitor"
#define ROLE_WIZARD "Wizard"
// NOVA EDIT START
#define ROLE_SPY "Spy"
// NOVA EDIT ADDITION START
#define ROLE_ASSAULT_OPERATIVE "Assault Operative"
#define ROLE_OPFOR_CANDIDATE "OPFOR Candidate"
// NOVA EDIT END
// NOVA EDIT ADDITION END

// Midround roles
#define ROLE_ABDUCTOR "Abductor"
Expand All @@ -41,13 +42,13 @@
#define ROLE_SPACE_DRAGON "Space Dragon"
#define ROLE_SPIDER "Spider"
#define ROLE_WIZARD_MIDROUND "Wizard (Midround)"
//NOVA EDIT START
//NOVA EDIT ADDITION START
#define ROLE_BORER "Borer"
#define ROLE_DRIFTING_CONTRACTOR "Drifting Contractor"
#define ROLE_LONE_INFILTRATOR "Lone Infiltrator"
#define ROLE_MUTANT "Mutated Abomination"
#define ROLE_CLOCK_CULTIST "Clock Cultist"
// NOVA EDIT END
// NOVA EDIT ADDITION END

// Latejoin roles
#define ROLE_HERETIC_SMUGGLER "Heretic Smuggler"
Expand Down Expand Up @@ -148,9 +149,8 @@ GLOBAL_LIST_INIT(special_roles, list(
ROLE_REV_HEAD = 14,
ROLE_TRAITOR = 0,
ROLE_WIZARD = 14,
// NOVA EDIT ADDITION
ROLE_ASSAULT_OPERATIVE = 14,
// NOVA EDIT END
ROLE_SPY = 0,
ROLE_ASSAULT_OPERATIVE = 14, // NOVA EDIT ADDITION

// Midround
ROLE_ABDUCTOR = 0,
Expand All @@ -172,12 +172,12 @@ GLOBAL_LIST_INIT(special_roles, list(
ROLE_SPACE_DRAGON = 0,
ROLE_SPIDER = 0,
ROLE_WIZARD_MIDROUND = 14,
//NOVA EDIT START
// NOVA EDIT ADDITION START
ROLE_LONE_INFILTRATOR = 0,
ROLE_BORER = 0,
ROLE_DRIFTING_CONTRACTOR = 14,
ROLE_MUTANT = 0,
//NOVA EDIT END
// NOVA EDIT ADDITION END

// Latejoin
ROLE_HERETIC_SMUGGLER = 0,
Expand Down
12 changes: 12 additions & 0 deletions code/__DEFINES/uplink.dm
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,22 @@
/// This item is purchasable to infiltrators (midround traitors)
#define UPLINK_INFILTRATORS (1 << 3)

/// Can be randomly given to spies for their bounties
#define UPLINK_SPY (1 << 4)

/// Progression gets turned into a user-friendly form. This is just an abstract equation that makes progression not too large.
#define DISPLAY_PROGRESSION(time) round(time/60, 0.01)

/// Traitor discount size categories
#define TRAITOR_DISCOUNT_BIG "big_discount"
#define TRAITOR_DISCOUNT_AVERAGE "average_discount"
#define TRAITOR_DISCOUNT_SMALL "small_discount"

/// Typepath used for uplink items which don't actually produce an item (essentially just a placeholder)
/// Future todo: Make this not necessary / make uplink items support item-less items natively
#define ABSTRACT_UPLINK_ITEM /obj/effect/gibspawner/generic

/// Lower threshold for which an uplink items's TC cost is considered "low" for spy bounties picking rewards
#define SPY_LOWER_COST_THRESHOLD 5
/// Upper threshold for which an uplink items's TC cost is considered "high" for spy bounties picking rewards
#define SPY_UPPER_COST_THRESHOLD 12
4 changes: 4 additions & 0 deletions code/__HELPERS/logging/antagonists.dm
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@
/// Logging for wizard powers learned
/proc/log_spellbook(text, list/data)
logger.Log(LOG_CATEGORY_UPLINK_SPELL, text, data)

/// Logs bounties completed by spies and their rewards
/proc/log_spy(text, list/data)
logger.Log(LOG_CATEGORY_UPLINK_SPY, text, data)
19 changes: 11 additions & 8 deletions code/controllers/subsystem/blackmarket.dm
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,20 @@ SUBSYSTEM_DEF(blackmarket)
for(var/market in subtypesof(/datum/market))
markets[market] += new market

for(var/item in subtypesof(/datum/market_item))
var/datum/market_item/I = new item()
if(!I.item)
for(var/datum/market_item/item as anything in subtypesof(/datum/market_item))
if(!initial(item.item))
continue
if(!prob(initial(item.availability_prob)))
continue

for(var/M in I.markets)
if(!markets[M])
stack_trace("SSblackmarket: Item [I] available in market that does not exist.")
var/datum/market_item/item_instance = new item()
for(var/potential_market in item_instance.markets)
if(!markets[potential_market])
stack_trace("SSblackmarket: Item [item_instance] available in market that does not exist.")
continue
markets[M].add_item(item)
qdel(I)
// If this fails the market item will just be GC'd
markets[potential_market].add_item(item_instance)

return SS_INIT_SUCCESS

/datum/controller/subsystem/blackmarket/fire(resumed)
Expand Down
42 changes: 42 additions & 0 deletions code/controllers/subsystem/dynamic/dynamic_rulesets_roundstart.dm
Original file line number Diff line number Diff line change
Expand Up @@ -698,3 +698,45 @@ GLOBAL_VAR_INIT(revolutionary_win, FALSE)
create_separatist_nation(department_type, announcement = FALSE, dangerous = FALSE, message_admins = FALSE)

GLOB.round_default_lawset = /datum/ai_laws/united_nations

/datum/dynamic_ruleset/roundstart/spies
name = "Spies"
antag_flag = ROLE_SPY
antag_datum = /datum/antagonist/spy
minimum_required_age = 0
protected_roles = list(
JOB_CAPTAIN,
JOB_DETECTIVE,
JOB_HEAD_OF_PERSONNEL, // AA = bad
JOB_HEAD_OF_SECURITY,
JOB_PRISONER,
JOB_SECURITY_OFFICER,
JOB_WARDEN,
)
restricted_roles = list(
JOB_AI,
JOB_CYBORG,
)
required_candidates = 3 // lives or dies by there being a few spies
weight = 5
cost = 8
scaling_cost = 101 // see below
minimum_players = 8
antag_cap = list("denominator" = 8, "offset" = 1) // should have quite a few spies to work against each other
requirements = list(8, 8, 8, 8, 8, 8, 8, 8, 8, 8)

/datum/dynamic_ruleset/roundstart/spies/pre_execute(population)
for(var/i in 1 to get_antag_cap(population) * (scaled_times + 1))
if(length(candidates) <= 0)
break
var/mob/picked_player = pick_n_take(candidates)
assigned += picked_player.mind
picked_player.mind.special_role = ROLE_SPY
picked_player.mind.restricted_roles = restricted_roles
GLOB.pre_setup_antags += picked_player.mind
return TRUE

/datum/dynamic_ruleset/roundstart/spies/scale_up(population, max_scale)
// Disabled (at least until dynamic can handle scaling this better)
// Because spies have a very low demoninator, this can easily spawn like 30 of them
return 0
3 changes: 3 additions & 0 deletions code/datums/lazy_template.dm
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
var/map_dir = "_maps/templates/lazy_templates"
/// The filename (without extension) of the map to load
var/map_name
/// place_on_top: Whether to use /turf/proc/PlaceOnTop rather than /turf/proc/ChangeTurf
var/place_on_top = FALSE

/datum/lazy_template/New()
reservations = list()
Expand Down Expand Up @@ -83,6 +85,7 @@
bottom_left.z,
z_upper = z_idx,
z_lower = z_idx,
place_on_top = place_on_top,
)
for(var/turf/turf as anything in block(bottom_left, top_right))
loaded_turfs += turf
Expand Down
87 changes: 45 additions & 42 deletions code/datums/mind/antag.dm
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,31 @@
var/datum/antagonist/rev/revolutionary = has_antag_datum(/datum/antagonist/rev)
revolutionary?.remove_revolutionary()

/**
* Gets an item that can be used as an uplink somewhere on the mob's person.
*
* * desired_location: the location to look for the uplink in. An UPLINK_ define.
* If the desired location is not found, defaults to another location.
*
* Returns the item found, or null if no item was found.
*/
/mob/living/carbon/proc/get_uplink_location(desired_location = UPLINK_PDA)
var/list/all_contents = get_all_contents()
var/obj/item/modular_computer/pda/my_pda = locate() in all_contents
var/obj/item/radio/my_radio = locate() in all_contents
var/obj/item/pen/my_pen = (locate() in my_pda) || (locate() in all_contents)

switch(desired_location)
if(UPLINK_PDA)
return my_pda || my_radio || my_pen

if(UPLINK_RADIO)
return my_radio || my_pda || my_pen

if(UPLINK_PEN)
return my_pen || my_pda || my_radio

return null

/**
* ## give_uplink
Expand All @@ -116,53 +141,26 @@
* * antag_datum: the antag datum of the uplink owner, for storing it in antag memory. optional!
*/
/datum/mind/proc/give_uplink(silent = FALSE, datum/antagonist/antag_datum)
if(!current)
if(isnull(current))
return
var/mob/living/carbon/human/traitor_mob = current
if (!istype(traitor_mob))
return

var/list/all_contents = traitor_mob.get_all_contents()
var/obj/item/modular_computer/pda/PDA = locate() in all_contents
var/obj/item/radio/R = locate() in all_contents
var/obj/item/pen/P

if (PDA) // Prioritize PDA pen, otherwise the pocket protector pens will be chosen, which causes numerous ahelps about missing uplink
P = locate() in PDA
if (!P) // If we couldn't find a pen in the PDA, or we didn't even have a PDA, do it the old way
P = locate() in all_contents

var/obj/item/uplink_loc
var/implant = FALSE

var/uplink_spawn_location = traitor_mob.client?.prefs?.read_preference(/datum/preference/choiced/uplink_location)
var/cant_speak = (HAS_TRAIT(traitor_mob, TRAIT_MUTE) || traitor_mob.mind?.assigned_role.title == JOB_MIME)
var/cant_speak = (HAS_TRAIT(traitor_mob, TRAIT_MUTE) || is_mime_job(assigned_role))
if(uplink_spawn_location == UPLINK_RADIO && cant_speak)
if(!silent)
to_chat(traitor_mob, span_warning("You have been deemed ineligible for a radio uplink. Supplying standard uplink instead."))
uplink_spawn_location = UPLINK_PDA
switch (uplink_spawn_location)
if(UPLINK_PDA)
uplink_loc = PDA
if(!uplink_loc)
uplink_loc = R
if(!uplink_loc)
uplink_loc = P
if(UPLINK_RADIO)
uplink_loc = R
if(!uplink_loc)
uplink_loc = PDA
if(!uplink_loc)
uplink_loc = P
if(UPLINK_PEN)
uplink_loc = P
if(UPLINK_IMPLANT)
implant = TRUE

if(!uplink_loc) // We've looked everywhere, let's just implant you
implant = TRUE
if(uplink_spawn_location != UPLINK_IMPLANT)
uplink_loc = traitor_mob.get_uplink_location(uplink_spawn_location)
if(istype(uplink_loc, /obj/item/radio) && cant_speak)
uplink_loc = null

if(implant)
if(isnull(uplink_loc))
var/obj/item/implant/uplink/starting/new_implant = new(traitor_mob)
new_implant.implant(traitor_mob, null, silent = TRUE)
if(!silent)
Expand All @@ -179,22 +177,27 @@
new_uplink.uplink_handler.owner = traitor_mob.mind
new_uplink.uplink_handler.assigned_role = traitor_mob.mind.assigned_role.title
new_uplink.uplink_handler.assigned_species = traitor_mob.dna.species.id
if(uplink_loc == R)
unlock_text = "Your Uplink is cunningly disguised as your [R.name]. Simply speak \"[new_uplink.unlock_code]\" into frequency [RADIO_TOKEN_UPLINK] to unlock its hidden features."
add_memory(/datum/memory/key/traitor_uplink, uplink_loc = R.name, uplink_code = new_uplink.unlock_code)
else if(uplink_loc == PDA)
unlock_text = "Your Uplink is cunningly disguised as your [PDA.name]. Simply enter the code \"[new_uplink.unlock_code]\" into the ring tone selection to unlock its hidden features."

unlock_text = "Your Uplink is cunningly disguised as your [uplink_loc.name]. "
if(istype(uplink_loc, /obj/item/modular_computer/pda))
unlock_text += "Simply enter the code \"[new_uplink.unlock_code]\" into the ring tone selection to unlock its hidden features."
add_memory(/datum/memory/key/traitor_uplink, uplink_loc = "PDA", uplink_code = new_uplink.unlock_code)
else if(uplink_loc == P)

else if(istype(uplink_loc, /obj/item/radio))
unlock_text += "Simply speak \"[new_uplink.unlock_code]\" into frequency [RADIO_TOKEN_UPLINK] to unlock its hidden features."
add_memory(/datum/memory/key/traitor_uplink, uplink_loc = uplink_loc.name, uplink_code = new_uplink.unlock_code)

else if(istype(uplink_loc, /obj/item/pen))
var/instructions = english_list(new_uplink.unlock_code)
unlock_text = "Your Uplink is cunningly disguised as your [P.name]. Simply twist the top of the pen [instructions] from its starting position to unlock its hidden features."
add_memory(/datum/memory/key/traitor_uplink, uplink_loc = "PDA pen", uplink_code = instructions)
unlock_text += "Simply twist the top of the pen [instructions] from its starting position to unlock its hidden features."
add_memory(/datum/memory/key/traitor_uplink, uplink_loc = uplink_loc.name, uplink_code = instructions)

new_uplink.unlock_text = unlock_text
if(!silent)
to_chat(traitor_mob, span_boldnotice(unlock_text))
if(antag_datum)
antag_datum.antag_memory += new_uplink.unlock_note + "<br>"
return .

/// 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)
Expand Down
Loading

0 comments on commit 4a335bc

Please sign in to comment.