part 1: battle stream
This commit is contained in:
@@ -34,6 +34,21 @@
|
||||
#define HIJACK_HIJACKER 1 //Needs to be present for shuttle to be hijacked
|
||||
#define HIJACK_PREVENT 2 //Prevents hijacking same way as non-antags
|
||||
|
||||
//Syndicate Contracts
|
||||
#define CONTRACT_STATUS_INACTIVE 1
|
||||
#define CONTRACT_STATUS_ACTIVE 2
|
||||
#define CONTRACT_STATUS_BOUNTY_CONSOLE_ACTIVE 3
|
||||
#define CONTRACT_STATUS_EXTRACTING 4
|
||||
#define CONTRACT_STATUS_COMPLETE 5
|
||||
#define CONTRACT_STATUS_ABORTED 6
|
||||
|
||||
#define CONTRACT_PAYOUT_LARGE 1
|
||||
#define CONTRACT_PAYOUT_MEDIUM 2
|
||||
#define CONTRACT_PAYOUT_SMALL 3
|
||||
|
||||
#define CONTRACT_UPLINK_PAGE_CONTRACTS "CONTRACTS"
|
||||
#define CONTRACT_UPLINK_PAGE_HUB "HUB"
|
||||
|
||||
//Overthrow time to update heads obj
|
||||
#define OBJECTIVE_UPDATING_TIME 300
|
||||
|
||||
|
||||
+17
-1
@@ -49,7 +49,7 @@
|
||||
alert("Invalid name.")
|
||||
return ""
|
||||
return sanitize(t)
|
||||
|
||||
|
||||
/proc/sanitize_filename(t)
|
||||
return sanitize_simple(t, list("\n"="", "\t"="", "/"="", "\\"="", "?"="", "%"="", "*"="", ":"="", "|"="", "\""="", "<"="", ">"=""))
|
||||
|
||||
@@ -798,3 +798,19 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
|
||||
out += prob(replaceprob)? pick(replacementchars) : char
|
||||
return out.Join("")
|
||||
|
||||
/proc/readable_corrupted_text(text)
|
||||
var/list/corruption_options = list("..", "£%", "~~\"", "!!", "*", "^", "$!", "-", "}", "?")
|
||||
var/corrupted_text = ""
|
||||
// Have every letter have a chance of creating corruption on either side
|
||||
// Small chance of letters being removed in place of corruption - still overall readable
|
||||
for(var/letter_index = 1; letter_index <= length(text); letter_index++)
|
||||
var/letter = text[letter_index]
|
||||
if(prob(15))
|
||||
corrupted_text += pick(corruption_options)
|
||||
if(prob(95))
|
||||
corrupted_text += letter
|
||||
else
|
||||
corrupted_text += pick(corruption_options)
|
||||
if(prob(15))
|
||||
corrupted_text += pick(corruption_options)
|
||||
return corrupted_text
|
||||
@@ -1075,7 +1075,7 @@ GLOBAL_LIST_EMPTY(cult_contraband)
|
||||
var/mob/living/carbon/human/H = owner
|
||||
H.equip_in_one_of_slots(I, list("backpack" = SLOT_IN_BACKPACK))
|
||||
hoarded_item = I
|
||||
|
||||
|
||||
|
||||
|
||||
GLOBAL_LIST_EMPTY(possible_sabotages)
|
||||
@@ -1092,7 +1092,7 @@ GLOBAL_LIST_EMPTY(possible_sabotages)
|
||||
if(!GLOB.possible_sabotages.len)//Only need to fill the list when it's needed.
|
||||
for(var/I in subtypesof(/datum/sabotage_objective))
|
||||
new I
|
||||
|
||||
|
||||
/datum/objective/sabotage/find_target()
|
||||
var/list/datum/mind/owners = get_owners()
|
||||
var/approved_targets = list()
|
||||
@@ -1155,3 +1155,23 @@ GLOBAL_LIST_EMPTY(possible_sabotages)
|
||||
|
||||
/datum/objective/flavor/wizard
|
||||
flavor_file = "strings/flavor_objectives/wizard.txt"
|
||||
|
||||
/datum/objective/contract
|
||||
var/payout = 0
|
||||
var/payout_bonus = 0
|
||||
var/area/dropoff = null
|
||||
|
||||
// Generate a random valid area on the station that the dropoff will happen.
|
||||
/datum/objective/contract/proc/generate_dropoff()
|
||||
var/found = FALSE
|
||||
while(!found)
|
||||
var/area/dropoff_area = pick(GLOB.sortedAreas)
|
||||
if(dropoff_area && is_station_level(dropoff_area.z) && dropoff_area.valid_territory)
|
||||
dropoff = dropoff_area
|
||||
found = TRUE
|
||||
|
||||
// Check if both the contractor and contract target are at the dropoff point.
|
||||
/datum/objective/contract/proc/dropoff_check(mob/user, mob/target)
|
||||
var/area/user_area = get_area(user)
|
||||
var/area/target_area = get_area(target)
|
||||
return (istype(user_area, dropoff) && istype(target_area, dropoff))
|
||||
|
||||
@@ -397,3 +397,47 @@
|
||||
/obj/item/storage/box/syndie_kit/revolver/PopulateContents()
|
||||
new /obj/item/gun/ballistic/revolver(src)
|
||||
new /obj/item/ammo_box/a357(src)
|
||||
|
||||
/obj/item/storage/box/syndie_kit/contract_kit
|
||||
name = "contractor kit"
|
||||
desc = "Supplied to Syndicate contractors in active mission areas."
|
||||
|
||||
/obj/item/storage/box/syndie_kit/contract_kit/PopulateContents()
|
||||
new /obj/item/modular_computer/tablet/syndicate_contract_uplink/preset/uplink(src)
|
||||
new /obj/item/storage/box/syndie_kit/space/contract(src)
|
||||
new /obj/item/clothing/under/chameleon(src)
|
||||
new /obj/item/clothing/mask/chameleon(src)
|
||||
new /obj/item/card/id/syndicate(src)
|
||||
|
||||
// All 4 TC or less - some nukeops only items, but fit nicely to the theme.
|
||||
var/list/item_list = list(
|
||||
/obj/item/storage/backpack/duffelbag/syndie/x4,
|
||||
/obj/item/storage/box/syndie_kit/emp,
|
||||
/obj/item/storage/box/syndie_kit/throwing_weapons,
|
||||
/obj/item/gun/syringe/syndicate,
|
||||
/obj/item/pen/edagger,
|
||||
/obj/item/pen/sleepy,
|
||||
/obj/item/gun/ballistic/automatic/toy/pistol/riot,
|
||||
/obj/item/flashlight/emp,
|
||||
/obj/item/reagent_containers/syringe/mulligan,
|
||||
/obj/item/clothing/shoes/chameleon/noslip,
|
||||
/obj/item/storage/toolbox/syndicate,
|
||||
/obj/item/storage/firstaid/tactical,
|
||||
/obj/item/storage/backpack/duffelbag/syndie/surgery,
|
||||
/obj/item/encryptionkey/syndicate,
|
||||
/obj/item/clothing/glasses/thermal/syndi,
|
||||
/obj/item/slimepotion/slime/sentience/nuclear,
|
||||
/obj/item/storage/box/syndie_kit/imp_radio,
|
||||
/obj/item/storage/box/syndie_kit/imp_uplink
|
||||
)
|
||||
|
||||
var/obj/item1 = pick_n_take(item_list)
|
||||
var/obj/item2 = pick_n_take(item_list)
|
||||
|
||||
// Create two, non repeat items from the list.
|
||||
new item1(src)
|
||||
new item2(src)
|
||||
|
||||
/obj/item/storage/box/syndie_kit/space/contract/PopulateContents()
|
||||
new /obj/item/clothing/suit/space/syndicate/black/red(src)
|
||||
new /obj/item/clothing/head/helmet/space/syndicate/black/red(src)
|
||||
@@ -13,6 +13,10 @@
|
||||
var/should_give_codewords = TRUE
|
||||
var/should_equip = TRUE
|
||||
var/traitor_kind = TRAITOR_HUMAN //Set on initial assignment
|
||||
var/datum/syndicate_contract/current_contract
|
||||
var/list/assigned_contracts = list()
|
||||
var/contract_TC_payed_out = 0
|
||||
var/contract_TC_to_redeem = 0
|
||||
hijack_speed = 0.5 //10 seconds per hijack stage by default
|
||||
|
||||
/datum/antagonist/traitor/on_gain()
|
||||
@@ -26,6 +30,14 @@
|
||||
finalize_traitor()
|
||||
..()
|
||||
|
||||
/datum/antagonist/traitor/proc/create_contracts()
|
||||
var/contract_generation_quantity = 6
|
||||
|
||||
for(var/i = 1; i <= contract_generation_quantity; i++)
|
||||
var/datum/syndicate_contract/contract_to_add = new(owner)
|
||||
contract_to_add.id = i
|
||||
assigned_contracts.Add(contract_to_add)
|
||||
|
||||
/datum/antagonist/traitor/apply_innate_effects()
|
||||
if(owner.assigned_role == "Clown")
|
||||
var/mob/living/carbon/human/traitor_mob = owner.current
|
||||
@@ -413,6 +425,20 @@
|
||||
|
||||
var/special_role_text = lowertext(name)
|
||||
|
||||
var/completed_contracts = 0
|
||||
var/tc_total = contract_TC_payed_out + contract_TC_to_redeem
|
||||
for (var/datum/syndicate_contract/contract in assigned_contracts)
|
||||
if (contract.status == CONTRACT_STATUS_COMPLETE)
|
||||
completed_contracts++
|
||||
|
||||
|
||||
if (completed_contracts > 0)
|
||||
var/pluralCheck = "contract"
|
||||
if (completed_contracts > 1)
|
||||
pluralCheck = "contracts"
|
||||
result += "<br>Completed <span class='greentext'>[completed_contracts]</span> [pluralCheck] for a total of \
|
||||
<span class='greentext'>[tc_total] TC</span>!<br>"
|
||||
|
||||
if(traitorwin)
|
||||
result += "<span class='greentext'>The [special_role_text] was successful!</span>"
|
||||
else
|
||||
|
||||
@@ -42,6 +42,8 @@
|
||||
var/soundVolume = 80 //Volume to play sounds at. Ignores the cap
|
||||
var/bay //Used specifically for the centcom_podlauncher datum. Holds the current bay the user is launching objects from. Bays are specific rooms on the centcom map.
|
||||
var/list/explosionSize = list(0,0,2,3)
|
||||
var/stay_after_drop = FALSE
|
||||
var/specialised = TRUE // It's not a general use pod for cargo/admin use
|
||||
|
||||
/obj/structure/closet/supplypod/bluespacepod
|
||||
style = STYLE_BLUESPACE
|
||||
@@ -49,6 +51,15 @@
|
||||
explosionSize = list(0,0,1,2)
|
||||
landingDelay = 15 //Slightly quicker than the supplypod
|
||||
|
||||
/obj/structure/closet/supplypod/extractionpod
|
||||
name = "Syndicate Extraction Pod"
|
||||
desc = "A specalised, blood-red styled pod for extracting high-value targets out of active mission areas."
|
||||
specialised = TRUE
|
||||
style = STYLE_SYNDICATE
|
||||
bluespace = TRUE
|
||||
explosionSize = list(0,0,1,2)
|
||||
landingDelay = 25 //Slightly longer than others
|
||||
|
||||
/obj/structure/closet/supplypod/centcompod
|
||||
style = STYLE_CENTCOM
|
||||
bluespace = TRUE
|
||||
@@ -56,6 +67,13 @@
|
||||
landingDelay = 20 //Very speedy!
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
|
||||
/obj/structure/closet/supplypod/proc/specialisedPod()
|
||||
return 1
|
||||
|
||||
/obj/structure/closet/supplypod/extractionpod/specialisedPod(atom/movable/holder)
|
||||
holder.forceMove(pick(GLOB.holdingfacility)) // land in ninja jail
|
||||
open(holder, forced = TRUE)
|
||||
|
||||
/obj/structure/closet/supplypod/Initialize()
|
||||
. = ..()
|
||||
setStyle(style, TRUE) //Upon initialization, give the supplypod an iconstate, name, and description based on the "style" variable. This system is important for the centcom_podlauncher to function correctly
|
||||
@@ -76,7 +94,7 @@
|
||||
return
|
||||
style = chosenStyle
|
||||
icon_state = POD_STYLES[chosenStyle][POD_ICON_STATE] //POD_STYLES is a 2D array we treat as a dictionary. The style represents the verticle index, with the icon state, name, and desc being stored in the horizontal indexes of the 2D array.
|
||||
if (!adminNamed) //We dont want to name it ourselves if it has been specifically named by an admin using the centcom_podlauncher datum
|
||||
if (!adminNamed && !specialised) //We dont want to name it ourselves if it has been specifically named by an admin using the centcom_podlauncher datum
|
||||
name = POD_STYLES[chosenStyle][POD_NAME]
|
||||
desc = POD_STYLES[chosenStyle][POD_DESC]
|
||||
update_icon()
|
||||
@@ -96,6 +114,30 @@
|
||||
/obj/structure/closet/supplypod/toggle(mob/living/user) //Supplypods shouldn't be able to be manually opened under any circumstances, as the open() proc generates supply order datums
|
||||
return
|
||||
|
||||
/obj/structure/closet/supplypod/proc/handleReturningClose(atom/movable/holder, returntobay)
|
||||
opened = FALSE
|
||||
INVOKE_ASYNC(holder, .proc/setClosed) //Use the INVOKE_ASYNC proc to call setClosed() on whatever the holder may be, without giving the atom/movable base class a setClosed() proc definition
|
||||
for(var/atom/movable/O in get_turf(holder))
|
||||
if ((ismob(O) && !isliving(O)) || (is_type_in_typecache(O, GLOB.blacklisted_cargo_types) && !isliving(O))) //We dont want to take ghosts with us, and we don't want blacklisted items going, but we allow mobs.
|
||||
continue
|
||||
O.forceMove(holder) //Put objects inside before we close
|
||||
var/obj/effect/temp_visual/risingPod = new /obj/effect/abstract/DPfall(get_turf(holder), src) //Make a nice animation of flying back up
|
||||
risingPod.pixel_z = 0 //The initial value of risingPod's pixel_z is 200 because it normally comes down from a high spot
|
||||
animate(risingPod, pixel_z = 200, time = 10, easing = LINEAR_EASING) //Animate our rising pod
|
||||
if(returntobay)
|
||||
holder.forceMove(bay) //Move the pod back to centcom, where it belongs
|
||||
QDEL_IN(risingPod, 10)
|
||||
reversing = FALSE //Now that we're done reversing, we set this to false (otherwise we would get stuck in an infinite loop of calling the close proc at the bottom of open() )
|
||||
bluespace = TRUE //Make it so that the pod doesn't stay in centcom forever
|
||||
open(holder, forced = TRUE)
|
||||
else
|
||||
reversing = FALSE //Now that we're done reversing, we set this to false (otherwise we would get stuck in an infinite loop of calling the close proc at the bottom of open() )
|
||||
bluespace = TRUE //Make it so that the pod doesn't stay in centcom forever
|
||||
QDEL_IN(risingPod, 10)
|
||||
audible_message("<span class='notice'>The pod hisses, closing quickly and launching itself away from the station.</span>", "<span class='notice'>The ground vibrates, the nearby pod launching away from the station.</span>")
|
||||
stay_after_drop = FALSE
|
||||
specialisedPod(holder) // Do special actions for specialised pods - this is likely if we were already doing manual launches
|
||||
|
||||
/obj/structure/closet/supplypod/proc/preOpen() //Called before the open() proc. Handles anything that occurs right as the pod lands.
|
||||
var/turf/T = get_turf(src)
|
||||
var/list/B = explosionSize //Mostly because B is more readable than explosionSize :p
|
||||
@@ -172,7 +214,8 @@
|
||||
if (style == STYLE_SEETHROUGH)
|
||||
depart(src)
|
||||
else
|
||||
addtimer(CALLBACK(src, .proc/depart, holder), departureDelay) //Finish up the pod's duties after a certain amount of time
|
||||
if(!stay_after_drop) // Departing should be handled manually
|
||||
addtimer(CALLBACK(src, .proc/depart, holder), departureDelay) //Finish up the pod's duties after a certain amount of time
|
||||
|
||||
/obj/structure/closet/supplypod/proc/depart(atom/movable/holder)
|
||||
if (leavingSound)
|
||||
@@ -187,20 +230,14 @@
|
||||
qdel(holder)
|
||||
|
||||
/obj/structure/closet/supplypod/centcompod/close(atom/movable/holder) //Closes the supplypod and sends it back to centcom. Should only ever be called if the "reversing" variable is true
|
||||
opened = FALSE
|
||||
INVOKE_ASYNC(holder, .proc/setClosed) //Use the INVOKE_ASYNC proc to call setClosed() on whatever the holder may be, without giving the atom/movable base class a setClosed() proc definition
|
||||
for (var/atom/movable/O in get_turf(holder))
|
||||
if (ismob(O) && !isliving(O)) //We dont want to take ghosts with us
|
||||
continue
|
||||
O.forceMove(holder) //Put objects inside before we close
|
||||
var/obj/effect/temp_visual/risingPod = new /obj/effect/abstract/DPfall(get_turf(holder), src) //Make a nice animation of flying back up
|
||||
risingPod.pixel_z = 0 //The initial value of risingPod's pixel_z is 200 because it normally comes down from a high spot
|
||||
holder.forceMove(bay) //Move the pod back to centcom, where it belongs
|
||||
animate(risingPod, pixel_z = 200, time = 10, easing = LINEAR_EASING) //Animate our rising pod
|
||||
QDEL_IN(risingPod, 10)
|
||||
reversing = FALSE //Now that we're done reversing, we set this to false (otherwise we would get stuck in an infinite loop of calling the close proc at the bottom of open() )
|
||||
bluespace = TRUE //Make it so that the pod doesn't stay in centcom forever
|
||||
open(holder, forced = TRUE)
|
||||
handleReturningClose(holder, TRUE)
|
||||
|
||||
/obj/structure/closet/supplypod/extractionpod/close(atom/movable/holder) //handles closing, and returns pod - deletes itself when returned
|
||||
if(!holder)
|
||||
holder = src
|
||||
if(leavingSound)
|
||||
playsound(get_turf(holder), leavingSound, soundVolume, 0, 0)
|
||||
handleReturningClose(holder, FALSE)
|
||||
|
||||
/obj/structure/closet/supplypod/proc/setOpened() //Proc exists here, as well as in any atom that can assume the role of a "holder" of a supplypod. Check the open() proc for more details
|
||||
update_icon()
|
||||
|
||||
@@ -20,4 +20,16 @@
|
||||
finish_color = pick("red","blue","brown","green","black")
|
||||
icon_state = "tablet-[finish_color]"
|
||||
icon_state_unpowered = "tablet-[finish_color]"
|
||||
icon_state_powered = "tablet-[finish_color]"
|
||||
icon_state_powered = "tablet-[finish_color]"
|
||||
|
||||
/obj/item/modular_computer/tablet/syndicate_contract_uplink
|
||||
name = "tablet computer"
|
||||
icon = 'icons/obj/modular_tablet.dmi'
|
||||
icon_state = "tablet-red"
|
||||
icon_state_unpowered = "tablet"
|
||||
icon_state_powered = "tablet"
|
||||
icon_state_menu = "hostile"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
slot_flags = ITEM_SLOT_ID | ITEM_SLOT_BELT
|
||||
comp_light_luminosity = 4.3
|
||||
finish_color = "red"
|
||||
@@ -27,3 +27,15 @@
|
||||
install_component(new /obj/item/computer_hardware/hard_drive/small)
|
||||
install_component(new /obj/item/computer_hardware/network_card)
|
||||
install_component(new /obj/item/computer_hardware/printer/mini)
|
||||
|
||||
// Given by the syndicate as part of the contract uplink bundle
|
||||
/obj/item/modular_computer/tablet/syndicate_contract_uplink/preset/uplink/Initialize()
|
||||
. = ..()
|
||||
var/obj/item/computer_hardware/hard_drive/small/syndicate/hard_drive = new
|
||||
hard_drive.store_file(new /datum/computer_file/program/contract_uplink)
|
||||
install_component(new /obj/item/computer_hardware/processor_unit/small)
|
||||
install_component(new /obj/item/computer_hardware/battery(src, /obj/item/stock_parts/cell/computer))
|
||||
install_component(hard_drive)
|
||||
install_component(new /obj/item/computer_hardware/network_card)
|
||||
install_component(new /obj/item/computer_hardware/card_slot)
|
||||
install_component(new /obj/item/computer_hardware/printer/mini)
|
||||
@@ -158,6 +158,13 @@
|
||||
icon_state = "ssd_mini"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
|
||||
// Syndicate variant - very slight better
|
||||
/obj/item/computer_hardware/hard_drive/small/syndicate
|
||||
desc = "An efficient SSD for portable devices developed by a rival organisation."
|
||||
power_usage = 8
|
||||
max_capacity = 70
|
||||
var/datum/antagonist/traitor/traitor_data // Syndicate hard drive has the user's data baked directly into it on creation
|
||||
|
||||
/obj/item/computer_hardware/hard_drive/micro
|
||||
name = "micro solid state drive"
|
||||
desc = "A highly efficient SSD chip for portable devices."
|
||||
|
||||
@@ -30,6 +30,17 @@
|
||||
cost = 14 // normally 16
|
||||
include_modes = list(/datum/game_mode/nuclear)
|
||||
|
||||
/datum/uplink_item/bundles_TC/contract_kit
|
||||
name = "Contract Kit"
|
||||
desc = "The Syndicate have a number of urgent contracts for you to take on, become a contractor and complete them for TC. Upon purchase, \
|
||||
you'll be granted your own contract uplink embedded within the supplied tablet computer. Additonally, you'll be granted contractor \
|
||||
gear to help with your mission - comes supplied with the tablet, space suit, chameleon jumpsuit and mask, agent card, and two \
|
||||
randomly selected low cost items."
|
||||
item = /obj/item/storage/box/syndie_kit/contract_kit
|
||||
cost = 20
|
||||
player_minimum = 20
|
||||
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
|
||||
|
||||
/datum/uplink_item/bundles_TC/cybernetics_bundle
|
||||
name = "Cybernetic Implants Bundle"
|
||||
desc = "A random selection of cybernetic implants. Guaranteed 5 high quality implants. Comes with an autosurgeon."
|
||||
|
||||
Reference in New Issue
Block a user