Merge branch 'master' into psychologist

This commit is contained in:
uomo91
2020-03-15 05:19:03 -05:00
20 changed files with 40151 additions and 39874 deletions
+2 -1
View File
@@ -4,6 +4,7 @@
#define SOUND_MIDI (1<<1)
#define SOUND_AMBIENCE (1<<2)
#define SOUND_LOBBY (1<<3)
#define SOUND_ENDOFROUND (1<<20)
#define MEMBER_PUBLIC (1<<4)
#define INTENT_STYLE (1<<5)
#define MIDROUND_ANTAG (1<<6)
@@ -22,7 +23,7 @@
#define DEADMIN_POSITION_SECURITY (1<<18)
#define DEADMIN_POSITION_SILICON (1<<19)
#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|MEMBER_PUBLIC|INTENT_STYLE|MIDROUND_ANTAG|SOUND_INSTRUMENTS|SOUND_SHIP_AMBIENCE|SOUND_PRAYERS|SOUND_ANNOUNCEMENTS)
#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|SOUND_ENDOFROUND|MEMBER_PUBLIC|INTENT_STYLE|MIDROUND_ANTAG|SOUND_INSTRUMENTS|SOUND_SHIP_AMBIENCE|SOUND_PRAYERS|SOUND_ANNOUNCEMENTS)
//Chat toggles
#define CHAT_OOC (1<<0)
+5 -1
View File
@@ -643,6 +643,10 @@ SUBSYSTEM_DEF(ticker)
'sound/roundend/scrunglartiy.ogg',
'sound/roundend/petersondisappointed.ogg'\
)
///The reference to the end of round sound that we have chosen.
var/sound/end_of_round_sound_ref = sound(round_end_sound)
for(var/mob/M in GLOB.player_list)
if(M.client.prefs?.toggles & SOUND_ENDOFROUND)
SEND_SOUND(M.client, end_of_round_sound_ref)
SEND_SOUND(world, sound(round_end_sound))
text2file(login_music, "data/last_round_lobby_music.txt")
+94 -135
View File
@@ -6,167 +6,126 @@
req_access = list(ACCESS_ROBOTICS)
circuit = /obj/item/circuitboard/computer/robotics
light_color = LIGHT_COLOR_PINK
var/temp = null
ui_x = 500
ui_y = 460
/obj/machinery/computer/robotics/proc/can_control(mob/user, mob/living/silicon/robot/R)
. = FALSE
if(!istype(R))
return
if(isAI(user))
if (R.connected_ai != user)
if(R.connected_ai != user)
return
if(iscyborg(user))
if (R != user)
if(R != user)
return
if(R.scrambledcodes)
return
return TRUE
/obj/machinery/computer/robotics/ui_interact(mob/user)
. = ..()
user.set_machine(src)
var/dat
var/list/robo_list = list()
var/robot_count
/obj/machinery/computer/robotics/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "robotics_control_console", name, ui_x, ui_y, master_ui, state)
ui.open()
/obj/machinery/computer/robotics/ui_data(mob/user)
var/list/data = list()
data["can_hack"] = FALSE
if(issilicon(user))
var/mob/living/silicon/S = user
if(S.hack_software)
data["can_hack"] = TRUE
else if(IsAdminGhost(user))
data["can_hack"] = TRUE
data["cyborgs"] = list()
for(var/mob/living/silicon/robot/R in GLOB.silicon_mobs)
if(!can_control(user, R))
continue
if(z != (get_turf(R)).z)
continue
robot_count++
var/unit_sync = "Independent"
if(R.connected_ai)
unit_sync = "Slaved to [R.connected_ai]"
if(!robo_list[unit_sync])
robo_list[unit_sync] = list()
robo_list[unit_sync] += R
var/list/cyborg_data = list(
name = R.name,
locked_down = R.lockcharge,
status = R.stat,
charge = R.cell ? round(R.cell.percent()) : null,
module = R.module ? "[R.module.name] Module" : "No Module Detected",
synchronization = R.connected_ai,
emagged = R.emagged,
ref = REF(R)
)
data["cyborgs"] += list(cyborg_data)
dat += "<center><h2>Cyborgs</h2><hr></center>"
if(!robo_list.len)
dat += "<center>No cyborg units detected within access parameters.</center><br><br>"
else
if(robo_list.len > 1)
sortTim(robo_list, /proc/cmp_text_asc)
for(var/ai_unit in robo_list)
dat += "<center><h3>[ai_unit]</h3></center><div class='statusDisplay'>"
var/spacer
for(var/robo in robo_list[ai_unit])
if(spacer)
dat += "<br><br>"
else
spacer = TRUE
var/mob/living/silicon/robot/R = robo
dat += "<b>Name:</b> [R.name]<br>"
var/can_move = (R.mobility_flags & MOBILITY_MOVE)
dat += "<b>Status:</b> [R.stat ? "Not Responding" : (can_move ? "Normal" : "Locked Down")]<br>"
if(can_move)
dat += "<b>Cell:</b> [R.cell ? "[R.cell.percent()]%" : "No Cell Detected"]<br>"
dat += "<b>Module:</b> [R.module ? "[R.module.name] Module" : "No Module Detected"]<br>"
dat += "<b>Unit Controls:</b> "
if(issilicon(user) && user != R)
var/mob/living/silicon/S = user
if(S.hack_software && !R.emagged)
dat += "<A href='?src=[REF(src)];magbot=[REF(R)]'>(<font color=blue><i>Hack</i></font>)</A> "
else if(IsAdminGhost(user) && !R.emagged)
dat += "<A href='?src=[REF(src)];magbot=[REF(R)]'>(<font color=blue><i>Hack</i></font>)</A> "
dat += "<A href='?src=[REF(src)];stopbot=[REF(R)]'>(<font color=green><i>[(R.mobility_flags & MOBILITY_MOVE) ? "Lockdown" : "Release"]</i></font>)</A> "
dat += "<A href='?src=[REF(src)];killbot=[REF(R)]'>(<font color=red><i>Destroy</i></font>)</A>"
dat += "</div>"
dat += "<center><h2>Drones</h2></center>"
var/drones = 0
data["drones"] = list()
for(var/mob/living/simple_animal/drone/D in GLOB.drones_list)
if(D.hacked)
continue
if(z != (get_turf(D)).z)
continue
if(drones)
dat += "<br><br>"
else
dat += "<div class='statusDisplay'>"
drones++
dat += "<b>Name:</b> [D.name]<br>"
dat += "<b>Status:</b> [D.stat ? "Not Responding" : "Normal"]<br>"
dat += "<b>Unit Controls:</b> "
dat += "<A href='?src=[REF(src)];killdrone=[REF(D)]'>(<font color=red><i>Destroy</i></font>)</A>"
var/list/drone_data = list(
name = D.name,
status = D.stat,
ref = REF(D)
)
data["drones"] += list(drone_data)
if(drones)
dat += "</div>"
else
dat += "<hr><center>No drone units detected within access parameters.</center>"
return data
var/window_height = min((300+((robot_count+drones) * 110)), 800)
var/datum/browser/popup = new(user, "computer", "Robotics Control Console", 375, window_height)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
popup.open()
/obj/machinery/computer/robotics/Topic(href, href_list)
. = ..()
if(.)
/obj/machinery/computer/robotics/ui_act(action, params)
if(..())
return
if (href_list["temp"])
temp = null
else if (href_list["killbot"])
if(allowed(usr))
var/mob/living/silicon/robot/R = locate(href_list["killbot"]) in GLOB.silicon_mobs
if(can_control(usr, R))
var/choice = input("Are you certain you wish to detonate [R.name]?") in list("Confirm", "Abort")
if(choice == "Confirm" && can_control(usr, R) && !..())
var/turf/T = get_turf(R)
message_admins("<span class='notice'>[ADMIN_LOOKUPFLW(usr)] detonated [key_name_admin(R, R.client)] at [ADMIN_VERBOSEJMP(T)]!</span>")
log_game("\<span class='notice'>[key_name(usr)] detonated [key_name(R)]!</span>")
if(R.connected_ai)
to_chat(R.connected_ai, "<br><br><span class='alert'>ALERT - Cyborg detonation detected: [R.name]</span><br>")
R.self_destruct()
else
to_chat(usr, "<span class='danger'>Access Denied.</span>")
else if (href_list["stopbot"])
if(allowed(usr))
var/mob/living/silicon/robot/R = locate(href_list["stopbot"]) in GLOB.silicon_mobs
if(can_control(usr, R))
var/choice = input("Are you certain you wish to [!R.lockcharge ? "lock down" : "release"] [R.name]?") in list("Confirm", "Abort")
if(choice == "Confirm" && can_control(usr, R) && !..())
message_admins("<span class='notice'>[ADMIN_LOOKUPFLW(usr)] [!R.lockcharge ? "locked down" : "released"] [ADMIN_LOOKUPFLW(R)]!</span>")
log_game("[key_name(usr)] [!R.lockcharge ? "locked down" : "released"] [key_name(R)]!")
R.SetLockdown(!R.lockcharge)
to_chat(R, "[!R.lockcharge ? "<span class='notice'>Your lockdown has been lifted!" : "<span class='alert'>You have been locked down!"]</span>")
if(R.connected_ai)
to_chat(R.connected_ai, "[!R.lockcharge ? "<span class='notice'>NOTICE - Cyborg lockdown lifted" : "<span class='alert'>ALERT - Cyborg lockdown detected"]: <a href='?src=[REF(R.connected_ai)];track=[html_encode(R.name)]'>[R.name]</a></span><br>")
else
to_chat(usr, "<span class='danger'>Access Denied.</span>")
else if (href_list["magbot"])
var/mob/living/silicon/S = usr
if((istype(S) && S.hack_software) || IsAdminGhost(usr))
var/mob/living/silicon/robot/R = locate(href_list["magbot"]) in GLOB.silicon_mobs
if(istype(R) && !R.emagged && (R.connected_ai == usr || IsAdminGhost(usr)) && !R.scrambledcodes && can_control(usr, R))
log_game("[key_name(usr)] emagged [key_name(R)] using robotic console!")
message_admins("[ADMIN_LOOKUPFLW(usr)] emagged cyborg [key_name_admin(R)] using robotic console!")
R.SetEmagged(TRUE)
else if (href_list["killdrone"])
if(allowed(usr))
var/mob/living/simple_animal/drone/D = locate(href_list["killdrone"]) in GLOB.mob_list
if(D.hacked)
to_chat(usr, "<span class='danger'>ERROR: [D] is not responding to external commands.</span>")
switch(action)
if("killbot")
if(allowed(usr))
var/mob/living/silicon/robot/R = locate(params["ref"]) in GLOB.silicon_mobs
if(can_control(usr, R))
var/choice = input("Are you certain you wish to detonate [R.name]?") in list("Confirm", "Abort")
if(choice == "Confirm" && can_control(usr, R) && !..())
var/turf/T = get_turf(R)
message_admins("<span class='notice'>[ADMIN_LOOKUPFLW(usr)] detonated [key_name_admin(R, R.client)] at [ADMIN_VERBOSEJMP(T)]!</span>")
log_game("\<span class='notice'>[key_name(usr)] detonated [key_name(R)]!</span>")
if(R.connected_ai)
to_chat(R.connected_ai, "<br><br><span class='alert'>ALERT - Cyborg detonation detected: [R.name]</span><br>")
R.self_destruct()
else
var/turf/T = get_turf(D)
message_admins("[ADMIN_LOOKUPFLW(usr)] detonated [key_name_admin(D)] at [ADMIN_VERBOSEJMP(T)]!")
log_game("[key_name(usr)] detonated [key_name(D)]!")
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(3, TRUE, D)
s.start()
D.visible_message("<span class='danger'>\the [D] self destructs!</span>")
D.gib()
updateUsrDialog()
to_chat(usr, "<span class='danger'>Access Denied.</span>")
if("stopbot")
if(allowed(usr))
var/mob/living/silicon/robot/R = locate(params["ref"]) in GLOB.silicon_mobs
if(can_control(usr, R))
var/choice = input("Are you certain you wish to [!R.lockcharge ? "lock down" : "release"] [R.name]?") in list("Confirm", "Abort")
if(choice == "Confirm" && can_control(usr, R) && !..())
message_admins("<span class='notice'>[ADMIN_LOOKUPFLW(usr)] [!R.lockcharge ? "locked down" : "released"] [ADMIN_LOOKUPFLW(R)]!</span>")
log_game("[key_name(usr)] [!R.lockcharge ? "locked down" : "released"] [key_name(R)]!")
R.SetLockdown(!R.lockcharge)
to_chat(R, "[!R.lockcharge ? "<span class='notice'>Your lockdown has been lifted!" : "<span class='alert'>You have been locked down!"]</span>")
if(R.connected_ai)
to_chat(R.connected_ai, "[!R.lockcharge ? "<span class='notice'>NOTICE - Cyborg lockdown lifted" : "<span class='alert'>ALERT - Cyborg lockdown detected"]: <a href='?src=[REF(R.connected_ai)];track=[html_encode(R.name)]'>[R.name]</a></span><br>")
else
to_chat(usr, "<span class='danger'>Access Denied.</span>")
if("magbot")
var/mob/living/silicon/S = usr
if((istype(S) && S.hack_software) || IsAdminGhost(usr))
var/mob/living/silicon/robot/R = locate(params["ref"]) in GLOB.silicon_mobs
if(istype(R) && !R.emagged && (R.connected_ai == usr || IsAdminGhost(usr)) && !R.scrambledcodes && can_control(usr, R))
log_game("[key_name(usr)] emagged [key_name(R)] using robotic console!")
message_admins("[ADMIN_LOOKUPFLW(usr)] emagged cyborg [key_name_admin(R)] using robotic console!")
R.SetEmagged(TRUE)
if("killdrone")
if(allowed(usr))
var/mob/living/simple_animal/drone/D = locate(params["ref"]) in GLOB.mob_list
if(D.hacked)
to_chat(usr, "<span class='danger'>ERROR: [D] is not responding to external commands.</span>")
else
var/turf/T = get_turf(D)
message_admins("[ADMIN_LOOKUPFLW(usr)] detonated [key_name_admin(D)] at [ADMIN_VERBOSEJMP(T)]!")
log_game("[key_name(usr)] detonated [key_name(D)]!")
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(3, TRUE, D)
s.start()
D.visible_message("<span class='danger'>\the [D] self destructs!</span>")
D.gib()
+2
View File
@@ -49,6 +49,8 @@
target = A.loc
else
target = user.loc
if (!isturf(target))
return
if (locate(/obj/structure/table) in target.contents)
return
var/i = 0
@@ -18,6 +18,7 @@
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
w_class = WEIGHT_CLASS_SMALL
slot_flags = ITEM_SLOT_BELT
item_flags = NOBLUDGEON
custom_materials = list(/datum/material/iron = 150, /datum/material/glass = 150)
var/grace = RAD_GRACE_PERIOD
+2 -1
View File
@@ -56,7 +56,8 @@
name = "Space Station 13"
icon = 'icons/blank_title.png'
icon_state = ""
layer = FLY_LAYER
layer = SPLASHSCREEN_LAYER
plane = SPLASHSCREEN_PLANE
bullet_bounce_sound = null
/turf/closed/indestructible/splashscreen/New()
+4
View File
@@ -631,6 +631,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "<br>"
dat += "<b>Play Admin MIDIs:</b> <a href='?_src_=prefs;preference=hear_midis'>[(toggles & SOUND_MIDI) ? "Enabled":"Disabled"]</a><br>"
dat += "<b>Play Lobby Music:</b> <a href='?_src_=prefs;preference=lobby_music'>[(toggles & SOUND_LOBBY) ? "Enabled":"Disabled"]</a><br>"
dat += "<b>Play End of Round Sounds:</b> <a href='?_src_=prefs;preference=endofround_sounds'>[(toggles & SOUND_ENDOFROUND) ? "Enabled":"Disabled"]</a><br>"
dat += "<b>See Pull Requests:</b> <a href='?_src_=prefs;preference=pull_requests'>[(chat_toggles & CHAT_PULLR) ? "Enabled":"Disabled"]</a><br>"
dat += "<br>"
@@ -1638,6 +1639,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
else
user.stop_sound_channel(CHANNEL_LOBBYMUSIC)
if("endofround_sounds")
toggles ^= SOUND_ENDOFROUND
if("ghost_ears")
chat_toggles ^= CHAT_GHOSTEARS
+4 -1
View File
@@ -5,7 +5,7 @@
// You do not need to raise this if you are adding new values that have sane defaults.
// Only raise this value when changing the meaning/format/name/layout of an existing value
// where you would want the updater procs below to run
#define SAVEFILE_VERSION_MAX 32
#define SAVEFILE_VERSION_MAX 33
/*
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
@@ -53,6 +53,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
if(current_version < 32) //If you remove this, remove force_reset_keybindings() too.
addtimer(CALLBACK(src, .proc/force_reset_keybindings), 30) //No mob available when this is run, timer allows user choice.
if(current_version < 33)
toggles |= SOUND_ENDOFROUND
/datum/preferences/proc/update_character(current_version, savefile/S)
if(current_version < 19)
pda_style = "mono"
@@ -144,6 +144,21 @@ TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Sound, toggletitlemusic)()
return C.prefs.toggles & SOUND_LOBBY
TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Sound, toggleendofroundsounds)()
set name = "Hear/Silence End of Round Sounds"
set category = "Preferences"
set desc = "Hear Round End Sounds"
usr.client.prefs.toggles ^= SOUND_ENDOFROUND
usr.client.prefs.save_preferences()
if(usr.client.prefs.toggles & SOUND_ENDOFROUND)
to_chat(usr, "You will now hear sounds played before the server restarts.")
else
to_chat(usr, "You will no longer hear sounds played before the server restarts.")
SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle End of Round Sounds", "[usr.client.prefs.toggles & SOUND_ENDOFROUND ? "Enabled" : "Disabled"]"))
/datum/verbs/menu/Settings/Sound/toggleendofroundsounds/Get_checked(client/C)
return C.prefs.toggles & SOUND_ENDOFROUND
TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Sound, togglemidis)()
set name = "Hear/Silence Midis"
set category = "Preferences"
+49 -40
View File
@@ -203,7 +203,6 @@
mask_type = /obj/item/clothing/mask/breath
storage_type = /obj/item/tank/internals/oxygen
/obj/machinery/loot_locator
name = "Booty Locator"
desc = "This sophisticated machine scans the nearby space for items of value."
@@ -256,7 +255,9 @@
/obj/machinery/computer/piratepad_control
name = "cargo hold control terminal"
var/status_report = "Idle"
ui_x = 600
ui_y = 230
var/status_report = "Ready for delivery."
var/obj/machinery/piratepad/pad
var/warmup_time = 100
var/sending = FALSE
@@ -274,7 +275,6 @@
if (istype(I) && istype(I.buffer,/obj/machinery/piratepad))
to_chat(user, "<span class='notice'>You link [src] with [I.buffer] in [I] buffer.</span>")
pad = I.buffer
updateDialog()
return TRUE
/obj/machinery/computer/piratepad_control/LateInitialize()
@@ -287,29 +287,44 @@
else
pad = locate() in range(4,src)
/obj/machinery/computer/piratepad_control/ui_interact(mob/user)
. = ..()
var/list/t = list()
t += "<div class='statusDisplay'>Cargo Hold Control<br>"
t += "Current cargo value : [points]"
t += "</div>"
if(!pad)
t += "<div class='statusDisplay'>No pad located.</div><BR>"
else
t += "<br>[status_report]<br>"
if(!sending)
t += "<a href='?src=[REF(src)];recalc=1;'>Recalculate Value</a><a href='?src=[REF(src)];send=1'>Send</a>"
else
t += "<a href='?src=[REF(src)];stop=1'>Stop sending</a>"
/obj/machinery/computer/piratepad_control/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "cargo_hold_terminal", name, ui_x, ui_y, master_ui, state)
ui.open()
var/datum/browser/popup = new(user, "piratepad", name, 300, 500)
popup.set_content(t.Join())
popup.open()
/obj/machinery/computer/piratepad_control/ui_data(mob/user)
var/list/data = list()
data["points"] = points
data["pad"] = pad ? TRUE : FALSE
data["sending"] = sending
data["status_report"] = status_report
return data
/obj/machinery/computer/piratepad_control/ui_act(action, params)
if(..())
return
if(!pad)
return
switch(action)
if("recalc")
recalc()
. = TRUE
if("send")
start_sending()
. = TRUE
if("stop")
stop_sending()
. = TRUE
/obj/machinery/computer/piratepad_control/proc/recalc()
if(sending)
return
status_report = "Predicted value:<br>"
status_report = "Predicted value: "
var/value = 0
var/datum/export_report/ex = new
for(var/atom/movable/AM in get_turf(pad))
if(AM == pad)
@@ -317,7 +332,12 @@
export_item_and_contents(AM, EXPORT_PIRATE | EXPORT_CARGO | EXPORT_CONTRABAND | EXPORT_EMAG, apply_elastic = FALSE, dry_run = TRUE, external_report = ex)
for(var/datum/export/E in ex.total_amount)
status_report += E.total_printout(ex,notes = FALSE) + "<br>"
status_report += E.total_printout(ex,notes = FALSE)
status_report += " "
value += ex.total_value[E]
if(!value)
status_report += "0"
/obj/machinery/computer/piratepad_control/proc/send()
if(!sending)
@@ -330,14 +350,15 @@
continue
export_item_and_contents(AM, EXPORT_PIRATE | EXPORT_CARGO | EXPORT_CONTRABAND | EXPORT_EMAG, apply_elastic = FALSE, delete_unsold = FALSE, external_report = ex)
status_report = "Sold:<br>"
status_report = "Sold: "
var/value = 0
for(var/datum/export/E in ex.total_amount)
var/export_text = E.total_printout(ex,notes = FALSE) //Don't want nanotrasen messages, makes no sense here.
if(!export_text)
continue
status_report += export_text + "<br>"
status_report += export_text
status_report += " "
value += ex.total_value[E]
if(!total_report)
@@ -350,11 +371,13 @@
points += value
if(!value)
status_report += "Nothing"
pad.visible_message("<span class='notice'>[pad] activates!</span>")
flick(pad.sending_state,pad)
pad.icon_state = pad.idle_state
sending = FALSE
updateDialog()
/obj/machinery/computer/piratepad_control/proc/start_sending()
if(sending)
@@ -369,24 +392,10 @@
if(!sending)
return
sending = FALSE
status_report = "Idle"
status_report = "Ready for delivery."
pad.icon_state = pad.idle_state
deltimer(sending_timer)
/obj/machinery/computer/piratepad_control/Topic(href, href_list)
if(..())
return
if(pad)
if(href_list["recalc"])
recalc()
if(href_list["send"])
start_sending()
if(href_list["stop"])
stop_sending()
updateDialog()
else
updateDialog()
/datum/export/pirate
export_category = EXPORT_PIRATE
@@ -78,6 +78,8 @@
if(!blocked)
visible_message("<span class='danger'>[src] is hit by [I]!</span>", \
"<span class='userdanger'>You're hit by [I]!</span>")
if(!I.throwforce)
return
var/armor = run_armor_check(zone, "melee", "Your armor has protected your [parse_zone(zone)].", "Your armor has softened hit to your [parse_zone(zone)].",I.armour_penetration)
apply_damage(I.throwforce, dtype, zone, armor)
if(I.thrownby)
@@ -166,7 +166,7 @@
health = 120
melee_damage_lower = 10
melee_damage_upper = 20
poison_per_bite = 5
poison_per_bite = 10
move_to_delay = 5
gold_core_spawnable = NO_SPAWN
+1844 -1816
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,4 @@
author: "Fikou"
delete-after: True
changes:
- balance: "hunter spider now has doubled poison injections"
Binary file not shown.

Before

Width:  |  Height:  |  Size: 855 B

After

Width:  |  Height:  |  Size: 836 B

@@ -0,0 +1,54 @@
import { Fragment } from 'inferno';
import { useBackend } from '../backend';
import { AnimatedNumber, Button, Box, Section, LabeledList } from '../components';
export const CargoHoldTerminal = props => {
const { act, data } = useBackend(props);
const {
points,
pad,
sending,
status_report,
} = data;
return (
<Fragment>
<Section>
<LabeledList>
<LabeledList.Item label="Current Cargo Value">
<Box inline bold>
<AnimatedNumber value={Math.round(points)} /> credits
</Box>
</LabeledList.Item>
</LabeledList>
</Section>
<Section
title="Cargo Pad"
buttons={(
<Fragment>
<Button
icon={"sync"}
content={"Recalculate Value"}
disabled={!pad}
onClick={() => act('recalc')} />
<Button
icon={sending ? 'times' : 'arrow-up'}
content={sending ? "Stop Sending" : "Send Goods"}
selected={sending}
disabled={!pad}
onClick={() => act(sending ? 'stop' : 'send')} />
</Fragment>
)}>
<LabeledList>
<LabeledList.Item
label="Status"
color={pad ? "good" : "bad"}>
{pad ? "Online" : "Not Found"}
</LabeledList.Item>
<LabeledList.Item label="Cargo Report">
{status_report}
</LabeledList.Item>
</LabeledList>
</Section>
</Fragment>
);
};
@@ -0,0 +1,163 @@
import { Fragment } from 'inferno';
import { useBackend } from '../backend';
import { Box, Button, NoticeBox, Section, Tabs, LabeledList } from '../components';
export const RoboticsControlConsole = props => {
const { state } = props;
const { act, data } = useBackend(props);
const {
can_hack,
cyborgs = [],
drones = [],
} = data;
return (
<Tabs>
<Tabs.Tab
key="cyborgs"
label={"Cyborgs " + `(${cyborgs.length})`}
icon="list"
lineHeight="23px">
{() => (
<Cyborgs state={state} cyborgs={cyborgs} can_hack={can_hack} />
)}
</Tabs.Tab>
<Tabs.Tab
key="drones"
label={"Drones " + `(${drones.length})`}
icon="list"
lineHeight="23px">
{() => (
<Drones state={state} drones={drones} />
)}
</Tabs.Tab>
</Tabs>
);
};
const Cyborgs = props => {
const { state, cyborgs, can_hack } = props;
const { act, data } = useBackend(props);
if (!cyborgs.length) {
return (
<Section>
<NoticeBox textAlign="center">
No cyborg units detected within access parameters
</NoticeBox>
</Section>
);
}
return cyborgs.map(cyborg => {
return (
<Section
key={cyborg.ref}
title={cyborg.name}
buttons={(
<Fragment>
{!!can_hack && !cyborg.emagged && (
<Button
icon="terminal"
content="Hack"
color="bad"
onClick={() => act('magbot', {
ref: cyborg.ref,
})} />
)}
<Button
icon={cyborg.locked_down ? 'unlock' : 'lock'}
color={cyborg.locked_down ? 'good' : 'default'}
content={cyborg.locked_down ? "Release" : "Lockdown"}
onClick={() => act('stopbot', {
ref: cyborg.ref,
})} />
<Button
icon="bomb"
content="Detonate"
color="bad"
onClick={() => act('killbot', {
ref: cyborg.ref,
})} />
</Fragment>
)}>
<LabeledList>
<LabeledList.Item label="Status">
<Box color={cyborg.status
? 'bad'
: cyborg.locked_down
? 'average'
: 'good'}>
{cyborg.status
? "Not Responding"
: cyborg.locked_down
? "Locked Down"
: "Nominal"}
</Box>
</LabeledList.Item>
<LabeledList.Item label="Charge">
<Box color={cyborg.charge <= 30
? 'bad'
: cyborg.charge <= 70
? 'average'
: 'good'}>
{typeof cyborg.charge === 'number'
? cyborg.charge + "%"
: "Not Found"}
</Box>
</LabeledList.Item>
<LabeledList.Item label="Module">
{cyborg.module}
</LabeledList.Item>
<LabeledList.Item label="Master AI">
{cyborg.synchronization || "None"}
</LabeledList.Item>
</LabeledList>
</Section>
);
});
};
const Drones = props => {
const { state, drones } = props;
const { act, data } = useBackend(props);
if (!drones.length) {
return (
<Section>
<NoticeBox textAlign="center">
No drone units detected within access parameters
</NoticeBox>
</Section>
);
}
return drones.map(drone => {
return (
<Section
key={drone.ref}
title={drone.name}
buttons={(
<Button
icon="bomb"
content="Detonate"
color="bad"
onClick={() => act('killdrone', {
ref: drone.ref,
})} />
)}>
<LabeledList>
<LabeledList.Item label="Status">
<Box color={drone.status
? 'bad'
: 'good'}>
{drone.status
? "Not Responding"
: 'Nominal'}
</Box>
</LabeledList.Item>
</LabeledList>
</Section>
);
});
};
File diff suppressed because one or more lines are too long
+10
View File
@@ -18,6 +18,7 @@ import { BrigTimer } from './interfaces/BrigTimer';
import { Canister } from './interfaces/Canister';
import { Canvas } from './interfaces/Canvas';
import { Cargo, CargoExpress } from './interfaces/Cargo';
import { CargoHoldTerminal } from './interfaces/CargoHoldTerminal';
import { CellularEmporium } from './interfaces/CellularEmporium';
import { CentcomPodLauncher } from './interfaces/CentcomPodLauncher';
import { ChemAcclimator } from './interfaces/ChemAcclimator';
@@ -97,6 +98,7 @@ import { ProximitySensor } from './interfaces/ProximitySensor';
import { Radio } from './interfaces/Radio';
import { RadioactiveMicrolaser } from './interfaces/RadioactiveMicrolaser';
import { RemoteRobotControl } from './interfaces/RemoteRobotControl';
import { RoboticsControlConsole } from './interfaces/RoboticsControlConsole';
import { RapidPipeDispenser } from './interfaces/RapidPipeDispenser';
import { Roulette } from './interfaces/Roulette';
import { SatelliteControl } from './interfaces/SatelliteControl';
@@ -212,6 +214,10 @@ const ROUTES = {
component: () => CargoExpress,
scrollable: true,
},
cargo_hold_terminal: {
component: () => CargoHoldTerminal,
scrollable: true,
},
cellular_emporium: {
component: () => CellularEmporium,
scrollable: true,
@@ -580,6 +586,10 @@ const ROUTES = {
component: () => RemoteRobotControl,
scrollable: true,
},
robotics_control_console: {
component: () => RoboticsControlConsole,
scrollable: true,
},
roulette: {
component: () => Roulette,
scrollable: false,