"
- dat += render_prompt(user)
- dat += render_choices(user)
+ dat += render_prompt()
+ dat += render_choices()
dat += " "
dat += " "
- dat += button("Submit", "submit=1", , result == null && !immediate_submit)
+ dat += render_buttons()
dat += "
"
return dat
-/datum/async_input/proc/render_prompt(mob/user)
+/datum/async_input/proc/render_prompt()
return "
"
if(convo.typing)
dat += "[current_title] is typing"
dat += " "
@@ -327,17 +339,23 @@
if(check_rights(R_ADMIN, FALSE, user))
dat += "Ping"
- var/datum/browser/popup = new(user, window_id, "Messages", 1000, 600, src)
popup.set_content(dat)
popup.open()
open = TRUE
/datum/pm_tracker/proc/fancy_title(title)
- var/client/C = pms[title].client
+ var/client/C = pms[title].client || update_client(title)
if(!C)
return "[title] (Disconnected)"
return "[key_name(C, FALSE)] ([ADMIN_QUE(C.mob,"?")]) ([ADMIN_PP(C.mob,"PP")]) ([ADMIN_VV(C.mob,"VV")]) ([ADMIN_SM(C.mob,"SM")]) ([admin_jump_link(C.mob)]) (CA)"
+/datum/pm_tracker/proc/update_client(title)
+ var/client/C = GLOB.directory[ckey(title)]
+ if(C)
+ pms[title].client = C
+ return C
+ return null
+
/datum/pm_tracker/Topic(href, href_list)
if(href_list["archive"])
pms[href_list["archive"]].archived = !pms[href_list["archive"]].archived
diff --git a/code/modules/admin/verbs/adminsay.dm b/code/modules/admin/verbs/adminsay.dm
index e3fe5af3263..6f6b3484924 100644
--- a/code/modules/admin/verbs/adminsay.dm
+++ b/code/modules/admin/verbs/adminsay.dm
@@ -17,6 +17,10 @@
feedback_add_details("admin_verb","M") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+/client/proc/get_admin_say()
+ var/msg = input(src, null, "asay \"text\"") as text|null
+ cmd_admin_say(msg)
+
/client/proc/cmd_mentor_say(msg as text)
set category = "Admin"
set name = "Msay"
diff --git a/code/modules/admin/verbs/deadsay.dm b/code/modules/admin/verbs/deadsay.dm
index 3874e26e9de..e1bbc885c75 100644
--- a/code/modules/admin/verbs/deadsay.dm
+++ b/code/modules/admin/verbs/deadsay.dm
@@ -43,3 +43,7 @@
say_dead_direct("[prefix] says, \"[msg]\"")
feedback_add_details("admin_verb","D") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/get_dead_say()
+ var/msg = input(src, null, "dsay \"text\"") as text
+ dsay(msg)
\ No newline at end of file
diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm
index 0d5a866e6c5..f2fde8df758 100644
--- a/code/modules/assembly/holder.dm
+++ b/code/modules/assembly/holder.dm
@@ -116,7 +116,7 @@
a_right.holder_movement()
/obj/item/assembly_holder/Move()
- ..()
+ . = ..()
process_movement()
return
diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm
index d6da1fb4d0e..98e59a7cbb5 100644
--- a/code/modules/assembly/infrared.dm
+++ b/code/modules/assembly/infrared.dm
@@ -106,7 +106,7 @@
/obj/item/assembly/infra/Move()
var/t = dir
- ..()
+ . = ..()
dir = t
qdel(first)
diff --git a/code/modules/client/client defines.dm b/code/modules/client/client defines.dm
index 995ee519474..fd89434331e 100644
--- a/code/modules/client/client defines.dm
+++ b/code/modules/client/client defines.dm
@@ -1,4 +1,8 @@
/client
+ //////////////////////
+ //BLACK MAGIC THINGS//
+ //////////////////////
+ parent_type = /datum
////////////////
//ADMIN THINGS//
////////////////
@@ -24,7 +28,7 @@
var/adminhelped = 0
- var/gc_destroyed //Time when this object was destroyed.
+ // var/gc_destroyed //Time when this object was destroyed. [Inherits from datum]
#ifdef TESTING
var/running_find_references
@@ -89,5 +93,5 @@
// If set to true, this client can interact with atoms such as buttons and doors on top of regular machinery interaction
var/advanced_admin_interaction = FALSE
- // Has the client been varedited by an admin?
- var/var_edited = FALSE
+ // Has the client been varedited by an admin? [Inherits from datum now]
+ // var/var_edited = FALSE
diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm
index 922502698fa..4e59dc2c1cf 100644
--- a/code/modules/client/client procs.dm
+++ b/code/modules/client/client procs.dm
@@ -297,14 +297,14 @@
return null
if(byond_build < config.minimum_client_build)
alert(src, "You are using a byond build which is not supported by this server. Please use a build version of atleast [config.minimum_client_build].", "Incorrect build", "OK")
- del(src)
+ qdel(src)
return
if(byond_version < SUGGESTED_CLIENT_VERSION) // Update is suggested, but not required.
to_chat(src,"Your BYOND client (v: [byond_version]) is out of date. This can cause glitches. We highly suggest you download the latest client from http://www.byond.com/ before playing. ")
if(IsGuestKey(key))
alert(src,"This server doesn't allow guest accounts to play. Please go to http://www.byond.com/ and register for a key.","Guest","OK")
- del(src)
+ qdel(src)
return
// Change the way they should download resources.
@@ -317,7 +317,6 @@
GLOB.clients += src
GLOB.directory[ckey] = src
-
//Admin Authorisation
// Automatically makes localhost connection an admin
if(!config.disable_localhost_admin)
@@ -365,11 +364,14 @@
. = ..() //calls mob.Login()
+
if(ckey in clientmessages)
for(var/message in clientmessages[ckey])
to_chat(src, message)
clientmessages.Remove(ckey)
+ if(SSinput.initialized)
+ set_macros()
donator_check()
check_ip_intel()
@@ -404,8 +406,7 @@
if(!winexists(src, "asset_cache_browser")) // The client is using a custom skin, tell them.
to_chat(src, "Unable to access asset cache browser, if you are using a custom skin file, please allow DS to download the updated version, if you are not, then make a bug report. This is not a critical issue but can cause issues with resource downloading, as it is impossible to know when extra resources arrived to you.")
-
-
+
//This is down here because of the browse() calls in tooltip/New()
if(!tooltips)
tooltips = new /datum/tooltip(src)
@@ -664,7 +665,7 @@
sleep(10) // Since browse is non-instant, and kinda async
to_chat(src, "
you're a huge nerd. wakka wakka doodle doop nobody's ever gonna see this, the chat system shouldn't be online by this point
")
- del(src)
+ qdel(src)
return TRUE
else
if (!topic || !topic["token"] || !tokens[ckey] || topic["token"] != tokens[ckey])
@@ -675,7 +676,7 @@
tokens[ckey] = cid_check_reconnect()
sleep(10) //browse is queued, we don't want them to disconnect before getting the browse() command.
- del(src)
+ qdel(src)
return TRUE
// We DO have their cached CID handy - compare it, now
if(oldcid != computer_id)
@@ -693,7 +694,7 @@
log_adminwarn("Failed Login: [key] [computer_id] [address] - CID randomizer confirmed (oldcid: [oldcid])")
- del(src)
+ qdel(src)
return TRUE
else
// don't shoot, I'm innocent
@@ -795,18 +796,15 @@
/* Mainwindow */
winset(src, "mainwindow.saybutton", "background-color=#40628a;text-color=#FFFFFF")
winset(src, "mainwindow.mebutton", "background-color=#40628a;text-color=#FFFFFF")
- winset(src, "mainwindow.hotkey_toggle", "background-color=#40628a;text-color=#FFFFFF")
///// UI ELEMENTS /////
/* Mainwindow */
winset(src, "mainwindow", "background-color=#272727")
winset(src, "mainwindow.mainvsplit", "background-color=#272727")
winset(src, "mainwindow.tooltip", "background-color=#272727")
/* Outputwindow */
- winset(src, "outputwindow.outputwindow", "background-color=#272727")
winset(src, "outputwindow.browseroutput", "background-color=#272727")
/* Rpane */
winset(src, "rpane", "background-color=#272727")
- winset(src, "rpane.rpane", "background-color=#272727")
winset(src, "rpane.rpanewindow", "background-color=#272727")
/* Browserwindow */
winset(src, "browserwindow", "background-color=#272727")
@@ -830,18 +828,15 @@
/* Mainwindow */
winset(src, "mainwindow.saybutton", "background-color=none;text-color=#000000")
winset(src, "mainwindow.mebutton", "background-color=none;text-color=#000000")
- winset(src, "mainwindow.hotkey_toggle", "background-color=none;text-color=#000000")
///// UI ELEMENTS /////
/* Mainwindow */
winset(src, "mainwindow", "background-color=none")
winset(src, "mainwindow.mainvsplit", "background-color=none")
winset(src, "mainwindow.tooltip", "background-color=none")
/* Outputwindow */
- winset(src, "outputwindow.outputwindow", "background-color=none")
winset(src, "outputwindow.browseroutput", "background-color=none")
/* Rpane */
winset(src, "rpane", "background-color=none")
- winset(src, "rpane.rpane", "background-color=none")
winset(src, "rpane.rpanewindow", "background-color=none")
/* Browserwindow */
winset(src, "browserwindow", "background-color=none")
diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm
index 75e0f549a1d..e09fc89736a 100644
--- a/code/modules/client/preference/preferences.dm
+++ b/code/modules/client/preference/preferences.dm
@@ -81,7 +81,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
var/lastchangelog = "" //Saved changlog filesize to detect if there was a change
var/exp
var/ooccolor = "#b82e00"
- var/be_special = list() //Special role selection
+ var/list/be_special = list() //Special role selection
var/UI_style = "Midnight"
var/nanoui_fancy = TRUE
var/toggles = TOGGLES_DEFAULT
@@ -455,6 +455,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
dat += "Ghost Ears:[(toggles & CHAT_GHOSTEARS) ? "All Speech" : "Nearest Creatures"] "
dat += "Ghost Radio:[(toggles & CHAT_GHOSTRADIO) ? "All Chatter" : "Nearest Speakers"] "
dat += "Ghost Sight:[(toggles & CHAT_GHOSTSIGHT) ? "All Emotes" : "Nearest Creatures"] "
+ dat += "Ghost PDA:[(toggles & CHAT_GHOSTPDA) ? "All PDA Messages" : "No PDA Messages"] "
if(check_rights(R_ADMIN,0))
dat += "OOC Color:Change "
if(config.allow_Metadata)
@@ -2029,6 +2030,9 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
if("ghost_radio")
toggles ^= CHAT_GHOSTRADIO
+
+ if("ghost_pda")
+ toggles ^= CHAT_GHOSTPDA
if("ghost_anonsay")
ghost_anonsay = !ghost_anonsay
@@ -2280,3 +2284,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
/datum/preferences/proc/close_load_dialog(mob/user)
user << browse(null, "window=saves")
+
+//Check if the user has ANY job selected.
+/datum/preferences/proc/check_any_job()
+ return(job_support_high || job_support_med || job_support_low || job_medsci_high || job_medsci_med || job_medsci_low || job_engsec_high || job_engsec_med || job_engsec_low || job_karma_high || job_karma_med || job_karma_low)
diff --git a/code/modules/client/preference/preferences_toggles.dm b/code/modules/client/preference/preferences_toggles.dm
index c4d7599d2de..e164a2ab843 100644
--- a/code/modules/client/preference/preferences_toggles.dm
+++ b/code/modules/client/preference/preferences_toggles.dm
@@ -241,4 +241,36 @@
to_chat(usr, "You have enabled text popup limiting.")
else
to_chat(usr, "You have disabled text popup limiting.")
+ return
+/client/verb/numpad_target()
+ set name = "Toggle Numpad targetting"
+ set category = "Preferences"
+ set desc = "This button will allow you to enable or disable Numpad Targetting"
+ prefs.toggles ^= NUMPAD_TARGET
+ prefs.save_preferences(src)
+ if (prefs.toggles & NUMPAD_TARGET)
+ to_chat(usr, "You have enabled Numpad Targetting.")
+ else
+ to_chat(usr, "You have disabled Numpad Targetting.")
+ return
+
+/client/verb/azerty_toggle()
+ set name = "Toggle QWERTY/AZERTY"
+ set category = "Preferences"
+ set desc = "This button will switch you between QWERTY and AZERTY control sets"
+ prefs.toggles ^= AZERTY
+ prefs.save_preferences(src)
+ if (prefs.toggles & AZERTY)
+ to_chat(usr, "You are now in AZERTY mode.")
+ else
+ to_chat(usr, "You are now in QWERTY mode.")
+ return
+/client/verb/toggle_ghost_pda()
+ set name = "Show/Hide GhostPDA"
+ set category = "Preferences"
+ set desc = ".Toggle seeing PDA messages as an observer."
+ prefs.toggles ^= CHAT_GHOSTPDA
+ to_chat(src, "As a ghost, you will now [(prefs.toggles & CHAT_GHOSTPDA) ? "see all PDA messages" : "no longer see PDA messages"].")
+ prefs.save_preferences(src)
+ feedback_add_details("admin_verb","TGP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm
index 227374bd420..8e5e658e31a 100644
--- a/code/modules/clothing/gloves/miscellaneous.dm
+++ b/code/modules/clothing/gloves/miscellaneous.dm
@@ -64,7 +64,6 @@
item_state = "lgloves"
flags = NODROP
-
/obj/item/clothing/gloves/color/yellow/stun
name = "stun gloves"
desc = "Horrendous and awful. It smells like cancer. The fact it has wires attached to it is incidental."
@@ -72,6 +71,9 @@
var/stun_strength = 5
var/stun_cost = 2000
+/obj/item/clothing/gloves/color/yellow/stun/get_cell()
+ return cell
+
/obj/item/clothing/gloves/color/yellow/stun/New()
..()
update_icon()
diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm
index 85840d5db42..b11dfd45d68 100644
--- a/code/modules/clothing/masks/miscellaneous.dm
+++ b/code/modules/clothing/masks/miscellaneous.dm
@@ -110,12 +110,23 @@
/obj/item/clothing/mask/muzzle/safety
name = "safety muzzle"
desc = "A muzzle designed to prevent biting."
- resist_time = 600
+ icon_state = "muzzle_secure"
+ item_state = "muzzle_secure"
+ resist_time = 0
mute = MUZZLE_MUTE_NONE
security_lock = TRUE
locked = FALSE
materials = list(MAT_METAL=500, MAT_GLASS=50)
+ sprite_sheets = list(
+ "Vox" = 'icons/mob/species/vox/mask.dmi',
+ "Unathi" = 'icons/mob/species/unathi/mask.dmi',
+ "Tajaran" = 'icons/mob/species/tajaran/mask.dmi',
+ "Vulpkanin" = 'icons/mob/species/vulpkanin/mask.dmi',
+ "Grey" = 'icons/mob/species/grey/mask.dmi',
+ "Drask" = 'icons/mob/species/drask/mask.dmi'
+ )
+
/obj/item/clothing/mask/muzzle/safety/shock
name = "shock muzzle"
desc = "A muzzle designed to prevent biting. This one is fitted with a behavior correction system."
diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm
index 913e65af734..b463a513764 100644
--- a/code/modules/clothing/spacesuits/rig/rig.dm
+++ b/code/modules/clothing/spacesuits/rig/rig.dm
@@ -97,6 +97,9 @@
to_chat(usr, "The maintenance panel is [open ? "open" : "closed"].")
to_chat(usr, "Hardsuit systems are [offline ? "offline" : "online"].")
+/obj/item/rig/get_cell()
+ return cell
+
/obj/item/rig/New()
..()
diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm
index adcb1639c12..91527f2dd19 100644
--- a/code/modules/clothing/under/miscellaneous.dm
+++ b/code/modules/clothing/under/miscellaneous.dm
@@ -857,3 +857,36 @@
icon_state = "burial"
item_state = "burial"
item_color = "burial"
+
+/obj/item/clothing/under/redhawaiianshirt
+ name = "red hawaiian shirt"
+ desc = "a floral shirt worn to most vacation destinations."
+ icon_state = "hawaiianred"
+ item_state = "hawaiianred"
+ item_color = "hawaiianred"
+ flags_size = ONESIZEFITSALL
+
+/obj/item/clothing/under/pinkhawaiianshirt
+ name = "pink hawaiian shirt"
+ desc = "a pink floral shirt the material feels cool and comfy."
+ icon_state = "hawaiianpink"
+ item_state = "hawaiianpink"
+ item_color = "hawaiianpink"
+ flags_size = ONESIZEFITSALL
+
+/obj/item/clothing/under/orangehawaiianshirt
+ name = "orange hawaiian shirt"
+ desc = "a orange floral shirt for a relaxing day in space."
+ icon_state = "hawaiianorange"
+ item_state = "hawaiianorange"
+ item_color = "hawaiianorange"
+ flags_size = ONESIZEFITSALL
+
+/obj/item/clothing/under/bluehawaiianshirt
+ name = "blue hawaiian shirt"
+ desc = "a blue floral shirt it has a oddly colored pink flower on it."
+ icon_state = "hawaiianblue"
+ item_state = "hawaiianblue"
+ item_color = "hawaiianblue"
+ flags_size = ONESIZEFITSALL
+
diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm
index e42030b6622..96fd9c11c1e 100644
--- a/code/modules/events/disease_outbreak.dm
+++ b/code/modules/events/disease_outbreak.dm
@@ -1,7 +1,7 @@
/datum/event/disease_outbreak
announceWhen = 15
- var/virus_type
+ var/datum/disease/advance/virus_type
/datum/event/disease_outbreak/setup()
announceWhen = rand(15, 30)
@@ -10,9 +10,13 @@
event_announcement.Announce("Confirmed outbreak of level 7 major viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak7.ogg')
/datum/event/disease_outbreak/start()
- if(!virus_type)
+ if(prob(25))
virus_type = pick(/datum/disease/advance/flu, /datum/disease/advance/cold, /datum/disease/brainrot, /datum/disease/magnitis, /datum/disease/beesease, /datum/disease/anxiety, /datum/disease/fake_gbs, /datum/disease/fluspanish, /datum/disease/pierrot_throat, /datum/disease/lycan)
-
+ else
+ virus_type = new /datum/disease/advance
+ virus_type.name = capitalize(pick(GLOB.adjectives)) + " " + capitalize(pick(GLOB.nouns,GLOB.verbs)) // random silly name
+ virus_type.GenerateSymptoms(1,9,6)
+ virus_type.AssignProperties(list("resistance" = rand(0,11), "stealth" = rand(0,2), "stage_rate" = rand(0,5), "transmittable" = rand(0,5), "severity" = rand(0,10)))
for(var/mob/living/carbon/human/H in shuffle(GLOB.living_mob_list))
if(issmall(H)) //don't infect monkies; that's a waste
continue
@@ -32,8 +36,8 @@
if(H.stat == DEAD || foundAlready)
continue
- var/datum/disease/D
- D = new virus_type()
+ var/datum/disease/advance/D
+ D = virus_type
D.carrier = TRUE
H.AddDisease(D)
break
diff --git a/code/modules/events/wormholes.dm b/code/modules/events/wormholes.dm
index c92ec910cdc..811eed6b9de 100644
--- a/code/modules/events/wormholes.dm
+++ b/code/modules/events/wormholes.dm
@@ -41,14 +41,14 @@
icon_state = "anom"
failchance = 0
+/obj/effect/portal/wormhole/can_teleport(atom/movable/M)
+ . = ..()
+
+ if(istype(M, /obj/singularity))
+ . = FALSE
+
/obj/effect/portal/wormhole/teleport(atom/movable/M)
- if(!istype(M))
- return FALSE
-
- if(!M.simulated || iseffect(M))
- return FALSE
-
- if(M.anchored && ismecha(M))
+ if(!can_teleport(M))
return FALSE
var/turf/target
diff --git a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
index 48b4453f6d4..3cd95f37923 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
@@ -164,7 +164,7 @@
// Virology Medical Smartfridge
// ----------------------------
/obj/machinery/smartfridge/secure/chemistry/virology
- name = "smart virus storage"
+ name = "Smart Virus Storage"
desc = "A refrigerated storage unit for volatile sample storage."
req_access_txt = "39"
spawn_meds = list(/obj/item/reagent_containers/syringe/antiviral = 4,
@@ -386,7 +386,8 @@
return data
/obj/machinery/smartfridge/Topic(href, href_list)
- if(..()) return 0
+ if(..())
+ return FALSE
var/mob/user = usr
var/datum/nanoui/ui = SSnanoui.get_open_ui(user, src, "main")
@@ -396,7 +397,7 @@
if(href_list["close"])
user.unset_machine()
ui.close()
- return 0
+ return FALSE
if(href_list["vend"])
var/index = text2num(href_list["vend"])
@@ -409,17 +410,26 @@
item_quants[K] = max(count - amount, 0)
var/i = amount
- for(var/obj/O in contents)
- if(O.name == K)
- O.forceMove(loc)
- adjust_item_drop_location(O)
- update_icon()
- i--
- if(i <= 0)
- return 1
-
- return 1
- return 0
+ if(i == 1 && Adjacent(user) && !issilicon(user))
+ for(var/obj/O in contents)
+ if(O.name == K)
+ if(!user.put_in_hands(O))
+ O.forceMove(loc)
+ adjust_item_drop_location(O)
+ update_icon()
+ break
+ return TRUE
+ else
+ for(var/obj/O in contents)
+ if(O.name == K)
+ O.forceMove(loc)
+ adjust_item_drop_location(O)
+ update_icon()
+ i--
+ if(i <= 0)
+ return TRUE
+ return TRUE
+ return FALSE
/obj/machinery/smartfridge/proc/throw_item()
var/obj/throw_item = null
diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm
index cc6c6115097..52f188a9d1d 100644
--- a/code/modules/hydroponics/biogenerator.dm
+++ b/code/modules/hydroponics/biogenerator.dm
@@ -319,6 +319,8 @@
else if(href_list["create"])
var/amount = (text2num(href_list["amount"]))
+ //Can't be outside these (if you change this keep a sane limit)
+ amount = Clamp(amount, 1, 10)
var/datum/design/D = locate(href_list["create"])
create_product(D, amount)
updateUsrDialog()
diff --git a/code/modules/keybindings/bindings_admin.dm b/code/modules/keybindings/bindings_admin.dm
new file mode 100644
index 00000000000..1413d9b0f8d
--- /dev/null
+++ b/code/modules/keybindings/bindings_admin.dm
@@ -0,0 +1,21 @@
+/datum/admins/key_down(_key, client/user)
+ switch(_key)
+ if("F5")
+ user.get_admin_say()
+ return
+ if("F6")
+ user.admin_ghost()
+ return
+ if("F7")
+ player_panel_new()
+ return
+ if("F8")
+ user.cmd_admin_pm_panel()
+ return
+ if("F9")
+ user.stealth()
+ return
+ if("F10")
+ user.get_dead_say()
+ return
+ ..()
diff --git a/code/modules/keybindings/bindings_atom.dm b/code/modules/keybindings/bindings_atom.dm
new file mode 100644
index 00000000000..6b1e0afe199
--- /dev/null
+++ b/code/modules/keybindings/bindings_atom.dm
@@ -0,0 +1,21 @@
+// You might be wondering why this isn't client level. If focus is null, we don't want you to move.
+// Only way to do that is to tie the behavior into the focus's keyLoop().
+
+/atom/movable/keyLoop(client/user)
+ if(!user.keys_held["Ctrl"])
+ var/movement_dir = NONE
+ var/list/movement = SSinput.movement_keys
+ if(user.prefs.toggles & AZERTY)
+ movement = SSinput.alt_movement_keys
+ for(var/_key in user.keys_held)
+ movement_dir = movement_dir | movement[_key]
+ if(user.next_move_dir_add)
+ movement_dir |= user.next_move_dir_add
+ if(user.next_move_dir_sub)
+ movement_dir &= ~user.next_move_dir_sub
+ // Sanity checks in case you hold left and right and up to make sure you only go up
+ if((movement_dir & NORTH) && (movement_dir & SOUTH))
+ movement_dir &= ~(NORTH|SOUTH)
+ if((movement_dir & EAST) && (movement_dir & WEST))
+ movement_dir &= ~(EAST|WEST)
+ user.Move(get_step(src, movement_dir), movement_dir)
\ No newline at end of file
diff --git a/code/modules/keybindings/bindings_carbon.dm b/code/modules/keybindings/bindings_carbon.dm
new file mode 100644
index 00000000000..81784696b35
--- /dev/null
+++ b/code/modules/keybindings/bindings_carbon.dm
@@ -0,0 +1,20 @@
+/mob/living/carbon/key_down(_key, client/user)
+ user.keys_held[_key] = world.time
+ if(!user.keys_held["Shift"])
+ switch(_key)
+ if("R", "Southwest") // Southwest is End
+ toggle_throw_mode()
+ return
+ if("1")
+ a_intent_change("help")
+ return
+ if("2")
+ a_intent_change("disarm")
+ return
+ if("3")
+ a_intent_change("grab")
+ return
+ if("4")
+ a_intent_change("harm")
+ return
+ return ..()
\ No newline at end of file
diff --git a/code/modules/keybindings/bindings_client.dm b/code/modules/keybindings/bindings_client.dm
new file mode 100644
index 00000000000..75c30f232b5
--- /dev/null
+++ b/code/modules/keybindings/bindings_client.dm
@@ -0,0 +1,56 @@
+// Clients aren't datums so we have to define these procs indpendently.
+// These verbs are called for all key press and release events
+/client/verb/keyDown(_key as text)
+ set instant = TRUE
+ set hidden = TRUE
+ keys_held[_key] = world.time
+ var/movement = SSinput.movement_keys[_key]
+ if (prefs.toggles & AZERTY) movement = SSinput.alt_movement_keys[_key]
+ if(!(next_move_dir_sub & movement) && !keys_held["Ctrl"])
+ next_move_dir_add |= movement
+
+ // Client-level keybindings are ones anyone should be able to do at any time
+ // Things like taking screenshots, hitting tab, and adminhelps.
+
+ switch(_key)
+ if("F1")
+ if(keys_held["Ctrl"] && keys_held["Shift"]) // Is this command ever used?
+ winset(src, null, "command=.options")
+ else
+ adminhelp()
+ return
+ if("F2") // Screenshot. Hold shift to choose a name and location to save in
+ ooc()
+ return
+ if("F4")
+ mob.me_verb()
+ return
+ if("F12") // Toggles minimal HUD
+ mob.button_pressed_F12()
+ return
+
+ if(holder)
+ holder.key_down(_key, src)
+ if(mob.focus)
+ mob.focus.key_down(_key, src)
+
+/client/verb/keyUp(_key as text)
+ set instant = TRUE
+ set hidden = TRUE
+ keys_held -= _key
+ var/movement = SSinput.movement_keys[_key]
+ if (prefs.toggles & AZERTY) movement = SSinput.alt_movement_keys[_key]
+ if(!(next_move_dir_add & movement))
+ next_move_dir_sub |= movement
+
+ if(holder)
+ holder.key_up(_key, src)
+ if(mob.focus)
+ mob.focus.key_up(_key, src)
+
+// Called every game tick
+/client/keyLoop()
+ if(holder)
+ holder.keyLoop(src)
+ if(mob.focus)
+ mob.focus.keyLoop(src)
\ No newline at end of file
diff --git a/code/modules/keybindings/bindings_human.dm b/code/modules/keybindings/bindings_human.dm
new file mode 100644
index 00000000000..5e8ced96ab6
--- /dev/null
+++ b/code/modules/keybindings/bindings_human.dm
@@ -0,0 +1,80 @@
+/mob/living/carbon/human/key_down(_key, client/user)
+ if(_key == "H")
+ var/obj/item/clothing/accessory/holster/H = null
+ if(istype(w_uniform, /obj/item/clothing/under))
+ var/obj/item/clothing/under/S = w_uniform
+ if(S.accessories.len)
+ H = locate() in S.accessories
+ if (!H)
+ return
+ if(!H.holstered)
+ if(!istype(get_active_hand(), /obj/item/gun))
+ to_chat(usr, "You need your gun equiped to holster it.")
+ return
+ var/obj/item/gun/W = get_active_hand()
+ H.holster(W, usr)
+ else
+ H.unholster(usr)
+ if(client.keys_held["Shift"])
+ switch(_key)
+ if("E") // Put held thing in belt or take out most recent thing from belt
+ quick_equip() // Implementing the storage component is going to take way too long
+ // var/obj/item/thing = get_active_hand()
+ // var/obj/item/equipped_belt = get_item_by_slot(slot_belt)
+ // if(!equipped_belt) // We also let you equip a belt like this
+ // if(!thing)
+ // to_chat(user, "You have no belt to take something out of.")
+ // return
+ // if(equip_to_slot_if_possible(thing, slot_belt))
+ // update_inv_r_hand()
+ // update_inv_l_hand()
+ // return
+ // if(!SEND_SIGNAL(equipped_belt, COMSIG_CONTAINS_STORAGE)) // not a storage item
+ // if(!thing)
+ // equipped_belt.attack_hand(src)
+ // else
+ // to_chat(user, "You can't fit anything in.")
+ // return
+ // if(thing) // put thing in belt
+ // if(!SEND_SIGNAL(equipped_belt, COMSIG_TRY_STORAGE_INSERT, thing, user.mob))
+ // to_chat(user, "You can't fit anything in.")
+ // return
+ // if(!equipped_belt.contents.len) // nothing to take out
+ // to_chat(user, "There's nothing in your belt to take out.")
+ // return
+ // var/obj/item/stored = equipped_belt.contents[equipped_belt.contents.len]
+ // if(!stored || stored.on_found(src))
+ // return
+ // stored.attack_hand(src) // take out thing from belt
+ // return
+
+ /* if("B") // Put held thing in backpack or take out most recent thing from backpack
+ var/obj/item/thing = get_active_hand()
+ var/obj/item/equipped_back = get_item_by_slot(slot_back)
+ if(!equipped_back) // We also let you equip a backpack like this
+ if(!thing)
+ to_chat(user, "You have no backpack to take something out of.")
+ return
+ if(equip_to_slot_if_possible(thing, slot_back))
+ update_inv_r_hand()
+ update_inv_l_hand()
+ return
+ if(!SEND_SIGNAL(equipped_back, COMSIG_CONTAINS_STORAGE)) // not a storage item
+ if(!thing)
+ equipped_back.attack_hand(src)
+ else
+ to_chat(user, "You can't fit anything in.")
+ return
+ if(thing) // put thing in backpack
+ if(!SEND_SIGNAL(equipped_back, COMSIG_TRY_STORAGE_INSERT, thing, user.mob))
+ to_chat(user, "You can't fit anything in.")
+ return
+ if(!equipped_back.contents.len) // nothing to take out
+ to_chat(user, "There's nothing in your backpack to take out.")
+ return
+ var/obj/item/stored = equipped_back.contents[equipped_back.contents.len]
+ if(!stored || stored.on_found(src))
+ return
+ stored.attack_hand(src) // take out thing from backpack
+ return */
+ return ..()
\ No newline at end of file
diff --git a/code/modules/keybindings/bindings_living.dm b/code/modules/keybindings/bindings_living.dm
new file mode 100644
index 00000000000..241bc15b608
--- /dev/null
+++ b/code/modules/keybindings/bindings_living.dm
@@ -0,0 +1,7 @@
+/mob/living/key_down(_key, client/user)
+ switch(_key)
+ if("B")
+ resist()
+ return
+
+ return ..()
\ No newline at end of file
diff --git a/code/modules/keybindings/bindings_mob.dm b/code/modules/keybindings/bindings_mob.dm
new file mode 100644
index 00000000000..4ede6b63c7b
--- /dev/null
+++ b/code/modules/keybindings/bindings_mob.dm
@@ -0,0 +1,145 @@
+// Technically the client argument is unncessary here since that SHOULD be src.client but let's not assume things
+// All it takes is one badmin setting their focus to someone else's client to mess things up
+// Or we can have NPC's send actual keypresses and detect that by seeing no client
+
+/mob/key_down(_key, client/user)
+ if(user.prefs.toggles & AZERTY)
+ switch(_key)
+ if("Delete")
+ if(!pulling)
+ to_chat(src, "You are not pulling anything.")
+ else
+ stop_pulling()
+ return
+ if("Insert", "G")
+ a_intent_change(INTENT_HOTKEY_RIGHT)
+ return
+ if("F")
+ a_intent_change(INTENT_HOTKEY_LEFT)
+ return
+ if("X", "Northeast") // Northeast is Page-up
+ swap_hand()
+ return
+ if("Y", "W", "Southeast") // Southeast is Page-down
+ mode() // attack_self(). No idea who came up with "mode()"
+ return
+ if("A", "Northwest") // Northwest is Home
+ var/obj/item/I = get_active_hand()
+ if(!I)
+ to_chat(src, "You have nothing to drop in your hand!")
+ else
+ drop_item(I)
+ return
+ if("E")
+ quick_equip()
+ return
+ if("Alt")
+ toggle_move_intent()
+ return
+ else
+ switch(_key)
+ if("Delete")
+ if(!pulling)
+ to_chat(src, "You are not pulling anything.")
+ else
+ stop_pulling()
+ return
+ if("Insert", "G")
+ a_intent_change(INTENT_HOTKEY_RIGHT)
+ return
+ if("F")
+ a_intent_change(INTENT_HOTKEY_LEFT)
+ return
+ if("X", "Northeast") // Northeast is Page-up
+ swap_hand()
+ return
+ if("Y", "Z", "Southeast") // Southeast is Page-down
+ mode() // attack_self(). No idea who came up with "mode()"
+ return
+ if("Q", "Northwest") // Northwest is Home
+ var/obj/item/I = get_active_hand()
+ if(!I)
+ to_chat(src, "You have nothing to drop in your hand!")
+ else
+ drop_item(I)
+ return
+ if("E")
+ quick_equip()
+ return
+ if("Alt")
+ toggle_move_intent()
+ return
+ //Bodypart selections
+ if(client.prefs.toggles & NUMPAD_TARGET)
+ switch(_key)
+ if("Numpad8")
+ user.body_toggle_head()
+ return
+ if("Numpad4")
+ user.body_r_arm()
+ return
+ if("Numpad5")
+ user.body_chest()
+ return
+ if("Numpad6")
+ user.body_l_arm()
+ return
+ if("Numpad1")
+ user.body_r_leg()
+ return
+ if("Numpad2")
+ user.body_groin()
+ return
+ if("Numpad3")
+ user.body_l_leg()
+ return
+ else
+ switch(_key)
+ if("Numpad1")
+ a_intent_change("help")
+ return
+ if("Numpad2")
+ a_intent_change("disarm")
+ return
+ if("Numpad3")
+ a_intent_change("grab")
+ return
+ if("Numpad4")
+ a_intent_change("harm")
+ return
+ if(client.keys_held["Ctrl"] && client.prefs.toggles & AZERTY)
+ switch(SSinput.alt_movement_keys[_key])
+ if(NORTH)
+ northface()
+ return
+ if(SOUTH)
+ southface()
+ return
+ if(WEST)
+ westface()
+ return
+ if(EAST)
+ eastface()
+ return
+ else if(client.keys_held["Ctrl"])
+ switch(SSinput.movement_keys[_key])
+ if(NORTH)
+ northface()
+ return
+ if(SOUTH)
+ southface()
+ return
+ if(WEST)
+ westface()
+ return
+ if(EAST)
+ eastface()
+ return
+ return ..()
+
+/mob/key_up(_key, client/user)
+ switch(_key)
+ if("Alt")
+ toggle_move_intent()
+ return
+ return ..()
\ No newline at end of file
diff --git a/code/modules/keybindings/bindings_robot.dm b/code/modules/keybindings/bindings_robot.dm
new file mode 100644
index 00000000000..a6b3cd3f21e
--- /dev/null
+++ b/code/modules/keybindings/bindings_robot.dm
@@ -0,0 +1,15 @@
+/mob/living/silicon/robot/key_down(_key, client/user)
+ switch(_key)
+ if("1", "2", "3")
+ toggle_module(text2num(_key))
+ return
+ if("4")
+ a_intent_change(INTENT_HOTKEY_LEFT)
+ return
+ if("X")
+ cycle_modules()
+ return
+ if("Q")
+ uneq_active()
+ return
+ return ..()
\ No newline at end of file
diff --git a/code/modules/keybindings/focus.dm b/code/modules/keybindings/focus.dm
new file mode 100644
index 00000000000..9cfbf36c5d3
--- /dev/null
+++ b/code/modules/keybindings/focus.dm
@@ -0,0 +1,8 @@
+/mob
+ var/datum/focus //What receives our keyboard inputs. src by default
+
+/mob/proc/set_focus(datum/new_focus)
+ if(focus == new_focus)
+ return
+ focus = new_focus
+ reset_perspective(focus) //Maybe this should be done manually? You figure it out, reader
\ No newline at end of file
diff --git a/code/modules/keybindings/readme.md b/code/modules/keybindings/readme.md
new file mode 100644
index 00000000000..f57d8d55ffa
--- /dev/null
+++ b/code/modules/keybindings/readme.md
@@ -0,0 +1,42 @@
+# In-code keypress handling system
+
+This whole system is heavily based off of forum_account's keyboard library.
+Thanks to forum_account for saving the day, the library can be found
+[here](https://secure.byond.com/developer/Forum_account/Keyboard)!
+
+.dmf macros have some very serious shortcomings. For example, they do not allow reusing parts
+of one macro in another, so giving cyborgs their own shortcuts to swap active module couldn't
+inherit the movement that all mobs should have anyways. The webclient only supports one macro,
+so having more than one was problematic. Additionally each keybind has to call an actual
+verb, which meant a lot of hidden verbs that just call one other proc. Also our existing
+macro was really bad and tied unrelated behavior into `Northeast()`, `Southeast()`, `Northwest()`,
+and `Southwest()`.
+
+The basic premise of this system is to not screw with .dmf macro setup at all and handle
+pressing those keys in the code instead. We have every key call `client.keyDown()`
+or `client.keyUp()` with the pressed key as an argument. Certain keys get processed
+directly by the client because they should be doable at any time, then we call
+`keyDown()` or `keyUp()` on the client's holder and the client's mob's focus.
+By default `mob.focus` is the mob itself, but you can set it to any datum to give control of a
+client's keypresses to another object. This would be a good way to handle a menu or driving
+a mech. You can also set it to null to disregard input from a certain user.
+
+Movement is handled by having each client call `client.keyLoop()` every game tick.
+As above, this calls holder and `focus.keyLoop()`. `atom/movable/keyLoop()` handles movement
+Try to keep the calculations in this proc light. It runs every tick for every client after all!
+
+You can also tell which keys are being held down now. Each client a list of keys pressed called
+`keys_held`. Each entry is a key as a text string associated with the world.time when it was
+pressed.
+
+No client-set keybindings at this time, but it shouldn't be too hard if someone wants.
+
+Notes about certain keys:
+
+* `Tab` has client-sided behavior but acts normally
+* `T`, `O`, and `M` move focus to the input when pressed. This fires the keyUp macro right away.
+* `\` needs to be escaped in the dmf so any usage is `\\`
+
+You cannot `TICK_CHECK` or check `world.tick_usage` inside of procs called by key down and up
+events. They happen outside of a byond tick and have no meaning there. Key looping
+works correctly since it's part of a subsystem, not direct input.
\ No newline at end of file
diff --git a/code/modules/keybindings/setup.dm b/code/modules/keybindings/setup.dm
new file mode 100644
index 00000000000..ad87622b709
--- /dev/null
+++ b/code/modules/keybindings/setup.dm
@@ -0,0 +1,46 @@
+/client
+ var/list/keys_held = list() // A list of any keys held currently
+ // These next two vars are to apply movement for keypresses and releases made while move delayed.
+ // Because discarding that input makes the game less responsive.
+ var/next_move_dir_add // On next move, add this dir to the move that would otherwise be done
+ var/next_move_dir_sub // On next move, subtract this dir from the move that would otherwise be done
+
+// Set a client's focus to an object and override these procs on that object to let it handle keypresses
+
+/datum/proc/key_down(key, client/user) // Called when a key is pressed down initially
+ return
+/datum/proc/key_up(key, client/user) // Called when a key is released
+ return
+/datum/proc/keyLoop(client/user) // Called once every frame
+ set waitfor = FALSE
+ return
+
+// removes all the existing macros
+/client/proc/erase_all_macros()
+ var/list/macro_sets = params2list(winget(src, null, "macros"))
+ var/erase_output = ""
+ for(var/i in 1 to macro_sets.len)
+ var/setname = macro_sets[i]
+ var/list/macro_set = params2list(winget(src, "[setname].*", "command")) // The third arg doesnt matter here as we're just removing them all
+ for(var/k in 1 to macro_set.len)
+ var/list/split_name = splittext(macro_set[k], ".")
+ var/macro_name = "[split_name[1]].[split_name[2]]" // [3] is "command"
+ erase_output = "[erase_output];[macro_name].parent=null"
+ winset(src, null, erase_output)
+
+/client/proc/set_macros()
+ set waitfor = FALSE
+
+ erase_all_macros()
+
+ var/list/macro_sets = SSinput.macro_sets
+ for(var/i in 1 to macro_sets.len)
+ var/setname = macro_sets[i]
+ if(setname != "default")
+ winclone(src, "default", setname)
+ var/list/macro_set = macro_sets[setname]
+ for(var/k in 1 to macro_set.len)
+ var/key = macro_set[k]
+ var/command = macro_set[key]
+ winset(src, "[setname]-\ref[key]", "parent=[setname];name=[key];command=[command]")
+ winset(src, null, "input.focus=true input.background-color=[COLOR_INPUT_ENABLED] mainwindow.macro=default")
diff --git a/code/modules/mining/equipment/survival_pod.dm b/code/modules/mining/equipment/survival_pod.dm
index d846e065761..9a88dd50259 100644
--- a/code/modules/mining/equipment/survival_pod.dm
+++ b/code/modules/mining/equipment/survival_pod.dm
@@ -238,6 +238,9 @@
/obj/machinery/smartfridge/survival_pod/accept_check(obj/item/O)
return isitem(O)
+/obj/machinery/smartfridge/survival_pod/default_unfasten_wrench()
+ return FALSE
+
/obj/machinery/smartfridge/survival_pod/empty
name = "dusty survival pod storage"
desc = "A heated storage unit. This one's seen better days."
diff --git a/code/modules/mining/equipment_locker.dm b/code/modules/mining/equipment_locker.dm
index 10823051563..9d6ca608759 100644
--- a/code/modules/mining/equipment_locker.dm
+++ b/code/modules/mining/equipment_locker.dm
@@ -905,6 +905,7 @@
throw_range = 5
var/loaded = 1
var/malfunctioning = 0
+ var/revive_type = SENTIENCE_ORGANIC //So you can't revive boss monsters or robots with it
/obj/item/lazarus_injector/afterattack(atom/target, mob/user, proximity_flag)
if(!loaded)
@@ -912,6 +913,9 @@
if(istype(target, /mob/living) && proximity_flag)
if(istype(target, /mob/living/simple_animal))
var/mob/living/simple_animal/M = target
+ if(M.sentience_type != revive_type)
+ to_chat(user, "[src] does not work on this sort of creature.")
+ return
if(M.stat == DEAD)
M.faction = list("neutral")
M.revive()
diff --git a/code/modules/mining/explorer_gear.dm b/code/modules/mining/explorer_gear.dm
index 6453f54c979..a9464efe959 100644
--- a/code/modules/mining/explorer_gear.dm
+++ b/code/modules/mining/explorer_gear.dm
@@ -1,43 +1,44 @@
-/****************Explorer's Suit and Mask****************/
-/obj/item/clothing/suit/hooded/explorer
- name = "explorer suit"
- desc = "An armoured suit for exploring harsh environments."
- icon_state = "explorer"
- item_state = "explorer"
- body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
- min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
- cold_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
- max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
- heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
- hoodtype = /obj/item/clothing/head/hooded/explorer
- armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50)
- allowed = list(/obj/item/flashlight, /obj/item/tank, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe)
- resistance_flags = FIRE_PROOF
-
- sprite_sheets = list(
- "Vox" = 'icons/mob/species/vox/suit.dmi',
- "Drask" = 'icons/mob/species/drask/suit.dmi',
- "Tajaran" = 'icons/mob/species/tajaran/suit.dmi',
- "Unathi" = 'icons/mob/species/unathi/suit.dmi',
- "Vulpkanin" = 'icons/mob/species/vulpkanin/suit.dmi'
- )
-
-/obj/item/clothing/head/hooded/explorer
- name = "explorer hood"
- desc = "An armoured hood for exploring harsh environments."
- icon_state = "explorer"
- item_state = "explorer"
- body_parts_covered = HEAD
- flags = BLOCKHAIR | NODROP
- flags_cover = HEADCOVERSEYES
- min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
- max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT
- armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50)
- resistance_flags = FIRE_PROOF
-
- sprite_sheets = list(
- "Vox" = 'icons/mob/species/vox/head.dmi',
- "Drask" = 'icons/mob/species/drask/head.dmi',
- "Grey" = 'icons/mob/species/grey/head.dmi',
- "Skrell" = 'icons/mob/species/skrell/head.dmi'
+/****************Explorer's Suit and Mask****************/
+/obj/item/clothing/suit/hooded/explorer
+ name = "explorer suit"
+ desc = "An armoured suit for exploring harsh environments."
+ icon_state = "explorer"
+ item_state = "explorer"
+ body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
+ min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
+ cold_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
+ max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
+ heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
+ hoodtype = /obj/item/clothing/head/hooded/explorer
+ armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50)
+ allowed = list(/obj/item/flashlight, /obj/item/tank, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe)
+ resistance_flags = FIRE_PROOF
+ hide_tail_by_species = list("Vox" , "Vulpkanin" , "Unathi" , "Tajaran")
+
+ sprite_sheets = list(
+ "Vox" = 'icons/mob/species/vox/suit.dmi',
+ "Drask" = 'icons/mob/species/drask/suit.dmi',
+ "Tajaran" = 'icons/mob/species/tajaran/suit.dmi',
+ "Unathi" = 'icons/mob/species/unathi/suit.dmi',
+ "Vulpkanin" = 'icons/mob/species/vulpkanin/suit.dmi'
+ )
+
+/obj/item/clothing/head/hooded/explorer
+ name = "explorer hood"
+ desc = "An armoured hood for exploring harsh environments."
+ icon_state = "explorer"
+ item_state = "explorer"
+ body_parts_covered = HEAD
+ flags = BLOCKHAIR | NODROP
+ flags_cover = HEADCOVERSEYES
+ min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
+ max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT
+ armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50)
+ resistance_flags = FIRE_PROOF
+
+ sprite_sheets = list(
+ "Vox" = 'icons/mob/species/vox/head.dmi',
+ "Drask" = 'icons/mob/species/drask/head.dmi',
+ "Grey" = 'icons/mob/species/grey/head.dmi',
+ "Skrell" = 'icons/mob/species/skrell/head.dmi'
)
\ No newline at end of file
diff --git a/code/modules/mining/laborcamp/laborstacker.dm b/code/modules/mining/laborcamp/laborstacker.dm
index d3e22e5bca2..fb2b915f146 100644
--- a/code/modules/mining/laborcamp/laborstacker.dm
+++ b/code/modules/mining/laborcamp/laborstacker.dm
@@ -1,3 +1,5 @@
+GLOBAL_LIST(labor_sheet_values)
+
/**********************Prisoners' Console**************************/
/obj/machinery/mineral/labor_claim_console
@@ -5,153 +7,153 @@
desc = "A stacking console with an electromagnetic writer, used to track ore mined by prisoners."
icon = 'icons/obj/machines/mining_machines.dmi'
icon_state = "console"
- density = 0
- anchored = 1
- var/obj/machinery/mineral/stacking_machine/laborstacker/machine = null
+ density = FALSE
+ var/obj/machinery/mineral/stacking_machine/laborstacker/stacking_machine = null
var/machinedir = SOUTH
var/obj/item/card/id/prisoner/inserted_id
var/obj/machinery/door/airlock/release_door
var/door_tag = "prisonshuttle"
- var/use_release_door = 0
var/obj/item/radio/intercom/announcer
-
-/obj/machinery/mineral/labor_claim_console/New()
- ..()
+/obj/machinery/mineral/labor_claim_console/Initialize()
+ . = ..()
announcer = new /obj/item/radio/intercom(null)
announcer.config(list("Security" = 0))
+ locate_stacking_machine()
- spawn(7)
- src.machine = locate(/obj/machinery/mineral/stacking_machine, get_step(src, machinedir))
- var/t
- for(var/obj/machinery/door/airlock/d in range(5,src))
- t = d.id_tag
- if(t == src.door_tag)
- src.release_door = d
- if(machine && (release_door || !use_release_door))
- machine.CONSOLE = src
+ if(!GLOB.labor_sheet_values)
+ var/sheet_list = list()
+ for(var/sheet_type in subtypesof(/obj/item/stack/sheet))
+ var/obj/item/stack/sheet/sheet = sheet_type
+ if(!initial(sheet.point_value) || (initial(sheet.merge_type) && initial(sheet.merge_type) != sheet_type)) //ignore no-value sheets and x/fifty subtypes
+ continue
+ sheet_list += list(list("ore" = initial(sheet.name), "value" = initial(sheet.point_value)))
+ GLOB.labor_sheet_values = sheet_list
+
+/obj/machinery/mineral/labor_claim_console/Destroy()
+ . = ..()
+ QDEL_NULL(announcer)
+
+/proc/cmp_sheet_list(list/a, list/b)
+ return a["value"] - b["value"]
+
+/obj/machinery/mineral/labor_claim_console/attackby(obj/item/I, mob/user, params)
+ if(istype(I, /obj/item/card/id/prisoner))
+ if(!inserted_id)
+ if(!user.unEquip(I))
+ return
+ I.forceMove(src)
+ inserted_id = I
+ to_chat(user, "You insert [I].")
+ SSnanoui.update_uis(src)
+ return
else
- qdel(src)
+ to_chat(user, "There's an ID inserted already.")
+ return ..()
+
+/obj/machinery/mineral/labor_claim_console/attack_hand(mob/user)
+ ui_interact(user)
+
+/obj/machinery/mineral/labor_claim_console/attack_ghost(mob/user)
+ attack_hand(user)
+
+/obj/machinery/mineral/labor_claim_console/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = default_state)
+ ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
+ if(!ui)
+ ui = new(user, src, ui_key, "labor_claim_console.tmpl", name, 450, 625, state)
+ ui.open()
+
+/obj/machinery/mineral/labor_claim_console/ui_data(mob/user)
+ var/list/data = list()
+ var/can_go_home = FALSE
+
+ data["emagged"] = (emagged) ? TRUE : FALSE
+ if(inserted_id)
+ data["id"] = inserted_id
+ data["id_name"] = inserted_id.registered_name
+ data["points"] = inserted_id.points
+ data["goal"] = inserted_id.goal
+ if(check_auth())
+ can_go_home = TRUE
+
+ if(stacking_machine)
+ data["unclaimed_points"] = stacking_machine.points
+
+ data["ores"] = GLOB.labor_sheet_values
+ data["can_go_home"] = can_go_home
+
+ return data
+
+/obj/machinery/mineral/labor_claim_console/Topic(href, href_list)
+ if(..())
+ return TRUE
+
+ if(href_list["handle_id"])
+ if(inserted_id)
+ if(!usr.put_in_hands(inserted_id))
+ inserted_id.forceMove(get_turf(src))
+ inserted_id = null
+ else
+ var/obj/item/I = usr.get_active_hand()
+ if(istype(I, /obj/item/card/id/prisoner))
+ if(!usr.unEquip(I))
+ return
+ I.forceMove(src)
+ inserted_id = I
+ if(href_list["claim_points"])
+ inserted_id.points += stacking_machine.points
+ stacking_machine.points = 0
+ to_chat(usr, "Points transferred.")
+ if(href_list["move_shuttle"])
+ if(!alone_in_area(get_area(src), usr))
+ to_chat(usr, "Prisoners are only allowed to be released while alone.")
+ else
+ switch(SSshuttle.moveShuttle("laborcamp", "laborcamp_home", TRUE))
+ if(1)
+ to_chat(usr, "Shuttle not found.")
+ if(2)
+ to_chat(usr, "Shuttle already at station.")
+ if(3)
+ to_chat(usr, "No permission to dock could be granted.")
+ else
+ if(!(emagged))
+ var/message = "[inserted_id.registered_name] has returned to the station. Minerals and Prisoner ID card ready for retrieval."
+ announcer.autosay(message, "Labor Camp Controller", "Security")
+ to_chat(usr, "Shuttle received message and will be sent shortly.")
+
+ return TRUE
/obj/machinery/mineral/labor_claim_console/proc/check_auth()
- if(emagged) return 1 //Shuttle is emagged, let any ol' person through
+ if(emagged)
+ return TRUE //Shuttle is emagged, let any ol' person through
return (istype(inserted_id) && inserted_id.points >= inserted_id.goal) //Otherwise, only let them out if the prisoner's reached his quota.
+/obj/machinery/mineral/labor_claim_console/proc/locate_stacking_machine()
+ stacking_machine = locate(/obj/machinery/mineral/stacking_machine, get_step(src, machinedir))
+ if(stacking_machine)
+ stacking_machine.CONSOLE = src
+ else
+ qdel(src)
-/obj/machinery/mineral/labor_claim_console/attack_hand(user as mob)
- var/dat
- dat += text("Point Claim Console
")
- if(emagged) //Shit's broken
- dat += text("QUt0A In%aL*D ")
- else if(istype(inserted_id)) //There's an ID in there.
- dat += text("ID: [inserted_id.registered_name] Eject ID. ")
- dat += text("Points Collected:[inserted_id.points] ")
- dat += text("Point Quota: [inserted_id.goal] - Reach your quota to earn your release ")
- dat += text("Unclaimed Collection Points: [machine.points]. Claim points. ")
- else //No ID in sight. Complain about it.
- dat += text("No ID inserted. Insert ID. ")
- if(check_auth())
- dat += text("Proceed to station. ")
- if(use_release_door)
- dat += text("Open release door. ")
- if(machine)
- dat += text("Mineral Value List: [machine.get_ore_values()]")
-
-
- user << browse("[dat]", "window=console_stacking_machine")
-
-
-/obj/machinery/mineral/labor_claim_console/attackby(obj/item/I as obj, mob/user as mob, params)
- if(istype(I, /obj/item/card/id))
- return attack_hand(user)
- ..()
-
-/obj/machinery/mineral/labor_claim_console/emag_act(user as mob)
- emag(user)
-
-/obj/machinery/mineral/labor_claim_console/proc/emag(mob/user as mob)
- if(!emagged)
- emagged = 1
+/obj/machinery/mineral/labor_claim_console/emag_act(mob/user)
+ if(!(emagged))
+ emagged = TRUE
to_chat(user, "PZZTTPFFFT")
-
-/obj/machinery/mineral/labor_claim_console/Topic(href, href_list)
- usr.set_machine(src)
- src.add_fingerprint(usr)
- if(href_list["choice"])
- if(istype(inserted_id)) //Sanity check against href spoofs
- if(href_list["choice"] == "eject")
- inserted_id.loc = loc
- inserted_id.verb_pickup()
- inserted_id = null
- if(href_list["choice"] == "claim")
- inserted_id.points += machine.points
- machine.points = 0
- to_chat(src, "Points transferred.")
- else if(href_list["choice"] == "insert")
- var/obj/item/card/id/prisoner/I = usr.get_active_hand()
- if(istype(I))
- usr.drop_item()
- I.loc = src
- inserted_id = I
- else
- to_chat(usr, "Invalid ID.")
- if(check_auth()) //Sanity check against hef spoofs
- if(href_list["choice"] == "station")
- if(!alone_in_area(get_area(src), usr))
- to_chat(usr, "Prisoners are only allowed to be released while alone.")
- else
- switch(SSshuttle.moveShuttle("laborcamp","laborcamp_home"))
- if(1)
- to_chat(usr, "Shuttle not found")
- if(2)
- to_chat(usr, "Shuttle already at station")
- if(3)
- to_chat(usr, "No permission to dock could be granted.")
- else
- var/message = "[inserted_id.registered_name] has returned to the station. Minerals and Prisoner ID card ready for retrieval."
- announcer.autosay(message, "Labor Camp Controller", "Security")
- to_chat(usr, "Shuttle received message and will be sent shortly.")
-
- if(href_list["choice"] == "release")
- if(alone_in_area(get_area(loc), usr))
- var/obj/docking_port/stationary/S = SSshuttle.getDock("laborcamp_home")
- if(S && S.get_docked())
- if(release_door && release_door.density)
- release_door.open()
- else
- to_chat(usr, "Prisoners can only be released while docked with the station.")
- else
- to_chat(usr, "Prisoners are only allowed to be released while alone.")
-
- src.updateUsrDialog()
- return
-
-
/**********************Prisoner Collection Unit**************************/
-
-
/obj/machinery/mineral/stacking_machine/laborstacker
- var/points = 0 //The unclaimed value of ore stacked. Value for each ore loosely relative to its rarity.
- var/list/ore_values = list(("glass" = 1), ("metal" = 2), ("solid plasma" = 20), ("plasteel" = 23), ("reinforced glass" = 4), ("gold" = 20), ("silver" = 20), ("uranium" = 20), ("diamond" = 25), ("bananium" = 50), ("tranquillite" = 50))
-
-/obj/machinery/mineral/stacking_machine/laborstacker/proc/get_ore_values()
- var/dat = "
"
- for(var/ore in ore_values)
- var/value = ore_values[ore]
- dat += "
[capitalize(ore)]
[value]
"
- dat += "
"
- return dat
+ var/points = 0 //The unclaimed value of ore stacked.
/obj/machinery/mineral/stacking_machine/laborstacker/process_sheet(obj/item/stack/sheet/inp)
- if(istype(inp))
- var/n = inp.name
- var/a = inp.amount
- if(n in ore_values)
- points += ore_values[n] * a
+ points += inp.point_value * inp.amount
..()
+/obj/machinery/mineral/stacking_machine/laborstacker/attackby(obj/item/I, mob/living/user)
+ if(istype(I, /obj/item/stack/sheet) && user.canUnEquip(I))
+ var/obj/item/stack/sheet/inp = I
+ points += inp.point_value * inp.amount
+ return ..()
/**********************Point Lookup Console**************************/
/obj/machinery/mineral/labor_points_checker
@@ -159,13 +161,15 @@
desc = "A console used by prisoners to check the progress on their quotas. Simply swipe a prisoner ID."
icon = 'icons/obj/machines/mining_machines.dmi'
icon_state = "console"
- density = 0
- anchored = 1
+ density = FALSE
/obj/machinery/mineral/labor_points_checker/attack_hand(mob/user)
- user.examine(src)
+ . = ..()
+ if(.)
+ return
+ user.examinate(src)
-/obj/machinery/mineral/labor_points_checker/attackby(obj/item/I as obj, mob/user as mob, params)
+/obj/machinery/mineral/labor_points_checker/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/card/id))
if(istype(I, /obj/item/card/id/prisoner))
var/obj/item/card/id/prisoner/prisoner_id = I
@@ -175,5 +179,5 @@
to_chat(user, "Collect points by bringing smelted minerals to the Labor Shuttle stacking machine. Reach your quota to earn your release.")
else
to_chat(user, "Error: Invalid ID")
- return
- ..()
+ else
+ return ..()
\ No newline at end of file
diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm
index 8ba8b13c09c..f10b78dc526 100644
--- a/code/modules/mining/mine_items.dm
+++ b/code/modules/mining/mine_items.dm
@@ -82,6 +82,7 @@
/obj/item/flashlight/lantern
name = "lantern"
icon_state = "lantern"
+ item_state = "lantern"
desc = "A mining lantern."
brightness_on = 6 // luminosity when on
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index c8c7d5c32e3..2d1ff8d82da 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -263,7 +263,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
..()
statpanel("Status")
if(client.statpanel == "Status")
- show_stat_station_time()
show_stat_emergency_shuttle_eta()
stat(null, "Respawnability: [(src in GLOB.respawnable_list) ? "Yes" : "No"]")
@@ -402,9 +401,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
to_chat(usr, "Not when you're not dead!")
return
- var/area/A = input("Area to jump to", "BOOYEA") as null|anything in ghostteleportlocs
- var/area/thearea = ghostteleportlocs[A]
+ var/datum/async_input/A = input_autocomplete_async(usr, "Area to jump to: ", ghostteleportlocs)
+ A.on_close(CALLBACK(src, .proc/teleport))
+/mob/dead/observer/proc/teleport(area/thearea)
if(!thearea)
return
@@ -425,9 +425,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set desc = "Follow and orbit a mob."
var/list/mobs = getpois(skip_mindless=1)
- var/input = input("Please, select a mob!", "Haunt", null, null) as null|anything in mobs
- var/mob/target = mobs[input]
- ManualFollow(target)
+ var/datum/async_input/A = input_autocomplete_async(usr, "Please, select a mob: ", mobs)
+ A.on_close(CALLBACK(src, .proc/ManualFollow))
// This is the ghost's follow verb with an argument
/mob/dead/observer/proc/ManualFollow(var/atom/movable/target)
@@ -499,25 +498,21 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set name = "Jump to Mob"
set desc = "Teleport to a mob"
- if(isobserver(usr)) //Make sure they're an observer!
- var/list/dest = list() //List of possible destinations (mobs)
- var/target = null //Chosen target.
+ if(isobserver(usr)) //Make sure they're an observer!
+ var/list/dest = getpois(mobs_only=1) //Fill list, prompt user with list
+ var/datum/async_input/A = input_autocomplete_async(usr, "Enter a mob name: ", dest)
+ A.on_close(CALLBACK(src, .proc/jump_to_mob))
- dest += getpois(mobs_only=1) //Fill list, prompt user with list
- target = input("Please, select a mob!", "Jump to Mob", null, null) as null|anything in dest
-
- if(!target) //Make sure we actually have a target
- return
- else
- var/mob/M = dest[target] //Destination mob
- var/mob/A = src //Source mob
- var/turf/T = get_turf(M) //Turf of the destination mob
-
- if(T && isturf(T)) //Make sure the turf exists, then move the source to that destination.
- A.forceMove(T)
- else
- to_chat(A, "This mob is not located in the game world.")
+/mob/dead/observer/proc/jump_to_mob(mob/M)
+ if(!M)
+ return
+ var/mob/A = src //Source mob
+ var/turf/T = get_turf(M) //Turf of the destination mob
+ if(T && isturf(T)) //Make sure the turf exists, then move the source to that destination.
+ A.forceMove(T)
+ return
+ to_chat(A, "This mob is not located in the game world.")
/* Now a spell. See spells.dm
/mob/dead/observer/verb/boo()
diff --git a/code/modules/mob/dead/observer/spells.dm b/code/modules/mob/dead/observer/spells.dm
index 916ff9aa9b8..e890098b29b 100644
--- a/code/modules/mob/dead/observer/spells.dm
+++ b/code/modules/mob/dead/observer/spells.dm
@@ -15,6 +15,7 @@ GLOBAL_LIST_INIT(boo_phrases, list(
ghost = TRUE
+ action_icon_state = "boo"
school = "transmutation"
charge_max = 600
starts_charged = FALSE
diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm
index bb7bcfc94e1..35a08d0ce10 100644
--- a/code/modules/mob/inventory.dm
+++ b/code/modules/mob/inventory.dm
@@ -6,6 +6,14 @@
if(hand) return l_hand
else return r_hand
+/mob/verb/quick_equip()
+ set name = "quick-equip"
+ set hidden = 1
+
+ var/obj/item/I = get_active_hand()
+ if(I)
+ I.equip_to_best_slot(src)
+
/mob/proc/is_in_active_hand(obj/item/I)
var/obj/item/item_to_test = get_active_hand()
@@ -254,3 +262,4 @@
if(slot_r_hand)
return r_hand
return null
+
diff --git a/code/modules/mob/living/carbon/brain/brain.dm b/code/modules/mob/living/carbon/brain/brain.dm
index df0afa62f49..8d17b84c724 100644
--- a/code/modules/mob/living/carbon/brain/brain.dm
+++ b/code/modules/mob/living/carbon/brain/brain.dm
@@ -95,7 +95,6 @@ I'm using this for Stat to give it a more nifty interface to work with
..()
if(has_synthetic_assistance())
statpanel("Status")
- show_stat_station_time()
show_stat_emergency_shuttle_eta()
if(client.statpanel == "Status")
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 2c7a2d67c55..a8dbaa7ac2f 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -216,56 +216,7 @@
add_attack_logs(M, src, "Shaked", ATKLOG_ALL)
if(health >= HEALTH_THRESHOLD_CRIT)
if(src == M && ishuman(src))
- var/mob/living/carbon/human/H = src
- visible_message( \
- text("[src] examines [].",gender==MALE?"himself":"herself"), \
- "You check yourself for injuries." \
- )
-
- var/list/missing = list("head", "chest", "groin", "l_arm", "r_arm", "l_hand", "r_hand", "l_leg", "r_leg", "l_foot", "r_foot")
- for(var/X in H.bodyparts)
- var/obj/item/organ/external/LB = X
- missing -= LB.limb_name
- var/status = ""
- var/brutedamage = LB.brute_dam
- var/burndamage = LB.burn_dam
-
- if(brutedamage > 0)
- status = "bruised"
- if(brutedamage > 20)
- status = "battered"
- if(brutedamage > 40)
- status = "mangled"
- if(brutedamage > 0 && burndamage > 0)
- status += " and "
- if(burndamage > 40)
- status += "peeling away"
-
- else if(burndamage > 10)
- status += "blistered"
- else if(burndamage > 0)
- status += "numb"
- if(LB.status & ORGAN_MUTATED)
- status = "weirdly shapen."
- if(status == "")
- status = "OK"
- to_chat(src, "\t Your [LB.name] is [status].")
-
- for(var/obj/item/I in LB.embedded_objects)
- to_chat(src, "\t There is \a [I] embedded in your [LB.name]!")
-
- for(var/t in missing)
- to_chat(src, "Your [parse_zone(t)] is missing!")
-
- if(H.bleed_rate)
- to_chat(src, "You are bleeding!")
- if(staminaloss)
- if(staminaloss > 30)
- to_chat(src, "You're completely exhausted.")
- else
- to_chat(src, "You feel fatigued.")
- if((SKELETON in H.mutations) && (!H.w_uniform) && (!H.wear_suit))
- H.play_xylophone()
+ check_self_for_injuries()
else
if(player_logged)
M.visible_message("[M] shakes [src], but [p_they()] [p_do()] not respond. Probably suffering from SSD.", \
@@ -308,6 +259,58 @@
else if(H.w_uniform)
H.w_uniform.add_fingerprint(M)
+/mob/living/carbon/proc/check_self_for_injuries()
+ var/mob/living/carbon/human/H = src
+ visible_message( \
+ text("[src] examines [].",gender==MALE?"himself":"herself"), \
+ "You check yourself for injuries." \
+ )
+
+ var/list/missing = list("head", "chest", "groin", "l_arm", "r_arm", "l_hand", "r_hand", "l_leg", "r_leg", "l_foot", "r_foot")
+ for(var/X in H.bodyparts)
+ var/obj/item/organ/external/LB = X
+ missing -= LB.limb_name
+ var/status = ""
+ var/brutedamage = LB.brute_dam
+ var/burndamage = LB.burn_dam
+
+ if(brutedamage > 0)
+ status = "bruised"
+ if(brutedamage > 20)
+ status = "battered"
+ if(brutedamage > 40)
+ status = "mangled"
+ if(brutedamage > 0 && burndamage > 0)
+ status += " and "
+ if(burndamage > 40)
+ status += "peeling away"
+
+ else if(burndamage > 10)
+ status += "blistered"
+ else if(burndamage > 0)
+ status += "numb"
+ if(LB.status & ORGAN_MUTATED)
+ status = "weirdly shapen."
+ if(status == "")
+ status = "OK"
+ to_chat(src, "\t Your [LB.name] is [status].")
+
+ for(var/obj/item/I in LB.embedded_objects)
+ to_chat(src, "\t There is \a [I] embedded in your [LB.name]!")
+
+ for(var/t in missing)
+ to_chat(src, "Your [parse_zone(t)] is missing!")
+
+ if(H.bleed_rate)
+ to_chat(src, "You are bleeding!")
+ if(staminaloss)
+ if(staminaloss > 30)
+ to_chat(src, "You're completely exhausted.")
+ else
+ to_chat(src, "You feel fatigued.")
+ if((SKELETON in H.mutations) && (!H.w_uniform) && (!H.wear_suit))
+ H.play_xylophone()
+
/mob/living/carbon/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0)
. = ..()
var/damage = intensity - check_eye_prot()
@@ -972,6 +975,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
to_chat(src, "You [slipVerb]ped on [description]!")
playsound(src.loc, 'sound/misc/slip.ogg', 50, 1, -3)
// Something something don't run with scissors
+ moving_diagonally = 0 //If this was part of diagonal move slipping will stop it.
Stun(stun)
Weaken(weaken)
return 1
diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm
index 52636efb896..c0e8badf35d 100644
--- a/code/modules/mob/living/carbon/human/emote.dm
+++ b/code/modules/mob/living/carbon/human/emote.dm
@@ -106,6 +106,12 @@
else //Everyone else fails, skip the emote attempt
return
+ if("warble", "warbles")
+ if(isskrell(src)) //Only Skrell can warble.
+ on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm'
+ else //Everyone else fails, skip the emote attempt
+ return
+
if("scream", "screams")
on_CD = handle_emote_CD(50) //longer cooldown
if("fart", "farts", "flip", "flips", "snap", "snaps")
@@ -221,6 +227,13 @@
playsound(loc, 'sound/effects/voxrustle.ogg', 50, 0) //Credit to sound-ideas (freesfx.co.uk) for the sound.
m_type = 2
+ if("warble", "warbles")
+ var/M = handle_emote_param(param)
+
+ message = "[src] warbles[M ? " at [M]" : ""]."
+ playsound(loc, 'sound/effects/warble.ogg', 50, 0) // Copyright CC BY 3.0 alienistcog (freesound.org) for the sound.
+ m_type = 2
+
if("yes")
var/M = handle_emote_param(param)
@@ -904,6 +917,8 @@
emotelist += "\nVox specific emotes :- quill(s)"
if("Diona")
emotelist += "\nDiona specific emotes :- creak(s)"
+ if("Skrell")
+ emotelist += "\nSkrell specific emotes :- warble(s)"
if(ismachine(src))
emotelist += "\nMachine specific emotes :- beep(s)-(none)/mob, buzz(es)-none/mob, no-(none)/mob, ping(s)-(none)/mob, yes-(none)/mob, buzz2-(none)/mob"
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index bc0c33c233d..6481f6bc04a 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -162,8 +162,6 @@
stat(null, "Intent: [a_intent]")
stat(null, "Move Mode: [m_intent]")
- show_stat_station_time()
-
show_stat_emergency_shuttle_eta()
if(client.statpanel == "Status")
@@ -1480,19 +1478,22 @@
if(usr != src)
return 0 //something is terribly wrong
-
+ if(incapacitated())
+ to_chat(src, "You can't write on the floor in your current state!")
+ return
if(!bloody_hands)
verbs -= /mob/living/carbon/human/proc/bloody_doodle
- if(src.gloves)
- to_chat(src, "Your [src.gloves] are getting in the way.")
+ if(gloves)
+ to_chat(src, "[gloves] are preventing you from writing anything down!")
return
- var/turf/simulated/T = src.loc
+ var/turf/simulated/T = loc
if(!istype(T)) //to prevent doodling out of mechs and lockers
to_chat(src, "You cannot reach the floor.")
return
+ var/turf/origin = T
var/direction = input(src,"Which way?","Tile selection") as anything in list("Here","North","South","East","West")
if(direction != "Here")
T = get_step(T,text2dir(direction))
@@ -1510,7 +1511,9 @@
var/max_length = bloody_hands * 30 //tweeter style
var/message = stripped_input(src,"Write a message. It cannot be longer than [max_length] characters.","Blood writing", "")
-
+ if(origin != loc)
+ to_chat(src, "Stay still while writing!")
+ return
if(message)
var/used_blood_amount = round(length(message) / 30, 1)
bloody_hands = max(0, bloody_hands - used_blood_amount) //use up some blood
@@ -1518,7 +1521,8 @@
if(length(message) > max_length)
message += "-"
to_chat(src, "You ran out of blood to write with!")
-
+ else
+ to_chat(src, "You daub '[message]' on [T] in shiny red lettering.")
var/obj/effect/decal/cleanable/blood/writing/W = new(T)
W.message = message
W.add_fingerprint(src)
@@ -1935,7 +1939,6 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
. += "---"
.["Set Species"] = "?_src_=vars;setspecies=[UID()]"
.["Make AI"] = "?_src_=vars;makeai=[UID()]"
- .["Make Mask of Nar'sie"] = "?_src_=vars;makemask=[UID()]"
.["Make cyborg"] = "?_src_=vars;makerobot=[UID()]"
.["Make monkey"] = "?_src_=vars;makemonkey=[UID()]"
.["Make alien"] = "?_src_=vars;makealien=[UID()]"
diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm
index 47dd5622379..cf9fcfd632c 100644
--- a/code/modules/mob/living/carbon/human/inventory.dm
+++ b/code/modules/mob/living/carbon/human/inventory.dm
@@ -1,11 +1,3 @@
-/mob/living/carbon/human/verb/quick_equip()
- set name = "quick-equip"
- set hidden = 1
-
- var/obj/item/I = get_active_hand()
- if(I)
- I.equip_to_best_slot(src)
-
/mob/living/carbon/human/proc/equip_in_one_of_slots(obj/item/W, list/slots, del_on_fail = 1)
for(var/slot in slots)
if(equip_to_slot_if_possible(W, slots[slot], del_on_fail = 0))
diff --git a/code/modules/mob/living/carbon/human/species/_species.dm b/code/modules/mob/living/carbon/human/species/_species.dm
index 85f491f71f0..438d3386948 100644
--- a/code/modules/mob/living/carbon/human/species/_species.dm
+++ b/code/modules/mob/living/carbon/human/species/_species.dm
@@ -341,9 +341,6 @@
if(SKELETON in target.mutations)
to_chat(user, "There is no blood in a skeleton!")
return
- if(issmall(target) && !target.ckey) //Monkeyized humans are okay, humanized monkeys are okay, NPC monkeys are not.
- to_chat(user, "Blood from a monkey is useless!")
- return
//we're good to suck the blood, blaah
user.mind.vampire.handle_bloodsucking(target)
add_attack_logs(user, target, "vampirebit")
@@ -603,20 +600,37 @@
H.healthdoll.cached_healthdoll_overlays = new_overlays
/datum/species/proc/handle_hud_icons_nutrition(mob/living/carbon/human/H)
- switch(H.nutrition)
- if(NUTRITION_LEVEL_FULL to INFINITY)
- H.throw_alert("nutrition", /obj/screen/alert/fat)
- if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL)
- H.throw_alert("nutrition", /obj/screen/alert/full)
- if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
- H.throw_alert("nutrition", /obj/screen/alert/well_fed)
- if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
- H.throw_alert("nutrition", /obj/screen/alert/fed)
- if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
- H.throw_alert("nutrition", /obj/screen/alert/hungry)
- else
- H.throw_alert("nutrition", /obj/screen/alert/starving)
- return 1
+ if(H.mind && H.mind.vampire && (H.mind in SSticker.mode.vampires)) //Vampires
+ switch(H.nutrition)
+ if(NUTRITION_LEVEL_FULL to INFINITY)
+ H.throw_alert("nutrition", /obj/screen/alert/fat/vampire)
+ if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL)
+ H.throw_alert("nutrition", /obj/screen/alert/full/vampire)
+ if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
+ H.throw_alert("nutrition", /obj/screen/alert/well_fed/vampire)
+ if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
+ H.throw_alert("nutrition", /obj/screen/alert/fed/vampire)
+ if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
+ H.throw_alert("nutrition", /obj/screen/alert/hungry/vampire)
+ else
+ H.throw_alert("nutrition", /obj/screen/alert/starving/vampire)
+ return 1
+
+ else ///Any other non-vampires
+ switch(H.nutrition)
+ if(NUTRITION_LEVEL_FULL to INFINITY)
+ H.throw_alert("nutrition", /obj/screen/alert/fat)
+ if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL)
+ H.throw_alert("nutrition", /obj/screen/alert/full)
+ if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
+ H.throw_alert("nutrition", /obj/screen/alert/well_fed)
+ if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
+ H.throw_alert("nutrition", /obj/screen/alert/fed)
+ if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
+ H.throw_alert("nutrition", /obj/screen/alert/hungry)
+ else
+ H.throw_alert("nutrition", /obj/screen/alert/starving)
+ return 1
/*
Returns the path corresponding to the corresponding organ
@@ -675,7 +689,7 @@ It'll return null if the organ doesn't correspond, so include null checks when u
H.see_invisible = G.invis_override
else
H.see_invisible = min(G.invis_view, H.see_invisible)
-
+
if(!isnull(G.lighting_alpha))
H.lighting_alpha = min(G.lighting_alpha, H.lighting_alpha)
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 727c900ac9c..f9dba949b4b 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -528,7 +528,7 @@
return
var/pull_dir = get_dir(src, pulling)
- if(get_dist(src, pulling) > 1 || ((pull_dir - 1) & pull_dir)) // puller and pullee more than one tile away or in diagonal position
+ if(get_dist(src, pulling) > 1 || (moving_diagonally != SECOND_DIAG_STEP && ((pull_dir - 1) & pull_dir))) // puller and pullee more than one tile away or in diagonal position
if(isliving(pulling))
var/mob/living/M = pulling
if(M.lying && !M.buckled && (prob(M.getBruteLoss() * 200 / M.maxHealth)))
diff --git a/code/modules/mob/living/silicon/robot/login.dm b/code/modules/mob/living/silicon/robot/login.dm
index d0262df743c..cf55cdd5f91 100644
--- a/code/modules/mob/living/silicon/robot/login.dm
+++ b/code/modules/mob/living/silicon/robot/login.dm
@@ -2,6 +2,3 @@
..()
regenerate_icons()
show_laws(0)
-
- var/datum/hotkey_mode/cyborg/C = new(src)
- C.set_winset_values()
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 100dd1ffbba..0c6ddf80fc6 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -103,6 +103,9 @@ var/list/robot_verbs_default = list(
var/datum/action/item_action/toggle_research_scanner/scanner = null
var/list/module_actions = list()
+/mob/living/silicon/robot/get_cell()
+ return cell
+
/mob/living/silicon/robot/New(loc,var/syndie = 0,var/unfinished = 0, var/alien = 0)
spark_system = new /datum/effect_system/spark_spread()
spark_system.set_up(5, 0, src)
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index 4a8d8c48f5b..2cb9ddf6252 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -156,7 +156,6 @@
/mob/living/silicon/Stat()
..()
if(statpanel("Status"))
- show_stat_station_time()
show_stat_emergency_shuttle_eta()
show_system_integrity()
diff --git a/code/modules/mob/living/simple_animal/bot/construction.dm b/code/modules/mob/living/simple_animal/bot/construction.dm
index 77eb74e5696..5feebb53059 100644
--- a/code/modules/mob/living/simple_animal/bot/construction.dm
+++ b/code/modules/mob/living/simple_animal/bot/construction.dm
@@ -594,7 +594,7 @@ var/robot_arm = /obj/item/robot_parts/l_arm
qdel(src)
/obj/item/honkbot_arm_assembly
- name = "incomplete honkbot assembly."
+ name = "incomplete honkbot assembly"
desc = "A clown box with a robot arm permanently grafted to it."
icon = 'icons/obj/aibots.dmi'
icon_state = "honkbot_arm"
@@ -625,8 +625,8 @@ var/robot_arm = /obj/item/robot_parts/l_arm
if(istype(W, /obj/item/instrument/trombone))
if(!user.unEquip(W))
return
- to_chat(user, "You add the trombone to [src]! Heeeenk! ")
+ to_chat(user, "You add the trombone to [src]! Heeeenk!")
qdel(W)
- var/mob/living/simple_animal/bot/honkbot/A = new /mob/living/simple_animal/bot/honkbot(T)
+ var/mob/living/simple_animal/bot/honkbot/A = new /mob/living/simple_animal/bot/honkbot(get_turf(src))
A.robot_arm = robot_arm
qdel(src)
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/bot/honkbot.dm b/code/modules/mob/living/simple_animal/bot/honkbot.dm
index 958f493e309..45b10950669 100644
--- a/code/modules/mob/living/simple_animal/bot/honkbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/honkbot.dm
@@ -37,7 +37,7 @@
. = ..()
update_icon()
auto_patrol = TRUE
- var/datum/job/clown/J = new/datum/job/clown
+ var/datum/job/clown/J = new /datum/job/clown()
access_card.access += J.get_access()
prev_access = access_card.access
diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm
index 49a3b2718db..1db149418c7 100644
--- a/code/modules/mob/living/simple_animal/bot/mulebot.dm
+++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm
@@ -50,6 +50,9 @@
var/currentBloodColor = "#A10808"
var/currentDNA = null
+/mob/living/simple_animal/bot/mulebot/get_cell()
+ return cell
+
/mob/living/simple_animal/bot/mulebot/New()
..()
wires = new /datum/wires/mulebot(src)
diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm
index ab9253b96cc..d5fabe96be4 100644
--- a/code/modules/mob/living/simple_animal/constructs.dm
+++ b/code/modules/mob/living/simple_animal/constructs.dm
@@ -113,7 +113,7 @@
status_flags = 0
const_type = "juggernaut"
mob_size = MOB_SIZE_LARGE
- construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/lesserforcewall)
+ construct_spells = list(/obj/effect/proc_holder/spell/targeted/night_vision, /obj/effect/proc_holder/spell/aoe_turf/conjure/lesserforcewall)
force_threshold = 11
playstyle_string = "You are a Juggernaut. Though slow, your shell can withstand extreme punishment, \
create shield walls, rip apart enemies and walls alike, and even deflect energy weapons."
@@ -171,7 +171,7 @@
see_in_dark = 8
attack_sound = 'sound/weapons/bladeslice.ogg'
const_type = "wraith"
- construct_spells = list(/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift)
+ construct_spells = list(/obj/effect/proc_holder/spell/targeted/night_vision, /obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift)
retreat_distance = 2 //AI wraiths will move in and out of combat
playstyle_string = "You are a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls."
@@ -202,7 +202,8 @@
minimum_distance = 10 //AI artificers will flee like fuck
attack_sound = 'sound/weapons/punch2.ogg'
const_type = "builder"
- construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/construct/lesser,
+ construct_spells = list(/obj/effect/proc_holder/spell/targeted/night_vision,
+ /obj/effect/proc_holder/spell/aoe_turf/conjure/construct/lesser,
/obj/effect/proc_holder/spell/aoe_turf/conjure/wall,
/obj/effect/proc_holder/spell/aoe_turf/conjure/floor,
/obj/effect/proc_holder/spell/aoe_turf/conjure/pylon,
@@ -311,7 +312,8 @@
see_in_dark = 8
attack_sound = 'sound/weapons/tap.ogg'
const_type = "harvester"
- construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/wall,
+ construct_spells = list(/obj/effect/proc_holder/spell/targeted/night_vision,
+ /obj/effect/proc_holder/spell/aoe_turf/conjure/wall,
/obj/effect/proc_holder/spell/aoe_turf/conjure/floor,
/obj/effect/proc_holder/spell/targeted/smoke/disable)
retreat_distance = 2 //AI harvesters will move in and out of combat, like wraiths, but shittier
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm
index 5fd5b4e9231..7fd32bd71ec 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm
@@ -1,265 +1,265 @@
-#define MINER_DASH_RANGE 4
-
-/*
-
-BLOOD-DRUNK MINER
-
-Effectively a highly aggressive miner, the blood-drunk miner has very few attacks but compensates by being highly aggressive.
-
-The blood-drunk miner's attacks are as follows
-- If not in KA range, it will rapidly dash at its target
-- If in KA range, it will fire its kinetic accelerator
-- If in melee range, will rapidly attack, akin to an actual player
-- After any of these attacks, may transform its cleaving saw:
- Untransformed, it attacks very rapidly for smaller amounts of damage
- Transformed, it attacks at normal speed for higher damage and cleaves enemies hit
-
-When the blood-drunk miner dies, it leaves behind the cleaving saw it was using and its kinetic accelerator.
-
-Difficulty: Medium
-
-*/
-
-/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner
- name = "blood-drunk miner"
- desc = "A miner destined to wander forever, engaged in an endless hunt."
- health = 900
- maxHealth = 900
- icon_state = "miner"
- icon_living = "miner"
- icon = 'icons/mob/alienqueen.dmi'
- light_color = "#E4C7C5"
- speak_emote = list("roars")
- speed = 1
- move_to_delay = 3
- projectiletype = /obj/item/projectile/kinetic/miner
- projectilesound = 'sound/weapons/kenetic_accel.ogg'
- ranged = 1
- ranged_cooldown_time = 16
- pixel_x = -16
- loot = list(/obj/item/melee/energy/cleaving_saw, /obj/item/gun/energy/kinetic_accelerator)
- wander = FALSE
- del_on_death = TRUE
- blood_volume = BLOOD_VOLUME_NORMAL
- var/obj/item/melee/energy/cleaving_saw/miner/miner_saw
- var/time_until_next_transform = 0
- var/dashing = FALSE
- var/dash_cooldown = 15
- var/guidance = FALSE
- deathmessage = "falls to the ground, decaying into glowing particles."
- death_sound = "bodyfall"
-
-/obj/item/gps/internal/miner
- icon_state = null
- gpstag = "Resonant Signal"
- desc = "The sweet blood, oh, it sings to me."
- invisibility = 100
-
-/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/guidance
- guidance = TRUE
-
-/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/hunter/AttackingTarget()
- . = ..()
- if(. && prob(12))
- INVOKE_ASYNC(src, .proc/dash)
-
-/obj/item/melee/energy/cleaving_saw/miner //nerfed saw because it is very murdery
- force = 6
- force_on = 10
-
-/obj/item/melee/energy/cleaving_saw/miner/attack(mob/living/target, mob/living/carbon/human/user)
- target.add_stun_absorption("miner", 10, INFINITY)
- ..()
- target.stun_absorption -= "miner"
-
-/obj/item/projectile/kinetic/miner
- damage = 20
- speed = 0.9
- icon_state = "ka_tracer"
- range = MINER_DASH_RANGE
-
-/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/Initialize()
- . = ..()
- miner_saw = new(src)
- internal_gps = new/obj/item/gps/internal/miner(src)
-
- // Add a zone selection UI; otherwise the mob can't melee attack properly.
- zone_sel = new /obj/screen/zone_sel()
-
-/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
- var/adjustment_amount = amount * 0.1
- if(world.time + adjustment_amount > next_move)
- changeNext_move(adjustment_amount) //attacking it interrupts it attacking, but only briefly
- . = ..()
-
-/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/death()
- if(health > 0)
- return
- new /obj/effect/temp_visual/dir_setting/miner_death(loc, dir)
- return ..()
-
-/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/Move(atom/newloc)
- if(dashing || (newloc && newloc.z == z && (islava(newloc) || ischasm(newloc)))) //we're not stupid!
- return FALSE
- return ..()
-
-/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/ex_act(severity, target)
- if(dash())
- return
- return ..()
-
-/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/AttackingTarget()
- if(QDELETED(target))
- return
- if(next_move > world.time || !Adjacent(target)) //some cheating
- INVOKE_ASYNC(src, .proc/quick_attack_loop)
- return
- face_atom(target)
- if(isliving(target))
- var/mob/living/L = target
- if(L.stat == DEAD)
- visible_message("[src] butchers [L]!",
- "You butcher [L], restoring your health!")
- if(!is_station_level(z) || client) //NPC monsters won't heal while on station
- if(guidance)
- adjustHealth(-L.maxHealth)
- else
- adjustHealth(-(L.maxHealth * 0.5))
- L.gib()
- return TRUE
- changeNext_move(CLICK_CD_MELEE)
- miner_saw.melee_attack_chain(src, target)
- if(guidance)
- adjustHealth(-2)
- transform_weapon()
- INVOKE_ASYNC(src, .proc/quick_attack_loop)
- return TRUE
-
-/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect)
- if(!used_item && !isturf(A))
- used_item = miner_saw
- ..()
-
-/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/GiveTarget(new_target)
- var/targets_the_same = (new_target == target)
- . = ..()
- if(. && target && !targets_the_same)
- wander = TRUE
- transform_weapon()
- INVOKE_ASYNC(src, .proc/quick_attack_loop)
-
-/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/OpenFire()
- Goto(target, move_to_delay, minimum_distance)
- if(get_dist(src, target) > MINER_DASH_RANGE && dash_cooldown <= world.time)
- INVOKE_ASYNC(src, .proc/dash, target)
- else
- shoot_ka()
- transform_weapon()
-
-/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/shoot_ka()
- if(ranged_cooldown <= world.time && get_dist(src, target) <= MINER_DASH_RANGE && !Adjacent(target))
- ranged_cooldown = world.time + ranged_cooldown_time
- visible_message("[src] fires the proto-kinetic accelerator!")
- face_atom(target)
- new /obj/effect/temp_visual/dir_setting/firing_effect(loc, dir)
- Shoot(target)
- changeNext_move(CLICK_CD_RANGE)
-
-//I'm still of the belief that this entire proc needs to be wiped from existence.
-// do not take my touching of it to be endorsement of it. ~mso
-/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/quick_attack_loop()
- while(!QDELETED(target) && next_move <= world.time) //this is done this way because next_move can change to be sooner while we sleep.
- stoplag(1)
- sleep((next_move - world.time) * 1.5) //but don't ask me what the fuck this is about
- if(QDELETED(target))
- return
- if(dashing || next_move > world.time || !Adjacent(target))
- if(dashing && next_move <= world.time)
- next_move = world.time + 1
- INVOKE_ASYNC(src, .proc/quick_attack_loop) //lets try that again.
- return
- AttackingTarget()
-
-/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/dash(atom/dash_target)
- if(world.time < dash_cooldown)
- return
- var/list/accessable_turfs = list()
- var/self_dist_to_target = 0
- var/turf/own_turf = get_turf(src)
- if(!QDELETED(dash_target))
- self_dist_to_target += get_dist(dash_target, own_turf)
- for(var/turf/simulated/O in RANGE_TURFS(MINER_DASH_RANGE, own_turf))
- var/turf_dist_to_target = 0
- if(!QDELETED(dash_target))
- turf_dist_to_target += get_dist(dash_target, O)
- if(get_dist(src, O) >= MINER_DASH_RANGE && turf_dist_to_target <= self_dist_to_target && !islava(O) && !ischasm(O))
- var/valid = TRUE
- for(var/turf/T in getline(own_turf, O))
- if(is_blocked_turf(T, TRUE))
- valid = FALSE
- continue
- if(valid)
- accessable_turfs[O] = turf_dist_to_target
- var/turf/target_turf
- if(!QDELETED(dash_target))
- var/closest_dist = MINER_DASH_RANGE
- for(var/t in accessable_turfs)
- if(accessable_turfs[t] < closest_dist)
- closest_dist = accessable_turfs[t]
- for(var/t in accessable_turfs)
- if(accessable_turfs[t] != closest_dist)
- accessable_turfs -= t
- if(!LAZYLEN(accessable_turfs))
- return
- dash_cooldown = world.time + initial(dash_cooldown)
- target_turf = pick(accessable_turfs)
- var/turf/step_back_turf = get_step(target_turf, get_cardinal_dir(target_turf, own_turf))
- var/turf/step_forward_turf = get_step(own_turf, get_cardinal_dir(own_turf, target_turf))
- new /obj/effect/temp_visual/small_smoke/halfsecond(step_back_turf)
- new /obj/effect/temp_visual/small_smoke/halfsecond(step_forward_turf)
- var/obj/effect/temp_visual/decoy/D = new /obj/effect/temp_visual/decoy(loc, src)
- animate(D, alpha = 0, time = 5)
- forceMove(step_back_turf)
- playsound(own_turf, 'sound/weapons/punchmiss.ogg', 40, 1, -1)
- dashing = TRUE
- alpha = 0
- animate(src, alpha = 255, time = 5)
- sleep(2)
- D.forceMove(step_forward_turf)
- forceMove(target_turf)
- playsound(target_turf, 'sound/weapons/punchmiss.ogg', 40, 1, -1)
- sleep(1)
- dashing = FALSE
- shoot_ka()
- return TRUE
-
-/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/transform_weapon()
- if(time_until_next_transform <= world.time)
- miner_saw.transform_cooldown = 0
- miner_saw.transform_weapon(src, TRUE)
- icon_state = "miner[miner_saw.active ? "_transformed":""]"
- icon_living = "miner[miner_saw.active ? "_transformed":""]"
- time_until_next_transform = world.time + rand(50, 100)
-
-/obj/effect/temp_visual/dir_setting/miner_death
- icon_state = "miner_death"
- duration = 15
-
-/obj/effect/temp_visual/dir_setting/miner_death/Initialize(mapload, set_dir)
- . = ..()
- INVOKE_ASYNC(src, .proc/fade_out)
-
-/obj/effect/temp_visual/dir_setting/miner_death/proc/fade_out()
- var/matrix/M = new
- M.Turn(pick(90, 270))
- var/final_dir = dir
- if(dir & (EAST|WEST)) //Facing east or west
- final_dir = pick(NORTH, SOUTH) //So you fall on your side rather than your face or ass
-
- animate(src, transform = M, pixel_y = -6, dir = final_dir, time = 2, easing = EASE_IN|EASE_OUT)
- sleep(5)
- animate(src, color = list("#A7A19E", "#A7A19E", "#A7A19E", list(0, 0, 0)), time = 10, easing = EASE_IN, flags = ANIMATION_PARALLEL)
- sleep(4)
- animate(src, alpha = 0, time = 6, easing = EASE_OUT, flags = ANIMATION_PARALLEL)
-
+#define MINER_DASH_RANGE 4
+
+/*
+
+BLOOD-DRUNK MINER
+
+Effectively a highly aggressive miner, the blood-drunk miner has very few attacks but compensates by being highly aggressive.
+
+The blood-drunk miner's attacks are as follows
+- If not in KA range, it will rapidly dash at its target
+- If in KA range, it will fire its kinetic accelerator
+- If in melee range, will rapidly attack, akin to an actual player
+- After any of these attacks, may transform its cleaving saw:
+ Untransformed, it attacks very rapidly for smaller amounts of damage
+ Transformed, it attacks at normal speed for higher damage and cleaves enemies hit
+
+When the blood-drunk miner dies, it leaves behind the cleaving saw it was using and its kinetic accelerator.
+
+Difficulty: Medium
+
+*/
+
+/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner
+ name = "blood-drunk miner"
+ desc = "A miner destined to wander forever, engaged in an endless hunt."
+ health = 900
+ maxHealth = 900
+ icon_state = "miner"
+ icon_living = "miner"
+ icon = 'icons/mob/alienqueen.dmi'
+ light_color = "#E4C7C5"
+ speak_emote = list("roars")
+ speed = 1
+ move_to_delay = 3
+ projectiletype = /obj/item/projectile/kinetic/miner
+ projectilesound = 'sound/weapons/kenetic_accel.ogg'
+ ranged = 1
+ ranged_cooldown_time = 16
+ pixel_x = -16
+ loot = list(/obj/item/melee/energy/cleaving_saw, /obj/item/gun/energy/kinetic_accelerator)
+ wander = FALSE
+ del_on_death = TRUE
+ blood_volume = BLOOD_VOLUME_NORMAL
+ var/obj/item/melee/energy/cleaving_saw/miner/miner_saw
+ var/time_until_next_transform = 0
+ var/dashing = FALSE
+ var/dash_cooldown = 15
+ var/guidance = FALSE
+ deathmessage = "falls to the ground, decaying into glowing particles."
+ death_sound = "bodyfall"
+
+/obj/item/gps/internal/miner
+ icon_state = null
+ gpstag = "Resonant Signal"
+ desc = "The sweet blood, oh, it sings to me."
+ invisibility = 100
+
+/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/guidance
+ guidance = TRUE
+
+/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/hunter/AttackingTarget()
+ . = ..()
+ if(. && prob(12))
+ INVOKE_ASYNC(src, .proc/dash)
+
+/obj/item/melee/energy/cleaving_saw/miner //nerfed saw because it is very murdery
+ force = 6
+ force_on = 10
+
+/obj/item/melee/energy/cleaving_saw/miner/attack(mob/living/target, mob/living/carbon/human/user)
+ target.add_stun_absorption("miner", 10, INFINITY)
+ ..()
+ target.stun_absorption -= "miner"
+
+/obj/item/projectile/kinetic/miner
+ damage = 20
+ speed = 0.9
+ icon_state = "ka_tracer"
+ range = MINER_DASH_RANGE
+
+/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/Initialize()
+ . = ..()
+ miner_saw = new(src)
+ internal_gps = new/obj/item/gps/internal/miner(src)
+
+ // Add a zone selection UI; otherwise the mob can't melee attack properly.
+ zone_sel = new /obj/screen/zone_sel()
+
+/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
+ var/adjustment_amount = amount * 0.1
+ if(world.time + adjustment_amount > next_move)
+ changeNext_move(adjustment_amount) //attacking it interrupts it attacking, but only briefly
+ . = ..()
+
+/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/death()
+ if(health > 0)
+ return
+ new /obj/effect/temp_visual/dir_setting/miner_death(loc, dir)
+ return ..()
+
+/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/Move(atom/newloc)
+ if(dashing || (newloc && newloc.z == z && (islava(newloc) || ischasm(newloc)))) //we're not stupid!
+ return FALSE
+ return ..()
+
+/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/ex_act(severity, target)
+ if(dash())
+ return
+ return ..()
+
+/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/AttackingTarget()
+ if(QDELETED(target))
+ return
+ if(next_move > world.time || !Adjacent(target)) //some cheating
+ INVOKE_ASYNC(src, .proc/quick_attack_loop)
+ return
+ face_atom(target)
+ if(isliving(target))
+ var/mob/living/L = target
+ if(L.stat == DEAD)
+ visible_message("[src] butchers [L]!",
+ "You butcher [L], restoring your health!")
+ if(!is_station_level(z) || client) //NPC monsters won't heal while on station
+ if(guidance)
+ adjustHealth(-L.maxHealth)
+ else
+ adjustHealth(-(L.maxHealth * 0.5))
+ L.gib()
+ return TRUE
+ changeNext_move(CLICK_CD_MELEE)
+ miner_saw.melee_attack_chain(src, target)
+ if(guidance)
+ adjustHealth(-2)
+ transform_weapon()
+ INVOKE_ASYNC(src, .proc/quick_attack_loop)
+ return TRUE
+
+/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect)
+ if(!used_item && !isturf(A))
+ used_item = miner_saw
+ ..()
+
+/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/GiveTarget(new_target)
+ var/targets_the_same = (new_target == target)
+ . = ..()
+ if(. && target && !targets_the_same)
+ wander = TRUE
+ transform_weapon()
+ INVOKE_ASYNC(src, .proc/quick_attack_loop)
+
+/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/OpenFire()
+ Goto(target, move_to_delay, minimum_distance)
+ if(get_dist(src, target) > MINER_DASH_RANGE && dash_cooldown <= world.time)
+ INVOKE_ASYNC(src, .proc/dash, target)
+ else
+ shoot_ka()
+ transform_weapon()
+
+/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/shoot_ka()
+ if(ranged_cooldown <= world.time && get_dist(src, target) <= MINER_DASH_RANGE && !Adjacent(target))
+ ranged_cooldown = world.time + ranged_cooldown_time
+ visible_message("[src] fires the proto-kinetic accelerator!")
+ face_atom(target)
+ new /obj/effect/temp_visual/dir_setting/firing_effect(loc, dir)
+ Shoot(target)
+ changeNext_move(CLICK_CD_RANGE)
+
+//I'm still of the belief that this entire proc needs to be wiped from existence.
+// do not take my touching of it to be endorsement of it. ~mso
+/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/quick_attack_loop()
+ while(!QDELETED(target) && next_move <= world.time) //this is done this way because next_move can change to be sooner while we sleep.
+ stoplag(1)
+ sleep((next_move - world.time) * 1.5) //but don't ask me what the fuck this is about
+ if(QDELETED(target))
+ return
+ if(dashing || next_move > world.time || !Adjacent(target))
+ if(dashing && next_move <= world.time)
+ next_move = world.time + 1
+ INVOKE_ASYNC(src, .proc/quick_attack_loop) //lets try that again.
+ return
+ AttackingTarget()
+
+/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/dash(atom/dash_target)
+ if(world.time < dash_cooldown)
+ return
+ var/list/accessable_turfs = list()
+ var/self_dist_to_target = 0
+ var/turf/own_turf = get_turf(src)
+ if(!QDELETED(dash_target))
+ self_dist_to_target += get_dist(dash_target, own_turf)
+ for(var/turf/simulated/O in RANGE_TURFS(MINER_DASH_RANGE, own_turf))
+ var/turf_dist_to_target = 0
+ if(!QDELETED(dash_target))
+ turf_dist_to_target += get_dist(dash_target, O)
+ if(get_dist(src, O) >= MINER_DASH_RANGE && turf_dist_to_target <= self_dist_to_target && !islava(O) && !ischasm(O))
+ var/valid = TRUE
+ for(var/turf/T in getline(own_turf, O))
+ if(is_blocked_turf(T, TRUE))
+ valid = FALSE
+ continue
+ if(valid)
+ accessable_turfs[O] = turf_dist_to_target
+ var/turf/target_turf
+ if(!QDELETED(dash_target))
+ var/closest_dist = MINER_DASH_RANGE
+ for(var/t in accessable_turfs)
+ if(accessable_turfs[t] < closest_dist)
+ closest_dist = accessable_turfs[t]
+ for(var/t in accessable_turfs)
+ if(accessable_turfs[t] != closest_dist)
+ accessable_turfs -= t
+ if(!LAZYLEN(accessable_turfs))
+ return
+ dash_cooldown = world.time + initial(dash_cooldown)
+ target_turf = pick(accessable_turfs)
+ var/turf/step_back_turf = get_step(target_turf, get_cardinal_dir(target_turf, own_turf))
+ var/turf/step_forward_turf = get_step(own_turf, get_cardinal_dir(own_turf, target_turf))
+ new /obj/effect/temp_visual/small_smoke/halfsecond(step_back_turf)
+ new /obj/effect/temp_visual/small_smoke/halfsecond(step_forward_turf)
+ var/obj/effect/temp_visual/decoy/D = new /obj/effect/temp_visual/decoy(loc, src)
+ animate(D, alpha = 0, time = 5)
+ forceMove(step_back_turf)
+ playsound(own_turf, 'sound/weapons/punchmiss.ogg', 40, 1, -1)
+ dashing = TRUE
+ alpha = 0
+ animate(src, alpha = 255, time = 5)
+ sleep(2)
+ D.forceMove(step_forward_turf)
+ forceMove(target_turf)
+ playsound(target_turf, 'sound/weapons/punchmiss.ogg', 40, 1, -1)
+ sleep(1)
+ dashing = FALSE
+ shoot_ka()
+ return TRUE
+
+/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/transform_weapon()
+ if(time_until_next_transform <= world.time)
+ miner_saw.transform_cooldown = 0
+ miner_saw.transform_weapon(src, TRUE)
+ icon_state = "miner[miner_saw.active ? "_transformed":""]"
+ icon_living = "miner[miner_saw.active ? "_transformed":""]"
+ time_until_next_transform = world.time + rand(50, 100)
+
+/obj/effect/temp_visual/dir_setting/miner_death
+ icon_state = "miner_death"
+ duration = 15
+
+/obj/effect/temp_visual/dir_setting/miner_death/Initialize(mapload, set_dir)
+ . = ..()
+ INVOKE_ASYNC(src, .proc/fade_out)
+
+/obj/effect/temp_visual/dir_setting/miner_death/proc/fade_out()
+ var/matrix/M = new
+ M.Turn(pick(90, 270))
+ var/final_dir = dir
+ if(dir & (EAST|WEST)) //Facing east or west
+ final_dir = pick(NORTH, SOUTH) //So you fall on your side rather than your face or ass
+
+ animate(src, transform = M, pixel_y = -6, dir = final_dir, time = 2, easing = EASE_IN|EASE_OUT)
+ sleep(5)
+ animate(src, color = list("#A7A19E", "#A7A19E", "#A7A19E", list(0, 0, 0)), time = 10, easing = EASE_IN, flags = ANIMATION_PARALLEL)
+ sleep(4)
+ animate(src, alpha = 0, time = 6, easing = EASE_OUT, flags = ANIMATION_PARALLEL)
+
#undef MINER_DASH_RANGE
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/mining/gutlunch.dm b/code/modules/mob/living/simple_animal/hostile/mining/gutlunch.dm
index d73fe3ca77c..6e5c840a401 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining/gutlunch.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining/gutlunch.dm
@@ -64,7 +64,7 @@
..()
/mob/living/simple_animal/hostile/asteroid/gutlunch/AttackingTarget()
- if(is_type_in_list(target, wanted_objects)) //we eats
+ if(is_type_in_typecache(target, wanted_objects)) //we eats
udder.generateMilk()
regenerate_icons()
visible_message("[src] slurps up [target].")
diff --git a/code/modules/mob/living/simple_animal/hostile/statue.dm b/code/modules/mob/living/simple_animal/hostile/statue.dm
index 3f649eae984..2e1e7508e1c 100644
--- a/code/modules/mob/living/simple_animal/hostile/statue.dm
+++ b/code/modules/mob/living/simple_animal/hostile/statue.dm
@@ -189,35 +189,6 @@
L.EyeBlind(4)
return
-//Toggle Night Vision
-/obj/effect/proc_holder/spell/targeted/night_vision
- name = "Toggle Nightvision"
- desc = "Toggle your nightvision mode."
-
- charge_max = 10
- clothes_req = 0
-
- message = "You toggle your night vision!"
- range = -1
- include_user = 1
-
-/obj/effect/proc_holder/spell/targeted/night_vision/cast(list/targets, mob/user = usr)
- for(var/mob/living/target in targets)
- switch(target.lighting_alpha)
- if (LIGHTING_PLANE_ALPHA_VISIBLE)
- target.lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
- name = "Toggle Nightvision \[More]"
- if (LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE)
- target.lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
- name = "Toggle Nightvision \[Full]"
- if (LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE)
- target.lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE
- name = "Toggle Nightvision \[OFF]"
- else
- target.lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE
- name = "Toggle Nightvision \[ON]"
- target.update_sight()
-
/mob/living/simple_animal/hostile/statue/sentience_act()
faction -= "neutral"
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm
index f73ee07441a..5b82f8d35dd 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm
@@ -202,7 +202,7 @@ var/global/list/ts_spiderling_list = list()
var/obj/machinery/door/airlock/A = target
if(A.density)
try_open_airlock(A)
- else if(isliving(target))
+ else if(isliving(target) && (!client || a_intent == INTENT_HARM))
var/mob/living/G = target
if(issilicon(G))
G.attack_animal(src)
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index c74d7545473..4e486baba20 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -2,6 +2,7 @@
GLOB.mob_list -= src
GLOB.dead_mob_list -= src
GLOB.living_mob_list -= src
+ focus = null
QDEL_NULL(hud_used)
if(mind && mind.current == src)
spellremove(src)
@@ -30,6 +31,7 @@
GLOB.dead_mob_list += src
else
GLOB.living_mob_list += src
+ set_focus(src)
prepare_huds()
..()
@@ -50,7 +52,6 @@
/mob/proc/GetAltName()
return ""
-
/mob/proc/Cell()
set category = "Admin"
set hidden = 1
@@ -173,6 +174,7 @@
return 0
/mob/proc/Life(seconds, times_fired)
+ set waitfor = FALSE
if(forced_look)
if(!isnum(forced_look))
var/atom/A = locateUID(forced_look)
@@ -988,6 +990,9 @@ var/list/slot_equipment_priority = list( \
statpanel("Status") // Switch to the Status panel again, for the sake of the lazy Stat procs
+ if(client && client.statpanel == "Status" && SSticker)
+ show_stat_station_time()
+
// this function displays the station time in the status panel
/mob/proc/show_stat_station_time()
stat(null, "Round Time: [worldtime2text()]")
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index beb474539f1..a26131b9504 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -399,9 +399,6 @@ var/list/intents = list(INTENT_HELP,INTENT_DISARM,INTENT_GRAB,INTENT_HARM)
set name = "Rest"
set category = "IC"
- if(world.time < client.move_delay)
- return
-
if(!resting)
client.move_delay = world.time + 20
to_chat(src, "You are now resting.")
@@ -641,5 +638,26 @@ var/list/intents = list(INTENT_HELP,INTENT_DISARM,INTENT_GRAB,INTENT_HARM)
// Cast to 1/0
return !!(client.prefs.toggles & toggleflag)
+// Used to make sure that a player has a valid job preference setup, used to knock players out of eligibility for anything if their prefs don't make sense.
+// A "valid job preference setup" in this situation means at least having one job set to low, or not having "return to lobby" enabled
+// Prevents "antag rolling" by setting antag prefs on, all jobs to never, and "return to lobby if preferences not availible"
+// Doing so would previously allow you to roll for antag, then send you back to lobby if you didn't get an antag role
+// This also does some admin notification and logging as well
+/mob/proc/has_valid_preferences()
+ if(!client)
+ return FALSE //Not sure how this would get run without the mob having a client, but let's just be safe.
+ if(client.prefs.alternate_option != RETURN_TO_LOBBY)
+ return TRUE
+ // If they have antags enabled, they're potentially doing this on purpose instead of by accident. Notify admins if so.
+ var/has_antags = FALSE
+ if(client.prefs.be_special.len > 0)
+ has_antags = TRUE
+ if(!client.prefs.check_any_job())
+ to_chat(src, "You have no jobs enabled, along with return to lobby if job is unavailable. This makes you ineligible for any round start role, please update your job preferences.")
+ if(has_antags)
+ log_admin("[src.ckey] just got booted back to lobby with no jobs, but antags enabled.")
+ message_admins("[src.ckey] just got booted back to lobby with no jobs enabled, but antag rolling enabled. Likely antag rolling abuse.")
+ return FALSE //This is the only case someone should actually be completely blocked from antag rolling as well
+ return TRUE
#define isterrorspider(A) (istype((A), /mob/living/simple_animal/hostile/poison/terror_spider))
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index f26961eace9..47909a5d0b9 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -15,102 +15,6 @@
return 1
return (!mover.density || !density || lying)
-//The byond version of these verbs wait for the next tick before acting.
-// instant verbs however can run mid tick or even during the time between ticks.
-#define DO_MOVE(this_dir) var/final_dir = turn(this_dir, -dir2angle(dir)); Move(get_step(mob, final_dir), final_dir);
-
-/client/verb/moveup()
- set name = ".moveup"
- set instant = 1
- DO_MOVE(NORTH)
-
-/client/verb/movedown()
- set name = ".movedown"
- set instant = 1
- DO_MOVE(SOUTH)
-
-/client/verb/moveright()
- set name = ".moveright"
- set instant = 1
- DO_MOVE(EAST)
-
-/client/verb/moveleft()
- set name = ".moveleft"
- set instant = 1
- DO_MOVE(WEST)
-
-#undef DO_MOVE
-
-/client/Northeast()
- swap_hand()
- return
-
-
-/client/Southeast()
- attack_self()
- return
-
-
-/client/Southwest()
- if(iscarbon(usr))
- var/mob/living/carbon/C = usr
- C.toggle_throw_mode()
- else if(isrobot(usr))
- var/mob/living/silicon/robot/R = usr
- var/module = R.get_selected_module()
- if(!module)
- to_chat(usr, "You have no module selected.")
- return
- R.cycle_modules()
- R.uneq_numbered(module)
- else
- to_chat(usr, "This mob type cannot throw items.")
- return
-
-
-/client/Northwest()
- if(iscarbon(usr))
- var/mob/living/carbon/C = usr
- if(!C.get_active_hand())
- to_chat(usr, "You have nothing to drop in your hand.")
- return
- drop_item()
- else if(isrobot(usr))
- var/mob/living/silicon/robot/R = usr
- if(!R.get_selected_module())
- to_chat(usr, "You have no module selected.")
- return
- R.deselect_module(R.get_selected_module())
- else
- to_chat(usr, "This mob type cannot drop items.")
- return
-
-//This gets called when you press the delete button.
-/client/verb/delete_key_pressed()
- set hidden = 1
-
- if(!usr.pulling)
- to_chat(usr, "You are not pulling anything.")
- return
- usr.stop_pulling()
-
-/client/verb/swap_hand()
- set hidden = 1
- if(istype(mob, /mob/living/carbon))
- mob:swap_hand()
- if(istype(mob,/mob/living/silicon/robot))
- var/mob/living/silicon/robot/R = mob
- R.cycle_modules()
- return
-
-
-
-/client/verb/attack_self()
- set hidden = 1
- if(mob)
- mob.mode()
- return
-
/client/verb/toggle_throw_mode()
set hidden = 1
@@ -128,7 +32,7 @@
return
-/client/Center()
+/* /client/Center()
/* No 3D movement in 2D spessman game. dir 16 is Z Up
if(isobj(mob.loc))
var/obj/O = mob.loc
@@ -136,7 +40,7 @@
return O.relaymove(mob, 16)
*/
return
-
+ */
/client/proc/Move_object(direct)
@@ -155,11 +59,17 @@
/client/Move(n, direct)
if(world.time < move_delay)
return
+ else
+ next_move_dir_add = 0
+ next_move_dir_sub = 0
var/old_move_delay = move_delay
move_delay = world.time + world.tick_lag //this is here because Move() can now be called multiple times per tick
if(!mob || !mob.loc)
return 0
+ if(!n || !direct) // why did we never check this before?
+ return FALSE
+
if(mob.notransform)
return 0 //This is sota the goto stop mobs from moving var
@@ -226,9 +136,9 @@
moving = 1
var/delay = mob.movement_delay()
if(old_move_delay + (delay * MOVEMENT_DELAY_BUFFER_DELTA) + MOVEMENT_DELAY_BUFFER > world.time)
- move_delay = old_move_delay + delay
+ move_delay = old_move_delay
else
- move_delay = delay + world.time
+ move_delay = world.time
mob.last_movement = world.time
if(locate(/obj/item/grab, mob))
@@ -264,19 +174,29 @@
return
else if(mob.confused)
- step(mob, pick(cardinal))
- else
- . = ..()
+ var/newdir = 0
+ if(mob.confused > 40)
+ newdir = pick(alldirs)
+ else if(prob(mob.confused * 1.5))
+ newdir = angle2dir(dir2angle(direct) + pick(90, -90))
+ else if(prob(mob.confused * 3))
+ newdir = angle2dir(dir2angle(direct) + pick(45, -45))
+ if(newdir)
+ direct = newdir
+ n = get_step(mob, direct)
+ . = ..()
mob.setDir(direct)
for(var/obj/item/grab/G in mob)
if(G.state == GRAB_NECK)
- mob.setDir(reverse_dir[direct])
+ mob.setDir(angle2dir((dir2angle(direct) + 202.5) % 365))
G.adjust_position()
for(var/obj/item/grab/G in mob.grabbed_by)
G.adjust_position()
-
+ if((direct & (direct - 1)) && mob.loc == n) //moved diagonally successfully
+ delay = mob.movement_delay() * 2
+ move_delay += delay
moving = 0
if(mob && .)
if(mob.throwing)
@@ -461,3 +381,123 @@
/mob/proc/update_gravity()
return
+/client/proc/check_has_body_select()
+ return mob && mob.hud_used && mob.zone_sel && istype(mob.zone_sel, /obj/screen/zone_sel)
+
+/client/verb/body_toggle_head()
+ set name = "body-toggle-head"
+ set hidden = 1
+
+ if(!check_has_body_select())
+ return
+
+ var/next_in_line
+ switch(mob.zone_sel.selecting)
+ if(BODY_ZONE_HEAD)
+ next_in_line = BODY_ZONE_PRECISE_EYES
+ if(BODY_ZONE_PRECISE_EYES)
+ next_in_line = BODY_ZONE_PRECISE_MOUTH
+ else
+ next_in_line = BODY_ZONE_HEAD
+
+ var/obj/screen/zone_sel/selector = mob.zone_sel
+ selector.set_selected_zone(next_in_line, mob)
+
+/client/verb/body_r_arm()
+ set name = "body-r-arm"
+ set hidden = 1
+ if(!check_has_body_select())
+ return
+
+ var/next_in_line
+ if(mob.zone_sel.selecting == BODY_ZONE_R_ARM)
+ next_in_line = BODY_ZONE_PRECISE_R_HAND
+ else
+ next_in_line = BODY_ZONE_R_ARM
+
+ var/obj/screen/zone_sel/selector = mob.zone_sel
+ selector.set_selected_zone(next_in_line, mob)
+
+/client/verb/body_chest()
+ set name = "body-chest"
+ set hidden = 1
+
+ if(!check_has_body_select())
+ return
+
+ var/obj/screen/zone_sel/selector = mob.zone_sel
+ selector.set_selected_zone(BODY_ZONE_CHEST, mob)
+
+/client/verb/body_l_arm()
+ set name = "body-l-arm"
+ set hidden = 1
+
+ if(!check_has_body_select())
+ return
+
+ var/next_in_line
+ if(mob.zone_sel.selecting == BODY_ZONE_L_ARM)
+ next_in_line = BODY_ZONE_PRECISE_L_HAND
+ else
+ next_in_line = BODY_ZONE_L_ARM
+
+ var/obj/screen/zone_sel/selector = mob.zone_sel
+ selector.set_selected_zone(next_in_line, mob)
+
+/client/verb/body_r_leg()
+ set name = "body-r-leg"
+ set hidden = 1
+
+ if(!check_has_body_select())
+ return
+
+ var/next_in_line
+ if(mob.zone_sel.selecting == BODY_ZONE_R_LEG)
+ next_in_line = BODY_ZONE_PRECISE_R_FOOT
+ else
+ next_in_line = BODY_ZONE_R_LEG
+
+ var/obj/screen/zone_sel/selector = mob.zone_sel
+ selector.set_selected_zone(next_in_line, mob)
+
+/client/verb/body_groin()
+ set name = "body-groin"
+ set hidden = 1
+
+ if(!check_has_body_select())
+ return
+
+ var/obj/screen/zone_sel/selector = mob.zone_sel
+ selector.set_selected_zone(BODY_ZONE_PRECISE_GROIN, mob)
+
+/client/verb/body_l_leg()
+ set name = "body-l-leg"
+ set hidden = 1
+
+ if(!check_has_body_select())
+ return
+
+ var/next_in_line
+ if(mob.zone_sel.selecting == BODY_ZONE_L_LEG)
+ next_in_line = BODY_ZONE_PRECISE_L_FOOT
+ else
+ next_in_line = BODY_ZONE_L_LEG
+
+ var/obj/screen/zone_sel/selector = mob.zone_sel
+ selector.set_selected_zone(next_in_line, mob)
+
+/client/verb/toggle_walk_run()
+ set name = "toggle-walk-run"
+ set hidden = TRUE
+ set instant = TRUE
+ if(mob)
+ mob.toggle_move_intent(usr)
+
+/mob/proc/toggle_move_intent(mob/user)
+ if(m_intent == MOVE_INTENT_RUN)
+ m_intent = MOVE_INTENT_WALK
+ else
+ m_intent = MOVE_INTENT_RUN
+ if(hud_used && hud_used.static_inventory)
+ for(var/obj/screen/mov_intent/selector in hud_used.static_inventory)
+ selector.update_icon(src)
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index a87cbf6c8d3..47a4e4a5d0e 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -136,8 +136,6 @@
..()
statpanel("Status")
- if(client.statpanel == "Status" && SSticker)
- show_stat_station_time()
/mob/new_player/Topic(href, href_list[])
diff --git a/code/modules/modular_computers/computers/item/computer_power.dm b/code/modules/modular_computers/computers/item/computer_power.dm
index 0a7955cfe52..27c81d48190 100644
--- a/code/modules/modular_computers/computers/item/computer_power.dm
+++ b/code/modules/modular_computers/computers/item/computer_power.dm
@@ -26,6 +26,10 @@
return battery_module.battery.give(amount)
return 0
+/obj/item/modular_computer/get_cell()
+ var/obj/item/computer_hardware/battery/battery_module = all_components[MC_CELL]
+ if(battery_module && battery_module.battery)
+ return battery_module.battery
// Used in following function to reduce copypaste
/obj/item/modular_computer/proc/power_failure()
diff --git a/code/modules/modular_computers/hardware/battery_module.dm b/code/modules/modular_computers/hardware/battery_module.dm
index 65b4ef1f640..98f1ab5667e 100644
--- a/code/modules/modular_computers/hardware/battery_module.dm
+++ b/code/modules/modular_computers/hardware/battery_module.dm
@@ -8,6 +8,9 @@
var/obj/item/stock_parts/cell/battery = null
device_type = MC_CELL
+/obj/item/computer_hardware/battery/get_cell()
+ return battery
+
/obj/item/computer_hardware/battery/New(loc, battery_type = null)
if(battery_type)
battery = new battery_type(src)
diff --git a/code/modules/ninja/suit/suit.dm b/code/modules/ninja/suit/suit.dm
index dfd430a5754..6e550e64893 100644
--- a/code/modules/ninja/suit/suit.dm
+++ b/code/modules/ninja/suit/suit.dm
@@ -27,6 +27,9 @@ Contents:
var/obj/item/clothing/mask/gas/space_ninja/suitMask
var/mob/living/carbon/human/suitOccupant
+/obj/item/clothing/suit/space/space_ninja/get_cell()
+ return suitCell
+
/obj/item/clothing/suit/space/space_ninja/proc/toggle_suit_lock(mob/living/carbon/human/user)
if(!suitActive)
if(!istype(user.wear_suit, /obj/item/clothing/suit/space/space_ninja))
diff --git a/code/modules/ninja/suit/suit_attackby.dm b/code/modules/ninja/suit/suit_attackby.dm
index ab6250a2b0f..2a2683a2826 100644
--- a/code/modules/ninja/suit/suit_attackby.dm
+++ b/code/modules/ninja/suit/suit_attackby.dm
@@ -1,5 +1,3 @@
-
-
/obj/item/clothing/suit/space/space_ninja/attackby(obj/item/I, mob/U, params)
if(U==suitOccupant)//Safety, in case you try doing this without wearing the suit/being the person with the suit.
if(istype(I, /obj/item/stock_parts/cell))
@@ -21,4 +19,4 @@
else
to_chat(U, "Procedure interrupted. Protocol terminated.")
return
- ..()
\ No newline at end of file
+ ..()
diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm
index 451687cd38c..23a37e06409 100644
--- a/code/modules/paperwork/paper.dm
+++ b/code/modules/paperwork/paper.dm
@@ -75,16 +75,19 @@
assets.send(user)
var/data
- if((!user.say_understands(null, GLOB.all_languages["Galactic Common"]) && !forceshow) || forcestars) //assuming all paper is written in common is better than hardcoded type checks
- data = "[name][stars(info)][stamps]"
- if(view)
- usr << browse(data, "window=[name];size=[paper_width]x[paper_height]")
- onclose(usr, "[name]")
+ var/stars = (!user.say_understands(null, GLOB.all_languages["Galactic Common"]) && !forceshow) || forcestars
+ if(stars) //assuming all paper is written in common is better than hardcoded type checks
+ data = "[stars(info)][stamps]"
else
- data = "[name][infolinks ? info_links : info][stamps]"
- if(view)
- usr << browse(data, "window=[name];size=[paper_width]x[paper_height]")
- onclose(usr, "[name]")
+ data = "
Clicking on a health doll icon will now check you for injuries
+
Rechargers now show their contents and charge status on close examine
+
Smartfridge will now try to put an item in your hands after vending, if able
+
+
AzuleUtama updated:
+
+
The cybernetic implant bundle can no longer be bought by traitors.
+
+
Citinited updated:
+
+
Alt-clicking the RPD now brings up a radial menu with rotate, flip, and delete modes accessible. The main interface remains unchanged.
+
Writing in blood can't be done while dead or incapacitated any more
+
You can't write stuff in blood at a distance any more
+
+
Couls updated:
+
+
lantern sprites
+
typo in msg
+
+
Improvedname updated:
+
+
Explorer suits now properly hide tails
+
+
JKnutson101 updated:
+
+
Fixed Construction Permits deleting themselves prematurely.
+
+
Kyep updated:
+
+
fixed a bug with biogenerator.
+
+
Markolie updated:
+
+
Ghosts can now see all PDA messages when enabled through a preference setting.
+
The Mask of Nar'Sie transformation buttons have been removed, as the mask was removed a long time ago.
+
+
Shadeykins updated:
+
+
Changed Quarantine, NT Default, Aggressive, and Corporate AI lawsets. balance: Reduced the ability for NT Default AI's to murder people just because.
+
Removed several redundancies in Aggressive lawset.
+
Fixed a few subject-verb disagreements (is -> are).
+
+
Tayyyyyyy updated:
+
+
paper supports markdown as well as pencode
+
Autocomplete for ghost buttons
+
PMs window scrollable
+
Fix a bug where a player who reconnects is still shown as disconnected
+
+
datlo updated:
+
+
Fix an antag rolling exploit.
+
+
+
30 June 2019
+
Crazylemon64 updated:
+
+
SDQL2 no longer allows a macro argument
+
+
+
28 June 2019
+
AffectedArc07 updated:
+
+
SSticker
+
You can no longer force-start a round unless its fully initialised.
+
Tweaks some preference orders
+
Moved a global define
+
+
Akatos updated:
+
+
Smartfridges now visually show approximate number of items inside
+
+
Arkatos updated:
+
+
Ragin' Mages gamemode should now be playable without any major issue
+
Slaughter and Laughter Demons no longer have duplicit objective shown at the Round End
+
Laughter Demon is now properly called Laughter Demon instead of Slaughter Demon in the role polls
+
Improved wording and fixed mistakes in Wizard and Ragin' Mages gamemodes
+
Wizards are now properly polled in the Ragin' Mages gamemode
+
You can no longer buy Summon Ghosts spell in the Ragin' Mages gamemode
+
You can no longer buy Bind Soul spell in the Ragin' Mages gamemode
+
Deck of tarot cards renamed to Guardian Deck in the Wizard spellbook
+
Rituals and Challenges categories merged into one in the Wizard spellbook
+
Laughter Demon is now slightly weaker compared to the Slaughter Demon
+
Bottle of Ooze now creates a magical morph instead of a normal one. Magical morph is capable of casting smoke and forcewall spells.
+
Visible ghosts will now get a special description about their visibility
+
Removed Cursed Heart from the Wizard spellbook
+
Changeling verbs replaced with action buttons
+
Changeling ability descriptions updated
+
Added custom icons for changeling action buttons
+
Added movement animation for mice, chickens and killer tomatoes
+
Added inhand sprite for eggbox
+
Added inhand sprites for all types of soaps
+
Added inhand sprite for small parcel
+
Added inhand sprite for sechailer
+
Added inhand sprite for bag of holding
+
Added new system for outputting contents of smartfridges
+
Blob split consciousness ability now requires you to directly target a node you want to turn into another sentient overmind instead of selecting a nearest one
+
Fixed and improved some descriptions regarding Blob offspring
+
Fixed a case where ghosts had an extra ghost icon visible on them
+
Fixed a case where some ghosts were too bright
+
You are now unable to swap forms with another changeling
+
You can no longer hiss while muzzled
+
Upon purchasing Augmented Eyesight changeling ability, changeling immediately receives passive version of the ability
+
Changelings in the lesser form can now toggle Augmented Eyesight ability
+
Changelings are now removed properly via Traitor Panel
+
Changelings do not get their action buttons bugged when using Swap Forms ability now
+
Action buttons should update their cooldown statuses more reliably
+
Changelings should now correctly receive their action buttons
+
Changelings now do not steal action buttons from other changelings
+
Added new Boo! spell icon
+
+
Christasmurf updated:
+
+
Fixes a random pixel on the leather shoes
+
+
Citinited updated:
+
+
Boo affects APCs again
+
Boo no longer fully charges when you enter your corpse
+
The button to close radial menus is much more obvious and easily-clickable now
+
Destroying a disposals trunk should no longer occasionally delete things held inside it.
+
Fixes conveyor belts not moving items spawned via an autolathe. (And other possible behaviours when machines switch between speed and normal processes)
+
Ports liquid dispenser sprites from tgstation.
+
+
Couls updated:
+
+
Only names from the manifest will be used for syndicate code phrases
+
randomly generated people names from syndicate code phrases
+
Medical category to exosuit fabricator with implants and cybernetics
+
t-t-t-typo!
+
codephrase names no longer appear blank
+
+
EmanTheAlmighty updated:
+
+
Admin made cultists can now properly summon their Gods if the gamemode wasn't initially Cult.
+
+
Evankhell561 updated:
+
+
Portable Seed Extractor designon the protolathe.
+
+
Fethas updated:
+
+
Fixes an oversight from the lavaland port invovling Laz injectors and sentience typing that didn't carry over from tg.
+
+
Fox McCloud updated:
+
+
Future proofs the coming Ticker subsystem
+
Removes the Process Scheduler
+
+
Improvedname updated:
+
+
Cargo miner starter kit crate will no longer include a ID
+
+
Kyep updated:
+
+
Ported XKeyScore from TG.
+
New system to securely link ingame/forum accounts
+
Removed old insecure 'link discord account' system
+
unanchored vending machines will no longer generate a runtime error when throwing products at people.
+
Disarming/grabbing a door with IDSCAN disabled no longer results in a can_admin_interact runtime error.
+
Terror Spiders no longer trigger their special attack when nuzzling someone on help intent.
+
+
Markolie updated:
+
+
Chameleon items now use the appropriate species icon.
+
Lighting now respects color blindness again.
+
pAI flashlights now work properly.
+
Rotatium can now be created properly.
+
Ghosts can now transition through space again. This is now done by clicking on the edge of space.
+
Added custom explorer gas mask sprites for Grey/Drask.
+
Added a lantern to the Hermit cave.
+
Added a bone setter, bone gel, FixOVein, sterile masks and sterile gloves to the Lavaland Syndicate base.
+
The pickaxes on the Lavaland labor camp have been replaced with safety variants. The flashlights have been replaced with lanterns.
+
Fixed many species missing sprites for explorer gas masks and jumpsuits. They now use the humans icons until we have custom sprites.
+
Resolved an issue with piping not working on the Lavaland mining bases.
+
Fixed all items being free in the mining vendor.
+
Fixed improper wiring to the turbine in the Lavaland Syndicate base.
+
Fixed the Lavaland Syndicate base oxygen sensor not working.
+
Moved the pipe dispenser in the Lavaland Syndicate base so it doesn't clip with tables.
+
Fixed the Lavaland Syndicate base incinerator doors not working.
+
Ash Walkers now once more have fine manipulation. Their lack of fine manipulation caused unintended side effects (such as them being unable to mine).
+
Ash Walkers (and other ghost spawner roles) can no longer be antagonist targets or become antagonists through the antagonist creation.
+
Fixed the Lavaland Syndicate base incinerator buttons not working.
+
Fixed the Syndicate communication agent spawning with a broken voice changer mask.
+
Fixed the Disk Compartmentalizer not having a sprite.
+
The Ancient Goliath now has a small chance of spawning instead of regular goliaths.
+
Survival capsules now have a NanoMed.
+
Water bottles now behave as glass containers.
+
The behaviour of glass reagent containers has changed. When used on non-mobs, contents will now only be spilled on harm intent. When used on mobs, on any intent aside from harm the contents will be fed to the mob like regular drinks. On harm intent it will still be spilled.
+
Hairless hide can now be made wet using most sources of water (minimum volume of 10), instead of just washing machines.
+
Added some additional offstation role checks to ensure ghost spawner roles don't become antagonists, are kidnap targets or are counted towards station goals.
+
Fixed some piping in the Lavaland Syndicate base incinerator and made sure the vault door starts locked.
+
Fixed the Lavaland swarmers getting stuck on propulsion.
+
Fix goliath tentacles sometimes being left behind.
+
The walls around the Lavaland Syndicate base turbine have been coated, to prevent them from starting a plasma fire in the base.
+
Syndicate agents can now access the air alarms on the Lavaland Syndicate base.
+
Air alarm control computers can no longer access the air alarms on the Lavaland Syndicate base.
+
Fixed the disk compartmentalizer/drying rack missing a sprite under certain circumstances.
+
Fixed the Lavaland Syndicate base triggering atmospherics alerts.
+
You can now properly place tiles on basalt.
+
An exploit with the sheet multiplier has been fixed.
+
Portals can now be activated by clicking on them with or without an object. Ghosts can now also click on them to be taken to their destination.
+
Portals now warn admins when they are used to teleport megafauna.
+
The singularity can now eat basalt and chasms on Lavaland. They get turned into lava.
+
AI swarmers will no longer get stuck on effects (such as blood).
+
Fixed the spectral blade turning all ghosts visible.
+
Fixed a runtime with assigning outfits to mindless mobs.
+
Fixed certain alarms triggering despite being outside of station contact and the Syndicate base still triggering fire alarms.
+
Fixed being unable to put the wormhole jaunter in the belt slot.
+
Fixed the disk compartmentalizer not accepting disks.
+
Gutlunches and Gubbucks will now reproduce properly.
+
The necropolis chest cult clothing drop no longer spawns with a cult hood as well, as that's part of the suit itself.
+
Goliath steaks can now be eaten properly.
+
Fixed a stray light on the beach ruin.
+
Lavaland ruins should no longer spawn on the Labor Camp.
+
Ancient goliaths will now properly randomly spawn tentacles.
+
The labor camp will now spawn properly with a processing console.
+
Water turfs in the beach ruin (and other water turfs that previously didn't do so) will now properly apply water to you.
+
Ash flora is now anchored.
+
Gutlunches will now eat properly.
+
The tesla can no longer travel through wormholes.
+
Fixed an issue with honkbot construction.
+
+
Markolie and Ionward updated:
+
+
Added Tajaran, Vulpkanin, Unathi and Vox sprites for the explorer gas mask (thanks to Ionward!)
+
Added custom species sprites for the explorer suits and hoods (thanks to Ionward!)
+
Added missing surgical tools and a pet vendor to the animal hospital.
+
Added a custom cigarette vendor to the beach biodome ruin.
+
Added an autolathe and RPD to the Lavaland Syndicate base. Also added a custom cigarette vendor and made the vendors not charge money.
+
Added tiny fans to the mining base and labor camp exist.
+
A separate jobban for ghost roles has been added.
+
The alternative sink now has directional sprites. This resolves an issue with shelters having sinks facing the wrong way.
+
Fixed the Syndicate sleepers on the Lavaland Syndicate base pointing the wrong way when a ghost role spawns in.
+
Fixed Lava being removed by the staff of lava not working. Also added a missing warning effect when the staff is turning regular turf into lava.
+
Fixed random bookcases not spawning books (hopefully).
+
Fixed surgical drapes not having a sprite.
+
Fixed being unable to modify the GPS tag of shelters.
+
Fixed the Lavaland swarmers not eating anything.
+
The ash drake swoop attack is no longer incredibly loud.
+
The Syndicate base self-destruct is now much more powerful and capable of destroying the entire base.
+
The flavor text of Ash Walkers and Syndicate operatives now clarifies what they can('t) do.
+
Ash walkers can no longer use machinery.
+
+
Ported by Markolie and CornMyCob. Developed by many /tg/ coders updated:
+
+
The mining asteroid has been replaced with Lavaland.
+
+
Shadeykins updated:
+
+
Fixes a paper exploit.
+
Fixes rogue pixels on breath masks/gas masks for Plasmamen.
+
+
TDSSS updated:
+
+
Vampire rejuv wakes you up if you're asleep now
+
Cling epinephrine wakes you up if you're asleep now
+
Sling glare popup no longer lists invalid targets for glaring
+
+
Tayyyyyyy updated:
+
+
Messages window (My PMs in OOC tab)
+
You no longer have to wait on others for ERT spawning
+
Admin jobs no longer announced
+
+
Terilia updated:
+
+
Added the Donksoft sniper into the Trader spawnpool.
+
+
Ty-Omaha updated:
+
+
Changed admin take ticket color from neon green to Asay pink
+
Manual bans now auto-note
+
Stops projectiles using the legacy system such as emitters from hurting shield blobs due to an exploit where it would always hit or go through.
+
+
craftxbox updated:
+
+
Highlight string uses regex
+
Removed jquery mark
+
+
datlo updated:
+
+
The Syndicate will no longer hire golems as agents.
+
Banana juice and Banana honk will now heal everyone with the Comic Sans mutation instead of checking for the clown job
+
Nothing will now check if the player has an active vow of silence instead of checking for the mime job
+
Ghosts will no longer get the wrong role offered when a nukie spawns a borg and will properly be informed whether they will spawn as a nuke ops or a syndi cyborg.
+
+
dovydas12345 updated:
+
+
Fixes cryopod removing ambulance, secway keys
+
Fixes cryopod recovering the invisible headpocket item
+
+
farie82 updated:
+
+
Can't use cuffs now while you have antidrop
+
can_equip now checks if you have the limbs required to equip something
+
Reverts the string highlighting done by regex
+
+
iantine updated:
+
+
Skrell *warble emote
+
+
uc_guy updated:
+
+
Theft objective locations hints now ignore the Centcomm Z level.
+
Adv. Pinpointer no longer targets items in Centcom Z level.
+
Fixed "Venus Human Traps" being invisible.
+
+
10 May 2019
AffectedArc07 updated:
diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml
index d0e51aa9571..49e86db023d 100644
--- a/html/changelogs/.all_changelog.yml
+++ b/html/changelogs/.all_changelog.yml
@@ -10162,3 +10162,295 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
- rscdel: Some of space hotel's functions.
- rscdel: Bodysnatch gland.
- tweak: process_ai has been deprecated
+2019-06-28:
+ AffectedArc07:
+ - rscadd: SSticker
+ - tweak: You can no longer force-start a round unless its fully initialised.
+ - tweak: Tweaks some preference orders
+ - tweak: Moved a global define
+ Akatos:
+ - tweak: Smartfridges now visually show approximate number of items inside
+ Arkatos:
+ - bugfix: Ragin' Mages gamemode should now be playable without any major issue
+ - bugfix: Slaughter and Laughter Demons no longer have duplicit objective shown
+ at the Round End
+ - bugfix: Laughter Demon is now properly called Laughter Demon instead of Slaughter
+ Demon in the role polls
+ - spellcheck: Improved wording and fixed mistakes in Wizard and Ragin' Mages gamemodes
+ - tweak: Wizards are now properly polled in the Ragin' Mages gamemode
+ - tweak: You can no longer buy Summon Ghosts spell in the Ragin' Mages gamemode
+ - tweak: You can no longer buy Bind Soul spell in the Ragin' Mages gamemode
+ - tweak: Deck of tarot cards renamed to Guardian Deck in the Wizard spellbook
+ - tweak: Rituals and Challenges categories merged into one in the Wizard spellbook
+ - tweak: Laughter Demon is now slightly weaker compared to the Slaughter Demon
+ - tweak: Bottle of Ooze now creates a magical morph instead of a normal one. Magical
+ morph is capable of casting smoke and forcewall spells.
+ - tweak: Visible ghosts will now get a special description about their visibility
+ - rscdel: Removed Cursed Heart from the Wizard spellbook
+ - rscadd: Changeling verbs replaced with action buttons
+ - tweak: Changeling ability descriptions updated
+ - imageadd: Added custom icons for changeling action buttons
+ - imageadd: Added movement animation for mice, chickens and killer tomatoes
+ - imageadd: Added inhand sprite for eggbox
+ - imageadd: Added inhand sprites for all types of soaps
+ - imageadd: Added inhand sprite for small parcel
+ - imageadd: Added inhand sprite for sechailer
+ - imageadd: Added inhand sprite for bag of holding
+ - tweak: Added new system for outputting contents of smartfridges
+ - tweak: Blob split consciousness ability now requires you to directly target a
+ node you want to turn into another sentient overmind instead of selecting a
+ nearest one
+ - spellcheck: Fixed and improved some descriptions regarding Blob offspring
+ - bugfix: Fixed a case where ghosts had an extra ghost icon visible on them
+ - bugfix: Fixed a case where some ghosts were too bright
+ - bugfix: You are now unable to swap forms with another changeling
+ - bugfix: You can no longer hiss while muzzled
+ - tweak: Upon purchasing Augmented Eyesight changeling ability, changeling immediately
+ receives passive version of the ability
+ - tweak: Changelings in the lesser form can now toggle Augmented Eyesight ability
+ - bugfix: Changelings are now removed properly via Traitor Panel
+ - bugfix: Changelings do not get their action buttons bugged when using Swap Forms
+ ability now
+ - bugfix: Action buttons should update their cooldown statuses more reliably
+ - bugfix: Changelings should now correctly receive their action buttons
+ - bugfix: Changelings now do not steal action buttons from other changelings
+ - imageadd: Added new Boo! spell icon
+ Christasmurf:
+ - bugfix: Fixes a random pixel on the leather shoes
+ Citinited:
+ - bugfix: Boo affects APCs again
+ - bugfix: Boo no longer fully charges when you enter your corpse
+ - tweak: The button to close radial menus is much more obvious and easily-clickable
+ now
+ - bugfix: Destroying a disposals trunk should no longer occasionally delete things
+ held inside it.
+ - bugfix: Fixes conveyor belts not moving items spawned via an autolathe. (And other
+ possible behaviours when machines switch between speed and normal processes)
+ - imageadd: Ports liquid dispenser sprites from tgstation.
+ Couls:
+ - rscadd: Only names from the manifest will be used for syndicate code phrases
+ - rscdel: randomly generated people names from syndicate code phrases
+ - rscadd: Medical category to exosuit fabricator with implants and cybernetics
+ - bugfix: t-t-t-typo!
+ - bugfix: codephrase names no longer appear blank
+ EmanTheAlmighty:
+ - tweak: Admin made cultists can now properly summon their Gods if the gamemode
+ wasn't initially Cult.
+ Evankhell561:
+ - bugfix: Portable Seed Extractor designon the protolathe.
+ Fethas:
+ - bugfix: Fixes an oversight from the lavaland port invovling Laz injectors and
+ sentience typing that didn't carry over from tg.
+ Fox McCloud:
+ - bugfix: Future proofs the coming Ticker subsystem
+ - rscdel: Removes the Process Scheduler
+ Improvedname:
+ - tweak: Cargo miner starter kit crate will no longer include a ID
+ Kyep:
+ - rscadd: Ported XKeyScore from TG.
+ - rscadd: New system to securely link ingame/forum accounts
+ - rscdel: Removed old insecure 'link discord account' system
+ - bugfix: unanchored vending machines will no longer generate a runtime error when
+ throwing products at people.
+ - bugfix: Disarming/grabbing a door with IDSCAN disabled no longer results in a
+ can_admin_interact runtime error.
+ - bugfix: Terror Spiders no longer trigger their special attack when nuzzling someone
+ on help intent.
+ Markolie:
+ - bugfix: Chameleon items now use the appropriate species icon.
+ - bugfix: Lighting now respects color blindness again.
+ - bugfix: pAI flashlights now work properly.
+ - bugfix: Rotatium can now be created properly.
+ - bugfix: Ghosts can now transition through space again. This is now done by clicking
+ on the edge of space.
+ - rscadd: Added custom explorer gas mask sprites for Grey/Drask.
+ - rscadd: Added a lantern to the Hermit cave.
+ - rscadd: Added a bone setter, bone gel, FixOVein, sterile masks and sterile gloves
+ to the Lavaland Syndicate base.
+ - rscadd: The pickaxes on the Lavaland labor camp have been replaced with safety
+ variants. The flashlights have been replaced with lanterns.
+ - bugfix: Fixed many species missing sprites for explorer gas masks and jumpsuits.
+ They now use the humans icons until we have custom sprites.
+ - bugfix: Resolved an issue with piping not working on the Lavaland mining bases.
+ - bugfix: Fixed all items being free in the mining vendor.
+ - bugfix: Fixed improper wiring to the turbine in the Lavaland Syndicate base.
+ - bugfix: Fixed the Lavaland Syndicate base oxygen sensor not working.
+ - bugfix: Moved the pipe dispenser in the Lavaland Syndicate base so it doesn't
+ clip with tables.
+ - bugfix: Fixed the Lavaland Syndicate base incinerator doors not working.
+ - tweak: Ash Walkers now once more have fine manipulation. Their lack of fine manipulation
+ caused unintended side effects (such as them being unable to mine).
+ - bugfix: Ash Walkers (and other ghost spawner roles) can no longer be antagonist
+ targets or become antagonists through the antagonist creation.
+ - bugfix: Fixed the Lavaland Syndicate base incinerator buttons not working.
+ - bugfix: Fixed the Syndicate communication agent spawning with a broken voice changer
+ mask.
+ - bugfix: Fixed the Disk Compartmentalizer not having a sprite.
+ - rscadd: The Ancient Goliath now has a small chance of spawning instead of regular
+ goliaths.
+ - rscadd: Survival capsules now have a NanoMed.
+ - tweak: Water bottles now behave as glass containers.
+ - tweak: The behaviour of glass reagent containers has changed. When used on non-mobs,
+ contents will now only be spilled on harm intent. When used on mobs, on any
+ intent aside from harm the contents will be fed to the mob like regular drinks.
+ On harm intent it will still be spilled.
+ - tweak: Hairless hide can now be made wet using most sources of water (minimum
+ volume of 10), instead of just washing machines.
+ - bugfix: Added some additional offstation role checks to ensure ghost spawner roles
+ don't become antagonists, are kidnap targets or are counted towards station
+ goals.
+ - bugfix: Fixed some piping in the Lavaland Syndicate base incinerator and made
+ sure the vault door starts locked.
+ - bugfix: Fixed the Lavaland swarmers getting stuck on propulsion.
+ - bugfix: Fix goliath tentacles sometimes being left behind.
+ - bugfix: The walls around the Lavaland Syndicate base turbine have been coated,
+ to prevent them from starting a plasma fire in the base.
+ - bugfix: Syndicate agents can now access the air alarms on the Lavaland Syndicate
+ base.
+ - bugfix: Air alarm control computers can no longer access the air alarms on the
+ Lavaland Syndicate base.
+ - bugfix: Fixed the disk compartmentalizer/drying rack missing a sprite under certain
+ circumstances.
+ - bugfix: Fixed the Lavaland Syndicate base triggering atmospherics alerts.
+ - bugfix: You can now properly place tiles on basalt.
+ - bugfix: An exploit with the sheet multiplier has been fixed.
+ - rscadd: Portals can now be activated by clicking on them with or without an object.
+ Ghosts can now also click on them to be taken to their destination.
+ - rscadd: Portals now warn admins when they are used to teleport megafauna.
+ - tweak: The singularity can now eat basalt and chasms on Lavaland. They get turned
+ into lava.
+ - bugfix: AI swarmers will no longer get stuck on effects (such as blood).
+ - bugfix: Fixed the spectral blade turning all ghosts visible.
+ - bugfix: Fixed a runtime with assigning outfits to mindless mobs.
+ - bugfix: Fixed certain alarms triggering despite being outside of station contact
+ and the Syndicate base still triggering fire alarms.
+ - bugfix: Fixed being unable to put the wormhole jaunter in the belt slot.
+ - bugfix: Fixed the disk compartmentalizer not accepting disks.
+ - bugfix: Gutlunches and Gubbucks will now reproduce properly.
+ - bugfix: The necropolis chest cult clothing drop no longer spawns with a cult hood
+ as well, as that's part of the suit itself.
+ - bugfix: Goliath steaks can now be eaten properly.
+ - bugfix: Fixed a stray light on the beach ruin.
+ - bugfix: Lavaland ruins should no longer spawn on the Labor Camp.
+ - bugfix: Ancient goliaths will now properly randomly spawn tentacles.
+ - bugfix: The labor camp will now spawn properly with a processing console.
+ - bugfix: Water turfs in the beach ruin (and other water turfs that previously didn't
+ do so) will now properly apply water to you.
+ - bugfix: Ash flora is now anchored.
+ - bugfix: Gutlunches will now eat properly.
+ - bugfix: The tesla can no longer travel through wormholes.
+ - bugfix: Fixed an issue with honkbot construction.
+ Markolie and Ionward:
+ - rscadd: Added Tajaran, Vulpkanin, Unathi and Vox sprites for the explorer gas
+ mask (thanks to Ionward!)
+ - rscadd: Added custom species sprites for the explorer suits and hoods (thanks
+ to Ionward!)
+ - rscadd: Added missing surgical tools and a pet vendor to the animal hospital.
+ - rscadd: Added a custom cigarette vendor to the beach biodome ruin.
+ - rscadd: Added an autolathe and RPD to the Lavaland Syndicate base. Also added
+ a custom cigarette vendor and made the vendors not charge money.
+ - rscadd: Added tiny fans to the mining base and labor camp exist.
+ - rscadd: A separate jobban for ghost roles has been added.
+ - bugfix: The alternative sink now has directional sprites. This resolves an issue
+ with shelters having sinks facing the wrong way.
+ - bugfix: Fixed the Syndicate sleepers on the Lavaland Syndicate base pointing the
+ wrong way when a ghost role spawns in.
+ - bugfix: Fixed Lava being removed by the staff of lava not working. Also added
+ a missing warning effect when the staff is turning regular turf into lava.
+ - bugfix: Fixed random bookcases not spawning books (hopefully).
+ - bugfix: Fixed surgical drapes not having a sprite.
+ - bugfix: Fixed being unable to modify the GPS tag of shelters.
+ - bugfix: Fixed the Lavaland swarmers not eating anything.
+ - bugfix: The ash drake swoop attack is no longer incredibly loud.
+ - tweak: The Syndicate base self-destruct is now much more powerful and capable
+ of destroying the entire base.
+ - tweak: The flavor text of Ash Walkers and Syndicate operatives now clarifies what
+ they can('t) do.
+ - tweak: Ash walkers can no longer use machinery.
+ Ported by Markolie and CornMyCob. Developed by many /tg/ coders:
+ - rscadd: The mining asteroid has been replaced with Lavaland.
+ Shadeykins:
+ - bugfix: Fixes a paper exploit.
+ - bugfix: Fixes rogue pixels on breath masks/gas masks for Plasmamen.
+ TDSSS:
+ - tweak: Vampire rejuv wakes you up if you're asleep now
+ - tweak: Cling epinephrine wakes you up if you're asleep now
+ - tweak: Sling glare popup no longer lists invalid targets for glaring
+ Tayyyyyyy:
+ - rscadd: Messages window (My PMs in OOC tab)
+ - tweak: You no longer have to wait on others for ERT spawning
+ - bugfix: Admin jobs no longer announced
+ Terilia:
+ - rscadd: Added the Donksoft sniper into the Trader spawnpool.
+ Ty-Omaha:
+ - tweak: Changed admin take ticket color from neon green to Asay pink
+ - bugfix: Manual bans now auto-note
+ - bugfix: Stops projectiles using the legacy system such as emitters from hurting
+ shield blobs due to an exploit where it would always hit or go through.
+ craftxbox:
+ - tweak: Highlight string uses regex
+ - rscdel: Removed jquery mark
+ datlo:
+ - bugfix: The Syndicate will no longer hire golems as agents.
+ - tweak: Banana juice and Banana honk will now heal everyone with the Comic Sans
+ mutation instead of checking for the clown job
+ - tweak: Nothing will now check if the player has an active vow of silence instead
+ of checking for the mime job
+ - bugfix: Ghosts will no longer get the wrong role offered when a nukie spawns a
+ borg and will properly be informed whether they will spawn as a nuke ops or
+ a syndi cyborg.
+ dovydas12345:
+ - bugfix: Fixes cryopod removing ambulance, secway keys
+ - bugfix: Fixes cryopod recovering the invisible headpocket item
+ farie82:
+ - bugfix: Can't use cuffs now while you have antidrop
+ - bugfix: can_equip now checks if you have the limbs required to equip something
+ - rscdel: Reverts the string highlighting done by regex
+ iantine:
+ - rscadd: Skrell *warble emote
+ uc_guy:
+ - bugfix: Theft objective locations hints now ignore the Centcomm Z level.
+ - bugfix: Adv. Pinpointer no longer targets items in Centcom Z level.
+ - bugfix: Fixed "Venus Human Traps" being invisible.
+2019-06-30:
+ Crazylemon64:
+ - rscdel: SDQL2 no longer allows a macro argument
+2019-07-08:
+ Arkatos:
+ - tweak: Clicking on a health doll icon will now check you for injuries
+ - rscadd: Rechargers now show their contents and charge status on close examine
+ - tweak: Smartfridge will now try to put an item in your hands after vending, if
+ able
+ AzuleUtama:
+ - bugfix: The cybernetic implant bundle can no longer be bought by traitors.
+ Citinited:
+ - rscadd: Alt-clicking the RPD now brings up a radial menu with rotate, flip, and
+ delete modes accessible. The main interface remains unchanged.
+ - bugfix: Writing in blood can't be done while dead or incapacitated any more
+ - bugfix: You can't write stuff in blood at a distance any more
+ Couls:
+ - imageadd: lantern sprites
+ - bugfix: typo in msg
+ Improvedname:
+ - bugfix: Explorer suits now properly hide tails
+ JKnutson101:
+ - bugfix: Fixed Construction Permits deleting themselves prematurely.
+ Kyep:
+ - bugfix: fixed a bug with biogenerator.
+ Markolie:
+ - rscadd: Ghosts can now see all PDA messages when enabled through a preference
+ setting.
+ - rscdel: The Mask of Nar'Sie transformation buttons have been removed, as the mask
+ was removed a long time ago.
+ Shadeykins:
+ - tweak: 'Changed Quarantine, NT Default, Aggressive, and Corporate AI lawsets.
+ balance: Reduced the ability for NT Default AI''s to murder people just because.'
+ - bugfix: Removed several redundancies in Aggressive lawset.
+ - spellcheck: Fixed a few subject-verb disagreements (is -> are).
+ Tayyyyyyy:
+ - tweak: paper supports markdown as well as pencode
+ - rscadd: Autocomplete for ghost buttons
+ - tweak: PMs window scrollable
+ - bugfix: Fix a bug where a player who reconnects is still shown as disconnected
+ datlo:
+ - bugfix: Fix an antag rolling exploit.
diff --git a/html/changelogs/AutoChangeLog-pr-11125.yml b/html/changelogs/AutoChangeLog-pr-11125.yml
new file mode 100644
index 00000000000..2208cf5854c
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11125.yml
@@ -0,0 +1,8 @@
+author: "Quantum-M"
+delete-after: True
+changes:
+ - rscadd: "New sprites for vampires being \"hungry\"."
+ - rscadd: "New sprite for vampire usable blood count."
+ - rscadd: "New sprites for the safety muzzle."
+ - tweak: "Safety muzzle (aka the anti-bitting one) can no longer be resisted out of."
+ - tweak: "Vampires can now suck blood from monkey mobs (e.g. monkeys, stoks, etc.) for sustenance but do not get blood power points."
diff --git a/html/changelogs/AutoChangeLog-pr-11196.yml b/html/changelogs/AutoChangeLog-pr-11196.yml
deleted file mode 100644
index fc5f502d62f..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11196.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ported by Markolie and CornMyCob. Developed by many /tg/ coders"
-delete-after: True
-changes:
- - rscadd: "The mining asteroid has been replaced with Lavaland."
diff --git a/html/changelogs/AutoChangeLog-pr-11358.yml b/html/changelogs/AutoChangeLog-pr-11358.yml
new file mode 100644
index 00000000000..ed5662b1047
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11358.yml
@@ -0,0 +1,8 @@
+author: "Couls"
+delete-after: True
+changes:
+ - rscadd: "Diagonal movement"
+ - rscadd: "Input subsystem(numpad targetting, press numpad 8 multiple times to target eyes and mouth, numpad 6 or 4 to target arms and press them again to target hands and numpad 1 or 3 to target legs and press them again to target feet) taken from https://github.com/tgstation/tgstation/pull/32751"
+ - rscadd: "change confused status to have you move diagonally randomly in the direction you're headed if not too confused(now you can drunkenly walk down the hall)"
+ - rscadd: "clients are now children of datums like everything else in BYOND taken from https://github.com/tgstation/tgstation/pull/20394"
+ - rscadd: "AZERTY and numpad targetting preferences"
diff --git a/html/changelogs/AutoChangeLog-pr-11359.yml b/html/changelogs/AutoChangeLog-pr-11359.yml
deleted file mode 100644
index 3f93a5677ef..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11359.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Kyep"
-delete-after: True
-changes:
- - rscadd: "Ported XKeyScore from TG."
- - rscadd: "New system to securely link ingame/forum accounts"
- - rscdel: "Removed old insecure 'link discord account' system"
diff --git a/html/changelogs/AutoChangeLog-pr-11368.yml b/html/changelogs/AutoChangeLog-pr-11368.yml
deleted file mode 100644
index f2d543bae3a..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11368.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "AffectedArc07"
-delete-after: True
-changes:
- - rscadd: "SSticker"
- - tweak: "You can no longer force-start a round unless its fully initialised."
diff --git a/html/changelogs/AutoChangeLog-pr-11421.yml b/html/changelogs/AutoChangeLog-pr-11421.yml
deleted file mode 100644
index 83e285205c3..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11421.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-author: "Arkatos"
-delete-after: True
-changes:
- - bugfix: "Ragin' Mages gamemode should now be playable without any major issue"
- - bugfix: "Slaughter and Laughter Demons no longer have duplicit objective shown at the Round End"
- - bugfix: "Laughter Demon is now properly called Laughter Demon instead of Slaughter Demon in the role polls"
- - spellcheck: "Improved wording and fixed mistakes in Wizard and Ragin' Mages gamemodes"
- - tweak: "Wizards are now properly polled in the Ragin' Mages gamemode"
- - tweak: "You can no longer buy Summon Ghosts spell in the Ragin' Mages gamemode"
- - tweak: "You can no longer buy Bind Soul spell in the Ragin' Mages gamemode"
- - tweak: "Deck of tarot cards renamed to Guardian Deck in the Wizard spellbook"
- - tweak: "Rituals and Challenges categories merged into one in the Wizard spellbook"
- - tweak: "Laughter Demon is now slightly weaker compared to the Slaughter Demon"
- - tweak: "Bottle of Ooze now creates a magical morph instead of a normal one. Magical morph is capable of casting smoke and forcewall spells."
- - tweak: "Visible ghosts will now get a special description about their visibility"
- - rscdel: "Removed Cursed Heart from the Wizard spellbook"
diff --git a/html/changelogs/AutoChangeLog-pr-11438.yml b/html/changelogs/AutoChangeLog-pr-11438.yml
deleted file mode 100644
index a276198bfa9..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11438.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "EmanTheAlmighty"
-delete-after: True
-changes:
- - tweak: "Admin made cultists can now properly summon their Gods if the gamemode wasn't initially Cult."
diff --git a/html/changelogs/AutoChangeLog-pr-11439.yml b/html/changelogs/AutoChangeLog-pr-11439.yml
deleted file mode 100644
index c5352502c88..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11439.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Arkatos"
-delete-after: True
-changes:
- - rscadd: "Changeling verbs replaced with action buttons"
- - tweak: "Changeling ability descriptions updated"
- - imageadd: "Added custom icons for changeling action buttons"
diff --git a/html/changelogs/AutoChangeLog-pr-11444.yml b/html/changelogs/AutoChangeLog-pr-11444.yml
deleted file mode 100644
index 08ad07a902d..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11444.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Kyep"
-delete-after: True
-changes:
- - bugfix: "unanchored vending machines will no longer generate a runtime error when throwing products at people."
diff --git a/html/changelogs/AutoChangeLog-pr-11460.yml b/html/changelogs/AutoChangeLog-pr-11460.yml
deleted file mode 100644
index b4fd18328dd..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11460.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Arkatos"
-delete-after: True
-changes:
- - imageadd: "Added movement animation for mice, chickens and killer tomatoes"
diff --git a/html/changelogs/AutoChangeLog-pr-11465.yml b/html/changelogs/AutoChangeLog-pr-11465.yml
deleted file mode 100644
index a38d2a20e15..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11465.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "farie82"
-delete-after: True
-changes:
- - bugfix: "Can't use cuffs now while you have antidrop"
diff --git a/html/changelogs/AutoChangeLog-pr-11466.yml b/html/changelogs/AutoChangeLog-pr-11466.yml
deleted file mode 100644
index 0cf1c132b42..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11466.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Markolie"
-delete-after: True
-changes:
- - bugfix: "Chameleon items now use the appropriate species icon."
diff --git a/html/changelogs/AutoChangeLog-pr-11472.yml b/html/changelogs/AutoChangeLog-pr-11472.yml
deleted file mode 100644
index acfaebf6e7f..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11472.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Couls"
-delete-after: True
-changes:
- - rscadd: "Only names from the manifest will be used for syndicate code phrases"
- - rscdel: "randomly generated people names from syndicate code phrases"
diff --git a/html/changelogs/AutoChangeLog-pr-11476.yml b/html/changelogs/AutoChangeLog-pr-11476.yml
deleted file mode 100644
index 540d77e7bf3..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11476.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-author: "Arkatos"
-delete-after: True
-changes:
- - imageadd: "Added inhand sprite for eggbox"
- - imageadd: "Added inhand sprites for all types of soaps"
- - imageadd: "Added inhand sprite for small parcel"
- - imageadd: "Added inhand sprite for sechailer"
- - imageadd: "Added inhand sprite for bag of holding"
diff --git a/html/changelogs/AutoChangeLog-pr-11477.yml b/html/changelogs/AutoChangeLog-pr-11477.yml
deleted file mode 100644
index 756b6c1e4e4..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11477.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Arkatos"
-delete-after: True
-changes:
- - tweak: "Added new system for outputting contents of smartfridges"
diff --git a/html/changelogs/AutoChangeLog-pr-11479.yml b/html/changelogs/AutoChangeLog-pr-11479.yml
deleted file mode 100644
index efa34ac077d..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11479.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "TDSSS"
-delete-after: True
-changes:
- - tweak: "Vampire rejuv wakes you up if you're asleep now"
- - tweak: "Cling epinephrine wakes you up if you're asleep now"
diff --git a/html/changelogs/AutoChangeLog-pr-11480.yml b/html/changelogs/AutoChangeLog-pr-11480.yml
deleted file mode 100644
index a4fcc50ceaa..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11480.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Tayyyyyyy"
-delete-after: True
-changes:
- - rscadd: "Messages window (My PMs in OOC tab)"
diff --git a/html/changelogs/AutoChangeLog-pr-11482.yml b/html/changelogs/AutoChangeLog-pr-11482.yml
deleted file mode 100644
index 65cc53a7f97..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11482.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "TDSSS"
-delete-after: True
-changes:
- - tweak: "Sling glare popup no longer lists invalid targets for glaring"
diff --git a/html/changelogs/AutoChangeLog-pr-11483.yml b/html/changelogs/AutoChangeLog-pr-11483.yml
deleted file mode 100644
index 635f5efede9..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11483.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "datlo"
-delete-after: True
-changes:
- - bugfix: "The Syndicate will no longer hire golems as agents."
- - tweak: "Banana juice and Banana honk will now heal everyone with the Comic Sans mutation instead of checking for the clown job"
- - tweak: "Nothing will now check if the player has an active vow of silence instead of checking for the mime job"
diff --git a/html/changelogs/AutoChangeLog-pr-11486.yml b/html/changelogs/AutoChangeLog-pr-11486.yml
deleted file mode 100644
index c854e1f9c4c..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11486.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Tayyyyyyy"
-delete-after: True
-changes:
- - tweak: "You no longer have to wait on others for ERT spawning"
diff --git a/html/changelogs/AutoChangeLog-pr-11508.yml b/html/changelogs/AutoChangeLog-pr-11508.yml
deleted file mode 100644
index ebe3ed56455..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11508.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "datlo"
-delete-after: True
-changes:
- - bugfix: "Ghosts will no longer get the wrong role offered when a nukie
-spawns a borg and will properly be informed whether they will spawn as a
-nuke ops or a syndi cyborg."
diff --git a/html/changelogs/AutoChangeLog-pr-11511.yml b/html/changelogs/AutoChangeLog-pr-11511.yml
deleted file mode 100644
index c32d89bc2fc..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11511.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Markolie"
-delete-after: True
-changes:
- - bugfix: "Lighting now respects color blindness again."
- - bugfix: "pAI flashlights now work properly."
diff --git a/html/changelogs/AutoChangeLog-pr-11518.yml b/html/changelogs/AutoChangeLog-pr-11518.yml
deleted file mode 100644
index 0ad85e1e84a..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11518.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "farie82"
-delete-after: True
-changes:
- - bugfix: "can_equip now checks if you have the limbs required to equip something"
diff --git a/html/changelogs/AutoChangeLog-pr-11520.yml b/html/changelogs/AutoChangeLog-pr-11520.yml
deleted file mode 100644
index ffc477deba7..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11520.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Citinited"
-delete-after: True
-changes:
- - bugfix: "Boo affects APCs again"
- - bugfix: "Boo no longer fully charges when you enter your corpse"
diff --git a/html/changelogs/AutoChangeLog-pr-11521.yml b/html/changelogs/AutoChangeLog-pr-11521.yml
deleted file mode 100644
index 48a73a71cac..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11521.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Arkatos"
-delete-after: True
-changes:
- - tweak: "Blob split consciousness ability now requires you to directly target a node you want to turn into another sentient overmind instead of selecting a nearest one"
- - spellcheck: "Fixed and improved some descriptions regarding Blob offspring"
diff --git a/html/changelogs/AutoChangeLog-pr-11523.yml b/html/changelogs/AutoChangeLog-pr-11523.yml
deleted file mode 100644
index 654203e359b..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11523.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Fox McCloud"
-delete-after: True
-changes:
- - bugfix: "Future proofs the coming Ticker subsystem"
diff --git a/html/changelogs/AutoChangeLog-pr-11524.yml b/html/changelogs/AutoChangeLog-pr-11524.yml
deleted file mode 100644
index e1036ef70a7..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11524.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Fox McCloud"
-delete-after: True
-changes:
- - rscdel: "Removes the Process Scheduler"
diff --git a/html/changelogs/AutoChangeLog-pr-11529.yml b/html/changelogs/AutoChangeLog-pr-11529.yml
deleted file mode 100644
index 6de125cb71f..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11529.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Citinited"
-delete-after: True
-changes:
- - tweak: "The button to close radial menus is much more obvious and easily-clickable now"
diff --git a/html/changelogs/AutoChangeLog-pr-11533.yml b/html/changelogs/AutoChangeLog-pr-11533.yml
deleted file mode 100644
index e1708e5901c..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11533.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Markolie"
-delete-after: True
-changes:
- - bugfix: "Rotatium can now be created properly."
diff --git a/html/changelogs/AutoChangeLog-pr-11536.yml b/html/changelogs/AutoChangeLog-pr-11536.yml
deleted file mode 100644
index 0fba2aa34e5..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11536.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "dovydas12345"
-delete-after: True
-changes:
- - bugfix: "Fixes cryopod removing ambulance, secway keys"
- - bugfix: "Fixes cryopod recovering the invisible headpocket item"
diff --git a/html/changelogs/AutoChangeLog-pr-11537.yml b/html/changelogs/AutoChangeLog-pr-11537.yml
deleted file mode 100644
index 304766c2b8d..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11537.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Akatos"
-delete-after: True
-changes:
- - tweak: "Smartfridges now visually show approximate number of items inside"
diff --git a/html/changelogs/AutoChangeLog-pr-11541.yml b/html/changelogs/AutoChangeLog-pr-11541.yml
deleted file mode 100644
index a317a29455f..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11541.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Tayyyyyyy"
-delete-after: True
-changes:
- - bugfix: "Admin jobs no longer announced"
diff --git a/html/changelogs/AutoChangeLog-pr-11546.yml b/html/changelogs/AutoChangeLog-pr-11546.yml
deleted file mode 100644
index 33a522e1d19..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11546.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Shadeykins"
-delete-after: True
-changes:
- - bugfix: "Fixes a paper exploit."
diff --git a/html/changelogs/AutoChangeLog-pr-11547.yml b/html/changelogs/AutoChangeLog-pr-11547.yml
deleted file mode 100644
index d3cd23d8632..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11547.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "AffectedArc07"
-delete-after: True
-changes:
- - tweak: "Tweaks some preference orders"
diff --git a/html/changelogs/AutoChangeLog-pr-11551.yml b/html/changelogs/AutoChangeLog-pr-11551.yml
deleted file mode 100644
index 5770e7a1488..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11551.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Arkatos"
-delete-after: True
-changes:
- - bugfix: "Fixed a case where ghosts had an extra ghost icon visible on them"
- - bugfix: "Fixed a case where some ghosts were too bright"
diff --git a/html/changelogs/AutoChangeLog-pr-11553.yml b/html/changelogs/AutoChangeLog-pr-11553.yml
deleted file mode 100644
index 9954dccfd28..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11553.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ty-Omaha"
-delete-after: True
-changes:
- - tweak: "Changed admin take ticket color from neon green to Asay pink"
diff --git a/html/changelogs/AutoChangeLog-pr-11554.yml b/html/changelogs/AutoChangeLog-pr-11554.yml
deleted file mode 100644
index 4923c690400..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11554.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Arkatos"
-delete-after: True
-changes:
- - bugfix: "You are now unable to swap forms with another changeling"
diff --git a/html/changelogs/AutoChangeLog-pr-11555.yml b/html/changelogs/AutoChangeLog-pr-11555.yml
deleted file mode 100644
index 63ff2434d6e..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11555.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Arkatos"
-delete-after: True
-changes:
- - bugfix: "You can no longer hiss while muzzled"
diff --git a/html/changelogs/AutoChangeLog-pr-11556.yml b/html/changelogs/AutoChangeLog-pr-11556.yml
deleted file mode 100644
index 246cc070f24..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11556.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "AffectedArc07"
-delete-after: True
-changes:
- - tweak: "Moved a global define"
diff --git a/html/changelogs/AutoChangeLog-pr-11559.yml b/html/changelogs/AutoChangeLog-pr-11559.yml
deleted file mode 100644
index 5bb8465ec94..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11559.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-author: "Arkatos"
-delete-after: True
-changes:
- - tweak: "Upon purchasing Augmented Eyesight changeling ability, changeling immediately receives passive version of the ability"
- - tweak: "Changelings in the lesser form can now toggle Augmented Eyesight ability"
- - bugfix: "Changelings are now removed properly via Traitor Panel"
- - bugfix: "Changelings do not get their action buttons bugged when using Swap Forms ability now"
- - bugfix: "Action buttons should update their cooldown statuses more reliably"
diff --git a/html/changelogs/AutoChangeLog-pr-11566.yml b/html/changelogs/AutoChangeLog-pr-11566.yml
new file mode 100644
index 00000000000..09138dc9324
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11566.yml
@@ -0,0 +1,5 @@
+author: "Arkatos"
+delete-after: True
+changes:
+ - rscadd: "You can ctrl-click any action button to lock/unlock its position"
+ - tweak: "All actions buttons now start with their position locked"
diff --git a/html/changelogs/AutoChangeLog-pr-11567.yml b/html/changelogs/AutoChangeLog-pr-11567.yml
deleted file mode 100644
index 8e0769768f9..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11567.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Couls"
-delete-after: True
-changes:
- - bugfix: "t-t-t-typo!"
diff --git a/html/changelogs/AutoChangeLog-pr-11573.yml b/html/changelogs/AutoChangeLog-pr-11573.yml
deleted file mode 100644
index bb4c67a6cc3..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11573.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Shadeykins"
-delete-after: True
-changes:
- - bugfix: "Fixes rogue pixels on breath masks/gas masks for Plasmamen."
diff --git a/html/changelogs/AutoChangeLog-pr-11574.yml b/html/changelogs/AutoChangeLog-pr-11574.yml
deleted file mode 100644
index 0acc59e9621..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11574.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Christasmurf"
-delete-after: True
-changes:
- - bugfix: "Fixes a random pixel on the leather shoes"
diff --git a/html/changelogs/AutoChangeLog-pr-11582.yml b/html/changelogs/AutoChangeLog-pr-11582.yml
deleted file mode 100644
index 455dfcea14e..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11582.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "uc_guy"
-delete-after: True
-changes:
- - bugfix: "Fixed \"Venus Human Traps\" being invisible."
diff --git a/html/changelogs/AutoChangeLog-pr-11584.yml b/html/changelogs/AutoChangeLog-pr-11584.yml
deleted file mode 100644
index 83db80c473f..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11584.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Markolie"
-delete-after: True
-changes:
- - bugfix: "Ghosts can now transition through space again. This is now done by clicking on the edge of space."
diff --git a/html/changelogs/AutoChangeLog-pr-11585.yml b/html/changelogs/AutoChangeLog-pr-11585.yml
deleted file mode 100644
index 053b6deb819..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11585.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Arkatos"
-delete-after: True
-changes:
- - bugfix: "Changelings should now correctly receive their action buttons"
- - bugfix: "Changelings now do not steal action buttons from other changelings"
diff --git a/html/changelogs/AutoChangeLog-pr-11605.yml b/html/changelogs/AutoChangeLog-pr-11605.yml
new file mode 100644
index 00000000000..46c791aaa32
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11605.yml
@@ -0,0 +1,4 @@
+author: "Couls"
+delete-after: True
+changes:
+ - tweak: "Reworks the biohazard event to have a chance of giving a randomized advanced disease with 6 varying symptoms instead of a preset disease."
diff --git a/html/changelogs/AutoChangeLog-pr-11620.yml b/html/changelogs/AutoChangeLog-pr-11620.yml
deleted file mode 100644
index 6511722a427..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11620.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Citinited"
-delete-after: True
-changes:
- - bugfix: "Fixes conveyor belts not moving items spawned via an autolathe. (And other possible behaviours when machines switch between speed and normal processes)"
diff --git a/html/changelogs/AutoChangeLog-pr-11628.yml b/html/changelogs/AutoChangeLog-pr-11628.yml
deleted file mode 100644
index 165e24173b7..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11628.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-author: "Markolie"
-delete-after: True
-changes:
- - rscadd: "Added custom explorer gas mask sprites for Grey/Drask."
- - rscadd: "Added a lantern to the Hermit cave."
- - rscadd: "Added a bone setter, bone gel, FixOVein, sterile masks and sterile gloves to the Lavaland Syndicate base."
- - rscadd: "The pickaxes on the Lavaland labor camp have been replaced with safety variants. The flashlights have been replaced with lanterns."
- - bugfix: "Fixed many species missing sprites for explorer gas masks and jumpsuits. They now use the humans icons until we have custom sprites."
- - bugfix: "Resolved an issue with piping not working on the Lavaland mining bases."
- - bugfix: "Fixed all items being free in the mining vendor."
- - bugfix: "Fixed improper wiring to the turbine in the Lavaland Syndicate base."
- - bugfix: "Fixed the Lavaland Syndicate base oxygen sensor not working."
- - bugfix: "Moved the pipe dispenser in the Lavaland Syndicate base so it doesn't clip with tables."
- - bugfix: "Fixed the Lavaland Syndicate base incinerator doors not working."
diff --git a/html/changelogs/AutoChangeLog-pr-11630.yml b/html/changelogs/AutoChangeLog-pr-11630.yml
deleted file mode 100644
index 043b23d37ac..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11630.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-author: "Markolie and Ionward"
-delete-after: True
-changes:
- - rscadd: "Added Tajaran, Vulpkanin, Unathi and Vox sprites for the explorer gas mask (thanks to Ionward!)"
- - rscadd: "Added custom species sprites for the explorer suits and hoods (thanks to Ionward!)"
- - rscadd: "Added missing surgical tools and a pet vendor to the animal hospital."
- - rscadd: "Added a custom cigarette vendor to the beach biodome ruin."
- - rscadd: "Added an autolathe and RPD to the Lavaland Syndicate base. Also added a custom cigarette vendor and made the vendors not charge money."
- - rscadd: "Added tiny fans to the mining base and labor camp exist."
- - rscadd: "A separate jobban for ghost roles has been added."
- - bugfix: "The alternative sink now has directional sprites. This resolves an issue with shelters having sinks facing the wrong way."
- - bugfix: "Fixed the Syndicate sleepers on the Lavaland Syndicate base pointing the wrong way when a ghost role spawns in."
- - bugfix: "Fixed Lava being removed by the staff of lava not working. Also added a missing warning effect when the staff is turning regular turf into lava."
- - bugfix: "Fixed random bookcases not spawning books (hopefully)."
- - bugfix: "Fixed surgical drapes not having a sprite."
- - bugfix: "Fixed being unable to modify the GPS tag of shelters."
- - bugfix: "Fixed the Lavaland swarmers not eating anything."
- - bugfix: "The ash drake swoop attack is no longer incredibly loud."
- - tweak: "The Syndicate base self-destruct is now much more powerful and capable of destroying the entire base."
- - tweak: "The flavor text of Ash Walkers and Syndicate operatives now clarifies what they can('t) do."
- - tweak: "Ash walkers can no longer use machinery."
diff --git a/html/changelogs/AutoChangeLog-pr-11634.yml b/html/changelogs/AutoChangeLog-pr-11634.yml
new file mode 100644
index 00000000000..c51b73a64ae
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11634.yml
@@ -0,0 +1,4 @@
+author: "Markolie"
+delete-after: True
+changes:
+ - rscadd: "The prison labor point system has been refactored so it works properly."
diff --git a/html/changelogs/AutoChangeLog-pr-11641.yml b/html/changelogs/AutoChangeLog-pr-11641.yml
deleted file mode 100644
index 8a74e6e0461..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11641.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-author: "Markolie"
-delete-after: True
-changes:
- - tweak: "Ash Walkers now once more have fine manipulation. Their lack of fine manipulation caused unintended side effects (such as them being unable to mine)."
- - bugfix: "Ash Walkers (and other ghost spawner roles) can no longer be antagonist targets or become antagonists through the antagonist creation."
- - bugfix: "Fixed the Lavaland Syndicate base incinerator buttons not working."
- - bugfix: "Fixed the Syndicate communication agent spawning with a broken voice changer mask."
- - bugfix: "Fixed the Disk Compartmentalizer not having a sprite."
diff --git a/html/changelogs/AutoChangeLog-pr-11643.yml b/html/changelogs/AutoChangeLog-pr-11643.yml
deleted file mode 100644
index 74fa2f18b4e..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11643.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-author: "Markolie"
-delete-after: True
-changes:
- - rscadd: "The Ancient Goliath now has a small chance of spawning instead of regular goliaths."
- - rscadd: "Survival capsules now have a NanoMed."
- - tweak: "Water bottles now behave as glass containers."
- - tweak: "The behaviour of glass reagent containers has changed. When used on non-mobs, contents will now only be spilled on harm intent. When used on mobs, on any intent aside from harm the contents will be fed to the mob like regular drinks. On harm intent it will still be spilled."
- - tweak: "Hairless hide can now be made wet using most sources of water (minimum volume of 10), instead of just washing machines."
- - bugfix: "Added some additional offstation role checks to ensure ghost spawner roles don't become antagonists, are kidnap targets or are counted towards station goals."
- - bugfix: "Fixed some piping in the Lavaland Syndicate base incinerator and made sure the vault door starts locked."
- - bugfix: "Fixed the Lavaland swarmers getting stuck on propulsion."
- - bugfix: "Fix goliath tentacles sometimes being left behind."
- - bugfix: "The walls around the Lavaland Syndicate base turbine have been coated, to prevent them from starting a plasma fire in the base."
- - bugfix: "Syndicate agents can now access the air alarms on the Lavaland Syndicate base."
- - bugfix: "Air alarm control computers can no longer access the air alarms on the Lavaland Syndicate base."
- - bugfix: "Fixed the disk compartmentalizer/drying rack missing a sprite under certain circumstances."
- - bugfix: "Fixed the Lavaland Syndicate base triggering atmospherics alerts."
- - bugfix: "You can now properly place tiles on basalt."
diff --git a/html/changelogs/AutoChangeLog-pr-11653.yml b/html/changelogs/AutoChangeLog-pr-11653.yml
new file mode 100644
index 00000000000..141c0adf1be
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11653.yml
@@ -0,0 +1,4 @@
+author: "Couls"
+delete-after: True
+changes:
+ - tweak: "change how bone breakage is calculated"
diff --git a/html/changelogs/AutoChangeLog-pr-11656.yml b/html/changelogs/AutoChangeLog-pr-11656.yml
deleted file mode 100644
index 5b0a8408162..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11656.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Markolie"
-delete-after: True
-changes:
- - bugfix: "An exploit with the sheet multiplier has been fixed."
diff --git a/html/changelogs/AutoChangeLog-pr-11658.yml b/html/changelogs/AutoChangeLog-pr-11658.yml
new file mode 100644
index 00000000000..a7deadb4af8
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11658.yml
@@ -0,0 +1,4 @@
+author: "Markolie"
+delete-after: True
+changes:
+ - rscadd: "Plating can now be removed (exposing the baseturf) using a welder."
diff --git a/html/changelogs/AutoChangeLog-pr-11664.yml b/html/changelogs/AutoChangeLog-pr-11664.yml
deleted file mode 100644
index 8acfb84a4f9..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11664.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-author: "Markolie"
-delete-after: True
-changes:
- - rscadd: "Portals can now be activated by clicking on them with or without an object. Ghosts can now also click on them to be taken to their destination."
- - rscadd: "Portals now warn admins when they are used to teleport megafauna."
- - tweak: "The singularity can now eat basalt and chasms on Lavaland. They get turned into lava."
- - bugfix: "AI swarmers will no longer get stuck on effects (such as blood)."
- - bugfix: "Fixed the spectral blade turning all ghosts visible."
- - bugfix: "Fixed a runtime with assigning outfits to mindless mobs."
- - bugfix: "Fixed certain alarms triggering despite being outside of station contact and the Syndicate base still triggering fire alarms."
- - bugfix: "Fixed being unable to put the wormhole jaunter in the belt slot."
- - bugfix: "Fixed the disk compartmentalizer not accepting disks."
- - bugfix: "Gutlunches and Gubbucks will now reproduce properly."
- - bugfix: "The necropolis chest cult clothing drop no longer spawns with a cult hood as well, as that's part of the suit itself."
- - bugfix: "Goliath steaks can now be eaten properly."
- - bugfix: "Fixed a stray light on the beach ruin."
- - bugfix: "Lavaland ruins should no longer spawn on the Labor Camp."
- - bugfix: "Ancient goliaths will now properly randomly spawn tentacles."
- - bugfix: "The labor camp will now spawn properly with a processing console."
- - bugfix: "Water turfs in the beach ruin (and other water turfs that previously didn't do so) will now properly apply water to you."
- - bugfix: "Ash flora is now anchored."
diff --git a/html/changelogs/AutoChangeLog-pr-11674.yml b/html/changelogs/AutoChangeLog-pr-11674.yml
new file mode 100644
index 00000000000..5c9edc40e27
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11674.yml
@@ -0,0 +1,4 @@
+author: "DoctorDrugs"
+delete-after: True
+changes:
+ - rscadd: "Adds additional roundstart miner slots and the additional gear required for them to do their jobs"
diff --git a/html/changelogs/AutoChangeLog-pr-11676.yml b/html/changelogs/AutoChangeLog-pr-11676.yml
deleted file mode 100644
index cf6f4267e66..00000000000
--- a/html/changelogs/AutoChangeLog-pr-11676.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Terilia"
-delete-after: True
-changes:
- - rscadd: "Added the Donksoft sniper into the Trader spawnpool."
diff --git a/html/changelogs/AutoChangeLog-pr-11684.yml b/html/changelogs/AutoChangeLog-pr-11684.yml
new file mode 100644
index 00000000000..0f1250497f2
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11684.yml
@@ -0,0 +1,4 @@
+author: "IAmBigCoat"
+delete-after: True
+changes:
+ - tweak: "Added explosion warnings to medbeams, because medbeams can cause explosions. DON'T CROSS THE BEAMS!"
diff --git a/html/changelogs/AutoChangeLog-pr-11687.yml b/html/changelogs/AutoChangeLog-pr-11687.yml
new file mode 100644
index 00000000000..b6ceea4d139
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11687.yml
@@ -0,0 +1,5 @@
+author: "Kyep"
+delete-after: True
+changes:
+ - rscadd: "Round time (h:mm) and station security level (green/red/blue/etc) are now visible on our server hub entry."
+ - tweak: "Round time is now visible to all player-controlled mobs in their status panel (including simple animals)."
diff --git a/html/changelogs/AutoChangeLog-pr-11804.yml b/html/changelogs/AutoChangeLog-pr-11804.yml
new file mode 100644
index 00000000000..355e6f0a32e
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11804.yml
@@ -0,0 +1,4 @@
+author: "Markolie"
+delete-after: True
+changes:
+ - bugfix: "Fixed an issue where slimes wouldn't take damage from water in space."
diff --git a/html/changelogs/AutoChangeLog-pr-11805.yml b/html/changelogs/AutoChangeLog-pr-11805.yml
new file mode 100644
index 00000000000..32aeba3f9eb
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11805.yml
@@ -0,0 +1,4 @@
+author: "Markolie"
+delete-after: True
+changes:
+ - bugfix: "It is no longer possible to unanchor the surivval pod storage units."
diff --git a/html/changelogs/AutoChangeLog-pr-11806.yml b/html/changelogs/AutoChangeLog-pr-11806.yml
new file mode 100644
index 00000000000..f70b8e32b82
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11806.yml
@@ -0,0 +1,4 @@
+author: "Tayyyyyyy"
+delete-after: True
+changes:
+ - bugfix: "autocomplete input mishandling single quotes (you can teleport to Wizard's den now)"
diff --git a/html/changelogs/AutoChangeLog-pr-11812.yml b/html/changelogs/AutoChangeLog-pr-11812.yml
new file mode 100644
index 00000000000..e5bad933f7e
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11812.yml
@@ -0,0 +1,5 @@
+author: "Couls"
+delete-after: True
+changes:
+ - rscadd: "adds a line to alert people as to why they're not getting blood from the monkeys"
+ - bugfix: "The vampires are finally off their monkey diet, theycan now suck blood from players and humanized monkeys"
diff --git a/html/changelogs/AutoChangeLog-pr-11821.yml b/html/changelogs/AutoChangeLog-pr-11821.yml
new file mode 100644
index 00000000000..2a98f4dbae6
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11821.yml
@@ -0,0 +1,4 @@
+author: "Couls"
+delete-after: True
+changes:
+ - bugfix: "Symptoms are now correctly generated for level 7 biohazards"
diff --git a/html/changelogs/AutoChangeLog-pr-11829.yml b/html/changelogs/AutoChangeLog-pr-11829.yml
new file mode 100644
index 00000000000..7af1b527603
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11829.yml
@@ -0,0 +1,9 @@
+author: "Couls"
+delete-after: True
+changes:
+ - tweak: "Borgs can now cycle modules with X again"
+ - tweak: "Ahelp message is less confusing"
+ - tweak: "F2 (say) F3(ooc) F4(me) buttons have been restored
+tweak:when numpad targetting is off you can use numpad 1-4 to change intents
+tweak:pressing shift before any of the intent buttons doesn't change intents(for people with shift+1-4 macros)
+tweak:backspace now sets the focus to the chat bar"
diff --git a/icons/mob/actions/actions.dmi b/icons/mob/actions/actions.dmi
index ea66e024a19..d3976bfff61 100644
Binary files a/icons/mob/actions/actions.dmi and b/icons/mob/actions/actions.dmi differ
diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi
index ae285a5453a..47cb86a2c89 100644
Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ
diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi
index 8b949a8e732..e4630c2764e 100644
Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ
diff --git a/icons/mob/mask.dmi b/icons/mob/mask.dmi
index 08aca040280..8027568e31b 100644
Binary files a/icons/mob/mask.dmi and b/icons/mob/mask.dmi differ
diff --git a/icons/mob/screen_alert.dmi b/icons/mob/screen_alert.dmi
index 60488151158..b18cb799817 100644
Binary files a/icons/mob/screen_alert.dmi and b/icons/mob/screen_alert.dmi differ
diff --git a/icons/mob/screen_gen.dmi b/icons/mob/screen_gen.dmi
index 62f732a224f..6209ce84949 100644
Binary files a/icons/mob/screen_gen.dmi and b/icons/mob/screen_gen.dmi differ
diff --git a/icons/mob/species/drask/mask.dmi b/icons/mob/species/drask/mask.dmi
index dffedfb1c78..9b9c341feb3 100644
Binary files a/icons/mob/species/drask/mask.dmi and b/icons/mob/species/drask/mask.dmi differ
diff --git a/icons/mob/species/drask/uniform.dmi b/icons/mob/species/drask/uniform.dmi
index d29b598dec3..ab315263ed9 100644
Binary files a/icons/mob/species/drask/uniform.dmi and b/icons/mob/species/drask/uniform.dmi differ
diff --git a/icons/mob/species/grey/mask.dmi b/icons/mob/species/grey/mask.dmi
index 112895a6009..6d13b33c4bf 100644
Binary files a/icons/mob/species/grey/mask.dmi and b/icons/mob/species/grey/mask.dmi differ
diff --git a/icons/mob/species/grey/uniform.dmi b/icons/mob/species/grey/uniform.dmi
index e71e020ff4a..ddf0250fdc5 100644
Binary files a/icons/mob/species/grey/uniform.dmi and b/icons/mob/species/grey/uniform.dmi differ
diff --git a/icons/mob/species/tajaran/mask.dmi b/icons/mob/species/tajaran/mask.dmi
index 3b2c1891c07..f73989fe9b0 100644
Binary files a/icons/mob/species/tajaran/mask.dmi and b/icons/mob/species/tajaran/mask.dmi differ
diff --git a/icons/mob/species/unathi/mask.dmi b/icons/mob/species/unathi/mask.dmi
index 5274697cdc1..ba9be383855 100644
Binary files a/icons/mob/species/unathi/mask.dmi and b/icons/mob/species/unathi/mask.dmi differ
diff --git a/icons/mob/species/vox/mask.dmi b/icons/mob/species/vox/mask.dmi
index b836b78538f..7023b2c3247 100644
Binary files a/icons/mob/species/vox/mask.dmi and b/icons/mob/species/vox/mask.dmi differ
diff --git a/icons/mob/species/vox/uniform.dmi b/icons/mob/species/vox/uniform.dmi
index b8169f9bd51..18a3e07ce76 100644
Binary files a/icons/mob/species/vox/uniform.dmi and b/icons/mob/species/vox/uniform.dmi differ
diff --git a/icons/mob/species/vulpkanin/mask.dmi b/icons/mob/species/vulpkanin/mask.dmi
index 43b527266b8..e50c3421fb0 100644
Binary files a/icons/mob/species/vulpkanin/mask.dmi and b/icons/mob/species/vulpkanin/mask.dmi differ
diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi
index e5102b7eee9..69f9e04895e 100644
Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ
diff --git a/icons/obj/clothing/masks.dmi b/icons/obj/clothing/masks.dmi
index f158b1df20d..b3a04ce73bf 100644
Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ
diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi
index c39331ce8d4..78586b72dfc 100644
Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ
diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi
index 469934ca932..f48f0e9f07a 100644
Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ
diff --git a/icons/obj/interface.dmi b/icons/obj/interface.dmi
index 3b64561d5e0..631bba214c8 100644
Binary files a/icons/obj/interface.dmi and b/icons/obj/interface.dmi differ
diff --git a/interface/interface.dm b/interface/interface.dm
index 0bec55ef51c..8edded38e93 100644
--- a/interface/interface.dm
+++ b/interface/interface.dm
@@ -96,27 +96,6 @@
src << link(config.donationsurl)
else
to_chat(src, "The rules URL is not set in the server configuration.")
-
-/client/verb/hotkey_mode()
- set name = "Set Hotkey Mode"
- set category = "Preferences"
-
- var/list/hotkey_modes = list()
- for(var/hotkey_mode in subtypesof(/datum/hotkey_mode))
- var/datum/hotkey_mode/H = hotkey_mode
- hotkey_modes[initial(H.name)] = H
-
- var/chosen_mode_name = input("Choose your preferred hotkey mode.", "Hotkey mode selection") as null|anything in hotkey_modes
- if(!chosen_mode_name)
- return
-
- var/datum/hotkey_mode/chosen_mode = hotkey_modes[chosen_mode_name]
- var/datum/hotkey_mode/hotkey_mode = new chosen_mode(src)
-
- hotkey_mode.set_winset_values()
- to_chat(usr, "Your hotkey mode has been changed to [hotkey_mode.name].")
-
- qdel(hotkey_mode)
/client/verb/hotkeys_help()
set name = "Hotkey Help"
@@ -144,56 +123,58 @@ Admin ghost:
/mob/proc/hotkey_help()
var/hotkey_mode = {"
Hotkey-Mode: (hotkey-mode must be on)
-\tTAB = Toggle Hotkey Mode
-\ta = Move Left
-\ts = Move Down
-\td = Move Right
-\tw = Move Up
-\tq = Drop Item
-\te = Equip Item
-\tr = Throw Item
-\tm = Me
-\tt = Say
-\to = OOC
-\tb = Resist
-\tx = Swap Hands
-\tz = Activate Held Object (or y)
-\tf = Cycle Intents Left
-\tg = Cycle Intents Right
-\t1 = Help Intent
-\t2 = Disarm Intent
-\t3 = Grab Intent
-\t4 = Harm Intent
+\tTAB = toggle hotkey-mode
+\tA = left
+\tS = down
+\tD = right
+\tW = up
+\tQ = drop
+\tE = equip
+\tR = throw
+\tM = me
+\tT = say
+\tO = OOC
+\tB = resist
+\tH = Holster/unholster gun if you have a holster
+\tX = swap-hand
+\tZ = activate held object (or y)
+\tF = cycle-intents-left
+\tG = cycle-intents-right
+\t1 = help-intent
+\t2 = disarm-intent
+\t3 = grab-intent
+\t4 = harm-intent
+\tNumpad = Body target selection (Press 8 repeatedly for Head->Eyes->Mouth)
+\tAlt(HOLD) = Alter movement intent
"}
var/other = {"
Any-Mode: (hotkey doesn't need to be on)
-\tCtrl+a = Move Left
-\tCtrl+s = Move Down
-\tCtrl+d = Move Right
-\tCtrl+w = Move Up
-\tCtrl+q = Drop Item
-\tCtrl+e = Equip Item
-\tCtrl+r = Throw Item
-\tCtrl+b = Resist
-\tCtrl+o = OOC
-\tCtrl+x = Swap Hands
-\tCtrl+z = Activate Held Object (or Ctrl+y)
-\tCtrl+f = Cycle Intents Left
-\tCtrl+g = Cycle Intents Right
-\tCtrl+1 = Help Intent
-\tCtrl+2 = Disarm Intent
-\tCtrl+3 = Grab Intent
-\tCtrl+4 = Harm Intent
-\tDEL = Pull
-\tINS = Cycle Intents Right
-\tHOME = Drop Item
-\tPGUP = Swap Hands
-\tPGDN = Activate Held Object
-\tEND = Throw Item
-\tF2 = OOC
-\tF3 = Say
-\tF4 = Me
+\tCtrl+A = left
+\tCtrl+S = down
+\tCtrl+D = right
+\tCtrl+W = up
+\tCtrl+Q = drop
+\tCtrl+E = equip
+\tCtrl+R = throw
+\tCtrl+B = resist
+\tCtrl+H = stop pulling
+\tCtrl+O = OOC
+\tCtrl+X = swap-hand
+\tCtrl+Z = activate held object (or Ctrl+y)
+\tCtrl+F = cycle-intents-left
+\tCtrl+G = cycle-intents-right
+\tCtrl+1 = help-intent
+\tCtrl+2 = disarm-intent
+\tCtrl+3 = grab-intent
+\tCtrl+4 = harm-intent
+\tDEL = stop pulling
+\tINS = cycle-intents-right
+\tHOME = drop
+\tPGUP = swap-hand
+\tPGDN = activate held object
+\tEND = throw
+\tCtrl+Numpad = Body target selection (Press 8 repeatedly for Head->Eyes->Mouth)
"}
to_chat(src, hotkey_mode)
@@ -203,19 +184,19 @@ Any-Mode: (hotkey doesn't need to be on)
var/hotkey_mode = {"
Hotkey-Mode: (hotkey-mode must be on)
\tTAB = Toggle Hotkey Mode
-\ta = Move Left
-\ts = Move Down
-\td = Move Right
-\tw = Move Up
-\tq = Unequip Active Module
-\tm = Me
-\tt = Say
-\to = OOC
-\tx = Cycle Active Modules
-\tb = Resist
-\tz = Activate Held Object (or y)
-\tf = Cycle Intents Left
-\tg = Cycle Intents Right
+\tA = Move Left
+\tS = Move Down
+\tD = Move Right
+\tW = Move Up
+\tQ = Unequip Active Module
+\tM = Me
+\tT = Say
+\tO = OOC
+\tX = Cycle Active Modules
+\tB = Resist
+\tZ or Y = Activate Held Object
+\tF = Cycle Intents Left
+\tG = Cycle Intents Right
\t1 = Activate Module 1
\t2 = Activate Module 2
\t3 = Activate Module 3
@@ -224,17 +205,17 @@ Hotkey-Mode: (hotkey-mode must be on)
var/other = {"
Any-Mode: (hotkey doesn't need to be on)
-\tCtrl+a = Move Left
-\tCtrl+s = Move Down
-\tCtrl+d = Move Right
-\tCtrl+w = Move Up
-\tCtrl+q = Unequip Active Module
-\tCtrl+x = Cycle Active Modules
-\tCtrl+b = Resist
-\tCtrl+o = OOC
-\tCtrl+z = Activate Held Object (or Ctrl+y)
-\tCtrl+f = Cycle Intents Left
-\tCtrl+g = Cycle Intents Right
+\tCtrl+A = Move Left
+\tCtrl+S = Move Down
+\tCtrl+D = Move Right
+\tCtrl+W = Move Up
+\tCtrl+Q = Unequip Active Module
+\tCtrl+X = Cycle Active Modules
+\tCtrl+B = Resist
+\tCtrl+O = OOC
+\tCtrl+Z or Ctrl+Y = Activate Held Object
+\tCtrl+F = Cycle Intents Left
+\tCtrl+G = Cycle Intents Right
\tCtrl+1 = Activate Module 1
\tCtrl+2 = Activate Module 2
\tCtrl+3 = Activate Module 3
diff --git a/interface/skin.dmf b/interface/skin.dmf
index e77ab2f9e33..a9af84c81ed 100644
--- a/interface/skin.dmf
+++ b/interface/skin.dmf
@@ -1,1411 +1,40 @@
-macro "macro"
- elem "MACRO-TAB"
- name = "TAB"
- command = ".winset \"mainwindow.macro=hotkeymode hotkey_toggle.is-checked=true mapwindow.map.focus=true input.background-color=#f0f0f0\""
- is-disabled = false
- elem "MACRO-CENTER+REP"
- name = "CENTER+REP"
- command = ".center"
- is-disabled = false
- elem "MACRO-NORTHEAST"
- name = "NORTHEAST"
- command = ".northeast"
- is-disabled = false
- elem "MACRO-SOUTHEAST"
- name = "SOUTHEAST"
- command = ".southeast"
- is-disabled = false
- elem "MACRO-SOUTHWEST"
- name = "SOUTHWEST"
- command = ".southwest"
- is-disabled = false
- elem "MACRO-NORTHWEST"
- name = "NORTHWEST"
- command = ".northwest"
- is-disabled = false
- elem "MACRO-CTRL+WEST"
- name = "CTRL+WEST"
- command = "westface"
- is-disabled = false
- elem "MACRO-WEST+REP"
- name = "WEST+REP"
- command = ".moveleft"
- is-disabled = false
- elem "MACRO-CTRL+NORTH"
- name = "CTRL+NORTH"
- command = "northface"
- is-disabled = false
- elem "MACRO-NORTH+REP"
- name = "NORTH+REP"
- command = ".moveup"
- is-disabled = false
- elem "MACRO-CTRL+EAST"
- name = "CTRL+EAST"
- command = "eastface"
- is-disabled = false
- elem "MACRO-EAST+REP"
- name = "EAST+REP"
- command = ".moveright"
- is-disabled = false
- elem "MACRO-CTRL+SOUTH"
- name = "CTRL+SOUTH"
- command = "southface"
- is-disabled = false
- elem "MACRO-SOUTH+REP"
- name = "SOUTH+REP"
- command = ".movedown"
- is-disabled = false
- elem "MACRO-INSERT"
- name = "INSERT"
- command = "a-intent right"
- is-disabled = false
- elem "MACRO-DELETE"
- name = "DELETE"
- command = "delete-key-pressed"
- is-disabled = false
- elem "MACRO-CTRL+1"
- name = "CTRL+1"
- command = "a-intent help"
- is-disabled = false
- elem "MACRO-CTRL+2"
- name = "CTRL+2"
- command = "a-intent disarm"
- is-disabled = false
- elem "MACRO-CTRL+3"
- name = "CTRL+3"
- command = "a-intent grab"
- is-disabled = false
- elem "MACRO-CTRL+4"
- name = "CTRL+4"
- command = "a-intent harm"
- is-disabled = false
- elem "MACRO-CTRL+A+REP"
- name = "CTRL+A+REP"
- command = ".moveleft"
- is-disabled = false
- elem "MACRO-CTRL+D+REP"
- name = "CTRL+D+REP"
- command = ".moveright"
- is-disabled = false
- elem "MACRO-CTRL+B"
- name = "CTRL+B"
- command = "resist"
- is-disabled = false
- elem "MACRO-CTRL+E"
- name = "CTRL+E"
- command = "quick-equip"
- is-disabled = false
- elem "MACRO-CTRL+F"
- name = "CTRL+F"
- command = "a-intent left"
- is-disabled = false
- elem "MACRO-CTRL+G"
- name = "CTRL+G"
- command = "a-intent right"
- is-disabled = false
- elem "MACRO-CTRL+Q"
- name = "CTRL+Q"
- command = ".northwest"
- is-disabled = false
- elem "MACRO-CTRL+R"
- name = "CTRL+R"
- command = ".southwest"
- is-disabled = false
- elem "MACRO-CTRL+S+REP"
- name = "CTRL+S+REP"
- command = ".movedown"
- is-disabled = false
- elem "MACRO-CTRL+W+REP"
- name = "CTRL+W+REP"
- command = ".moveup"
- is-disabled = false
- elem "MACRO-CTRL+X"
- name = "CTRL+X"
- command = ".northeast"
- is-disabled = false
- elem "MACRO-CTRL+Y"
- name = "CTRL+Y"
- command = "Activate-Held-Object"
- is-disabled = false
- elem "MACRO-CTRL+Z"
- name = "CTRL+Z"
- command = "Activate-Held-Object"
- is-disabled = false
- elem "MACRO-F1"
- name = "F1"
- command = "adminhelp"
- is-disabled = false
- elem "MACRO-CTRL+SHIFT+F1+REP"
- name = "CTRL+SHIFT+F1+REP"
- command = ".options"
- is-disabled = false
- elem "MACRO-F2"
- name = "F2"
- command = "ooc"
- is-disabled = false
- elem "MACRO-F2+REP"
- name = "F2+REP"
- command = ".screenshot auto"
- is-disabled = false
- elem "MACRO-SHIFT+F2+REP"
- name = "SHIFT+F2+REP"
- command = ".screenshot"
- is-disabled = false
- elem "MACRO-F3"
- name = "F3"
- command = ".say"
- is-disabled = false
- elem "MACRO-F4"
- name = "F4"
- command = ".me"
- is-disabled = false
- elem "MACRO-F5"
- name = "F5"
- command = "asay"
- is-disabled = false
- elem "MACRO-F6"
- name = "F6"
- command = "Aghost"
- is-disabled = false
- elem "MACRO-F7"
- name = "F7"
- command = "player-panel-new"
- is-disabled = false
- elem "MACRO-F8"
- name = "F8"
- command = "admin-pm-key"
- is-disabled = false
- elem "MACRO-F9"
- name = "F9"
- command = "Invisimin"
- is-disabled = false
- elem "MACRO-F12"
- name = "F12"
- command = "F12"
- is-disabled = false
-
-macro "hotkeymode"
- elem "HKMODE-TAB"
- name = "TAB"
- command = ".winset \"mainwindow.macro=macro hotkey_toggle.is-checked=false input.focus=true input.background-color=#d3b5b5\""
- is-disabled = false
- elem "HKMODE-CENTER+REP"
- name = "CENTER+REP"
- command = ".center"
- is-disabled = false
- elem "HKMODE-NORTHEAST"
- name = "NORTHEAST"
- command = ".northeast"
- is-disabled = false
- elem "HKMODE-SOUTHEAST"
- name = "SOUTHEAST"
- command = ".southeast"
- is-disabled = false
- elem "HKMODE-SOUTHWEST"
- name = "SOUTHWEST"
- command = ".southwest"
- is-disabled = false
- elem "HKMODE-NORTHWEST"
- name = "NORTHWEST"
- command = ".northwest"
- is-disabled = false
- elem "HKMODE-CTRL+WEST"
- name = "CTRL+WEST"
- command = "westface"
- is-disabled = false
- elem "HKMODE-WEST+REP"
- name = "WEST+REP"
- command = ".moveleft"
- is-disabled = false
- elem "HKMODE-CTRL+NORTH"
- name = "CTRL+NORTH"
- command = "northface"
- is-disabled = false
- elem "HKMODE-NORTH+REP"
- name = "NORTH+REP"
- command = ".moveup"
- is-disabled = false
- elem "HKMODE-CTRL+EAST"
- name = "CTRL+EAST"
- command = "eastface"
- is-disabled = false
- elem "HKMODE-EAST+REP"
- name = "EAST+REP"
- command = ".moveright"
- is-disabled = false
- elem "HKMODE-CTRL+SOUTH"
- name = "CTRL+SOUTH"
- command = "southface"
- is-disabled = false
- elem "HKMODE-SOUTH+REP"
- name = "SOUTH+REP"
- command = ".movedown"
- is-disabled = false
- elem "HKMODE-INSERT"
- name = "INSERT"
- command = "a-intent right"
- is-disabled = false
- elem "HKMODE-DELETE"
- name = "DELETE"
- command = "delete-key-pressed"
- is-disabled = false
- elem "HKMODE-1"
- name = "1"
- command = "a-intent help"
- is-disabled = false
- elem "HKMODE-CTRL+1"
- name = "CTRL+1"
- command = "a-intent help"
- is-disabled = false
- elem "HKMODE-2"
- name = "2"
- command = "a-intent disarm"
- is-disabled = false
- elem "HKMODE-CTRL+2"
- name = "CTRL+2"
- command = "a-intent disarm"
- is-disabled = false
- elem "HKMODE-3"
- name = "3"
- command = "a-intent grab"
- is-disabled = false
- elem "HKMODE-CTRL+3"
- name = "CTRL+3"
- command = "a-intent grab"
- is-disabled = false
- elem "HKMODE-4"
- name = "4"
- command = "a-intent harm"
- is-disabled = false
- elem "HKMODE-CTRL+4"
- name = "CTRL+4"
- command = "a-intent harm"
- is-disabled = false
- elem "HKMODE-T"
- name = "T"
- command = ".say"
- is-disabled = false
- elem "HKMODE-O"
- name = "O"
- command = "ooc"
- is-disabled = false
- elem "HKMODE-M"
- name = "M"
- command = ".me"
- is-disabled = false
- elem "HKMODE-A+REP"
- name = "A+REP"
- command = ".moveleft"
- is-disabled = false
- elem "HKMODE-CTRL+A+REP"
- name = "CTRL+A+REP"
- command = ".moveleft"
- is-disabled = false
- elem "HKMODE-D+REP"
- name = "D+REP"
- command = ".moveright"
- is-disabled = false
- elem "HKMODE-CTRL+D+REP"
- name = "CTRL+D+REP"
- command = ".moveright"
- is-disabled = false
- elem "HKMODE-B"
- name = "B"
- command = "resist"
- is-disabled = false
- elem "HKMODE-CTRL+B"
- name = "CTRL+B"
- command = "resist"
- is-disabled = false
- elem "HKMODE-E"
- name = "E"
- command = "quick-equip"
- is-disabled = false
- elem "HKMODE-CTRL+E"
- name = "CTRL+E"
- command = "quick-equip"
- is-disabled = false
- elem "HKMODE-F"
- name = "F"
- command = "a-intent left"
- is-disabled = false
- elem "HKMODE-CTRL+F"
- name = "CTRL+F"
- command = "a-intent left"
- is-disabled = false
- elem "HKMODE-G"
- name = "G"
- command = "a-intent right"
- is-disabled = false
- elem "HKMODE-CTRL+G"
- name = "CTRL+G"
- command = "a-intent right"
- is-disabled = false
- elem "HKMODE-H"
- name = "H"
- command = "holster"
- is-disabled = false
- elem "HKMODE-CTRL+H"
- name = "CTRL+H"
- command = "holster"
- is-disabled = false
- elem "HKMODE-Q"
- name = "Q"
- command = ".northwest"
- is-disabled = false
- elem "HKMODE-CTRL+Q"
- name = "CTRL+Q"
- command = ".northwest"
- is-disabled = false
- elem "HKMODE-R"
- name = "R"
- command = ".southwest"
- is-disabled = false
- elem "HKMODE-CTRL+R"
- name = "CTRL+R"
- command = ".southwest"
- is-disabled = false
- elem "s_key"
- name = "S+REP"
- command = ".movedown"
- is-disabled = false
- elem "HKMODE-CTRL+S+REP"
- name = "CTRL+S+REP"
- command = ".movedown"
- is-disabled = false
- elem "HKMODE-T"
- name = "T"
- command = ".say"
- is-disabled = false
- elem "w_key"
- name = "W+REP"
- command = ".moveup"
- is-disabled = false
- elem "HKMODE-CTRL+W+REP"
- name = "CTRL+W+REP"
- command = ".moveup"
- is-disabled = false
- elem "HKMODE-X"
- name = "X"
- command = ".northeast"
- is-disabled = false
- elem "HKMODE-CTRL+X"
- name = "CTRL+X"
- command = ".northeast"
- is-disabled = false
- elem "HKMODE-Y"
- name = "Y"
- command = "Activate-Held-Object"
- is-disabled = false
- elem "HKMODE-CTRL+Y"
- name = "CTRL+Y"
- command = "Activate-Held-Object"
- is-disabled = false
- elem "HKMODE-Z"
- name = "Z"
- command = "Activate-Held-Object"
- is-disabled = false
- elem "HKMODE-CTRL+Z"
- name = "CTRL+Z"
- command = "Activate-Held-Object"
- is-disabled = false
- elem "HKMODE-F1"
- name = "F1"
- command = "adminhelp"
- is-disabled = false
- elem "HKMODE-CTRL+SHIFT+F1+REP"
- name = "CTRL+SHIFT+F1+REP"
- command = ".options"
- is-disabled = false
- elem "HKMODE-F2"
- name = "F2"
- command = "ooc"
- is-disabled = false
- elem "HKMODE-F2+REP"
- name = "F2+REP"
- command = ".screenshot auto"
- is-disabled = false
- elem "HKMODE-SHIFT+F2+REP"
- name = "SHIFT+F2+REP"
- command = ".screenshot"
- is-disabled = false
- elem "HKMODE-F3"
- name = "F3"
- command = ".say"
- is-disabled = false
- elem "HKMODE-F4"
- name = "F4"
- command = ".me"
- is-disabled = false
- elem "HKMODE-F5"
- name = "F5"
- command = "asay"
- is-disabled = false
- elem "HKMODE-F6"
- name = "F6"
- command = "Aghost"
- is-disabled = false
- elem "HKMODE-F7"
- name = "F7"
- command = "player-panel-new"
- is-disabled = false
- elem "HKMODE-F8"
- name = "F8"
- command = "admin-pm-key"
- is-disabled = false
- elem "HKMODE-F9"
- name = "F9"
- command = "Invisimin"
- is-disabled = false
- elem "HKMODE-F12"
- name = "F12"
- command = "F12"
- is-disabled = false
-
-macro "borgmacro"
- elem "BRGMACRO-TAB"
- name = "TAB"
- command = ".winset \"mainwindow.macro=borghotkeymode hotkey_toggle.is-checked=true mapwindow.map.focus=true input.background-color=#F0F0F0\""
- is-disabled = false
- elem "BRGMACRO-CENTER+REP"
- name = "CENTER+REP"
- command = ".center"
- is-disabled = false
- elem "BRGMACRO-NORTHEAST"
- name = "NORTHEAST"
- command = ".northeast"
- is-disabled = false
- elem "BRGMACRO-SOUTHEAST"
- name = "SOUTHEAST"
- command = ".southeast"
- is-disabled = false
- elem "BRGMACRO-NORTHWEST"
- name = "NORTHWEST"
- command = "unequip-module"
- is-disabled = false
- elem "BRGMACRO-CTRL+WEST"
- name = "CTRL+WEST"
- command = "westface"
- is-disabled = false
- elem "BRGMACRO-WEST+REP"
- name = "WEST+REP"
- command = ".moveleft"
- is-disabled = false
- elem "BRGMACRO-CTRL+NORTH"
- name = "CTRL+NORTH"
- command = "northface"
- is-disabled = false
- elem "BRGMACRO-NORTH+REP"
- name = "NORTH+REP"
- command = ".moveup"
- is-disabled = false
- elem "BRGMACRO-CTRL+EAST"
- name = "CTRL+EAST"
- command = "eastface"
- is-disabled = false
- elem "BRGMACRO-EAST+REP"
- name = "EAST+REP"
- command = ".moveright"
- is-disabled = false
- elem "BRGMACRO-CTRL+SOUTH"
- name = "CTRL+SOUTH"
- command = "southface"
- is-disabled = false
- elem "BRGMACRO-SOUTH+REP"
- name = "SOUTH+REP"
- command = ".movedown"
- is-disabled = false
- elem "BRGMACRO-INSERT"
- name = "INSERT"
- command = "a-intent right"
- is-disabled = false
- elem "BRGMACRO-DELETE"
- name = "DELETE"
- command = "delete-key-pressed"
- is-disabled = false
- elem "BRGMACRO-CTRL+1"
- name = "CTRL+1"
- command = "toggle-module 1"
- is-disabled = false
- elem "BRGMACRO-CTRL+2"
- name = "CTRL+2"
- command = "toggle-module 2"
- is-disabled = false
- elem "BRGMACRO-CTRL+3"
- name = "CTRL+3"
- command = "toggle-module 3"
- is-disabled = false
- elem "BRGMACRO-CTRL+4"
- name = "CTRL+4"
- command = "a-intent left"
- is-disabled = false
- elem "BRGMACRO-CTRL+A+REP"
- name = "CTRL+A+REP"
- command = ".moveleft"
- is-disabled = false
- elem "BRGMACRO-CTRL+B"
- name = "CTRL+B"
- command = "resist"
- is-disabled = false
- elem "BRGMACRO-CTRL+O"
- name = "CTRL+O"
- command = "ooc"
- is-disabled = false
- elem "BRGMACRO-CTRL+D+REP"
- name = "CTRL+D+REP"
- command = ".moveright"
- is-disabled = false
- elem "BRGMACRO-CTRL+F"
- name = "CTRL+F"
- command = "a-intent left"
- is-disabled = false
- elem "BRGMACRO-CTRL+G"
- name = "CTRL+G"
- command = "a-intent right"
- is-disabled = false
- elem "BRGMACRO-CTRL+Q"
- name = "CTRL+Q"
- command = "unequip-module"
- is-disabled = false
- elem "BRGMACRO-CTRL+S+REP"
- name = "CTRL+S+REP"
- command = ".movedown"
- is-disabled = false
- elem "BRGMACRO-CTRL+W+REP"
- name = "CTRL+W+REP"
- command = ".moveup"
- is-disabled = false
- elem "BRGMACRO-CTRL+X"
- name = "CTRL+X"
- command = ".northeast"
- is-disabled = false
- elem "BRGMACRO-CTRL+Y"
- name = "CTRL+Y"
- command = "Activate-Held-Object"
- is-disabled = false
- elem "BRGMACRO-CTRL+Z"
- name = "CTRL+Z"
- command = "Activate-Held-Object"
- is-disabled = false
- elem "BRGMACRO-F1"
- name = "F1"
- command = "adminhelp"
- is-disabled = false
- elem "BRGMACRO-CTRL+SHIFT+F1+REP"
- name = "CTRL+SHIFT+F1+REP"
- command = ".options"
- is-disabled = false
- elem "BRGMACRO-F2"
- name = "F2"
- command = "ooc"
- is-disabled = false
- elem "BRGMACRO-F2+REP"
- name = "F2+REP"
- command = ".screenshot auto"
- is-disabled = false
- elem "BRGMACRO-SHIFT+F2+REP"
- name = "SHIFT+F2+REP"
- command = ".screenshot"
- is-disabled = false
- elem "BRGMACRO-F3"
- name = "F3"
- command = ".say"
- is-disabled = false
- elem "BRGMACRO-F4"
- name = "F4"
- command = ".me"
- is-disabled = false
- elem "BRGMACRO-F5"
- name = "F5"
- command = "asay"
- is-disabled = false
- elem "BRGMACRO-F6"
- name = "F6"
- command = "Aghost"
- is-disabled = false
- elem "BRGMACRO-F7"
- name = "F7"
- command = "player-panel-new"
- is-disabled = false
- elem "BRGMACRO-F8"
- name = "F8"
- command = "admin-pm-key"
- is-disabled = false
- elem "BRGMACRO-F9"
- name = "F9"
- command = "Invisimin"
- is-disabled = false
- elem "BRGMACRO-F12"
- name = "F12"
- command = "F12"
- is-disabled = false
-
-macro "borghotkeymode"
- elem "BRGHK-TAB"
- name = "TAB"
- command = ".winset \"mainwindow.macro=borgmacro hotkey_toggle.is-checked=false input.focus=true input.background-color=#d3b5b5\""
- is-disabled = false
- elem "BRGHK-CENTER+REP"
- name = "CENTER+REP"
- command = ".center"
- is-disabled = false
- elem "BRGHK-NORTHEAST"
- name = "NORTHEAST"
- command = ".northeast"
- is-disabled = false
- elem "BRGHK-SOUTHEAST"
- name = "SOUTHEAST"
- command = ".southeast"
- is-disabled = false
- elem "BRGHK-NORTHWEST"
- name = "NORTHWEST"
- command = "unequip-module"
- is-disabled = false
- elem "BRGHK-CTRL+WEST"
- name = "CTRL+WEST"
- command = "westface"
- is-disabled = false
- elem "BRGHK-WEST+REP"
- name = "WEST+REP"
- command = ".moveleft"
- is-disabled = false
- elem "BRGHK-CTRL+NORTH"
- name = "CTRL+NORTH"
- command = "northface"
- is-disabled = false
- elem "BRGHK-NORTH+REP"
- name = "NORTH+REP"
- command = ".moveup"
- is-disabled = false
- elem "BRGHK-CTRL+EAST"
- name = "CTRL+EAST"
- command = "eastface"
- is-disabled = false
- elem "BRGHK-EAST+REP"
- name = "EAST+REP"
- command = ".moveright"
- is-disabled = false
- elem "BRGHK-CTRL+SOUTH"
- name = "CTRL+SOUTH"
- command = "southface"
- is-disabled = false
- elem "BRGHK-SOUTH+REP"
- name = "SOUTH+REP"
- command = ".movedown"
- is-disabled = false
- elem "BRGHK-INSERT"
- name = "INSERT"
- command = "a-intent right"
- is-disabled = false
- elem "BRGHK-DELETE"
- name = "DELETE"
- command = "delete-key-pressed"
- is-disabled = false
- elem "BRGHK-1"
- name = "1"
- command = "toggle-module 1"
- is-disabled = false
- elem "BRGHK-CTRL+1"
- name = "CTRL+1"
- command = "toggle-module 1"
- is-disabled = false
- elem "BRGHK-2"
- name = "2"
- command = "toggle-module 2"
- is-disabled = false
- elem "BRGHK-CTRL+2"
- name = "CTRL+2"
- command = "toggle-module 2"
- is-disabled = false
- elem "BRGHK-3"
- name = "3"
- command = "toggle-module 3"
- is-disabled = false
- elem "BRGHK-CTRL+3"
- name = "CTRL+3"
- command = "toggle-module 3"
- is-disabled = false
- elem "BRGHK-4"
- name = "4"
- command = "a-intent left"
- is-disabled = false
- elem "BRGHK-CTRL+4"
- name = "CTRL+4"
- command = "a-intent left"
- is-disabled = false
- elem "BRGHK-A+REP"
- name = "A+REP"
- command = ".moveleft"
- is-disabled = false
- elem "BRGHK-CTRL+A+REP"
- name = "CTRL+A+REP"
- command = ".moveleft"
- is-disabled = false
- elem "BRGHK-B"
- name = "B"
- command = "resist"
- is-disabled = false
- elem "BRGHK-CTRL+B"
- name = "CTRL+B"
- command = "resist"
- is-disabled = false
- elem "BRGHK-T"
- name = "T"
- command = ".say"
- is-disabled = false
- elem "BRGHK-O"
- name = "O"
- command = "ooc"
- is-disabled = false
- elem "BRGHK-M"
- name = "M"
- command = ".me"
- is-disabled = false
- elem "BRGHK-CTRL+O"
- name = "CTRL+O"
- command = "ooc"
- is-disabled = false
- elem "BRGHK-D+REP"
- name = "D+REP"
- command = ".moveright"
- is-disabled = false
- elem "BRGHK-CTRL+D+REP"
- name = "CTRL+D+REP"
- command = ".moveright"
- is-disabled = false
- elem "BRGHK-F"
- name = "F"
- command = "a-intent left"
- is-disabled = false
- elem "BRGHK-CTRL+F"
- name = "CTRL+F"
- command = "a-intent left"
- is-disabled = false
- elem "BRGHK-G"
- name = "G"
- command = "a-intent right"
- is-disabled = false
- elem "BRGHK-CTRL+G"
- name = "CTRL+G"
- command = "a-intent right"
- is-disabled = false
- elem "BRGHK-Q"
- name = "Q"
- command = "unequip-module"
- is-disabled = false
- elem "BRGHK-CTRL+Q"
- name = "CTRL+Q"
- command = "unequip-module"
- is-disabled = false
- elem "s_key"
- name = "S+REP"
- command = ".movedown"
- is-disabled = false
- elem "BRGHK-CTRL+S+REP"
- name = "CTRL+S+REP"
- command = ".movedown"
- is-disabled = false
- elem "w_key"
- name = "W+REP"
- command = ".moveup"
- is-disabled = false
- elem "BRGHK-CTRL+W+REP"
- name = "CTRL+W+REP"
- command = ".moveup"
- is-disabled = false
- elem "BRGHK-X"
- name = "X"
- command = ".northeast"
- is-disabled = false
- elem "BRGHK-CTRL+X"
- name = "CTRL+X"
- command = ".northeast"
- is-disabled = false
- elem "BRGHK-Y"
- name = "Y"
- command = "Activate-Held-Object"
- is-disabled = false
- elem "BRGHK-CTRL+Y"
- name = "CTRL+Y"
- command = "Activate-Held-Object"
- is-disabled = false
- elem "BRGHK-Z"
- name = "Z"
- command = "Activate-Held-Object"
- is-disabled = false
- elem "BRGHK-CTRL+Z"
- name = "CTRL+Z"
- command = "Activate-Held-Object"
- is-disabled = false
- elem "BRGHK-F1"
- name = "F1"
- command = "adminhelp"
- is-disabled = false
- elem "BRGHK-CTRL+SHIFT+F1+REP"
- name = "CTRL+SHIFT+F1+REP"
- command = ".options"
- is-disabled = false
- elem "BRGHK-F2"
- name = "F2"
- command = "ooc"
- is-disabled = false
- elem "BRGHK-F2+REP"
- name = "F2+REP"
- command = ".screenshot auto"
- is-disabled = false
- elem "BRGHK-SHIFT+F2+REP"
- name = "SHIFT+F2+REP"
- command = ".screenshot"
- is-disabled = false
- elem "BRGHK-F3"
- name = "F3"
- command = ".say"
- is-disabled = false
- elem "BRGHK-F4"
- name = "F4"
- command = ".me"
- is-disabled = false
- elem "BRGHK-F5"
- name = "F5"
- command = "asay"
- is-disabled = false
- elem "BRGHK-F6"
- name = "F6"
- command = "Aghost"
- is-disabled = false
- elem "BRGHK-F7"
- name = "F7"
- command = "player-panel-new"
- is-disabled = false
- elem "BRGHK-F8"
- name = "F8"
- command = "admin-pm-key"
- is-disabled = false
- elem "BRGHK-F9"
- name = "F9"
- command = "Invisimin"
- is-disabled = false
- elem "BRGHK-F12"
- name = "F12"
- command = "F12"
- is-disabled = false
-
-macro "azertymacro"
- elem "AZRFF-TAB"
- name = "TAB"
- command = ".winset \"mainwindow.macro=azertyhotkeymode hotkey_toggle.is-checked=true mapwindow.map.focus=true input.background-color=#F0F0F0\""
- is-disabled = false
- elem "AZRFF-CENTER+REP"
- name = "CENTER+REP"
- command = ".center"
- is-disabled = false
- elem "AZRFF-NORTHEAST"
- name = "NORTHEAST"
- command = ".northeast"
- is-disabled = false
- elem "AZRFF-SOUTHEAST"
- name = "SOUTHEAST"
- command = ".southeast"
- is-disabled = false
- elem "AZRFF-SOUTHWEST"
- name = "SOUTHWEST"
- command = ".southwest"
- is-disabled = false
- elem "AZRFF-NORTHWEST"
- name = "NORTHWEST"
- command = ".northwest"
- is-disabled = false
- elem "AZRFF-CTRL+WEST"
- name = "CTRL+WEST"
- command = "westface"
- is-disabled = false
- elem "AZRFF-WEST+REP"
- name = "WEST+REP"
- command = ".moveleft"
- is-disabled = false
- elem "AZRFF-CTRL+NORTH"
- name = "CTRL+NORTH"
- command = "northface"
- is-disabled = false
- elem "AZRFF-NORTH+REP"
- name = "NORTH+REP"
- command = ".moveup"
- is-disabled = false
- elem "AZRFF-CTRL+EAST"
- name = "CTRL+EAST"
- command = "eastface"
- is-disabled = false
- elem "AZRFF-EAST+REP"
- name = "EAST+REP"
- command = ".moveright"
- is-disabled = false
- elem "AZRFF-CTRL+SOUTH"
- name = "CTRL+SOUTH"
- command = "southface"
- is-disabled = false
- elem "AZRFF-SOUTH+REP"
- name = "SOUTH+REP"
- command = ".movedown"
- is-disabled = false
- elem "AZRFF-INSERT"
- name = "INSERT"
- command = "a-intent right"
- is-disabled = false
- elem "AZRFF-DELETE"
- name = "DELETE"
- command = "delete-key-pressed"
- is-disabled = false
- elem "AZRFF-CTRL+1"
- name = "CTRL+1"
- command = "a-intent help"
- is-disabled = false
- elem "AZRFF-CTRL+2"
- name = "CTRL+2"
- command = "a-intent disarm"
- is-disabled = false
- elem "AZRFF-CTRL+3"
- name = "CTRL+3"
- command = "a-intent grab"
- is-disabled = false
- elem "AZRFF-CTRL+4"
- name = "CTRL+4"
- command = "a-intent harm"
- is-disabled = false
- elem "AZRFF-CTRL+A"
- name = "CTRL+A"
- command = ".northwest"
- is-disabled = false
- elem "AZRFF-CTRL+D+REP"
- name = "CTRL+D+REP"
- command = ".moveright"
- is-disabled = false
- elem "AZRFF-CTRL+B"
- name = "CTRL+B"
- command = "resist"
- is-disabled = false
- elem "AZRFF-CTRL+E"
- name = "CTRL+E"
- command = "quick-equip"
- is-disabled = false
- elem "AZRFF-CTRL+F"
- name = "CTRL+F"
- command = "a-intent left"
- is-disabled = false
- elem "AZRFF-CTRL+G"
- name = "CTRL+G"
- command = "a-intent right"
- is-disabled = false
- elem "AZRFF-CTRL+Q+REP"
- name = "CTRL+Q+REP"
- command = ".moveleft"
- is-disabled = false
- elem "AZRFF-CTRL+R"
- name = "CTRL+R"
- command = ".southwest"
- is-disabled = false
- elem "AZRFF-CTRL+S+REP"
- name = "CTRL+S+REP"
- command = ".movedown"
- is-disabled = false
- elem "AZRFF-CTRL+W"
- name = "CTRL+W"
- command = "Activate-Held-Object"
- is-disabled = false
- elem "AZRFF-CTRL+X"
- name = "CTRL+X"
- command = ".northeast"
- is-disabled = false
- elem "AZRFF-CTRL+Y"
- name = "CTRL+Y"
- command = "Activate-Held-Object"
- is-disabled = false
- elem "AZRFF-CTRL+Z+REP"
- name = "CTRL+Z+REP"
- command = ".moveup"
- is-disabled = false
- elem "AZRFF-F1"
- name = "F1"
- command = "adminhelp"
- is-disabled = false
- elem "AZRFF-CTRL+SHIFT+F1+REP"
- name = "CTRL+SHIFT+F1+REP"
- command = ".options"
- is-disabled = false
- elem "AZRFF-F2"
- name = "F2"
- command = "ooc"
- is-disabled = false
- elem "AZRFF-F2+REP"
- name = "F2+REP"
- command = ".screenshot auto"
- is-disabled = false
- elem "AZRFF-SHIFT+F2+REP"
- name = "SHIFT+F2+REP"
- command = ".screenshot"
- is-disabled = false
- elem "AZRFF-F3"
- name = "F3"
- command = ".say"
- is-disabled = false
- elem "AZRFF-F4"
- name = "F4"
- command = ".me"
- is-disabled = false
- elem "AZRFF-F5"
- name = "F5"
- command = "asay"
- is-disabled = false
- elem "AZRFF-F6"
- name = "F6"
- command = "Aghost"
- is-disabled = false
- elem "AZRFF-F7"
- name = "F7"
- command = "player-panel-new"
- is-disabled = false
- elem "AZRFF-F8"
- name = "F8"
- command = "admin-pm-key"
- is-disabled = false
- elem "AZRFF-F9"
- name = "F9"
- command = "Invisimin"
- is-disabled = false
- elem "AZRFF-F12"
- name = "F12"
- command = "F12"
- is-disabled = false
-
-macro "azertyhotkeymode"
- elem "AZRON-TAB"
- name = "TAB"
- command = ".winset \"mainwindow.macro=azertymacro hotkey_toggle.is-checked=false input.focus=true input.background-color=#d3b5b5\""
- is-disabled = false
- elem "AZRON-CENTER+REP"
- name = "CENTER+REP"
- command = ".center"
- is-disabled = false
- elem "AZRON-NORTHEAST"
- name = "NORTHEAST"
- command = ".northeast"
- is-disabled = false
- elem "AZRON-SOUTHEAST"
- name = "SOUTHEAST"
- command = ".southeast"
- is-disabled = false
- elem "AZRON-SOUTHWEST"
- name = "SOUTHWEST"
- command = ".southwest"
- is-disabled = false
- elem "AZRON-NORTHWEST"
- name = "NORTHWEST"
- command = ".northwest"
- is-disabled = false
- elem "AZRON-CTRL+WEST"
- name = "CTRL+WEST"
- command = "westface"
- is-disabled = false
- elem "AZRON-WEST+REP"
- name = "WEST+REP"
- command = ".moveleft"
- is-disabled = false
- elem "AZRON-CTRL+NORTH"
- name = "CTRL+NORTH"
- command = "northface"
- is-disabled = false
- elem "AZRON-NORTH+REP"
- name = "NORTH+REP"
- command = ".moveup"
- is-disabled = false
- elem "AZRON-CTRL+EAST"
- name = "CTRL+EAST"
- command = "eastface"
- is-disabled = false
- elem "AZRON-EAST+REP"
- name = "EAST+REP"
- command = ".moveright"
- is-disabled = false
- elem "AZRON-CTRL+SOUTH"
- name = "CTRL+SOUTH"
- command = "southface"
- is-disabled = false
- elem "AZRON-SOUTH+REP"
- name = "SOUTH+REP"
- command = ".movedown"
- is-disabled = false
- elem "AZRON-INSERT"
- name = "INSERT"
- command = "a-intent right"
- is-disabled = false
- elem "AZRON-DELETE"
- name = "DELETE"
- command = "delete-key-pressed"
- is-disabled = false
- elem "AZRON-1"
- name = "1"
- command = "a-intent help"
- is-disabled = false
- elem "AZRON-CTRL+1"
- name = "CTRL+1"
- command = "a-intent help"
- is-disabled = false
- elem "AZRON-2"
- name = "2"
- command = "a-intent disarm"
- is-disabled = false
- elem "AZRON-CTRL+2"
- name = "CTRL+2"
- command = "a-intent disarm"
- is-disabled = false
- elem "AZRON-3"
- name = "3"
- command = "a-intent grab"
- is-disabled = false
- elem "AZRON-CTRL+3"
- name = "CTRL+3"
- command = "a-intent grab"
- is-disabled = false
- elem "AZRON-4"
- name = "4"
- command = "a-intent harm"
- is-disabled = false
- elem "AZRON-CTRL+4"
- name = "CTRL+4"
- command = "a-intent harm"
- is-disabled = false
- elem "AZRON-A"
- name = "A"
- command = ".northwest"
- is-disabled = false
- elem "AZRON-CTRL+A"
- name = "CTRL+A"
- command = ".northwest"
- is-disabled = false
- elem "AZRON-D+REP"
- name = "D+REP"
- command = ".moveright"
- is-disabled = false
- elem "AZRON-CTRL+D+REP"
- name = "CTRL+D+REP"
- command = ".moveright"
- is-disabled = false
- elem "AZRON-CTRL+B"
- name = "CTRL+B"
- command = "resist"
- is-disabled = false
- elem "AZRON-E"
- name = "E"
- command = "quick-equip"
- is-disabled = false
- elem "AZRON-CTRL+E"
- name = "CTRL+E"
- command = "quick-equip"
- is-disabled = false
- elem "AZRON-F"
- name = "F"
- command = "a-intent left"
- is-disabled = false
- elem "AZRON-CTRL+F"
- name = "CTRL+F"
- command = "a-intent left"
- is-disabled = false
- elem "AZRON-G"
- name = "G"
- command = "a-intent right"
- is-disabled = false
- elem "AZRON-CTRL+G"
- name = "CTRL+G"
- command = "a-intent right"
- is-disabled = false
- elem "AZRON-H"
- name = "H"
- command = "holster"
- is-disabled = false
- elem "AZRON-CTRL+H"
- name = "CTRL+H"
- command = "holster"
- is-disabled = false
- elem "AZRON-Q+REP"
- name = "Q+REP"
- command = ".moveleft"
- is-disabled = false
- elem "AZRON-CTRL+Q+REP"
- name = "CTRL+Q+REP"
- command = ".moveleft"
- is-disabled = false
- elem "AZRON-R"
- name = "R"
- command = ".southwest"
- is-disabled = false
- elem "AZRON-CTRL+R"
- name = "CTRL+R"
- command = ".southwest"
- is-disabled = false
- elem "s_key"
- name = "S+REP"
- command = ".movedown"
- is-disabled = false
- elem "AZRON-CTRL+S+REP"
- name = "CTRL+S+REP"
- command = ".movedown"
- is-disabled = false
- elem "AZRON-T"
- name = "T"
- command = ".say"
- is-disabled = false
- elem "AZRON-O"
- name = "O"
- command = "ooc"
- is-disabled = false
- elem "AZRON-M"
- name = "M"
- command = ".me"
- is-disabled = false
- elem "AZRON-W"
- name = "W"
- command = "Activate-Held-Object"
- is-disabled = false
- elem "AZRON-CTRL+W"
- name = "CTRL+W"
- command = "Activate-Held-Object"
- is-disabled = false
- elem "AZRON-X"
- name = "X"
- command = ".northeast"
- is-disabled = false
- elem "AZRON-CTRL+X"
- name = "CTRL+X"
- command = ".northeast"
- is-disabled = false
- elem "AZRON-Y"
- name = "Y"
- command = "Activate-Held-Object"
- is-disabled = false
- elem "AZRON-CTRL+Y"
- name = "CTRL+Y"
- command = "Activate-Held-Object"
- is-disabled = false
- elem "w_key"
- name = "Z+REP"
- command = ".moveup"
- is-disabled = false
- elem "AZRON-CTRL+Z+REP"
- name = "CTRL+Z+REP"
- command = ".moveup"
- is-disabled = false
- elem "AZRON-F1"
- name = "F1"
- command = "adminhelp"
- is-disabled = false
- elem "AZRON-CTRL+SHIFT+F1+REP"
- name = "CTRL+SHIFT+F1+REP"
- command = ".options"
- is-disabled = false
- elem "AZRON-F2"
- name = "F2"
- command = "ooc"
- is-disabled = false
- elem "AZRON-F2+REP"
- name = "F2+REP"
- command = ".screenshot auto"
- is-disabled = false
- elem "AZRON-SHIFT+F2+REP"
- name = "SHIFT+F2+REP"
- command = ".screenshot"
- is-disabled = false
- elem "AZRON-F3"
- name = "F3"
- command = ".say"
- is-disabled = false
- elem "AZRON-F4"
- name = "F4"
- command = ".me"
- is-disabled = false
- elem "AZRON-F5"
- name = "F5"
- command = "asay"
- is-disabled = false
- elem "AZRON-F6"
- name = "F6"
- command = "Aghost"
- is-disabled = false
- elem "AZRON-F7"
- name = "F7"
- command = "player-panel-new"
- is-disabled = false
- elem "AZRON-F8"
- name = "F8"
- command = "admin-pm-key"
- is-disabled = false
- elem "AZRON-F9"
- name = "F9"
- command = "Invisimin"
- is-disabled = false
- elem "AZRON-F12"
- name = "F12"
- command = "F12"
- is-disabled = false
+macro "default"
menu "menu"
- elem
+ elem
name = "&File"
command = ""
- category = ""
- is-checked = false
- can-check = false
- group = ""
- is-disabled = false
saved-params = "is-checked"
- elem
+ elem
name = "&Quick screenshot\tF2"
command = ".screenshot auto"
category = "&File"
- is-checked = false
- can-check = false
- group = ""
- is-disabled = false
saved-params = "is-checked"
- elem
+ elem
name = "&Save screenshot as...\tShift+F2"
command = ".screenshot"
category = "&File"
- is-checked = false
- can-check = false
- group = ""
- is-disabled = false
saved-params = "is-checked"
elem "reconnectbutton"
name = "&Reconnect"
command = ".reconnect"
category = "&File"
- is-checked = false
- can-check = false
- group = ""
- is-disabled = false
saved-params = "is-checked"
- elem
+ elem
name = ""
command = ""
category = "&File"
- is-checked = false
- can-check = false
- group = ""
- is-disabled = false
saved-params = "is-checked"
- elem
+ elem
name = "&Quit"
command = ".quit"
category = "&File"
- is-checked = false
- can-check = false
- group = ""
- is-disabled = false
saved-params = "is-checked"
- elem
+ elem
name = "&Icons"
command = ""
saved-params = "is-checked"
- elem
+ elem
name = "&Size"
command = ""
category = "&Icons"
@@ -1453,7 +82,7 @@ menu "menu"
can-check = true
group = "size"
saved-params = "is-checked"
- elem
+ elem
name = "&Scaling"
command = ""
category = "&Icons"
@@ -1484,106 +113,79 @@ menu "menu"
command = ".winset \"menu.textmode.is-checked=true?mapwindow.map.text-mode=true:mapwindow.map.text-mode=false\""
category = "&Icons"
can-check = true
- group = ""
saved-params = "is-checked"
-
- elem
+ elem
name = "&Help"
command = ""
- category = ""
- is-checked = false
- can-check = false
- group = ""
- is-disabled = false
saved-params = "is-checked"
- elem
+ elem
name = "&Admin help\tF1"
command = "adminhelp"
category = "&Help"
- is-checked = false
- can-check = false
- group = ""
- is-disabled = false
saved-params = "is-checked"
- elem
+ elem
name = "&Hotkeys"
command = "hotkeys-help"
category = "&Help"
- is-checked = false
- can-check = false
- group = ""
- is-disabled = false
saved-params = "is-checked"
window "mainwindow"
elem "mainwindow"
type = MAIN
+ pos = 0,0
size = 640x440
+ anchor1 = none
+ anchor2 = none
is-default = true
- is-maximized = true
- title = "Paradise Station 13"
- icon = 'icons\\paradise.png'
- menu = "menu"
- macro = "macro"
saved-params = "pos;size;is-minimized;is-maximized"
+ title = "Paradise Station 13"
+ is-maximized = true
+ icon = 'icons\\paradise.png'
+ macro = "default"
+ menu = "menu"
elem "asset_cache_browser"
type = BROWSER
- is-visible = false
- elem "hotkey_toggle"
- type = BUTTON
- button-type = pushbox
- pos = 560,420
- size = 80x20
- anchor1 = 100,100
+ pos = 0,0
+ size = 200x200
+ anchor1 = none
anchor2 = none
- background-color = none
+ is-visible = false
saved-params = ""
- is-flat = false
- text = "Hotkey Toggle"
- command = ".winset \"mainwindow.macro != macro ? mainwindow.macro=macro hotkey_toggle.is-checked=false input.focus=true input.background-color=#d3b5b5 : mainwindow.macro=hotkeymode hotkey_toggle.is-checked=true mapwindow.map.focus=true input.background-color=#f0f0f0\""
elem "mainvsplit"
type = CHILD
pos = 3,0
size = 634x416
anchor1 = 0,0
anchor2 = 100,100
- is-vert = true
- splitter = 50
- show-splitter = true
+ saved-params = "splitter"
left = "mapwindow"
right = "rpane"
- saved-params = "splitter"
+ is-vert = true
elem "input"
type = INPUT
pos = 3,420
size = 477x20
anchor1 = 0,100
anchor2 = 100,100
+ background-color = #d3b5b5
is-default = true
border = sunken
- font-family = ""
- font-size = 0
- font-style = ""
- text-color = #000000
- background-color = #d3b5b5
saved-params = "command"
elem "saybutton"
type = BUTTON
- button-type = pushbox
- pos = 520,420
- size = 40x20
+ pos = 480,420
+ size = 80x20
anchor1 = 100,100
anchor2 = none
- is-flat = false
+ saved-params = "is-checked"
text = "Chat"
command = ".winset \"saybutton.is-checked=true?input.command=\"!say \\\"\" macrobutton.is-checked=false:input.command=\"\"saybutton.is-checked=true?mebutton.is-checked=false\""
- is-checked = false
- saved-params = "is-checked"
+ button-type = pushbox
elem "mebutton"
type = BUTTON
- pos = 480,420
- size = 40x20
+ pos = 560,420
+ size = 80x20
anchor1 = 100,100
anchor2 = none
saved-params = "is-checked"
@@ -1594,54 +196,63 @@ window "mainwindow"
type = BROWSER
pos = 0,0
size = 999x999
+ anchor1 = none
+ anchor2 = none
is-visible = false
+ saved-params = ""
window "mapwindow"
elem "mapwindow"
type = MAIN
- is-pane = true
- title = "Map window"
+ pos = 0,0
+ size = 640x480
+ anchor1 = none
+ anchor2 = none
saved-params = "pos;size;is-minimized;is-maximized"
+ title = "Map window"
+ is-pane = true
elem "map"
type = MAP
- is-default = true
pos = 0,0
size = 640x480
anchor1 = 0,0
anchor2 = 100,100
font-family = "Arial"
font-size = 7
- font-style = ""
text-color = none
- background-color = none
- icon-size = 0
+ is-default = true
saved-params = "icon-size"
window "outputwindow"
elem "outputwindow"
type = MAIN
- is-pane = true
- can-close = false
- can-minimize = false
+ pos = 0,0
+ size = 640x480
+ anchor1 = none
+ anchor2 = none
saved-params = "pos;size;is-minimized;is-maximized"
title = "Output window"
+ can-close = false
+ can-minimize = false
+ is-pane = true
elem "browseroutput"
type = BROWSER
- is-disabled = true
- auto-format = false
pos = 0,0
size = 640x480
anchor1 = 0,0
anchor2 = 100,100
- font-family = ""
- font-size = 0
- font-style = ""
- text-color = #000000
background-color = #ffffff
+ is-disabled = true
+ saved-params = ""
+ auto-format = false
window "rpane"
elem "rpane"
type = MAIN
+ pos = 0,0
+ size = 640x480
+ anchor1 = none
+ anchor2 = none
saved-params = "pos;size;is-minimized;is-maximized"
is-pane = true
elem "rpanewindow"
@@ -1651,15 +262,14 @@ window "rpane"
anchor1 = 0,0
anchor2 = 100,100
saved-params = "splitter"
- left = ""
right = "outputwindow"
is-vert = false
- splitter = 50
- show-splitter = true
elem "textb"
type = BUTTON
pos = 0,7
size = 60x16
+ anchor1 = none
+ anchor2 = none
is-visible = false
saved-params = "is-checked"
text = "Text"
@@ -1671,6 +281,8 @@ window "rpane"
type = BUTTON
pos = 64,7
size = 60x16
+ anchor1 = none
+ anchor2 = none
is-visible = false
saved-params = "is-checked"
text = "Info"
@@ -1681,63 +293,89 @@ window "rpane"
type = BUTTON
pos = 155,7
size = 60x16
+ anchor1 = none
+ anchor2 = none
+ saved-params = "is-checked"
text = "Wiki"
command = "wiki"
elem "forumb"
type = BUTTON
pos = 220,7
size = 60x16
+ anchor1 = none
+ anchor2 = none
+ saved-params = "is-checked"
text = "Forum"
command = "forum"
elem "rulesb"
type = BUTTON
pos = 285,7
size = 60x16
+ anchor1 = none
+ anchor2 = none
+ saved-params = "is-checked"
text = "Rules"
command = "rules"
elem "githubb"
type = BUTTON
pos = 350,7
size = 60x16
+ anchor1 = none
+ anchor2 = none
+ saved-params = "is-checked"
text = "GitHub"
command = "github"
elem "changelog"
type = BUTTON
pos = 415,7
size = 67x16
+ anchor1 = none
+ anchor2 = none
+ saved-params = "is-checked"
text = "Changelog"
command = "Changelog"
elem "discordb"
type = BUTTON
pos = 487,7
size = 60x16
- background-color = #7289DA
- text-color = #FFFFFF
- font-style = bold
+ anchor1 = none
+ anchor2 = none
+ font-style = "bold"
+ text-color = #ffffff
+ background-color = #7289da
+ saved-params = "is-checked"
text = "Discord"
command = "discord"
elem "karma"
type = BUTTON
pos = 552,7
size = 60x16
- background-color = #FF4500
- text-color = #FFFFFF
- font-style = bold
+ anchor1 = none
+ anchor2 = none
+ font-style = "bold"
+ text-color = #ffffff
+ background-color = #ff4500
+ saved-params = "is-checked"
text = "Karma"
command = "karmashop"
elem "donate"
type = BUTTON
pos = 617,7
size = 60x16
+ anchor1 = none
+ anchor2 = none
+ font-style = "bold"
+ text-color = #ffffff
background-color = #008000
- text-color = #FFFFFF
- font-style = bold
+ saved-params = "is-checked"
text = "Donate"
command = "Donate"
elem "browseb"
type = BUTTON
pos = 561,7
size = 60x16
+ anchor1 = none
+ anchor2 = none
is-visible = false
saved-params = "is-checked"
text = "Browser"
@@ -1748,9 +386,13 @@ window "rpane"
window "browserwindow"
elem "browserwindow"
type = MAIN
- is-pane = true
+ pos = 0,0
+ size = 640x480
+ anchor1 = none
+ anchor2 = none
saved-params = "pos;size;is-minimized;is-maximized"
title = "Browser"
+ is-pane = true
elem "browser"
type = BROWSER
pos = 0,0
@@ -1758,15 +400,20 @@ window "browserwindow"
anchor1 = 0,0
anchor2 = 100,100
is-default = true
+ saved-params = ""
on-show = ".winset\"rpane.infob.is-visible=true?rpane.infob.pos=130,7;rpane.textb.is-visible=true;rpane.browseb.is-visible=true;rpane.browseb.is-checked=true;rpane.rpanewindow.pos=0,30;rpane.rpanewindow.size=0x0;rpane.rpanewindow.left=browserwindow\""
on-hide = ".winset\"rpane.infob.is-visible=true?rpane.infob.is-checked=true rpane.infob.pos=65,7 rpane.rpanewindow.left=infowindow:rpane.rpanewindow.left=textwindow rpane.textb.is-visible=true rpane.rpanewindow.pos=0,30 rpane.rpanewindow.size=0x0\""
window "infowindow"
elem "infowindow"
type = MAIN
- is-pane = true
+ pos = 0,0
+ size = 640x480
+ anchor1 = none
+ anchor2 = none
saved-params = "pos;size;is-minimized;is-maximized"
title = "Info"
+ is-pane = true
elem "info"
type = INFO
pos = 0,0
@@ -1774,9 +421,8 @@ window "infowindow"
anchor1 = 0,0
anchor2 = 100,100
is-default = true
+ saved-params = ""
highlight-color = #00aa00
- tab-text-color = #000000
- allow-html = true
- multi-line = true
on-show = ".winset\"rpane.infob.is-visible=true;rpane.browseb.is-visible=true?rpane.infob.pos=130,7:rpane.infob.pos=65,7 rpane.textb.is-visible=true rpane.infob.is-checked=true rpane.rpanewindow.pos=0,30 rpane.rpanewindow.size=0x0 rpane.rpanewindow.left=infowindow\""
on-hide = ".winset\"rpane.infob.is-visible=false;rpane.browseb.is-visible=true?rpane.browseb.is-checked=true rpane.rpanewindow.left=browserwindow:rpane.textb.is-visible=true rpane.rpanewindow.pos=0,30 rpane.rpanewindow.size=0x0 rpane.rpanewindow.left=\""
+
diff --git a/nano/templates/labor_claim_console.tmpl b/nano/templates/labor_claim_console.tmpl
new file mode 100644
index 00000000000..efbdb5796d6
--- /dev/null
+++ b/nano/templates/labor_claim_console.tmpl
@@ -0,0 +1,76 @@
+
+
+
+
+