Fucky wucky gateway and ccslab

This commit is contained in:
Artur
2020-04-27 10:43:08 +03:00
parent f97f264fb7
commit 5d53ead547
9 changed files with 173 additions and 65 deletions
@@ -25,6 +25,9 @@
/datum/clockwork_scripture/ranged_ability/kindle, /datum/clockwork_scripture/ranged_ability/hateful_manacles) //quickbound scripture, accessed by index
var/maximum_quickbound = 5 //how many quickbound scriptures we can have
var/ui_x = 800
var/ui_z = 420
var/obj/structure/destructible/clockwork/trap/linking //If we're linking traps together, which ones we're doing
/obj/item/clockwork/slab/internal //an internal motor for mobs running scripture
@@ -165,18 +168,19 @@
user.emote("scream")
user.apply_damage(5, BURN, BODY_ZONE_L_ARM)
user.apply_damage(5, BURN, BODY_ZONE_R_ARM)
return 0
return FALSE
if(!is_servant_of_ratvar(user))
to_chat(user, "<span class='warning'>The information on [src]'s display shifts rapidly. After a moment, your head begins to pound, and you tear your eyes away.</span>")
user.confused += 5
user.dizziness += 5
return 0
if(user.confused || user.dizziness) //We dont want this to stack.
user.confused += 5
user.dizziness += 5
return FALSE
if(busy)
to_chat(user, "<span class='warning'>[src] refuses to work, displaying the message: \"[busy]!\"</span>")
return 0
return FALSE
if(!no_cost && !can_recite_scripture(user))
to_chat(user, "<span class='nezbere'>[src] hums fitfully in your hands, but doesn't seem to do anything...</span>")
return 0
return FALSE
access_display(user)
/obj/item/clockwork/slab/AltClick(mob/living/user)
@@ -195,11 +199,9 @@
/obj/item/clockwork/slab/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.inventory_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "clockwork_slab", name, 800, 420, master_ui, state)
ui.set_autoupdate(FALSE) //we'll update this occasionally, but not as often as possible
ui.set_style("clockwork")
ui = new(user, src, ui_key, "ClockworkSlab", name, ui_x, ui_z, master_ui, state)
ui.open()
/obj/item/clockwork/slab/proc/recite_scripture(datum/clockwork_scripture/scripture, mob/living/user)
if(!scripture || !user || !user.canUseTopic(src) || (!no_cost && !can_recite_scripture(user)))
return FALSE
@@ -426,8 +428,29 @@
/obj/item/clockwork/slab/ui_data(mob/user) //we display a lot of data via TGUI
var/list/data = list()
data["power"] = "<b><font color=#B18B25>[DisplayPower(get_clockwork_power())]</b> power is available for scripture and other consumers.</font>"
data["power"] = DisplayPower(get_clockwork_power())
data["scripture"] = list()
for(var/s in GLOB.all_scripture)
var/datum/clockwork_scripture/S = GLOB.all_scripture[s]
if(S.tier == selected_scripture) //display only scriptures of the selected tier
var/scripture_color = get_component_color_bright(S.primary_component)
var/list/temp_info = list("name" = "<font color=[scripture_color]><b>[S.name]</b></font>",
"descname" = "<font color=[scripture_color]>([S.descname])</font>",
"tip" = "[S.desc]\n[S.usage_tip]",
"required" = "([DisplayPower(S.power_cost)][S.special_power_text ? "+ [replacetext(S.special_power_text, "POWERCOST", "[DisplayPower(S.special_power_cost)]")]" : ""])",
"type" = "[S.type]",
"quickbind" = S.quickbind)
if(S.important)
temp_info["name"] = "<i>[temp_info["name"]]</i>"
var/found = quickbound.Find(S.type)
if(found)
temp_info["bound"] = "<b>[found]</b>"
if(S.invokers_required > 1)
temp_info["invokers"] = "<font color=#B18B25>Invokers: <b>[S.invokers_required]</b></font>"
data["scripture"] += list(temp_info)
/obj/item/clockwork/slab/ui_static_data(mob/user)
var/list/data = list()
switch(selected_scripture) //display info based on selected scripture tier
if(SCRIPTURE_DRIVER)
data["tier_info"] = "<font color=#B18B25><b>These scriptures are permanently unlocked.</b></font>"
@@ -449,26 +472,6 @@
<font color=#AF0AAF>Scriptures in <b>purple</b> are niche but still important!</font><br>\
<font color=#DAAA18><i>Scriptures with italicized names are important to success.</i></font>"
generate_all_scripture()
data["scripture"] = list()
for(var/s in GLOB.all_scripture)
var/datum/clockwork_scripture/S = GLOB.all_scripture[s]
if(S.tier == selected_scripture) //display only scriptures of the selected tier
var/scripture_color = get_component_color_bright(S.primary_component)
var/list/temp_info = list("name" = "<font color=[scripture_color]><b>[S.name]</b></font>",
"descname" = "<font color=[scripture_color]>([S.descname])</font>",
"tip" = "[S.desc]\n[S.usage_tip]",
"required" = "([DisplayPower(S.power_cost)][S.special_power_text ? "+ [replacetext(S.special_power_text, "POWERCOST", "[DisplayPower(S.special_power_cost)]")]" : ""])",
"type" = "[S.type]",
"quickbind" = S.quickbind)
if(S.important)
temp_info["name"] = "<i>[temp_info["name"]]</i>"
var/found = quickbound.Find(S.type)
if(found)
temp_info["bound"] = "<b>[found]</b>"
if(S.invokers_required > 1)
temp_info["invokers"] = "<font color=#B18B25>Invokers: <b>[S.invokers_required]</b></font>"
data["scripture"] += list(temp_info)
data["recollection"] = recollecting
if(recollecting)
data["recollection_categories"] = GLOB.ratvar_awakens ? list() : list(\
@@ -1,4 +1,4 @@
// Support unit gets it's own very basic antag datum for admin logging.
/// Support unit gets it's own very basic antag datum for admin logging.
/datum/antagonist/traitor/contractor_support
name = "Contractor Support Unit"
antag_moodlet = /datum/mood_event/focused
@@ -8,11 +8,13 @@
should_equip = FALSE /// Don't give them an uplink.
var/datum/team/contractor_team/contractor_team
/datum/team/contractor_team // Team for storing both the contractor and their support unit - only really for the HUD and admin logging.
/// Team for storing both the contractor and their support unit - only really for the HUD and admin logging.
/datum/team/contractor_team
show_roundend_report = FALSE
/datum/antagonist/traitor/contractor_support/forge_traitor_objectives()
var/datum/objective/generic_objective = new
generic_objective.name = "Follow Contractor's Orders"
generic_objective.explanation_text = "Follow your orders. Assist agents in this mission area."
generic_objective.completed = TRUE
@@ -25,7 +27,9 @@
var/static/list/contractor_items = typecacheof(/datum/contractor_item/, TRUE)
var/datum/syndicate_contract/current_contract
var/list/datum/syndicate_contract/assigned_contracts = list()
var/list/assigned_targets = list() // used as a blacklist to make sure we're not assigning targets already assigned
var/contracts_completed = 0
var/contract_TC_payed_out = 0 // Keeping track for roundend reporting
var/contract_TC_to_redeem = 0 // Used internally and roundend reporting - what TC we have available to cashout.
@@ -34,7 +38,8 @@
var/datum/contractor_item/contractor_item = new path
hub_items.Add(contractor_item)
/datum/contractor_hub/proc/create_contracts(datum/mind/owner) // 6 initial contracts
/datum/contractor_hub/proc/create_contracts(datum/mind/owner)
// 6 initial contracts
var/list/to_generate = list(
CONTRACT_PAYOUT_LARGE,
CONTRACT_PAYOUT_MEDIUM,
@@ -44,61 +49,74 @@
CONTRACT_PAYOUT_SMALL
)
var/lowest_TC_threshold = 30 // We don't want the sum of all the payouts to be under this amount
//What the fuck
if(length(to_generate) > length(GLOB.data_core.locked))
to_generate.Cut(1, length(GLOB.data_core.locked))
// We don't want the sum of all the payouts to be under this amount
var/lowest_TC_threshold = 30
var/total = 0
var/lowest_paying_sum = 0
var/datum/syndicate_contract/lowest_paying_contract
to_generate = shuffle(to_generate) // Randomise order, so we don't have contracts always in payout order.
var/start_index = 1 // Support contract generation happening multiple times
if(assigned_contracts.len != 0)
// Randomise order, so we don't have contracts always in payout order.
to_generate = shuffle(to_generate)
// Support contract generation happening multiple times
var/start_index = 1
if (assigned_contracts.len != 0)
start_index = assigned_contracts.len + 1
for(var/i = 1; i <= to_generate.len; i++) // Generate contracts, and find the lowest paying.
// Generate contracts, and find the lowest paying.
for (var/i = 1; i <= to_generate.len; i++)
var/datum/syndicate_contract/contract_to_add = new(owner, assigned_targets, to_generate[i])
var/contract_payout_total = contract_to_add.contract.payout + contract_to_add.contract.payout_bonus
assigned_targets.Add(contract_to_add.contract.target)
if(!lowest_paying_contract || (contract_payout_total < lowest_paying_sum))
if (!lowest_paying_contract || (contract_payout_total < lowest_paying_sum))
lowest_paying_sum = contract_payout_total
lowest_paying_contract = contract_to_add
total += contract_payout_total
contract_to_add.id = start_index
assigned_contracts.Add(contract_to_add)
start_index++
if(total < lowest_TC_threshold) // If the threshold for TC payouts isn't reached, boost the lowest paying contract
// If the threshold for TC payouts isn't reached, boost the lowest paying contract
if (total < lowest_TC_threshold)
lowest_paying_contract.contract.payout_bonus += (lowest_TC_threshold - total)
/datum/contractor_item
var/name // Name of item
var/desc // description of item
var/item // item path, no item path means the purchase needs it's own handle_purchase()
var/item_icon = "fa-broadcast-tower" // fontawesome icon to use inside the hub - https://fontawesome.com/icons/
var/item_icon = "broadcast-tower" // fontawesome icon to use inside the hub - https://fontawesome.com/icons/
var/limited = -1 // Any number above 0 for how many times it can be bought in a round for a single traitor. -1 is unlimited.
var/cost // Cost of the item in contract rep.
/datum/contractor_item/contract_reroll
name = "Contract Reroll"
desc = "Request a reroll of your current contract list. Will generate a new target, payment, and dropoff for the contracts you currently have available."
item_icon = "fa-dice"
item_icon = "dice"
limited = 2
cost = 0
/datum/contractor_item/contract_reroll/handle_purchase(var/datum/contractor_hub/hub)
. = ..()
if (.)
var/list/new_target_list = list() // We're not regenerating already completed/aborted/extracting contracts, but we don't want to repeat their targets.
/// We're not regenerating already completed/aborted/extracting contracts, but we don't want to repeat their targets.
var/list/new_target_list = list()
for(var/datum/syndicate_contract/contract_check in hub.assigned_contracts)
if (contract_check.status != CONTRACT_STATUS_ACTIVE && contract_check.status != CONTRACT_STATUS_INACTIVE)
if (contract_check.contract.target)
new_target_list.Add(contract_check.contract.target)
continue
for(var/datum/syndicate_contract/rerolling_contract in hub.assigned_contracts) // Reroll contracts without duplicates
/// Reroll contracts without duplicates
for(var/datum/syndicate_contract/rerolling_contract in hub.assigned_contracts)
if (rerolling_contract.status != CONTRACT_STATUS_ACTIVE && rerolling_contract.status != CONTRACT_STATUS_INACTIVE)
continue
rerolling_contract.generate(new_target_list)
new_target_list.Add(rerolling_contract.contract.target)
hub.assigned_targets = new_target_list // Set our target list with the new set we've generated.
/// Set our target list with the new set we've generated.
hub.assigned_targets = new_target_list
/datum/contractor_item/contractor_pinpointer
name = "Contractor Pinpointer"
desc = "A pinpointer that finds targets even without active suit sensors. Due to taking advantage of an exploit within the system, it can't pinpoint to the same accuracy as the traditional models. Becomes permanently locked to the user that first activates it."
@@ -125,20 +143,25 @@
/datum/contractor_item/contractor_partner/handle_purchase(var/datum/contractor_hub/hub, mob/living/user)
. = ..()
if (.)
to_chat(user, "<span class='notice'>The uplink vibrates quietly, connecting to nearby agents...</span>")
var/list/mob/candidates = pollGhostCandidates("Do you want to play as the Contractor Support Unit for [user.real_name]?", ROLE_PAI, null, FALSE, 100, POLL_IGNORE_CONTRACTOR_SUPPORT)
var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as the Contractor Support Unit for [user.real_name]?", ROLE_PAI, null, FALSE, 100, POLL_IGNORE_CONTRACTOR_SUPPORT)
if(LAZYLEN(candidates))
var/mob/dead/observer/C = pick(candidates)
spawn_contractor_partner(user, C.key)
else
to_chat(user, "<span class='notice'>No available agents at this time, please try again later.</span>")
limited += 1 // refund and add the limit back.
// refund and add the limit back.
limited += 1
hub.contract_rep += cost
hub.purchased_items -= src
/datum/outfit/contractor_partner
name = "Contractor Support Unit"
uniform = /obj/item/clothing/under/chameleon
suit = /obj/item/clothing/suit/chameleon
back = /obj/item/storage/backpack
@@ -148,28 +171,35 @@
ears = /obj/item/radio/headset/chameleon
id = /obj/item/card/id/syndicate
r_hand = /obj/item/storage/toolbox/syndicate
backpack_contents = list(/obj/item/storage/box/survival, /obj/item/implanter/uplink, /obj/item/clothing/mask/chameleon,
/obj/item/storage/fancy/cigarettes/cigpack_syndicate, /obj/item/lighter)
/datum/outfit/contractor_partner/post_equip(mob/living/carbon/human/H, visualsOnly)
. = ..()
var/obj/item/clothing/mask/cigarette/syndicate/cig = H.get_item_by_slot(SLOT_WEAR_MASK)
cig.light() // pre-light their cig for extra badass
var/obj/item/clothing/mask/cigarette/syndicate/cig = H.get_item_by_slot(ITEM_SLOT_MASK)
// pre-light their cig
cig.light()
/datum/contractor_item/contractor_partner/proc/spawn_contractor_partner(mob/living/user, key)
var/mob/living/carbon/human/partner = new()
var/datum/outfit/contractor_partner/partner_outfit = new()
partner_outfit.equip(partner)
var/obj/structure/closet/supplypod/arrival_pod = new()
arrival_pod.style = STYLE_SYNDICATE
arrival_pod.explosionSize = list(0,0,0,1)
arrival_pod.bluespace = TRUE
var/turf/free_location = find_obstruction_free_location(2, user)
if (!free_location) // We really want to send them - if we can't find a nice location just land it on top of them.
// We really want to send them - if we can't find a nice location just land it on top of them.
if (!free_location)
free_location = get_turf(user)
partner.forceMove(arrival_pod)
partner.ckey = key
partner_mind = partner.mind // We give a reference to the mind that'll be the support unit
/// We give a reference to the mind that'll be the support unit
partner_mind = partner.mind
partner_mind.make_Contractor_Support()
to_chat(partner_mind.current, "\n<span class='alertwarning'>[user.real_name] is your superior. Follow any, and all orders given by them. You're here to support their mission only.</span>")
to_chat(partner_mind.current, "<span class='alertwarning'>Should they perish, or be otherwise unavailable, you're to assist other active agents in this mission area to the best of your ability.</span>\n\n")
@@ -186,7 +216,7 @@
. = ..()
if (.)
power_fail(35, 50)
priority_announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", "poweroff")
priority_announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", "poweroff.ogg")
// Subtract cost, and spawn if it's an item.
/datum/contractor_item/proc/handle_purchase(var/datum/contractor_hub/hub, mob/living/user)
@@ -199,6 +229,7 @@
else if (limited == 0)
return FALSE
hub.purchased_items.Add(src)
user.playsound_local(user, 'sound/machines/uplinkpurchase.ogg', 100)
if (item && ispath(item))
var/atom/item_to_create = new item(get_turf(user))
@@ -68,7 +68,7 @@
empty_pod.explosionSize = list(0,0,0,1)
empty_pod.leavingSound = 'sound/effects/podwoosh.ogg'
new /obj/effect/DPtarget(empty_pod_turf, empty_pod)
new /obj/effect/abstract/DPtarget(empty_pod_turf, empty_pod)
/datum/syndicate_contract/proc/enter_check(datum/source, sent_mob)
if(istype(source, /obj/structure/closet/supplypod/extractionpod))
@@ -131,7 +131,7 @@
SSshuttle.points -= points_to_check
priority_announce("One of your crew was captured by a rival organisation - we've needed to pay their ransom to bring them back. \
As is policy we've taken a portion of the station's funds to offset the overall cost.", null, 'sound/ai/attention.ogg', null, "Nanotrasen Asset Protection")
As is policy we've taken a portion of the station's funds to offset the overall cost.", null, "attention", null, "Nanotrasen Asset Protection")
// They're off to holding - handle the return timer and give some text about what's going on.
/datum/syndicate_contract/proc/handleVictimExperience(var/mob/living/M)
@@ -199,7 +199,7 @@
M.blur_eyes(30)
M.Dizzy(35)
M.confused += 20
new /obj/effect/DPtarget(possible_drop_loc[pod_rand_loc], return_pod)
new /obj/effect/abstract/DPtarget(possible_drop_loc[pod_rand_loc], return_pod)
else
to_chat(M, "<span class='reallybig hypnophrase'>A million voices echo in your head... <i>\"Seems where you got sent here from won't \
be able to handle our pod... You will die here instead.\"</i></span>")
+2 -2
View File
@@ -138,8 +138,8 @@ GLOBAL_LIST_EMPTY(asset_datums)
var/size_id = "[I.Width()]x[I.Height()]"
var/size = sizes[size_id]
if (sprites[sprite_name])
CRASH("duplicate sprite \"[sprite_name]\" in sheet [name] ([type])")
//if (sprites[sprite_name])
//CRASH("duplicate sprite \"[sprite_name]\" in sheet [name] ([type])") TODO FIGURE OUT WHERE THE FUCK ARE THE DUPLICATES.
if (size)
var/position = size[SPRSZ_COUNT]++
+2 -2
View File
@@ -168,9 +168,9 @@
/datum/asset/spritesheet/goonchat/register()
InsertAll("emoji", 'icons/emoji.dmi')
// pre-loading all lanugage icons also helps to avoid meta
// Pre-loading all language icons also helps to avoid meta
InsertAll("language", 'icons/misc/language.dmi')
// catch languages which are pulling icons from another file
// Catch languages which are pulling icons from another file
for(var/path in typesof(/datum/language))
var/datum/language/L = path
var/icon = initial(L.icon)
@@ -19,7 +19,7 @@ GLOBAL_LIST_INIT(marker_beacon_colors, list(
singular_name = "marker beacon"
desc = "Prism-brand path illumination devices. Used by miners to mark paths and warn of danger."
icon = 'icons/obj/lighting.dmi'
icon_state = "marker"
icon_state = "markerbronze"
merge_type = /obj/item/stack/marker_beacon
max_amount = 100
novariants = TRUE