tgui: Abductors (#51920)

* Gland Dispenser

* ProbingConsole and Abductor theme

* State tweaks, Abductor Console DM side, Abductor Uplink, Abductor orderable gear datum

* Line endings

* Finished UIs
This commit is contained in:
Arkatos1
2020-06-30 15:09:07 -04:00
committed by GitHub
parent 9483d2e3a3
commit 160a4e1a76
12 changed files with 620 additions and 241 deletions
@@ -0,0 +1,79 @@
GLOBAL_LIST_INIT(abductor_gear, subtypesof(/datum/abductor_gear))
/datum/abductor_gear
/// Name of the gear
var/name = "Generic Abductor Gear"
/// Description of the gear
var/description = "Generic description."
/// Unique ID of the gear
var/id = "abductor_generic"
/// Credit cost of the gear
var/cost = 1
/// Build path of the gear itself
var/build_path = null
/// Category of the gear
var/category = "Basic Gear"
/datum/abductor_gear/agent_helmet
name = "Agent Helmet"
description = "Abduct with style - spiky style. Prevents digital tracking."
id = "agent_helmet"
build_path = /obj/item/clothing/head/helmet/abductor
/datum/abductor_gear/agent_vest
name = "Agent Vest"
description = "A vest outfitted with advanced stealth technology. It has two modes - combat and stealth."
id = "agent_vest"
build_path = /obj/item/clothing/suit/armor/abductor/vest
/datum/abductor_gear/radio_silencer
name = "Radio Silencer"
description = "A compact device used to shut down communications equipment."
id = "radio_silencer"
build_path = /obj/item/abductor/silencer
/datum/abductor_gear/science_tool
name = "Science Tool"
description = "A dual-mode tool for retrieving specimens and scanning appearances. Scanning can be done through cameras."
id = "science_tool"
build_path = /obj/item/abductor/gizmo
/datum/abductor_gear/advanced_baton
name = "Advanced Baton"
description = "A quad-mode baton used for incapacitation and restraining of specimens."
id = "advanced_baton"
cost = 2
build_path = /obj/item/melee/baton/abductor
/datum/abductor_gear/superlingual_matrix
name = "Superlingual Matrix"
description = "A mysterious structure that allows for instant communication between users. Pretty impressive until you need to eat something."
id = "superlingual_matrix"
build_path = /obj/item/organ/tongue/abductor
category = "Advanced Gear"
/datum/abductor_gear/mental_interface
name = "Mental Interface Device"
description = "A dual-mode tool for directly communicating with sentient brains. It can be used to send a direct message to a target, \
or to send a command to a test subject with a charged gland."
id = "mental_interface"
cost = 2
build_path = /obj/item/abductor/mind_device
category = "Advanced Gear"
/datum/abductor_gear/reagent_synthesizer
name = "Reagent Synthesizer"
description = "Synthesizes a variety of reagents using proto-matter."
id = "reagent_synthesizer"
cost = 2
build_path = /obj/item/abductor_machine_beacon/chem_dispenser
category = "Advanced Gear"
/datum/abductor_gear/shrink_ray
name = "Shrink Ray Blaster"
description = "This is a piece of frightening alien tech that enhances the magnetic pull of atoms in a localized space to temporarily make an object shrink. \
That or it's just space magic. Either way, it shrinks stuff."
id = "shrink_ray"
cost = 2
build_path = /obj/item/gun/energy/shrink_ray
category = "Advanced Gear"
@@ -17,12 +17,36 @@
icon = 'icons/obj/abductor.dmi'
icon_state = "console"
density = TRUE
ui_x = 600
ui_y = 532
var/obj/item/abductor/gizmo/gizmo
var/obj/item/clothing/suit/armor/abductor/vest/vest
var/obj/machinery/abductor/experiment/experiment
var/obj/machinery/abductor/pad/pad
var/obj/machinery/computer/camera_advanced/abductor/camera
var/list/datum/icon_snapshot/disguises = list()
/// Currently selected gear category
var/selected_cat
/// Dictates if the compact mode of the interface is on or off
var/compact_mode = FALSE
/// Possible gear to be dispensed
var/list/possible_gear
/obj/machinery/abductor/console/Initialize(mapload)
. = ..()
possible_gear = get_abductor_gear()
/**
* get_abductor_gear: Returns a list of a filtered abductor gear sorted by categories
*/
/obj/machinery/abductor/console/proc/get_abductor_gear()
var/list/filtered_modules = list()
for(var/path in GLOB.abductor_gear)
var/datum/abductor_gear/AG = new path
if(!filtered_modules[AG.category])
filtered_modules[AG.category] = list()
filtered_modules[AG.category][AG] = AG
return filtered_modules
/obj/machinery/abductor/console/attack_hand(mob/user)
. = ..()
@@ -32,96 +56,91 @@
to_chat(user, "<span class='warning'>You start mashing alien buttons at random!</span>")
if(do_after(user,100, target = src))
TeleporterSend()
return
user.set_machine(src)
var/dat = ""
dat += "<H3> Abductsoft 3000 </H3>"
/obj/machinery/abductor/console/ui_status(mob/user)
if(!isabductor(user) && !isobserver(user))
return UI_CLOSE
return ..()
/obj/machinery/abductor/console/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "AbductorConsole", name, ui_x, ui_y, master_ui, state)
ui.open()
/obj/machinery/abductor/console/ui_static_data(mob/user)
var/list/data = list()
data["categories"] = list()
for(var/category in possible_gear)
var/list/cat = list(
"name" = category,
"items" = (category == selected_cat ? list() : null))
for(var/gear in possible_gear[category])
var/datum/abductor_gear/AG = possible_gear[category][gear]
cat["items"] += list(list(
"name" = AG.name,
"cost" = AG.cost,
"desc" = AG.description,
))
data["categories"] += list(cat)
return data
/obj/machinery/abductor/console/ui_data(mob/user)
var/list/data = list()
data["compactMode"] = compact_mode
data["experiment"] = experiment ? TRUE : FALSE
if(experiment)
var/points = experiment.points
var/credits = experiment.credits
dat += "Collected Samples : [points] <br>"
dat += "Gear Credits: [credits] <br>"
dat += "<b>Transfer data in exchange for supplies:</b><br>"
dat += "<a href='?src=[REF(src)];dispense=baton'>Advanced Baton (2 Credits)</A><br>"
dat += "<a href='?src=[REF(src)];dispense=mind_device'>Mental Interface Device (2 Credits)</A><br>"
dat += "<a href='?src=[REF(src)];dispense=chem_dispenser'>Reagent Synthesizer (2 Credits)</A><br>"
dat += "<a href='?src=[REF(src)];dispense=shrink_ray'>Shrink Ray Blaster (2 Credits)</a><br>"
dat += "<a href='?src=[REF(src)];dispense=helmet'>Agent Helmet</A><br>"
dat += "<a href='?src=[REF(src)];dispense=vest'>Agent Vest</A><br>"
dat += "<a href='?src=[REF(src)];dispense=silencer'>Radio Silencer</A><br>"
dat += "<a href='?src=[REF(src)];dispense=tool'>Science Tool</A><br>"
dat += "<a href='?src=[REF(src)];dispense=tongue'>Superlingual Matrix</a><br>"
else
dat += "<span class='bad'>NO EXPERIMENT MACHINE DETECTED</span> <br>"
data["points"] = experiment.points
data["credits"] = experiment.credits
data["pad"] = pad ? TRUE : FALSE
if(pad)
dat += "<span class='bad'>Emergency Teleporter System.</span>"
dat += "<span class='bad'>Consider using primary observation console first.</span>"
dat += "<a href='?src=[REF(src)];teleporter_send=1'>Activate Teleporter</A><br>"
if(gizmo && gizmo.marked)
dat += "<a href='?src=[REF(src)];teleporter_retrieve=1'>Retrieve Mark</A><br>"
else
dat += "<span class='linkOff'>Retrieve Mark</span><br>"
else
dat += "<span class='bad'>NO TELEPAD DETECTED</span></br>"
data["gizmo"] = gizmo && gizmo.marked ? TRUE : FALSE
data["vest"] = vest ? TRUE : FALSE
if(vest)
dat += "<h4> Agent Vest Mode </h4><br>"
var/mode = vest.mode
if(mode == VEST_STEALTH)
dat += "<a href='?src=[REF(src)];flip_vest=1'>Combat</A>"
dat += "<span class='linkOff'>Stealth</span>"
else
dat += "<span class='linkOff'>Combat</span>"
dat += "<a href='?src=[REF(src)];flip_vest=1'>Stealth</A>"
data["vest_mode"] = vest.mode
data["vest_lock"] = HAS_TRAIT_FROM(vest, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT)
return data
dat+="<br>"
dat += "<a href='?src=[REF(src)];select_disguise=1'>Select Agent Vest Disguise</a><br>"
dat += "<a href='?src=[REF(src)];toggle_vest=1'>[HAS_TRAIT_FROM(vest, TRAIT_NODROP, ABDUCTOR_VEST_TRAIT) ? "Unlock" : "Lock"] Vest</a><br>"
else
dat += "<span class='bad'>NO AGENT VEST DETECTED</span>"
var/datum/browser/popup = new(user, "computer", "Abductor Console", 400, 500)
popup.set_content(dat)
popup.open()
/obj/machinery/abductor/console/Topic(href, href_list)
if(..())
/obj/machinery/abductor/console/ui_act(action, list/params)
. = ..()
if(.)
return
usr.set_machine(src)
if(href_list["teleporter_send"])
TeleporterSend()
else if(href_list["teleporter_retrieve"])
TeleporterRetrieve()
else if(href_list["flip_vest"])
FlipVest()
else if(href_list["toggle_vest"])
if(vest)
switch(action)
if("buy")
var/item_name = params["name"]
var/list/buyable_items = list()
for(var/category in possible_gear)
buyable_items += possible_gear[category]
for(var/key in buyable_items)
var/datum/abductor_gear/AG = buyable_items[key]
if(AG.name == item_name)
Dispense(AG.build_path, AG.cost)
return TRUE
if("teleporter_send")
TeleporterSend()
return TRUE
if("teleporter_retrieve")
TeleporterRetrieve()
return TRUE
if("flip_vest")
FlipVest()
return TRUE
if("toggle_vest")
if(!vest)
return
vest.toggle_nodrop()
else if(href_list["select_disguise"])
SelectDisguise()
else if(href_list["dispense"])
switch(href_list["dispense"])
if("baton")
Dispense(/obj/item/melee/baton/abductor,cost=2)
if("helmet")
Dispense(/obj/item/clothing/head/helmet/abductor)
if("silencer")
Dispense(/obj/item/abductor/silencer)
if("tool")
Dispense(/obj/item/abductor/gizmo)
if("vest")
Dispense(/obj/item/clothing/suit/armor/abductor/vest)
if("mind_device")
Dispense(/obj/item/abductor/mind_device,cost=2)
if("chem_dispenser")
Dispense(/obj/item/abductor_machine_beacon/chem_dispenser,cost=2)
if("tongue")
Dispense(/obj/item/organ/tongue/abductor)
if("shrink_ray")
Dispense(/obj/item/gun/energy/shrink_ray,cost=2)
updateUsrDialog()
return TRUE
if("select_disguise")
SelectDisguise()
return TRUE
if("select")
selected_cat = params["category"]
return TRUE
if("compact_toggle")
compact_mode = !compact_mode
return TRUE
/obj/machinery/abductor/console/proc/TeleporterRetrieve()
if(pad && gizmo && gizmo.marked)
@@ -162,7 +181,6 @@
pad.teleport_target = location
to_chat(user, "<span class='notice'>Location marked as test subject release point.</span>")
/obj/machinery/abductor/console/Initialize(mapload)
..()
return INITIALIZE_HINT_LATELOAD
@@ -232,8 +250,6 @@
else
return ..()
/obj/machinery/abductor/console/proc/Dispense(item,cost=1)
if(experiment && experiment.credits >= cost)
experiment.credits -=cost
@@ -4,6 +4,8 @@
icon = 'icons/obj/abductor.dmi'
icon_state = "dispenser"
density = TRUE
ui_x = 300
ui_y = 338
var/list/gland_types
var/list/gland_colors
var/list/amounts
@@ -22,41 +24,42 @@
gland_colors[i] = random_color()
amounts[i] = rand(1,5)
/obj/machinery/abductor/gland_dispenser/attack_hand(mob/user)
/obj/machinery/abductor/gland_dispenser/ui_status(mob/user)
if(!isabductor(user) && !isobserver(user))
return UI_CLOSE
return ..()
/obj/machinery/abductor/gland_dispenser/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "GlandDispenser", name, ui_x, ui_y, master_ui, state)
ui.open()
/obj/machinery/abductor/gland_dispenser/ui_data(mob/user)
var/list/data = list()
data["glands"] = list()
for(var/gland_number=1,gland_number<=gland_colors.len,gland_number++)
var/list/gland_information = list(
"color" = gland_colors[gland_number],
"amount" = amounts[gland_number],
"id" = gland_number,
)
data["glands"] += list(gland_information)
return data
/obj/machinery/abductor/gland_dispenser/ui_act(action, list/params)
. = ..()
if(.)
return
if(!isabductor(user))
return
user.set_machine(src)
var/box_css = {"
<style>
a.box.gland {
float: left;
width: 20px;
height: 20px;
margin: 5px;
border-width: 1px;
border-style: solid;
border-color: rgba(0,0,0,.2);
text-align: center;
}
</style>"}
var/dat = ""
var/item_count = 0
for(var/i=1,i<=gland_colors.len,i++)
item_count++
var/g_color = gland_colors[i]
var/amount = amounts[i]
dat += "<a class='box gland' style='background-color:[g_color]' href='?src=[REF(src)];dispense=[i]'>[amount]</a>"
if(item_count == 4) // Four boxes per line
dat +="</br></br>"
item_count = 0
var/datum/browser/popup = new(user, "glands", "Gland Dispenser", 200, 200)
popup.add_head_content(box_css)
popup.set_content(dat)
popup.open()
return
switch(action)
if("dispense")
var/gland_id = text2num(params["gland_id"])
if(!gland_id)
return
Dispense(gland_id)
return TRUE
/obj/machinery/abductor/gland_dispenser/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/organ/heart/gland))
@@ -68,15 +71,6 @@
else
return ..()
/obj/machinery/abductor/gland_dispenser/Topic(href, href_list)
if(..())
return
usr.set_machine(src)
if(href_list["dispense"])
Dispense(text2num(href_list["dispense"]))
updateUsrDialog()
/obj/machinery/abductor/gland_dispenser/proc/Dispense(count)
if(amounts[count]>0)
amounts[count]--
@@ -5,11 +5,14 @@
icon_state = "experiment-open"
density = FALSE
state_open = TRUE
ui_x = 330
ui_y = 207
var/points = 0
var/credits = 0
var/list/history
var/list/abductee_minds
var/flash = " - || - "
/// Machine feedback message
var/flash = "Awaiting subject."
var/obj/machinery/abductor/console/console
var/message_cooldown = 0
var/breakout_time = 450
@@ -22,13 +25,6 @@
return
close_machine(target)
/obj/machinery/abductor/experiment/attack_hand(mob/user)
. = ..()
if(.)
return
experimentUI(user)
/obj/machinery/abductor/experiment/open_machine()
if(!state_open && !panel_open)
..()
@@ -60,121 +56,81 @@
"<span class='notice'>You successfully break out of [src]!</span>")
open_machine()
/obj/machinery/abductor/experiment/proc/dissection_icon(mob/living/carbon/human/H)
var/icon/photo = null
var/g = (H.gender == FEMALE) ? "f" : "m"
if(H.dna.species.use_skintones)
photo = icon("icon" = 'icons/mob/human.dmi', "icon_state" = "[H.skin_tone]_[g]")
else
photo = icon("icon" = 'icons/mob/human.dmi', "icon_state" = "[H.dna.species.id]_[g]")
photo.Blend("#[H.dna.features["mcolor"]]", ICON_MULTIPLY)
/obj/machinery/abductor/experiment/ui_status(mob/user)
if(user == occupant)
return UI_CLOSE
return ..()
var/icon/eyes
if(EYECOLOR in H.dna.species.species_traits)
eyes = icon("icon" = 'icons/mob/human_face.dmi', "icon_state" = "eyes")
eyes.Blend("#[H.eye_color]", ICON_MULTIPLY)
/obj/machinery/abductor/experiment/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "ProbingConsole", name, ui_x, ui_y, master_ui, state)
ui.open()
var/datum/sprite_accessory/S
S = GLOB.hairstyles_list[H.hairstyle]
if(S && (HAIR in H.dna.species.species_traits))
var/icon/hair = icon("icon" = S.icon, "icon_state" = "[S.icon_state]")
hair.Blend("#[H.hair_color]", ICON_MULTIPLY)
eyes.Blend(hair, ICON_OVERLAY)
S = GLOB.facial_hairstyles_list[H.facial_hairstyle]
if(S && (FACEHAIR in H.dna.species.species_traits))
var/icon/facial = icon("icon" = S.icon, "icon_state" = "[S.icon_state]")
facial.Blend("#[H.facial_hair_color]", ICON_MULTIPLY)
eyes.Blend(facial, ICON_OVERLAY)
if(eyes)
photo.Blend(eyes, ICON_OVERLAY)
var/icon/splat = icon("icon" = 'icons/mob/dam_mob.dmi',"icon_state" = "chest30")
photo.Blend(splat,ICON_OVERLAY)
return photo
/obj/machinery/abductor/experiment/proc/experimentUI(mob/user)
var/dat
dat += "<h3> Experiment </h3>"
if(occupant)
var/obj/item/photo/P = new
P.picture = new
P.picture.picture_image = icon(dissection_icon(occupant), dir = SOUTH)
user << browse_rsc(P.picture.picture_image, "dissection_img")
dat += "<table><tr><td>"
dat += "<img src=dissection_img height=80 width=80>" //Avert your eyes
dat += "</td><td>"
dat += "<a href='?src=[REF(src)];experiment=1'>Probe</a><br>"
dat += "<a href='?src=[REF(src)];experiment=2'>Dissect</a><br>"
dat += "<a href='?src=[REF(src)];experiment=3'>Analyze</a><br>"
dat += "</td></tr></table>"
else
dat += "<span class='linkOff'>Experiment </span>"
if(!occupant)
dat += "<h3>Machine Unoccupied</h3>"
else
dat += "<h3>Subject Status : </h3>"
dat += "[occupant.name] => "
var/mob/living/mob_occupant = occupant
switch(mob_occupant.stat)
if(CONSCIOUS)
dat += "<span class='good'>Conscious</span>"
if(UNCONSCIOUS)
dat += "<span class='average'>Unconscious</span>"
else // DEAD
dat += "<span class='bad'>Deceased</span>"
dat += "<br>"
dat += "[flash]"
dat += "<br>"
dat += "<a href='?src=[REF(src)];refresh=1'>Scan</a>"
dat += "<a href='?src=[REF(src)];[state_open ? "close=1'>Close</a>" : "open=1'>Open</a>"]"
var/datum/browser/popup = new(user, "experiment", "Probing Console", 300, 300)
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
popup.set_content(dat)
popup.open()
/obj/machinery/abductor/experiment/Topic(href, href_list)
if(..() || usr == occupant)
return
usr.set_machine(src)
if(href_list["refresh"])
updateUsrDialog()
return
if(href_list["open"])
open_machine()
return
if(href_list["close"])
close_machine()
return
/obj/machinery/abductor/experiment/ui_data(mob/user)
var/list/data = list()
data["open"] = state_open
data["feedback"] = flash
data["occupant"] = occupant ? TRUE : FALSE
data["occupant_name"] = null
data["occupant_status"] = null
if(occupant)
var/mob/living/mob_occupant = occupant
if(mob_occupant.stat != DEAD)
if(href_list["experiment"])
flash = Experiment(occupant,href_list["experiment"],usr)
updateUsrDialog()
add_fingerprint(usr)
data["occupant_name"] = mob_occupant.name
data["occupant_status"] = mob_occupant.stat
return data
/obj/machinery/abductor/experiment/proc/Experiment(mob/occupant,type,mob/user)
/obj/machinery/abductor/experiment/ui_act(action, list/params)
. = ..()
if(.)
return
switch(action)
if("door")
if(state_open)
close_machine()
return TRUE
else
open_machine()
return TRUE
if("experiment")
if(!occupant)
return
var/mob/living/mob_occupant = occupant
if(mob_occupant.stat == DEAD)
return
flash = experiment(occupant, params["experiment_type"], usr)
return TRUE
/**
* experiment: Performs selected experiment on occupant mob, resulting in a point reward on success
*
* Arguments:
* * occupant The mob inside the machine
* * type The type of experiment to be performed
* * user The mob starting the experiment
*/
/obj/machinery/abductor/experiment/proc/experiment(mob/occupant, type, mob/user)
LAZYINITLIST(history)
var/mob/living/carbon/human/H = occupant
var/datum/antagonist/abductor/user_abductor = user.mind.has_antag_datum(/datum/antagonist/abductor)
if(!user_abductor)
return "<span class='bad'>Authorization failure. Contact mothership immidiately.</span>"
return "Authorization failure. Contact mothership immediately."
var/point_reward = 0
if(!H)
return "Invalid or missing specimen."
if(H in history)
return "<span class='bad'>Specimen already in database.</span>"
return "Specimen already in database."
if(H.stat == DEAD)
say("Specimen deceased - please provide fresh sample.")
return "<span class='bad'>Specimen deceased.</span>"
return "Specimen deceased."
var/obj/item/organ/heart/gland/GlandTest = locate() in H.internal_organs
if(!GlandTest)
say("Experimental dissection not detected!")
return "<span class='bad'>No glands detected!</span>"
return "No glands detected!"
if(H.mind != null && H.ckey != null)
LAZYINITLIST(abductee_minds)
LAZYADD(history, H)
@@ -197,22 +153,27 @@
point_reward++
if(point_reward > 0)
open_machine()
SendBack(H)
send_back(H)
playsound(src.loc, 'sound/machines/ding.ogg', 50, TRUE)
points += point_reward
credits += point_reward
return "<span class='good'>Experiment successful! [point_reward] new data-points collected.</span>"
return "Experiment successful! [point_reward] new data-points collected."
else
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, TRUE)
return "<span class='bad'>Experiment failed! No replacement organ detected.</span>"
return "Experiment failed! No replacement organ detected."
else
say("Brain activity nonexistent - disposing sample...")
open_machine()
SendBack(H)
return "<span class='bad'>Specimen braindead - disposed.</span>"
send_back(H)
return "Specimen braindead - disposed."
/obj/machinery/abductor/experiment/proc/SendBack(mob/living/carbon/human/H)
/**
* send_back: Sends a mob back to a selected teleport location if safe
*
* Arguments:
* * H The human mob to be sent back
*/
/obj/machinery/abductor/experiment/proc/send_back(mob/living/carbon/human/H)
H.Sleeping(160)
H.uncuff()
if(console && console.pad && console.pad.teleport_target)
@@ -222,7 +183,6 @@
SSjob.SendToLateJoin(H, FALSE)
return
/obj/machinery/abductor/experiment/update_icon_state()
if(state_open)
icon_state = "experiment-open"
+1
View File
@@ -1373,6 +1373,7 @@
#include "code\modules\antagonists\abductor\equipment\abduction_outfits.dm"
#include "code\modules\antagonists\abductor\equipment\abduction_surgery.dm"
#include "code\modules\antagonists\abductor\equipment\gland.dm"
#include "code\modules\antagonists\abductor\equipment\orderable_gear.dm"
#include "code\modules\antagonists\abductor\equipment\glands\access.dm"
#include "code\modules\antagonists\abductor\equipment\glands\blood.dm"
#include "code\modules\antagonists\abductor\equipment\glands\chem.dm"
+1
View File
@@ -18,6 +18,7 @@ import './polyfills/inferno';
// Themes
import './styles/main.scss';
import './styles/themes/abductor.scss';
import './styles/themes/cardtable.scss';
import './styles/themes/malfunction.scss';
import './styles/themes/ntos.scss';
@@ -0,0 +1,155 @@
import { GenericUplink } from './Uplink';
import { useBackend, useSharedState } from '../backend';
import { Button, LabeledList, NoticeBox, Section, Tabs } from '../components';
import { Fragment } from 'inferno';
import { Window } from '../layouts';
export const AbductorConsole = (props, context) => {
const [tab, setTab] = useSharedState(context, 'tab', 1);
return (
<Window
theme="abductor"
resizable>
<Window.Content scrollable>
<Tabs>
<Tabs.Tab
icon="list"
lineHeight="23px"
selected={tab === 1}
onClick={() => setTab(1)}>
Abductsoft 3000
</Tabs.Tab>
<Tabs.Tab
icon="list"
lineHeight="23px"
selected={tab === 2}
onClick={() => setTab(2)}>
Mission Settings
</Tabs.Tab>
</Tabs>
{tab === 1 && (
<Abductsoft />
)}
{tab === 2 && (
<Fragment>
<EmergencyTeleporter />
<VestSettings />
</Fragment>
)}
</Window.Content>
</Window>
);
};
const Abductsoft = (props, context) => {
const { act, data } = useBackend(context);
const {
experiment,
points,
credits,
} = data;
if (!experiment) {
return (
<NoticeBox danger>
No Experiment Machine Detected
</NoticeBox>
);
}
return (
<Fragment>
<Section>
<LabeledList>
<LabeledList.Item label="Collected Samples">
{points}
</LabeledList.Item>
</LabeledList>
</Section>
<GenericUplink
currencyAmount={credits}
currencySymbol="Credits" />
</Fragment>
);
};
const EmergencyTeleporter = (props, context) => {
const { act, data } = useBackend(context);
const {
pad,
gizmo,
} = data;
if (!pad) {
return (
<NoticeBox danger>
No Telepad Detected
</NoticeBox>
);
}
return (
<Section
title="Emergency Teleport"
buttons={(
<Button
icon="exclamation-circle"
content="Activate"
color="bad"
onClick={() => act('teleporter_send')} />
)}>
<LabeledList>
<LabeledList.Item label="Mark Retrieval">
<Button
icon={gizmo ? "user-plus" : "user-slash"}
content={gizmo ? "Retrieve" : "No Mark"}
disabled={!gizmo}
onClick={() => act('teleporter_retrieve')} />
</LabeledList.Item>
</LabeledList>
</Section>
);
};
const VestSettings = (props, context) => {
const { act, data } = useBackend(context);
const {
vest,
vest_mode,
vest_lock,
} = data;
if (!vest) {
return (
<NoticeBox danger>
No Agent Vest Detected
</NoticeBox>
);
}
return (
<Section
title="Agent Vest Settings"
buttons={(
<Button
icon={vest_lock ? 'lock' : 'unlock'}
content={vest_lock ? 'Locked' : 'Unlocked'}
onClick={() => act('toggle_vest')} />
)}>
<LabeledList>
<LabeledList.Item label="Mode">
<Button
icon={vest_mode === 1 ? 'eye-slash' : 'fist-raised'}
content={vest_mode === 1 ? "Stealth" : "Combat"}
onClick={() => act('flip_vest')} />
</LabeledList.Item>
<LabeledList.Item label="Disguise">
<Button
icon="user-secret"
content="Select"
onClick={() => act('select_disguise')} />
</LabeledList.Item>
</LabeledList>
</Section>
);
};
@@ -0,0 +1,34 @@
import { useBackend } from '../backend';
import { Button, Section } from '../components';
import { Window } from '../layouts';
export const GlandDispenser = (props, context) => {
const { act, data } = useBackend(context);
const {
glands = [],
} = data;
return (
<Window theme="abductor">
<Window.Content>
<Section>
{glands.map(gland => (
<Button
key={gland.id}
width="60px"
height="60px"
m={0.75}
textAlign="center"
lineHeight="55px"
icon="eject"
backgroundColor={gland.color}
content={gland.amount || "0"}
disabled={!gland.amount}
onClick={() => act('dispense', {
gland_id: gland.id,
})} />
))}
</Section>
</Window.Content>
</Window>
);
};
@@ -0,0 +1,80 @@
import { useBackend } from '../backend';
import { Button, Section, LabeledList, NoticeBox } from '../components';
import { Window } from '../layouts';
export const ProbingConsole = (props, context) => {
const { act, data } = useBackend(context);
const {
open,
feedback,
occupant,
occupant_name,
occupant_status,
} = data;
return (
<Window theme="abductor">
<Window.Content>
<Section>
<LabeledList>
<LabeledList.Item label="Machine Report">
{feedback}
</LabeledList.Item>
</LabeledList>
</Section>
<Section
title="Scanner"
buttons={(
<Button
icon={open ? 'sign-out-alt' : 'sign-in-alt'}
content={open ? 'Close' : 'Open'}
onClick={() => act('door')} />
)}>
{occupant && (
<LabeledList>
<LabeledList.Item label="Name">
{occupant_name}
</LabeledList.Item>
<LabeledList.Item
label="Status"
color={occupant_status === 3
? 'bad'
: occupant_status === 2
? 'average'
: 'good'}>
{occupant_status === 3
? 'Deceased'
: occupant_status === 2
? 'Unconcious'
: 'Concious'}
</LabeledList.Item>
<LabeledList.Item label="Experiments">
<Button
icon="thermometer"
content="Probe"
onClick={() => act('experiment', {
experiment_type: 1,
})} />
<Button
icon="brain"
content="Dissect"
onClick={() => act('experiment', {
experiment_type: 2,
})} />
<Button
icon="search"
content="Analyze"
onClick={() => act('experiment', {
experiment_type: 3,
})} />
</LabeledList.Item>
</LabeledList>
) || (
<NoticeBox>
No Subject
</NoticeBox>
)}
</Section>
</Window.Content>
</Window>
);
};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,59 @@
/**
* Copyright (c) 2020 Aleksej Komarov
* SPDX-License-Identifier: MIT
*/
@use 'sass:color';
@use 'sass:meta';
@use '../colors.scss' with (
$primary: #ad2350,
$fg-map-keys: (),
$bg-map-keys: (),
);
@use '../base.scss' with (
$color-bg: #2a314a,
$color-bg-grad-spread: 6%,
$border-radius: 2px,
);
.theme-abductor {
// Atomic classes
@include meta.load-css('../atomic/color.scss');
// Components
@include meta.load-css('../components/Button.scss', $with: (
'color-default': colors.$primary,
'color-disabled': #363636,
'color-selected': #465899,
'color-caution': #be6209,
'color-danger': #9a9d00,
));
@include meta.load-css('../components/Input.scss', $with: (
'border-color': #404b6e,
));
@include meta.load-css('../components/NoticeBox.scss', $with: (
'color-background': #a82d55,
));
@include meta.load-css('../components/NumberInput.scss', $with: (
'border-color': #404b6e,
));
@include meta.load-css('../components/ProgressBar.scss', $with: (
'color-background': rgba(0, 0, 0, 0.5),
));
@include meta.load-css('../components/Section.scss');
@include meta.load-css('../components/Tooltip.scss', $with: (
'color-background': #a82d55,
));
// Layouts
@include meta.load-css('../layouts/Layout.scss');
@include meta.load-css('../layouts/Window.scss');
@include meta.load-css('../layouts/TitleBar.scss', $with: (
'color-background': #9e1b46,
));
.Layout__content {
background-image: none;
}
}