Skip to content

Commit

Permalink
[READY] Syndicate Contractors (ParadiseSS13#14605)
Browse files Browse the repository at this point in the history
* Syndicate Contractors initial PR

* Finalize initial version

DNP

Finalize initial version

* Baton now costs 6 Rep, show dead extraction penalty, fix scroll

* Reduce total TC, add zippo, balloon, icon tweaks

* Address moxian, AA and Farie

* Fix mode.txt

* oops

* Address Farie 2

* Tweak baton to work around stam crits, address SteelSlayer

* Address TM issues, TP menu

* Fix wrongly merged DME

* Tick contractor DM files again

* Remove step_y

* TC rewards always higher than preceding difficulty's reward

* Address Farie

* Remove extraction_turf from handle_target_return

* fix doc

* Merge part2

* Address AA again
  • Loading branch information
dearmochi authored Dec 9, 2020
1 parent 2897b82 commit 5edee29
Show file tree
Hide file tree
Showing 73 changed files with 3,588 additions and 250 deletions.
730 changes: 544 additions & 186 deletions _maps/map_files/cyberiad/z2.dmm

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions code/__DEFINES/combat.dm
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
#define DROWSY "drowsy"
#define JITTER "jitter"

/// Jitter decays at a rate of 3 per life cycle, 15 if resting.
#define SECONDS_TO_JITTER SECONDS_TO_LIFE_CYCLES*3

//I hate adding defines like this but I'd much rather deal with bitflags than lists and string searches
#define BRUTELOSS 1
#define FIRELOSS 2
Expand Down
28 changes: 28 additions & 0 deletions code/__DEFINES/contractors.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Contract Statuses
/// The contract is invalid for some reason and cannot be taken. It may be made valid later.
#define CONTRACT_STATUS_INVALID -1
/// The contract hasn't been started yet.
#define CONTRACT_STATUS_INACTIVE 0
/// The contract is in progress.
#define CONTRACT_STATUS_ACTIVE 1
/// The contract has been completed successfully.
#define CONTRACT_STATUS_COMPLETED 2
/// The contract failed for some reason.
#define CONTRACT_STATUS_FAILED 3

// Difficulties. Note that they follow each other numerically and should stay that way as some code relies on that.
/// Easy difficulty area to extract the kidnapee. Low rewards.
#define EXTRACTION_DIFFICULTY_EASY 1
/// Medium difficulty area to extract the kidnapee. Moderate rewards.
#define EXTRACTION_DIFFICULTY_MEDIUM 2
/// Hard difficulty area to extract the kidnapee. High rewards.
#define EXTRACTION_DIFFICULTY_HARD 3

/// The name of the strings file containing data to use for contract fluff texts.
#define CONTRACT_STRINGS_WANTED "syndicate_wanted_messages.json"

// UI page numbers.
#define HUB_PAGE_CONTRACTS 1
#define HUB_PAGE_SHOP 2

GLOBAL_DATUM(prisoner_belongings, /obj/structure/closet/secure_closet/contractor)
1 change: 1 addition & 0 deletions code/__DEFINES/gamemode.dm
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#define TARGET_INVALID_GOLEM 6
#define TARGET_INVALID_EVENT 7
#define TARGET_INVALID_IS_TARGET 8
#define TARGET_INVALID_BLACKLISTED 9

//gamemode istype helpers
#define GAMEMODE_IS_BLOB (SSticker && istype(SSticker.mode, /datum/game_mode/blob))
Expand Down
2 changes: 2 additions & 0 deletions code/__HELPERS/time.dm
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

#define TICKS *world.tick_lag

#define SECONDS_TO_LIFE_CYCLES /2

#define DS2TICKS(DS) ((DS)/world.tick_lag)

#define TICKS2DS(T) ((T) TICKS)
Expand Down
1 change: 1 addition & 0 deletions code/_globalvars/mapping.dm
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ GLOBAL_LIST_EMPTY(latejoin_gateway)
GLOBAL_LIST_EMPTY(latejoin_cryo)
GLOBAL_LIST_EMPTY(latejoin_cyborg)
GLOBAL_LIST_EMPTY(prisonwarp) //prisoners go to these
GLOBAL_LIST_EMPTY(syndieprisonwarp) //contractor targets go to these
GLOBAL_LIST_EMPTY(xeno_spawn)//Aliens spawn at these.
GLOBAL_LIST_EMPTY(ertdirector)
GLOBAL_LIST_EMPTY(emergencyresponseteamspawn)
Expand Down
281 changes: 281 additions & 0 deletions code/datums/mind.dm
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,57 @@
. += "<a href='?src=[UID()];traitor=traitor'>traitor</a>|<b>NO</b>"

. += _memory_edit_role_enabled(ROLE_TRAITOR)
// Contractor
. += "<br><b><i>contractor</i></b>: "
var/datum/antagonist/traitor/contractor/C = has_antag_datum(/datum/antagonist/traitor/contractor)
if(C)
var/status
if(C.contractor_uplink) // Offer accepted
status = "<b><font color='red'>CONTRACTOR</font></b>"
else if(world.time >= C.offer_deadline)
status = "<b><font color='darkorange'>CONTRACTOR (EXPIRED)</font></b>"
else
status = "<b><font color='orange'>CONTRACTOR (PENDING)</font></b>"
. += "[status]|<a href='?src=[UID()];contractor=clear'>no</a>"
// List all their contracts
if(C.contractor_uplink)
. += "<br><b>Contracts:</b>"
if(C.contractor_uplink.hub.contracts)
var/count = 1
for(var/co in C.contractor_uplink.hub.contracts)
var/datum/syndicate_contract/CO = co
. += "<br><B>Contract #[count++]</B>: "
. += "<a href='?src=[UID()];cuid=[CO.UID()];contractor=target'><b>[CO.contract.target?.name || "Invalid target!"]</b></a>|"
. += "<a href='?src=[UID()];cuid=[CO.UID()];contractor=locations'>locations</a>|"
. += "<a href='?src=[UID()];cuid=[CO.UID()];contractor=other'>more</a>|"
switch(CO.status)
if(CONTRACT_STATUS_INVALID)
. += "<b>INVALID</b>"
if(CONTRACT_STATUS_INACTIVE)
. += "inactive"
if(CONTRACT_STATUS_ACTIVE)
. += "<b><font color='orange'>ACTIVE</font></b>|"
. += "<a href='?src=[UID()];cuid=[CO.UID()];contractor=interrupt'>interrupt</a>|"
. += "<a href='?src=[UID()];cuid=[CO.UID()];contractor=fail'>fail</a>"
if(CONTRACT_STATUS_COMPLETED)
. += "<font color='green'>COMPLETED</font>"
if(CONTRACT_STATUS_FAILED)
. += "<font color='red'>FAILED</font>"
. += "<br>"
. += "<a href='?src=[UID()];contractor=add'>Add Contract</a><br>"
. += "Claimable TC: <a href='?src=[UID()];contractor=tc'>[C.contractor_uplink.hub.reward_tc_available]</a><br>"
. += "Available Rep: <a href='?src=[UID()];contractor=rep'>[C.contractor_uplink.hub.rep]</a><br>"
else
. += "<br>"
. += "<i>Has not logged in to contractor uplink</i>"
else
if(has_antag_datum(/datum/antagonist/traitor))
if(find_syndicate_uplink())
. += "<a href='?src=[UID()];contractor=contractor'>contractor</a>|<b>NO</b>"
else
. += "contractor|<b>NO</b>|No Uplink"
else
. += "contractor|<b>NO</b>"
// Mindslave
. += "<br><b><i>mindslaved</i></b>: "
if(has_antag_datum(/datum/antagonist/mindslave))
Expand Down Expand Up @@ -1167,6 +1218,236 @@
log_admin("[key_name(usr)] has automatically forged objectives for [key_name(current)]")
message_admins("[key_name_admin(usr)] has automatically forged objectives for [key_name_admin(current)]")

else if(href_list["contractor"])
var/datum/antagonist/traitor/contractor/C = has_antag_datum(/datum/antagonist/traitor/contractor)
var/datum/contractor_hub/H = C && C.contractor_uplink?.hub
switch(href_list["contractor"])
if("clear")
if(!C)
return
var/memory = C.antag_memory // Need to preserve the codewords and such
// Clean up contractor stuff
var/obj/item/uplink/hidden/U = find_syndicate_uplink()
U?.contractor = null
C.silent = TRUE
remove_antag_datum(/datum/antagonist/traitor/contractor)
// Traitor them again
if(!has_antag_datum(/datum/antagonist/traitor, FALSE))
var/datum/antagonist/traitor/T = new()
T.give_objectives = FALSE
T.should_equip = FALSE
T.silent = TRUE
T.antag_memory += memory
add_antag_datum(T)
// Notify
to_chat(current, "<span class='warning'><font size=3><b>You are no longer a Contractor!</b></font></span>")
log_admin("[key_name(usr)] has de-contractored [key_name(current)]")
message_admins("[key_name_admin(usr)] has de-contractored [key_name_admin(current)]")

if("contractor")
if(has_antag_datum(/datum/antagonist/traitor/contractor))
return
var/datum/antagonist/traitor/T = has_antag_datum(/datum/antagonist/traitor)
var/memory = T?.antag_memory // Need to preserve the codewords and such
// Replace the traitor datum by a contractor one
remove_antag_datum(/datum/antagonist/traitor)
C = new()
C.give_objectives = FALSE
C.should_equip = FALSE
C.silent = TRUE
C.antag_memory += memory
add_antag_datum(C)
// Notify
log_admin("[key_name(usr)] has contractored [key_name(current)]")
message_admins("[key_name_admin(usr)] has contractored [key_name_admin(current)]")

if("add")
if(!C)
return
var/list/possible_targets = list()
for(var/foo in SSticker.minds)
var/datum/mind/possible_target = foo
if(src == possible_target || !possible_target.current || !possible_target.key)
continue
possible_targets[possible_target.name] = possible_target

var/choice = input(usr, "Select the contract target:", "Add Contract") as null|anything in possible_targets
var/datum/mind/target = possible_targets[choice]
if(!target || !target.current || !target.key)
return
var/datum/syndicate_contract/new_contract = new(H, src, list(), target)
new_contract.reward_tc = list(0, 0, 0)
H.contracts += new_contract
SStgui.update_uis(C.contractor_uplink.hub)
log_admin("[key_name(usr)] has given a new contract to [key_name(current)] with [target.current] as the target")
message_admins("[key_name_admin(usr)] has given a new contract to [key_name_admin(current)] with [target.current] as the target")

if("tc")
if(!C)
return
var/new_tc = input(usr, "Enter the new amount of TC:", "Set Claimable TC", H.reward_tc_available) as num|null
new_tc = text2num(new_tc)
if(isnull(new_tc) || new_tc < 0)
return
H.reward_tc_available = new_tc
SStgui.update_uis(C.contractor_uplink.hub)
log_admin("[key_name(usr)] has set [key_name(current)]'s claimable TC to [new_tc]")
message_admins("[key_name_admin(usr)] has set [key_name_admin(current)]'s claimable TC to [new_tc]")

if("rep")
if(!C)
return
var/new_rep = input(usr, "Enter the new amount of Rep:", "Set Available Rep", H.rep) as num|null
new_rep = text2num(new_rep)
if(isnull(new_rep) || new_rep < 0)
return
H.rep = new_rep
SStgui.update_uis(C.contractor_uplink.hub)
log_admin("[key_name(usr)] has set [key_name(current)]'s contractor Rep to [new_rep]")
message_admins("[key_name_admin(usr)] has set [key_name_admin(current)]'s contractor Rep to [new_rep]")

// Contract specific actions
if("target")
if(!C)
return
var/datum/syndicate_contract/CO = locateUID(href_list["cuid"])
if(!istype(CO))
return

var/list/possible_targets = list()
for(var/foo in SSticker.minds)
var/datum/mind/possible_target = foo
if(src == possible_target || !possible_target.current || !possible_target.key)
continue
possible_targets[possible_target.name] = possible_target

var/choice = input(usr, "Select the new contract target:", "Set Contract Target") as null|anything in possible_targets
var/datum/mind/target = possible_targets[choice]
if(!target || !target.current || !target.key)
return
// Update
var/datum/data/record/R = find_record("name", target.name, GLOB.data_core.general)
var/name = R?.fields["name"] || target.name || "Unknown"
var/rank = R?.fields["rank"] || target.assigned_role || "Unknown"
CO.contract.target = target
CO.target_name = "[name], the [rank]"
if(R?.fields["photo"])
var/icon/temp = new('icons/turf/floors.dmi', pick("floor", "wood", "darkfull", "stairs"))
temp.Blend(R.fields["photo"], ICON_OVERLAY)
CO.target_photo = temp
// Notify
SStgui.update_uis(C.contractor_uplink.hub)
log_admin("[key_name(usr)] has set [key_name(current)]'s contract target to [target.current]")
message_admins("[key_name_admin(usr)] has set [key_name_admin(current)]'s contract target to [target.current]")

if("locations")
if(!C)
return
var/datum/syndicate_contract/CO = locateUID(href_list["cuid"])
if(!istype(CO))
return

var/list/difficulty_choices = list()
for(var/diff in EXTRACTION_DIFFICULTY_EASY to EXTRACTION_DIFFICULTY_HARD)
var/area/A = CO.contract.candidate_zones[diff]
difficulty_choices["[A.name] ([CO.reward_tc[diff]] TC)"] = diff

var/choice_diff = input(usr, "Select the location to change:", "Set Contract Location") as null|anything in difficulty_choices
var/difficulty = difficulty_choices[choice_diff]
if(!difficulty)
return

var/list/area_choices = list()
for(var/a in return_sorted_areas())
var/area/A = a
if(A.outdoors || !is_station_level(A.z))
continue
area_choices += A

var/new_area = input(usr, "Select the new location:", "Set Contract Location", CO.contract.candidate_zones[difficulty]) in area_choices
if(!new_area)
return

var/new_reward = input(usr, "Enter the new amount of rewarded TC:", "Set Contract Location", CO.reward_tc[difficulty]) as num|null
new_reward = text2num(new_reward)
if(isnull(new_reward) || new_reward < 0)
return
CO.contract.candidate_zones[difficulty] = new_area
CO.reward_tc[difficulty] = new_reward
SStgui.update_uis(C.contractor_uplink.hub)
log_admin("[key_name(usr)] has set [key_name(current)]'s contract location to [new_area] with [new_reward] TC as reward")
message_admins("[key_name_admin(usr)] has set [key_name_admin(current)]'s contract location to [new_area] with [new_reward] TC as reward")

if("other")
if(!C)
return
var/datum/syndicate_contract/CO = locateUID(href_list["cuid"])
if(!istype(CO))
return

var/choice = input(usr, "Select an action to take:", "Other Contract Actions") in list("Edit Fluff Message", "Edit Prison Time", "Edit Credits Reward", "Delete Contract", "Cancel")
if(!choice)
return

switch(choice)
if("Edit Fluff Message")
var/new_message = input(usr, "Enter the new fluff message:", "Edit Fluff Message", CO.fluff_message) as message|null
if(!new_message)
return
CO.fluff_message = new_message
log_admin("[key_name(usr)] has edited [key_name(current)]'s contract fluff message")
message_admins("[key_name_admin(usr)] has edited [key_name_admin(current)]'s contract fluff message")
if("Edit Prison Time")
var/new_time = input(usr, "Enter the new prison time in seconds:", "Edit Prison Time", CO.prison_time / 10) as num|null
if(!new_time || new_time < 0)
return
CO.prison_time = new_time SECONDS
log_admin("[key_name(usr)] has edited [key_name(current)]'s contract prison time to [new_time] seconds")
message_admins("[key_name_admin(usr)] has edited [key_name_admin(current)]'s contract prison time to [new_time] seconds")
if("Edit Credits Reward")
var/new_creds = input(usr, "Enter the new credits reward:", "Edit Credits Reward", CO.reward_credits) as num|null
if(!new_creds || new_creds < 0)
return
CO.reward_credits = new_creds
log_admin("[key_name(usr)] has edited [key_name(current)]'s contract reward credits to [new_creds]")
message_admins("[key_name_admin(usr)] has edited [key_name_admin(current)]'s contract reward credits to [new_creds]")
if("Delete Contract")
if(CO.status == CONTRACT_STATUS_ACTIVE)
CO.fail("Contract interrupted forcibly.")
H.contracts -= CO
log_admin("[key_name(usr)] has deleted [key_name(current)]'s contract")
message_admins("[key_name_admin(usr)] has deleted [key_name_admin(current)]'s contract")
else
return
SStgui.update_uis(C.contractor_uplink.hub)

if("interrupt")
if(!C)
return
var/datum/syndicate_contract/CO = locateUID(href_list["cuid"])
if(!istype(CO) || CO.status != CONTRACT_STATUS_ACTIVE)
return
H.current_contract = null
CO.contract.extraction_zone = null
CO.status = CONTRACT_STATUS_INACTIVE
CO.clean_up()
log_admin("[key_name(usr)] has interrupted [key_name(current)]'s contract")
message_admins("[key_name_admin(usr)] has interrupted [key_name_admin(current)]'s contract")

if("fail")
if(!C)
return
var/datum/syndicate_contract/CO = locateUID(href_list["cuid"])
if(!istype(CO) || CO.status != CONTRACT_STATUS_ACTIVE)
return
var/fail_reason = sanitize(input(usr, "Enter the fail reason:", "Fail Contract") as text|null)
if(!fail_reason || CO.status != CONTRACT_STATUS_ACTIVE)
return
CO.fail(fail_reason)
SStgui.update_uis(C.contractor_uplink.hub)
log_admin("[key_name(usr)] has failed [key_name(current)]'s contract with reason: [fail_reason]")
message_admins("[key_name_admin(usr)] has failed [key_name_admin(current)]'s contract with reason: [fail_reason]")

else if(href_list["mindslave"])
switch(href_list["mindslave"])
if("clear")
Expand Down
3 changes: 3 additions & 0 deletions code/game/area/ss13_areas.dm
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,9 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
name = "\improper Syndicate Infiltrators"
icon_state = "syndie-elite"

/area/syndicate_mothership/jail
name = "\improper Syndicate Jail"

//EXTRA

/area/asteroid // -- TLE
Expand Down
Loading

0 comments on commit 5edee29

Please sign in to comment.