mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-24 05:30:05 +01:00
Merge branch 'master' into psychologist
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
+37894
-37877
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
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user