[MIRROR] refreshes syndi-kits and syndicate surplus crates, introduces shared limited stock [MDB IGNORE] (#18209)

* refreshes syndi-kits and syndicate surplus crates, introduces shared limited stock

* merge conflict

* Surplus balance, Consolidated our surplus crate and the new tg one to just use our stats

* use upstream surplus loot crates

* syndicrate

Co-authored-by: Sol N <116288367+flowercuco@users.noreply.github.com>
Co-authored-by: tastyfish <crazychris32@gmail.com>
This commit is contained in:
SkyratBot
2023-01-07 01:42:14 -05:00
committed by GitHub
co-authored by Sol N tastyfish
parent d1a52ae6ad
commit b80abedb59
21 changed files with 397 additions and 141 deletions
+6
View File
@@ -249,6 +249,12 @@ GLOBAL_LIST_INIT(ai_employers, list(
/// because they have nothing else that supports an implant.
#define UPLINK_IMPLANT_TELECRYSTAL_COST 4
/// Items with this stock key do not share stock with other items
#define UPLINK_SHARED_STOCK_UNIQUE "uplink_shared_stock_unique"
/// Stock keys for items that share inventory stock
#define UPLINK_SHARED_STOCK_KITS "uplink_shared_stock_kits"
#define UPLINK_SHARED_STOCK_SURPLUS "uplink_shared_stock_surplus"
// Used for traitor objectives
/// If the objective hasn't been taken yet
#define OBJECTIVE_STATE_INACTIVE 1
+2 -2
View File
@@ -230,8 +230,8 @@
))
var/list/remaining_stock = list()
for(var/datum/uplink_item/item as anything in stock_list)
remaining_stock[item.type] = stock_list[item]
for(var/item as anything in stock_list)
remaining_stock[item] = stock_list[item]
data["extra_purchasable"] = extra_purchasable
data["extra_purchasable_stock"] = extra_purchasable_stock
data["current_stock"] = remaining_stock
@@ -0,0 +1,16 @@
/obj/item/book/granter/action/spell/lightningbolt
granted_action = /datum/action/cooldown/spell/pointed/projectile/lightningbolt
action_name = "lightning bolt"
icon_state ="booklightning"
desc = "Become like lightning, the rain transformed."
remarks = list(
"I never quite liked insulated gloves...",
"Will this effect my haircut?",
"I wonder if I can use this to charge a MODsuit?",
"Ouch! That page had static...",
"Is cackling optional?",
"Just think like a tesla ball...",
"UNLIMITED power? Well... maybe if I practice...",
"Wait until they're grouped up...",
)
+96 -81
View File
@@ -20,6 +20,7 @@
#define KIT_MR_FREEZE "mr_freeze"
#define KIT_TRAITOR_2006 "ancient"
/// last audited december 2022
/obj/item/storage/box/syndicate
/obj/item/storage/box/syndicate/bundle_a/PopulateContents()
@@ -44,7 +45,7 @@
new /obj/item/storage/box/syndie_kit/space(src) //4 tc
new /obj/item/grenade/frag(src) // ~2 tc each?
new /obj/item/grenade/frag(src)
new /obj/item/flashlight/emp(src)
new /obj/item/flashlight/emp(src) // 4 tc
if(KIT_BLOODY_SPAI)
new /obj/item/card/id/advanced/chameleon(src) // 2 tc
@@ -61,84 +62,86 @@
new /obj/item/chameleon(src) // 7 tc
if(KIT_STEALTHY)
new /obj/item/gun/energy/recharge/ebow(src)
new /obj/item/pen/sleepy(src)
new /obj/item/healthanalyzer/rad_laser(src)
new /obj/item/chameleon(src)
new /obj/item/soap/syndie(src)
new /obj/item/clothing/glasses/thermal/syndi(src)
new /obj/item/flashlight/emp(src)
new /obj/item/jammer(src)
new /obj/item/gun/energy/recharge/ebow(src) // 10 tc
new /obj/item/pen/sleepy(src) // 4 tc
new /obj/item/healthanalyzer/rad_laser(src) // 3 tc
new /obj/item/chameleon(src) // 7 tc
new /obj/item/soap/syndie(src) // 1 tc
new /obj/item/clothing/glasses/thermal/syndi(src) // 4 tc
new /obj/item/flashlight/emp(src) // 2 tc
new /obj/item/jammer(src) // 5 tc
if(KIT_GUN)
new /obj/item/gun/ballistic/revolver/syndicate(src)
new /obj/item/gun/ballistic/revolver/syndicate(src) // 13 tc
new /obj/item/ammo_box/a357(src) // 4tc
new /obj/item/ammo_box/a357(src)
new /obj/item/ammo_box/a357(src)
new /obj/item/card/emag(src)
new /obj/item/grenade/c4(src)
new /obj/item/clothing/gloves/color/latex/nitrile(src)
new /obj/item/storage/belt/holster/chameleon(src) // 1 tc
new /obj/item/card/emag/doorjack(src) // 3 tc replaced the emag with the doorjack
new /obj/item/grenade/c4(src) // 1 tc
new /obj/item/clothing/gloves/color/latex/nitrile(src) // ~1 tc for whole outfit
new /obj/item/clothing/mask/gas/clown_hat(src)
new /obj/item/clothing/under/suit/black_really(src)
new /obj/item/clothing/neck/tie/red/hitman(src)
if(KIT_SCREWED)
new /obj/item/sbeacondrop/bomb(src)
new /obj/item/grenade/syndieminibomb(src)
new /obj/item/sbeacondrop/powersink(src)
new /obj/item/clothing/suit/space/syndicate/black/red(src)
new /obj/item/sbeacondrop/bomb(src) // 11 tc
new /obj/item/grenade/syndieminibomb(src) // 6 tc
new /obj/item/sbeacondrop/powersink(src) // 11 tc
new /obj/item/clothing/suit/space/syndicate/black/red(src) // outfit 1 tc
new /obj/item/clothing/head/helmet/space/syndicate/black/red(src)
new /obj/item/encryptionkey/syndicate(src)
new /obj/item/encryptionkey/syndicate(src) // 2 tc
if(KIT_MURDER)
new /obj/item/melee/energy/sword/saber(src)
new /obj/item/clothing/glasses/thermal/syndi(src)
new /obj/item/card/emag(src)
new /obj/item/clothing/shoes/chameleon/noslip(src)
new /obj/item/encryptionkey/syndicate(src)
new /obj/item/grenade/syndieminibomb(src)
new /obj/item/melee/energy/sword/saber(src) // 8 tc
new /obj/item/clothing/glasses/thermal/syndi(src) // 4 tc
new /obj/item/card/emag/doorjack(src) // 3 tc
new /obj/item/clothing/shoes/chameleon/noslip(src) // 2 tc
new /obj/item/encryptionkey/syndicate(src) // 2 tc
new /obj/item/grenade/syndieminibomb(src) // 6 tc
if(KIT_IMPLANTS)
new /obj/item/implanter/freedom(src)
new /obj/item/implanter/uplink/precharged(src)
new /obj/item/implanter/emp(src)
new /obj/item/implanter/explosive(src)
new /obj/item/implanter/storage(src)
new /obj/item/implanter/freedom(src) // 5 tc
new /obj/item/implanter/uplink/precharged(src) // 10 tc is inside this thing
new /obj/item/implanter/emp(src) // 1 tc
new /obj/item/implanter/explosive(src) // 2 tc
new /obj/item/implanter/storage(src) // 8 tc
if(KIT_HACKER) //L-L--LOOK AT YOU, HACKER
new /obj/item/ai_module/syndicate(src)
new /obj/item/card/emag(src)
new /obj/item/encryptionkey/binary(src)
new /obj/item/ai_module/toy_ai(src)
new /obj/item/multitool/ai_detect(src)
new /obj/item/storage/toolbox/syndicate(src)
new /obj/item/camera_bug(src)
new /obj/item/clothing/glasses/thermal/syndi(src)
new /obj/item/card/id/advanced/chameleon(src)
new /obj/item/ai_module/syndicate(src) // 4 tc
new /obj/item/card/emag(src) // 4 tc
new /obj/item/card/emag/doorjack(src) // 3 tc
new /obj/item/encryptionkey/binary(src) // 5 tc
new /obj/item/ai_module/toy_ai(src) // ~6 tc
new /obj/item/multitool/ai_detect(src) // 1 tc
new /obj/item/storage/toolbox/syndicate(src) // 1 tc
new /obj/item/camera_bug(src) // 1 tc
new /obj/item/clothing/glasses/thermal/syndi(src) // 4 tc
new /obj/item/card/id/advanced/chameleon(src) // 2 tc
if(KIT_LORD_SINGULOTH) //can't loose the goose anymore without SM :(
new /obj/item/sbeacondrop(src)
if(KIT_LORD_SINGULOTH) //currently disabled, i might return with another anti-engine kit
new /obj/item/sbeacondrop(src) // 10 tc
new /obj/item/clothing/suit/space/syndicate/black/red(src)
new /obj/item/clothing/head/helmet/space/syndicate/black/red(src)
new /obj/item/card/emag(src)
new /obj/item/storage/toolbox/syndicate(src)
new /obj/item/card/emag(src) // 4 tc
new /obj/item/storage/toolbox/syndicate(src) // 1 tc
new /obj/item/card/id/advanced/mining(src)
new /obj/item/stack/spacecash/c10000(src)
new /obj/item/stack/spacecash/c10000(src) // this is technically 10 tc but not really
new /obj/item/toy/spinningtoy(src) //lol
if(KIT_SABOTAGE)
/obj/item/storage/backpack/duffelbag/syndie/sabotage
new /obj/item/camera_bug(src)
new /obj/item/sbeacondrop/powersink(src)
new /obj/item/computer_disk/virus/detomatix(src)
new /obj/item/storage/toolbox/syndicate(src)
new /obj/item/pizzabox/bomb(src)
new /obj/item/storage/box/syndie_kit/emp(src)
new /obj/item/storage/backpack/duffelbag/syndie/sabotage(src) // 5 tc for 3 c4 and 2 x4
new /obj/item/camera_bug(src) // 1 tc
new /obj/item/sbeacondrop/powersink(src) // 11 tc
new /obj/item/computer_disk/virus/detomatix(src) // 6 tc
new /obj/item/storage/toolbox/syndicate(src) // 1 tc
new /obj/item/pizzabox/bomb(src) // 6 tc
new /obj/item/storage/box/syndie_kit/emp(src) // 2 tc
if(KIT_SNIPER) //This shit is unique so can't really balance it around tc, also no silencer because getting killed without ANY indicator on what killed you sucks
new /obj/item/gun/ballistic/automatic/sniper_rifle(src) // 12 tc
new /obj/item/ammo_box/magazine/sniper_rounds/penetrator(src)
new /obj/item/clothing/glasses/thermal/syndi(src)
new /obj/item/clothing/gloves/color/latex/nitrile(src)
new /obj/item/ammo_box/magazine/sniper_rounds/penetrator(src) // 5 tc
new /obj/item/clothing/glasses/thermal/syndi(src) // 4 tc
new /obj/item/clothing/gloves/color/latex/nitrile(src) // ~ 1 tc for outfit
new /obj/item/clothing/mask/gas/clown_hat(src)
new /obj/item/clothing/under/suit/black_really(src)
new /obj/item/clothing/neck/tie/red/hitman(src)
@@ -166,31 +169,40 @@
KIT_TRAITOR_2006 = 1
)))
if(KIT_JAMES_BOND)
new /obj/item/gun/ballistic/automatic/pistol(src)
new /obj/item/suppressor(src)
new /obj/item/gun/ballistic/automatic/pistol(src) // 7 tc
new /obj/item/suppressor(src) // 3 tc
new /obj/item/ammo_box/magazine/m9mm(src) // 1 tc
new /obj/item/ammo_box/magazine/m9mm(src)
new /obj/item/ammo_box/magazine/m9mm(src)
new /obj/item/card/id/advanced/chameleon(src)
new /obj/item/clothing/under/chameleon(src)
new /obj/item/reagent_containers/hypospray/medipen/stimulants(src)
new /obj/item/card/id/advanced/chameleon(src) // 2 tc
new /obj/item/clothing/under/chameleon(src) // 1 tc
new /obj/item/reagent_containers/hypospray/medipen/stimulants(src) // 5 tc
new /obj/item/reagent_containers/cup/rag(src)
new /obj/item/implanter/freedom(src) // 5 tc
new /obj/item/flashlight/emp(src) // 2 tc
new /obj/item/grenade/c4/x4(src) // 1ish tc
new /obj/item/reagent_containers/pill/cyanide(src)
new /obj/item/toy/cards/deck/syndicate(src) // 1 tc, for poker
if(KIT_NINJA)
new /obj/item/katana(src) // Unique , hard to tell how much tc this is worth. 8 tc?
new /obj/item/reagent_containers/hypospray/medipen/stimulants(src) // 5 tc
for(var/i in 1 to 6)
new /obj/item/throwing_star(src) // ~5 tc for all 6
new /obj/item/storage/belt/chameleon(src) // Unique but worth at least 2 tc
new /obj/item/throwing_star(src) // 1 tc
new /obj/item/storage/belt/chameleon(src) // worth some fraction of a tc
new /obj/item/chameleon(src) // 7 tc
new /obj/item/card/id/advanced/chameleon(src) // 2 tc
new /obj/item/card/emag/doorjack(src) // 3 tc
new /obj/item/book/granter/action/spell/smoke(src) // ninja smoke bomb. 1 tc
new /obj/item/clothing/shoes/bhop(src) // mining item, lets you jump at people, at least 2 tc
if(KIT_DARK_LORD)
new /obj/item/dualsaber(src)
new /obj/item/dnainjector/telemut/darkbundle(src)
new /obj/item/dualsaber/red(src) // 16 tc
new /obj/item/dnainjector/telemut/darkbundle(src) // ~ 4 tc for tk
new /obj/item/clothing/suit/hooded/chaplain_hoodie(src)
new /obj/item/card/id/advanced/chameleon(src)
new /obj/item/clothing/shoes/chameleon/noslip(src) //because slipping while being a dark lord sucks
new /obj/item/book/granter/action/spell/summonitem(src)
new /obj/item/card/id/advanced/chameleon(src) // 2 tc
new /obj/item/clothing/shoes/chameleon/noslip(src) //2 tc ,because slipping while being a dark lord sucks
new /obj/item/book/granter/action/spell/summonitem(src) // ~2 tc
new /obj/item/book/granter/action/spell/lightningbolt(src) // 4 tc
if(KIT_WHITE_WHALE_HOLY_GRAIL) //Unique items that don't appear anywhere else
new /obj/item/gun/ballistic/rifle/boltaction/harpoon(src)
@@ -198,6 +210,7 @@
new /obj/item/clothing/suit/hooded/carp_costume/spaceproof(src)
new /obj/item/clothing/mask/gas/carp(src)
new /obj/item/grenade/spawnergrenade/spesscarp(src)
new /obj/item/toy/plush/carpplushie/dehy_carp(src) // 1 tc, for use as a personal mount
if(KIT_MAD_SCIENTIST)
new /obj/item/clothing/suit/toggle/labcoat/mad(src) // 0 tc
@@ -211,17 +224,17 @@
new /obj/item/assembly/signaler(src) // 0 tc
new /obj/item/assembly/signaler(src) // 0 tc
new /obj/item/storage/toolbox/syndicate(src) // 1 tc
new /obj/item/pen/edagger(src)
new /obj/item/gun/energy/wormhole_projector/core_inserted(src)
new /obj/item/gun/energy/decloner/unrestricted(src)
new /obj/item/pen/edagger(src) // 2 tc
new /obj/item/gun/energy/wormhole_projector/core_inserted(src) // 5 tc easily
new /obj/item/gun/energy/decloner/unrestricted(src) // 5 tc at least also
if(KIT_BEES)
new /obj/item/paper/fluff/bee_objectives(src) // 0 tc (motivation)
new /obj/item/clothing/suit/hooded/bee_costume(src) // 0 tc
new /obj/item/clothing/mask/animal/small/bee(src) // 0 tc
new /obj/item/storage/belt/fannypack/yellow(src) // 0 tc
new /obj/item/grenade/spawnergrenade/buzzkill(src)
new /obj/item/grenade/spawnergrenade/buzzkill(src)
new /obj/item/grenade/spawnergrenade/buzzkill(src) // these are the random super bees this is definitely all of the tc budget for this one
new /obj/item/grenade/spawnergrenade/buzzkill(src) // 10 tc per grenade
new /obj/item/reagent_containers/cup/bottle/beesease(src) // 10 tc?
new /obj/item/melee/beesword(src) //priceless
@@ -231,14 +244,15 @@
new /obj/item/clothing/mask/chameleon(src)
new /obj/item/clothing/suit/hooded/wintercoat(src)
new /obj/item/clothing/shoes/winterboots(src)
new /obj/item/grenade/gluon(src) // whole belt is 22 and gluon is weight 4 so lets just go with like 7 total
new /obj/item/grenade/gluon(src)
new /obj/item/grenade/gluon(src)
new /obj/item/grenade/gluon(src)
new /obj/item/grenade/gluon(src)
new /obj/item/dnainjector/geladikinesis(src)
new /obj/item/dnainjector/geladikinesis(src) // both abilities are probably 3 tc total
new /obj/item/dnainjector/cryokinesis(src)
new /obj/item/gun/energy/temperature/security(src)
new /obj/item/melee/energy/sword/saber/blue(src) //see see it fits the theme bc its blue and ice is blue
new /obj/item/gun/energy/temperature/freeze(src) // ~6 tc
new /obj/item/gun/energy/laser/thermal/cryo(src) // ~6 tc
new /obj/item/melee/energy/sword/saber/blue(src) //see see it fits the theme bc its blue and ice is blue, 8 tc
if(KIT_TRAITOR_2006) //A kit so old, it's probably older than you. //This bundle is filled with the entire unlink contents traitors had access to in 2006, from OpenSS13. Notably the esword was not a choice but existed in code.
new /obj/item/storage/toolbox/emergency/old/ancientbundle(src) //Items fit neatly into a classic toolbox just to remind you what the theme is.
@@ -246,12 +260,13 @@
/obj/item/storage/toolbox/emergency/old/ancientbundle/ //So the subtype works
/obj/item/storage/toolbox/emergency/old/ancientbundle/PopulateContents()
new /obj/item/card/emag(src)
new /obj/item/pen/sleepy(src)
new /obj/item/card/emag(src) // 4 tc
new /obj/item/card/emag/doorjack(src) //emag used to do both. 3 tc
new /obj/item/pen/sleepy(src) // 4 tc
new /obj/item/reagent_containers/pill/cyanide(src)
new /obj/item/chameleon(src) //its not the original cloaking device, but it will do.
new /obj/item/gun/ballistic/revolver/syndicate(src)
new /obj/item/implanter/freedom(src)
new /obj/item/chameleon(src) //its not the original cloaking device, but it will do. 8 tc
new /obj/item/gun/ballistic/revolver(src) // 13 tc old one stays in the old box
new /obj/item/implanter/freedom(src) // 5 tc
new /obj/item/stack/telecrystal(src) //The failsafe/self destruct isn't an item we can physically include in the kit, but 1 TC is technically enough to buy the equivalent.
/obj/item/storage/box/syndicate/contract_kit //SKYRAT EDIT - CHANGED IN MODULAR FOLDER
@@ -0,0 +1,76 @@
/obj/structure/closet/crate/syndicrate
name = "surplus syndicrate"
desc = "A conspicuous crate with the Syndicate logo on it. You don't know how to open it."
icon_state = "syndicrate"
max_integrity = 500
armor = list(MELEE = 30, BULLET = 50, LASER = 50, ENERGY = 100, BOMB = 0, BIO = 0)
resistance_flags = FIRE_PROOF | ACID_PROOF
integrity_failure = 0 //prevents bust_open from activating
/// variable that only lets the crate open if opened by a key from the uplink
var/created_items = FALSE
/// this is what will spawn when it is opened with a syndicrate key
var/list/unlock_contents = list()
/// if the crate takes damage it will explode 25% of the time
/obj/structure/closet/crate/syndicrate/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1)
if(created_items)
return ..()
if(damage_amount < DAMAGE_PRECISION)
return ..()
if(prob(75))
return ..()
visible_message(span_danger("The syndicrate's anti-tamper system activates!"))
explosion(src, heavy_impact_range = 1, light_impact_range = 2, flash_range = 2)
qdel(src)
///ensures that the syndicrate can only be unlocked by opening it with a syndicrate_key
/obj/structure/closet/crate/syndicrate/attackby(obj/item/item, mob/user, params)
if(!istype(item, /obj/item/syndicrate_key) || created_items)
return ..()
created_items = TRUE
for(var/item_path as anything in unlock_contents)
new item_path(src)
unlock_contents = list()
qdel(item)
to_chat(user, span_notice("You twist the key into both locks at once, opening the crate."))
playsound(src, 'sound/machines/boltsup.ogg', 50, vary = FALSE)
update_appearance(updates = UPDATE_OVERLAYS)
togglelock(user)
/obj/structure/closet/crate/syndicrate/attackby_secondary(obj/item/weapon, mob/user, params)
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
///overwrites default opening behavior until it is unlocked via the syndicrate key
/obj/structure/closet/crate/syndicrate/can_open(mob/living/user, force = FALSE)
if(!created_items)
balloon_alert(user, "Locked!")
return FALSE
return ..()
///syndicrate has a unique overlay for being unlocked
/obj/structure/closet/crate/syndicrate/closet_update_overlays(list/new_overlays)
. = new_overlays
if(created_items)
. += "syndicrate_unlocked"
/obj/item/syndicrate_key
name = "syndicrate key"
desc = "A device bearing a serpentine emblem, capable of splitting itself into two keys. Can be used to open one syndicrate."
icon = 'icons/obj/storage/crates.dmi'
icon_state = "syndicrate_key"
w_class = WEIGHT_CLASS_TINY
/obj/item/syndicrate_key/Initialize(mapload)
. = ..()
register_item_context()
/obj/item/add_item_context(obj/item/source, list/context, atom/target, mob/living/user,)
. = ..()
var/obj/structure/closet/crate/syndicrate/target_structure = target
if(!istype(target_structure))
return NONE
if(target_structure.created_items)
return NONE
context[SCREENTIP_CONTEXT_LMB] = "Unlock Syndicrate"
return CONTEXTUAL_SCREENTIP_SET
@@ -16,8 +16,8 @@
var/progression_points = 0
/// The purchase log of this uplink handler
var/datum/uplink_purchase_log/purchase_log
/// Associative array of uplink item = stock left
var/list/item_stock = list()
/// Associative array of stock keys = stock left. For items that don't share stock, the key is their typepath
var/list/item_stock = list(UPLINK_SHARED_STOCK_KITS = 1 , UPLINK_SHARED_STOCK_SURPLUS = 1)
/// Extra stuff that can be purchased by an uplink, regardless of flag.
var/list/extra_purchasable = list()
/// Whether this uplink handler has objectives.
@@ -56,22 +56,32 @@
SEND_SIGNAL(src, COMSIG_UPLINK_HANDLER_ON_UPDATE)
return
/// Checks if traitor has enough reputation to purchase an item
/datum/uplink_handler/proc/not_enough_reputation(datum/uplink_item/to_purchase)
return has_progression && progression_points < to_purchase.progression_minimum
/// Checks for uplink flags as well as items restricted to roles and species
/datum/uplink_handler/proc/check_if_restricted(datum/uplink_item/to_purchase)
if((to_purchase in extra_purchasable))
return TRUE
if(!(to_purchase.purchasable_from & uplink_flag))
return FALSE
if(length(to_purchase.restricted_roles) && !(assigned_role in to_purchase.restricted_roles))
return FALSE
if(length(to_purchase.restricted_species) && !(assigned_species in to_purchase.restricted_species))
return FALSE
return TRUE
/datum/uplink_handler/proc/can_purchase_item(mob/user, datum/uplink_item/to_purchase)
if(debug_mode)
return TRUE
if(!(to_purchase in extra_purchasable))
if(!(to_purchase.purchasable_from & uplink_flag))
return FALSE
if(!check_if_restricted(to_purchase))
return FALSE
if(length(to_purchase.restricted_roles) && !(assigned_role in to_purchase.restricted_roles))
return FALSE
if(length(to_purchase.restricted_species) && !(assigned_species in to_purchase.restricted_species))
return FALSE
var/current_stock = item_stock[to_purchase]
var/current_stock = item_stock[to_purchase.stock_key]
var/stock = current_stock != null? current_stock : INFINITY
if(telecrystals < to_purchase.cost || stock <= 0 || (has_progression && progression_points < to_purchase.progression_minimum))
if(telecrystals < to_purchase.cost || stock <= 0 || not_enough_reputation(to_purchase))
return FALSE
return TRUE
@@ -80,14 +90,14 @@
if(!can_purchase_item(user, to_purchase))
return
if(to_purchase.limited_stock != -1 && !(to_purchase in item_stock))
item_stock[to_purchase] = to_purchase.limited_stock
if(to_purchase.limited_stock != -1 && !(to_purchase.stock_key in item_stock))
item_stock[to_purchase.stock_key] = to_purchase.limited_stock
telecrystals -= to_purchase.cost
to_purchase.purchase(user, src, source)
if(to_purchase in item_stock)
item_stock[to_purchase] -= 1
if(to_purchase.stock_key in item_stock)
item_stock[to_purchase.stock_key] -= 1
SSblackbox.record_feedback("nested tally", "traitor_uplink_items_bought", 1, list("[initial(to_purchase.name)]", "[to_purchase.cost]"))
on_update()
@@ -28,6 +28,7 @@
"purchasable_from" = item.purchasable_from,
"restricted" = item.restricted,
"limited_stock" = item.limited_stock,
"stock_key" = item.stock_key,
"restricted_roles" = item.restricted_roles,
"restricted_species" = item.restricted_species,
"progression_minimum" = item.progression_minimum,
+5 -2
View File
@@ -256,11 +256,12 @@
/datum/supply_pack/misc/syndicate
name = "Assorted Syndicate Gear"
desc = "Contains a random assortment of syndicate gear."
special = TRUE ///Cannot be ordered via cargo
special = TRUE //Cannot be ordered via cargo
contains = list()
crate_name = "syndicate gear crate"
crate_type = /obj/structure/closet/crate
var/crate_value = 30 ///Total TC worth of contained uplink items
///Total TC worth of contained uplink items
var/crate_value = 30
var/uplink_flag = UPLINK_TRAITORS
///Generate assorted uplink items, taking into account the same surplus modifiers used for surplus crates
@@ -275,6 +276,8 @@
var/datum/uplink_item/uplink_item = pick(uplink_items)
if(!uplink_item.surplus || prob(100 - uplink_item.surplus))
continue
if(length(uplink_item.restricted_roles) || length(uplink_item.restricted_species))
continue
if(crate_value < uplink_item.cost)
continue
crate_value -= uplink_item.cost
@@ -338,6 +338,12 @@
desc = "A weapon that can only be used to its full potential by the truly robust."
pin = /obj/item/firing_pin
/obj/item/gun/energy/temperature/freeze
name = "cryogenic temperature gun"
desc = "A gun that reduces temperatures. Only for those with ice in their veins."
pin = /obj/item/firing_pin
ammo_type = list(/obj/item/ammo_casing/energy/temp)
/obj/item/gun/energy/gravity_gun
name = "one-point gravitational manipulator"
desc = "An experimental, multi-mode device that fires bolts of Zero-Point Energy, causing local distortions in gravity. Requires a gravitational anomaly core to function."
@@ -67,6 +67,7 @@ GLOBAL_LIST_INIT(summoned_magic, list(
/obj/item/book/granter/action/spell/barnyard,
/obj/item/book/granter/action/spell/charge,
/obj/item/book/granter/action/spell/summonitem,
/obj/item/book/granter/action/spell/lightningbolt,
/obj/item/gun/magic/wand/nothing,
/obj/item/gun/magic/wand/death,
/obj/item/gun/magic/wand/resurrection,
+11
View File
@@ -46,6 +46,8 @@
var/surplus = 100
/// Whether this can be discounted or not
var/cant_discount = FALSE
/// If this value is changed on two items they will share stock, defaults to not sharing stock with any other item
var/stock_key = UPLINK_SHARED_STOCK_UNIQUE
/// How many items of this stock can be purchased.
var/limited_stock = -1 //Setting this above zero limits how many times this item can be bought by the same traitor in a round, -1 is unlimited
/// A bitfield to represent what uplinks can purchase this item.
@@ -66,6 +68,12 @@
// String to be shown instead of the price, e.g for the Random item.
var/cost_override_string = ""
/datum/uplink_item/New()
. = ..()
if(stock_key != UPLINK_SHARED_STOCK_UNIQUE)
return
stock_key = type
/datum/uplink_category
/// Name of the category
var/name
@@ -125,3 +133,6 @@
..()
if(user?.mind?.failed_special_equipment)
user.mind.failed_special_equipment -= item
/// Code that enables the ability to have limited stock that is shared by different items
/datum/shared_uplink_stock
+123
View File
@@ -51,3 +51,126 @@
desc = "Twenty telecrystals in their rawest and purest form; can be utilized on active uplinks to increase their telecrystal count."
item = /obj/item/stack/telecrystal/twenty
cost = 20
/datum/uplink_item/bundles_tc/bundle_a
name = "Syndi-kit Tactical"
desc = "Syndicate Bundles, also known as Syndi-Kits, are specialized groups of items that arrive in a plain box. \
These items are collectively worth more than 25 telecrystals, but you do not know which specialization \
you will receive. May contain discontinued and/or exotic items. \
The Syndicate will only provide one Syndi-Kit per agent."
progression_minimum = 30 MINUTES
item = /obj/item/storage/box/syndicate/bundle_a
cost = 25
stock_key = UPLINK_SHARED_STOCK_KITS
purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS)
/datum/uplink_item/bundles_tc/bundle_b
name = "Syndi-kit Special"
desc = "Syndicate Bundles, also known as Syndi-Kits, are specialized groups of items that arrive in a plain box. \
In Syndi-kit Special, you will receive items used by famous syndicate agents of the past. \
Collectively worth more than 25 telecrystals, the syndicate loves a good throwback. \
The Syndicate will only provide one Syndi-Kit per agent."
progression_minimum = 30 MINUTES
item = /obj/item/storage/box/syndicate/bundle_b
cost = 25
stock_key = UPLINK_SHARED_STOCK_KITS
purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS)
/datum/uplink_item/bundles_tc/surplus
name = "Syndicate Surplus Crate"
desc = "A dusty crate from the back of the Syndicate warehouse delivered directly to you via Supply Pod. \
If the rumors are true, it will fill it's contents based on your current reputation. Get on that grind. \
Contents are sorted to always be worth 30 TC. The Syndicate will only provide one surplus item per agent."
item = /obj/structure/closet/crate // will be replaced in purchase()
cost = 20
purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS)
stock_key = UPLINK_SHARED_STOCK_SURPLUS
/// Value of items inside the crate in TC
var/crate_tc_value = 30
/// crate that will be used for the surplus crate
var/crate_type = /obj/structure/closet/crate
/// generates items that can go inside crates, edit this proc to change what items could go inside your specialized crate
/datum/uplink_item/bundles_tc/surplus/proc/generate_possible_items(mob/user, datum/uplink_handler/handler)
var/list/possible_items = list()
for(var/datum/uplink_item/item_path as anything in SStraitor.uplink_items_by_type)
var/datum/uplink_item/uplink_item = SStraitor.uplink_items_by_type[item_path]
if(src == uplink_item || !uplink_item.item)
continue
if(!handler.check_if_restricted(uplink_item))
continue
if(!uplink_item.surplus)
continue
if(handler.not_enough_reputation(uplink_item))
continue
possible_items += uplink_item
return possible_items
/// picks items from the list given to proc and generates a valid uplink item that is less or equal to the amount of TC it can spend
/datum/uplink_item/bundles_tc/surplus/proc/pick_possible_item(list/possible_items, tc_budget)
var/datum/uplink_item/uplink_item = pick(possible_items)
if(prob(100 - uplink_item.surplus))
return null
if(tc_budget < uplink_item.cost)
return null
return uplink_item
/// fills the crate that will be given to the traitor, edit this to change the crate and how the item is filled
/datum/uplink_item/bundles_tc/surplus/proc/fill_crate(obj/structure/closet/crate/surplus_crate, list/possible_items)
var/tc_budget = crate_tc_value
while(tc_budget)
var/datum/uplink_item/uplink_item = pick_possible_item(possible_items, tc_budget)
if(!uplink_item)
continue
tc_budget -= uplink_item.cost
new uplink_item.item(surplus_crate)
/// overwrites purchase for surplus items to instead spawn this crate and run the previous procs
/datum/uplink_item/bundles_tc/surplus/purchase(mob/user, datum/uplink_handler/handler, atom/movable/source)
var/obj/structure/closet/crate/surplus_crate = new crate_type()
if(!istype(surplus_crate))
CRASH("crate_type is not a crate")
var/list/possible_items = generate_possible_items(user, handler)
fill_crate(surplus_crate, possible_items)
podspawn(list(
"target" = get_turf(user),
"style" = STYLE_SYNDICATE,
"spawn" = surplus_crate,
))
/datum/uplink_item/bundles_tc/surplus/united
name = "United Surplus Crate"
desc = "A shiny and large crate to be delivered directly to you via Supply Pod. It has an advanced locking mechanism with an anti-tampering protocol. \
It is recommended that you only attempt to open it by having another agent purchase a Surplus Crate Key. Unite and fight. \
Rumored to contain a valuable assortment of items based on your current reputation, but you never know. Contents are sorted to always be worth 80 TC. \
The Syndicate will only provide one surplus item per agent."
cost = 20
item = /obj/structure/closet/crate/syndicrate
progression_minimum = 30 MINUTES
stock_key = UPLINK_SHARED_STOCK_SURPLUS
crate_tc_value = 80
crate_type = /obj/structure/closet/crate/syndicrate
/// edited version of fill crate for super surplus to ensure it can only be unlocked with the syndicrate key
/datum/uplink_item/bundles_tc/surplus/united/fill_crate(obj/structure/closet/crate/syndicrate/surplus_crate, list/possible_items)
if(!istype(surplus_crate))
return
var/tc_budget = crate_tc_value
while(tc_budget)
var/datum/uplink_item/uplink_item = pick_possible_item(possible_items, tc_budget)
if(!uplink_item)
continue
tc_budget -= uplink_item.cost
surplus_crate.unlock_contents += uplink_item.item
/datum/uplink_item/bundles_tc/surplus_key
name = "United Surplus Crate Key"
desc = "This inconscpicous device is actually a key that can open any United Surplus Crate. It can only be used once. \
Though initially designed to encourage cooperation, agents quickly discovered that you can turn the key to the crate by yourself. \
The Syndicate will only provide one surplus item per agent."
cost = 20
item = /obj/item/syndicrate_key
progression_minimum = 30 MINUTES
stock_key = UPLINK_SHARED_STOCK_SURPLUS
@@ -252,6 +252,7 @@
progression_minimum = 30 MINUTES
item = /obj/item/sbeacondrop
cost = 10
surplus = 0 // not while there isnt one on any station
purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS)
/datum/uplink_item/device_tools/powersink
+15 -4
View File
@@ -7,7 +7,6 @@
/datum/uplink_item/role_restricted
category = /datum/uplink_category/role_restricted
purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS)
surplus = 0
// No progression cost
/datum/uplink_item/role_restricted/haunted_magic_eightball
@@ -18,6 +17,7 @@
cost = 2
restricted_roles = list(JOB_CURATOR)
limited_stock = 1 //please don't spam deadchat
surplus = 5
/datum/uplink_item/role_restricted/bureaucratic_error_remote
name = "Organic Resources Disturbance Inducer"
@@ -26,6 +26,7 @@
limited_stock = 1
item = /obj/item/devices/bureaucratic_error_remote
restricted_roles = list(JOB_HEAD_OF_PERSONNEL, JOB_QUARTERMASTER)
surplus = 5
/datum/uplink_item/role_restricted/clumsinessinjector //clown ops can buy this too, but it's in the pointless badassery section for them
name = "Clumsiness Injector"
@@ -34,6 +35,7 @@
cost = 1
restricted_roles = list(JOB_CLOWN)
illegal_tech = FALSE
surplus = 25
/datum/uplink_item/role_restricted/ancient_jumpsuit
name = "Ancient Jumpsuit"
@@ -61,6 +63,7 @@
item = /obj/item/firing_pin/clown/ultra
restricted_roles = list(JOB_CLOWN)
illegal_tech = FALSE
surplus = 25
/datum/uplink_item/role_restricted/clownsuperpin
name = "Super Ultra Hilarious Firing Pin"
@@ -70,6 +73,7 @@
item = /obj/item/firing_pin/clown/ultra/selfdestruct
restricted_roles = list(JOB_CLOWN)
illegal_tech = FALSE
surplus = 25
/datum/uplink_item/role_restricted/syndimmi
name = "Syndicate Brand MMI"
@@ -87,7 +91,6 @@
progression_minimum = 10 MINUTES
item = /obj/item/hot_potato/syndicate
cost = 4
surplus = 0
restricted_roles = list(JOB_COOK, JOB_BOTANIST, JOB_CLOWN, JOB_MIME)
/datum/uplink_item/role_restricted/combat_baking
@@ -171,6 +174,7 @@
item = /obj/item/disk/surgery/brainwashing
restricted_roles = list(JOB_MEDICAL_DOCTOR, JOB_CHIEF_MEDICAL_OFFICER, JOB_ROBOTICIST)
cost = 5
surplus = 50
/datum/uplink_item/role_restricted/springlock_module
name = "Heavily Modified Springlock MODsuit Module"
@@ -183,6 +187,7 @@
item = /obj/item/mod/module/springlock/bite_of_87
restricted_roles = list(JOB_ROBOTICIST, JOB_RESEARCH_DIRECTOR)
cost = 2
surplus = 15
/datum/uplink_item/role_restricted/reverse_revolver
name = "Reverse Revolver"
@@ -202,6 +207,7 @@
cost = 5 //you need two for full damage, so total of 10 for maximum damage
limited_stock = 2 //you can't use more than two!
restricted_roles = list("Shaft Miner")
surplus = 20
/datum/uplink_item/role_restricted/mimery
name = "Guide to Advanced Mimery Series"
@@ -220,6 +226,7 @@
cost = 10
item = /obj/item/autosurgeon/syndicate/laser_arm
restricted_roles = list(JOB_ROBOTICIST, JOB_RESEARCH_DIRECTOR)
surplus = 20
/datum/uplink_item/role_restricted/chemical_gun
name = "Reagent Dartgun"
@@ -236,7 +243,6 @@
cost = 10
item = /obj/item/pneumatic_cannon/pie/selfcharge
restricted_roles = list(JOB_CLOWN)
surplus = 0 //No fun unless you're the clown!
/datum/uplink_item/role_restricted/clown_bomb
name = "Clown Bomb"
@@ -249,6 +255,7 @@
item = /obj/item/sbeacondrop/clownbomb
cost = 15
restricted_roles = list(JOB_CLOWN)
surplus = 10
/datum/uplink_item/role_restricted/clown_bomb/New()
. = ..()
@@ -266,6 +273,7 @@
item = /obj/vehicle/sealed/car/clowncar
cost = 20
restricted_roles = list(JOB_CLOWN)
surplus = 10
/datum/uplink_item/role_restricted/concealed_weapon_bay
name = "Concealed Weapon Bay"
@@ -277,6 +285,7 @@
item = /obj/item/mecha_parts/mecha_equipment/concealed_weapon_bay
cost = 3
restricted_roles = list(JOB_ROBOTICIST, JOB_RESEARCH_DIRECTOR)
surplus = 15
/* //SKYRAT REMOVAL START
/datum/uplink_item/role_restricted/his_grace
@@ -289,7 +298,7 @@
item = /obj/item/his_grace
cost = 20
restricted_roles = list(JOB_CHAPLAIN)
surplus = 5 //Very low chance to get it in a surplus crate even without being the chaplain
surplus = 5
*/ //SKYRAT REMOVAL END
// High progression cost
@@ -306,6 +315,7 @@
item = /obj/item/reagent_containers/syringe/spider_extract
cost = 10
restricted_roles = list(JOB_RESEARCH_DIRECTOR, JOB_SCIENTIST, JOB_ROBOTICIST)
surplus = 10
*/
// SKYRAT EDIT END
@@ -319,3 +329,4 @@
item = /obj/item/gun/blastcannon
cost = 14 //High cost because of the potential for extreme damage in the hands of a skilled scientist.
restricted_roles = list(JOB_RESEARCH_DIRECTOR, JOB_SCIENTIST)
surplus = 5
+1 -1
View File
@@ -5,7 +5,6 @@
/datum/uplink_item/species_restricted
category = /datum/uplink_category/species
purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS)
surplus = 0
/datum/uplink_item/species_restricted/moth_lantern
name = "Extra-Bright Lantern"
@@ -14,3 +13,4 @@
cost = 2
item = /obj/item/flashlight/lantern/syndicate
restricted_species = list(SPECIES_MOTH)
surplus = 0
Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 27 KiB

@@ -1,6 +1,9 @@
/obj/structure/closet/crate
icon = 'modular_skyrat/modules/aesthetics/crates/icons/crates.dmi'
/obj/structure/closet/crate/syndicrate
icon = 'icons/obj/storage/crates.dmi'
/obj/item/delivery
icon = 'modular_skyrat/modules/aesthetics/crates/icons/crates.dmi'
@@ -15,38 +15,8 @@
cost = 20
purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS)
/datum/uplink_item/bundles_tc/surplus_crate
name = "Surplus Crate"
desc = "A dusty crate from the back of the Syndicate warehouse. Rumored to contain a valuable assortment of items, \
but you never know. Contents are sorted to always be worth 50 TC."
item = /obj/effect/gibspawner/generic
cost = 20
/// The contents of the surplus crate will be equal to this var in TC
var/telecrystal_count = 50
/datum/uplink_item/bundles_tc/surplus
crate_tc_value = 50
/datum/uplink_item/bundles_tc/surplus_crate/spawn_item(spawn_path, mob/user, datum/uplink_handler/uplink_handler, atom/movable/source)
telecrystal_count = initial(telecrystal_count)
var/list/uplink_items = list()
var/obj/structure/closet/crate/holder_crate = new(get_turf(user))
for(var/datum/uplink_item/item_path as anything in SStraitor.uplink_items_by_type)
var/datum/uplink_item/item = SStraitor.uplink_items_by_type[item_path]
if(item.purchasable_from & UPLINK_TRAITORS)
uplink_items += item
while(telecrystal_count)
var/datum/uplink_item/uplink_item = pick(uplink_items)
if(!uplink_item.surplus || prob(100 - uplink_item.surplus))
continue
if(telecrystal_count < uplink_item.cost)
continue
if(!uplink_item.item)
continue
telecrystal_count -= uplink_item.cost
new uplink_item.item(holder_crate)
/datum/uplink_item/bundles_tc/surplus_crate/super
name = "Super Surplus Crate"
desc = "A dusty SUPER-SIZED crate from the back of the Syndicate warehouse. Rumored to contain a valuable assortment of items, \
but you never know. Contents are sorted to always be worth 125 TC."
telecrystal_count = 125
cost = 40
/datum/uplink_item/bundles_tc/surplus/united
crate_tc_value = 125
+2
View File
@@ -1901,6 +1901,7 @@
#include "code\game\objects\items\granters\magic\fireball.dm"
#include "code\game\objects\items\granters\magic\forcewall.dm"
#include "code\game\objects\items\granters\magic\knock.dm"
#include "code\game\objects\items\granters\magic\lightning_bolt.dm"
#include "code\game\objects\items\granters\magic\mime.dm"
#include "code\game\objects\items\granters\magic\mindswap.dm"
#include "code\game\objects\items\granters\magic\sacred_flame.dm"
@@ -2125,6 +2126,7 @@
#include "code\game\objects\structures\crates_lockers\crates\critter.dm"
#include "code\game\objects\structures\crates_lockers\crates\large.dm"
#include "code\game\objects\structures\crates_lockers\crates\secure.dm"
#include "code\game\objects\structures\crates_lockers\crates\syndicrate.dm"
#include "code\game\objects\structures\crates_lockers\crates\wooden.dm"
#include "code\game\objects\structures\icemoon\cave_entrance.dm"
#include "code\game\objects\structures\lavaland\geyser.dm"
@@ -19,6 +19,7 @@ type UplinkItem = {
purchasable_from: number;
restricted: BooleanLike;
limited_stock: number;
stock_key: string;
restricted_roles: string;
restricted_species: string;
progression_minimum: number;
@@ -187,7 +188,7 @@ export class Uplink extends Component<{}, UplinkState> {
const hasEnoughProgression =
progression_points >= item.progression_minimum;
let stock: number | null = current_stock[item.id];
let stock: number | null = current_stock[item.stock_key];
if (item.ref) {
stock = extra_purchasable_stock[item.ref];
}