diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm
index 97f4f8d25db..ded86bf0afd 100644
--- a/_maps/map_files/cyberiad/cyberiad.dmm
+++ b/_maps/map_files/cyberiad/cyberiad.dmm
@@ -65442,6 +65442,7 @@
name = "\improper Virology Lobby"
})
"cnE" = (
+/obj/machinery/atmospherics/unary/passive_vent,
/turf/simulated/floor/engine/insulated/vacuum,
/area/toxins/mixing)
"cnF" = (
diff --git a/code/__DEFINES/gamemode.dm b/code/__DEFINES/gamemode.dm
index 617cdf3cb21..a1e469e3c94 100644
--- a/code/__DEFINES/gamemode.dm
+++ b/code/__DEFINES/gamemode.dm
@@ -11,7 +11,6 @@
#define GAMEMODE_IS_BLOB (ticker && istype(ticker.mode, /datum/game_mode/blob))
#define GAMEMODE_IS_CULT (ticker && istype(ticker.mode, /datum/game_mode/cult))
#define GAMEMODE_IS_HEIST (ticker && istype(ticker.mode, /datum/game_mode/heist))
-#define GAMEMODE_IS_NATIONS (ticker && istype(ticker.mode, /datum/game_mode/nations))
#define GAMEMODE_IS_NUCLEAR (ticker && istype(ticker.mode, /datum/game_mode/nuclear))
#define GAMEMODE_IS_REVOLUTION (ticker && istype(ticker.mode, /datum/game_mode/revolution))
#define GAMEMODE_IS_WIZARD (ticker && istype(ticker.mode, /datum/game_mode/wizard))
diff --git a/code/__DEFINES/hud.dm b/code/__DEFINES/hud.dm
index 59cf95a72d7..45953a2e47b 100644
--- a/code/__DEFINES/hud.dm
+++ b/code/__DEFINES/hud.dm
@@ -16,18 +16,17 @@
#define DIAG_MECH_HUD "11"// Mech health bar
#define STATUS_HUD_OOC "12"// STATUS_HUD without virus db check for someone being ill.
#define SPECIALROLE_HUD "13" //for antag huds. these are used at the /mob level
-#define NATIONS_HUD "14" //Show nations icons during nations gamemode
-#define DIAG_BOT_HUD "15"// Bot HUDS
-#define PLANT_NUTRIENT_HUD "16"// Plant nutrient level
-#define PLANT_WATER_HUD "17"// Plant water level
-#define PLANT_STATUS_HUD "18"// Plant harvest/dead
-#define PLANT_HEALTH_HUD "19"// Plant health
-#define PLANT_TOXIN_HUD "20"// Toxin level
-#define PLANT_PEST_HUD "21"// Pest level
-#define PLANT_WEED_HUD "22"// Weed level
-#define DIAG_TRACK_HUD "23"// Mech tracking beacon
-#define DIAG_PATH_HUD "24"//Bot path indicators
-#define GLAND_HUD "25"//Gland indicators for abductors
+#define DIAG_BOT_HUD "14"// Bot HUDS
+#define PLANT_NUTRIENT_HUD "15"// Plant nutrient level
+#define PLANT_WATER_HUD "16"// Plant water level
+#define PLANT_STATUS_HUD "17"// Plant harvest/dead
+#define PLANT_HEALTH_HUD "18"// Plant health
+#define PLANT_TOXIN_HUD "19"// Toxin level
+#define PLANT_PEST_HUD "20"// Pest level
+#define PLANT_WEED_HUD "21"// Weed level
+#define DIAG_TRACK_HUD "22"// Mech tracking beacon
+#define DIAG_PATH_HUD "23"//Bot path indicators
+#define GLAND_HUD "24"//Gland indicators for abductors
//by default everything in the hud_list of an atom is an image
//a value in hud_list with one of these will change that behavior
@@ -42,22 +41,20 @@
#define DATA_HUD_DIAGNOSTIC 5
#define DATA_HUD_DIAGNOSTIC_ADVANCED 6
#define DATA_HUD_HYDROPONIC 7
-//NATIONS
-#define GAME_HUD_NATIONS 8
//antag HUD defines
-#define ANTAG_HUD_CULT 9
-#define ANTAG_HUD_REV 10
-#define ANTAG_HUD_OPS 11
-#define ANTAG_HUD_WIZ 12
-#define ANTAG_HUD_SHADOW 13
-#define ANTAG_HUD_TRAITOR 14
-#define ANTAG_HUD_NINJA 15
-#define ANTAG_HUD_CHANGELING 16
-#define ANTAG_HUD_VAMPIRE 17
-#define ANTAG_HUD_ABDUCTOR 18
-#define DATA_HUD_ABDUCTOR 19
-#define ANTAG_HUD_DEVIL 20
-#define ANTAG_HUD_EVENTMISC 21
+#define ANTAG_HUD_CULT 8
+#define ANTAG_HUD_REV 9
+#define ANTAG_HUD_OPS 10
+#define ANTAG_HUD_WIZ 11
+#define ANTAG_HUD_SHADOW 12
+#define ANTAG_HUD_TRAITOR 13
+#define ANTAG_HUD_NINJA 14
+#define ANTAG_HUD_CHANGELING 15
+#define ANTAG_HUD_VAMPIRE 16
+#define ANTAG_HUD_ABDUCTOR 17
+#define DATA_HUD_ABDUCTOR 18
+#define ANTAG_HUD_DEVIL 19
+#define ANTAG_HUD_EVENTMISC 20
// Notification action types
#define NOTIFY_JUMP "jump"
diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm
index f8f9609aced..aa3652046b5 100644
--- a/code/__DEFINES/preferences.dm
+++ b/code/__DEFINES/preferences.dm
@@ -28,6 +28,9 @@
#define CHAT_NO_TICKETLOGS 65536
#define UI_DARKMODE 131072
#define DISABLE_KARMA 262144
+#define CHAT_NO_MENTORTICKETLOGS 524288
+
+#define TYPING_ONCE 1048576
#define TOGGLES_DEFAULT (CHAT_OOC|CHAT_DEAD|CHAT_GHOSTEARS|CHAT_GHOSTSIGHT|CHAT_PRAYER|CHAT_RADIO|CHAT_LOOC|MEMBER_PUBLIC|DONATOR_PUBLIC)
diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm
index 5b830a72b9f..dc2b2e4ec0a 100644
--- a/code/__HELPERS/global_lists.dm
+++ b/code/__HELPERS/global_lists.dm
@@ -28,7 +28,6 @@
init_datum_subtypes(/datum/job, GLOB.joblist, list(/datum/job/ai, /datum/job/cyborg), "title")
init_datum_subtypes(/datum/superheroes, GLOB.all_superheroes, null, "name")
- init_datum_subtypes(/datum/nations, GLOB.all_nations, null, "default_name")
init_datum_subtypes(/datum/language, GLOB.all_languages, null, "name")
for(var/language_name in GLOB.all_languages)
diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm
index 9dd3c870d51..5b639cc80f8 100644
--- a/code/__HELPERS/text.dm
+++ b/code/__HELPERS/text.dm
@@ -109,6 +109,15 @@
else
return trim(html_encode(name), max_length) //trim is "outside" because html_encode can expand single symbols into multiple symbols (such as turning < into <)
+// Uses client.typing to check if the popup should appear or not
+/proc/typing_input(mob/user, message = "", title = "", default = "")
+ if(user.client.checkTyping()) // Prevent double windows
+ return null
+ user.client.typing = TRUE
+ var/msg = input(user, message, title, default) as text|null
+ user.client.typing = FALSE
+ return msg
+
//Filters out undesirable characters from names
/proc/reject_bad_name(var/t_in, var/allow_numbers=0, var/max_length=MAX_NAME_LEN)
if(!t_in || length(t_in) > max_length)
diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm
index ff902473329..551b729028e 100644
--- a/code/_globalvars/lists/mobs.dm
+++ b/code/_globalvars/lists/mobs.dm
@@ -3,7 +3,6 @@ GLOBAL_LIST_EMPTY(all_species)
GLOBAL_LIST_EMPTY(all_languages)
GLOBAL_LIST_EMPTY(language_keys) // Table of say codes for all languages
GLOBAL_LIST_EMPTY(all_superheroes)
-GLOBAL_LIST_EMPTY(all_nations)
GLOBAL_LIST_INIT(whitelisted_species, list())
GLOBAL_LIST_INIT(clients, list()) //list of all clients
diff --git a/code/_onclick/click_override.dm b/code/_onclick/click_override.dm
index 7dfa8020cb8..fe2acfa3023 100644
--- a/code/_onclick/click_override.dm
+++ b/code/_onclick/click_override.dm
@@ -43,26 +43,50 @@
..()
/datum/middleClickOverride/power_gloves
- var/last_shocked = 0
- var/shock_delay = 120
-/datum/middleClickOverride/power_gloves/onClick(var/atom/A, var/mob/living/user)
+/datum/middleClickOverride/power_gloves/onClick(atom/A, mob/living/carbon/human/user)
+ if(A == user || user.a_intent == INTENT_HELP || user.a_intent == INTENT_GRAB)
+ return
if(user.incapacitated())
return
- if(world.time < last_shocked + shock_delay)
+ var/obj/item/clothing/gloves/color/yellow/power/P = user.gloves
+ if(world.time < P.last_shocked + P.shock_delay)
to_chat(user, "The gloves are still recharging.")
return
- if(!isliving(A))
- to_chat(user, "Shocking an inanimate object would be pointless.")
- return
- var/mob/living/L = A
var/turf/T = get_turf(user)
var/obj/structure/cable/C = locate() in T
- if(!C || !istype(C))
- to_chat(user, "There is no cable here to power the gloves.")
- return
- user.visible_message("[user.name] fires an arc of electricity at [L]!", "You fire an arc of electricity at [L]!", "You hear the loud crackle of electricity!")
- playsound(user.loc, 'sound/effects/eleczap.ogg', 75, 1)
- user.Beam(L,icon_state="lightning[rand(1,12)]",icon='icons/effects/effects.dmi',time=5)
- electrocute_mob(L, C, user)
- last_shocked = world.time
+ if(!P.unlimited_power)
+ if(!C || !istype(C))
+ to_chat(user, "There is no cable here to power the gloves.")
+ return
+ var/turf/target_turf = get_turf(A)
+ target_turf.hotspot_expose(2000, 400)
+ playsound(user.loc, 'sound/effects/eleczap.ogg', 40, 1)
+
+ var/atom/beam_from = user
+ var/atom/target_atom = A
+
+ for(var/i in 0 to 3)
+ beam_from.Beam(target_atom, icon_state = "lightning[rand(1, 12)]", icon = 'icons/effects/effects.dmi', time = 6)
+ if(isliving(target_atom))
+ var/mob/living/L = target_atom
+ if(user.a_intent == INTENT_DISARM)
+ L.Weaken(3)
+ else
+ if(P.unlimited_power)
+ L.electrocute_act(1000, P, 0) //Just kill them
+ else
+ electrocute_mob(L, C, P)
+ break
+ var/list/next_shocked = list()
+ for(var/atom/movable/AM in orange(3, target_atom))
+ if(AM == user || istype(AM, /obj/effect) || isobserver(AM))
+ continue
+ next_shocked.Add(AM)
+
+ beam_from = target_atom
+ target_atom = pick(next_shocked)
+ A = target_atom
+ next_shocked.Cut()
+
+ P.last_shocked = world.time
\ No newline at end of file
diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm
index 47036da9cf8..bed8c64b054 100644
--- a/code/_onclick/item_attack.dm
+++ b/code/_onclick/item_attack.dm
@@ -24,7 +24,7 @@
return FALSE
/obj/attackby(obj/item/I, mob/living/user, params)
- return ..() || (can_be_hit && isitem(I) && I.attack_obj(src, user))
+ return ..() || (can_be_hit && I.attack_obj(src, user))
/mob/living/attackby(obj/item/I, mob/living/user, params)
user.changeNext_move(CLICK_CD_MELEE)
@@ -37,8 +37,6 @@
SEND_SIGNAL(user, COMSIG_MOB_ITEM_ATTACK, M, user)
if(flags & (NOBLUDGEON))
return 0
- if(check_martial_counter(M, user))
- return 0
if(can_operate(M)) //Checks if mob is lying down on table for surgery
if(istype(src,/obj/item/robot_parts))//popup override for direct attach
if(!attempt_initiate_surgery(src, M, user,1))
diff --git a/code/controllers/subsystem/tickets/mentor_tickets.dm b/code/controllers/subsystem/tickets/mentor_tickets.dm
new file mode 100644
index 00000000000..708bc682634
--- /dev/null
+++ b/code/controllers/subsystem/tickets/mentor_tickets.dm
@@ -0,0 +1,21 @@
+GLOBAL_REAL(SSmentor_tickets, /datum/controller/subsystem/tickets/mentor_tickets)
+
+/datum/controller/subsystem/tickets/mentor_tickets/New()
+ NEW_SS_GLOBAL(SSmentor_tickets);
+ PreInit();
+
+/datum/controller/subsystem/tickets/mentor_tickets
+ name = "Mentor Tickets"
+ ticket_system_name = "Mentor Tickets"
+ ticket_name = "Mentor Ticket"
+ span_text = ""
+ close_rights = R_MENTOR
+
+/datum/controller/subsystem/tickets/mentor_tickets/message_staff(var/msg)
+ message_mentorTicket(msg)
+
+/datum/controller/subsystem/tickets/mentor_tickets/Initialize()
+ close_messages = list("- [ticket_name] Closed -",
+ "Please try to be as descriptive as possible in mentor helps. Mentors do not know the full situation you're in and need more information to give you a helpful response.",
+ "[span_text]Your [ticket_name] has now been closed.")
+ return ..()
diff --git a/code/controllers/subsystem/tickets.dm b/code/controllers/subsystem/tickets/tickets.dm
similarity index 57%
rename from code/controllers/subsystem/tickets.dm
rename to code/controllers/subsystem/tickets/tickets.dm
index b8b1f8410a0..99130025786 100644
--- a/code/controllers/subsystem/tickets.dm
+++ b/code/controllers/subsystem/tickets/tickets.dm
@@ -1,28 +1,36 @@
//Defines
//Deciseconds until ticket becomes stale if unanswered. Alerts admins.
-#define ADMIN_TICKET_TIMEOUT 6000 // 10 minutes
+#define TICKET_TIMEOUT 6000 // 10 minutes
//Decisecions before the user is allowed to open another ticket while their existing one is open.
-#define ADMIN_TICKET_DUPLICATE_COOLDOWN 3000 // 5 minutes
+#define TICKET_DUPLICATE_COOLDOWN 3000 // 5 minutes
//Status defines
-#define ADMIN_TICKET_OPEN 1
-#define ADMIN_TICKET_CLOSED 2
-#define ADMIN_TICKET_RESOLVED 3
-#define ADMIN_TICKET_STALE 4
+#define TICKET_OPEN 1
+#define TICKET_CLOSED 2
+#define TICKET_RESOLVED 3
+#define TICKET_STALE 4
SUBSYSTEM_DEF(tickets)
- name = "Tickets"
+ name = "Admin Tickets"
+ var/span_text = ""
+ var/ticket_system_name = "Admin Tickets"
+ var/ticket_name = "Admin Ticket"
+ var/close_rights = R_ADMIN
+ var/list/close_messages
init_order = INIT_ORDER_TICKETS
wait = 300
priority = FIRE_PRIORITY_TICKETS
-
+
flags = SS_BACKGROUND
-
+
var/list/allTickets
var/ticketCounter = 1
/datum/controller/subsystem/tickets/Initialize()
+ close_messages = list("- [ticket_name] Rejected! -",
+ "Please try to be calm, clear, and descriptive in admin helps, do not assume the staff member has seen any related events, and clearly state the names of anybody you are reporting. If you asked a question, please ensure it was clear what you were asking.",
+ "[span_text]Your [ticket_name] has now been closed.")
LAZYINITLIST(allTickets)
return ..()
@@ -32,7 +40,7 @@ SUBSYSTEM_DEF(tickets)
var/report
for(var/num in stales)
report += "[num], "
- message_adminTicket("Tickets [report] have been open for over [ADMIN_TICKET_TIMEOUT / 600] minutes. Changing status to stale.")
+ message_staff("[span_text]Tickets [report] have been open for over [TICKET_TIMEOUT / 600] minutes. Changing status to stale.")
/datum/controller/subsystem/tickets/stat_entry()
..("Tickets: [LAZYLEN(allTickets)]")
@@ -40,10 +48,10 @@ SUBSYSTEM_DEF(tickets)
/datum/controller/subsystem/tickets/proc/checkStaleness()
var/stales = list()
for(var/T in allTickets)
- var/datum/admin_ticket/ticket = T
- if(!(ticket.ticketState == ADMIN_TICKET_OPEN))
+ var/datum/ticket/ticket = T
+ if(!(ticket.ticketState == TICKET_OPEN))
continue
- if(world.time > ticket.timeUntilStale && (!ticket.lastAdminResponse || !ticket.adminAssigned))
+ if(world.time > ticket.timeUntilStale && (!ticket.lastStaffResponse || !ticket.staffAssigned))
var/id = ticket.makeStale()
stales += id
return stales
@@ -60,7 +68,7 @@ SUBSYSTEM_DEF(tickets)
/datum/controller/subsystem/tickets/proc/resolveAllOpenTickets() // Resolve all open tickets
for(var/i in allTickets)
- var/datum/admin_ticket/T = i
+ var/datum/ticket/T = i
resolveTicket(T.ticketNum)
//Open a new ticket and populate details then add to the list of open tickets
@@ -69,56 +77,57 @@ SUBSYSTEM_DEF(tickets)
return
//Check if the user has an open ticket already within the cooldown period, if so we don't create a new one and re-set the cooldown period
- var/datum/admin_ticket/existingTicket = checkForOpenTicket(C)
+ var/datum/ticket/existingTicket = checkForOpenTicket(C)
if(existingTicket)
existingTicket.setCooldownPeriod()
- to_chat(C.mob, "Your ticket #[existingTicket.ticketNum] remains open! Visit \"My tickets\" under the Admin Tab to view it.")
+ to_chat(C.mob, "[span_text]Your [ticket_name] #[existingTicket.ticketNum] remains open! Visit \"My tickets\" under the Admin Tab to view it.")
return
if(!title)
title = passedContent
- var/datum/admin_ticket/T = new(title, passedContent)
+ var/datum/ticket/T = new(title, passedContent, getTicketCounterAndInc())
+ allTickets += T
T.clientName = C
T.locationSent = C.mob.loc.name
T.mobControlled = C.mob
//Inform the user that they have opened a ticket
- to_chat(C, "You have opened admin ticket number #[(SStickets.getTicketCounter() - 1)]! Please be patient and we will help you soon!")
+ to_chat(C, "[span_text]You have opened [ticket_name] number #[(getTicketCounter() - 1)]! Please be patient and we will help you soon!")
//Set ticket state with key N to open
/datum/controller/subsystem/tickets/proc/openTicket(N)
- var/datum/admin_ticket/T = SStickets.allTickets[N]
- if(T.ticketState != ADMIN_TICKET_OPEN)
- T.ticketState = ADMIN_TICKET_OPEN
+ var/datum/ticket/T = allTickets[N]
+ if(T.ticketState != TICKET_OPEN)
+ T.ticketState = TICKET_OPEN
return TRUE
//Set ticket state with key N to resolved
/datum/controller/subsystem/tickets/proc/resolveTicket(N)
- var/datum/admin_ticket/T = SStickets.allTickets[N]
- if(T.ticketState != ADMIN_TICKET_RESOLVED)
- T.ticketState = ADMIN_TICKET_RESOLVED
+ var/datum/ticket/T = allTickets[N]
+ if(T.ticketState != TICKET_RESOLVED)
+ T.ticketState = TICKET_RESOLVED
return TRUE
//Set ticket state with key N to closed
/datum/controller/subsystem/tickets/proc/closeTicket(N)
- var/datum/admin_ticket/T = SStickets.allTickets[N]
- if(T.ticketState != ADMIN_TICKET_CLOSED)
- T.ticketState = ADMIN_TICKET_CLOSED
+ var/datum/ticket/T = allTickets[N]
+ if(T.ticketState != TICKET_CLOSED)
+ T.ticketState = TICKET_CLOSED
return TRUE
//Check if the user already has a ticket open and within the cooldown period.
/datum/controller/subsystem/tickets/proc/checkForOpenTicket(client/C)
- for(var/datum/admin_ticket/T in allTickets)
- if(T.clientName == C && T.ticketState == ADMIN_TICKET_OPEN && (T.ticketCooldown > world.time))
+ for(var/datum/ticket/T in allTickets)
+ if(T.clientName == C && T.ticketState == TICKET_OPEN && (T.ticketCooldown > world.time))
return T
return FALSE
//Check if the user has ANY ticket not resolved or closed.
/datum/controller/subsystem/tickets/proc/checkForTicket(client/C)
var/list/tickets = list()
- for(var/datum/admin_ticket/T in allTickets)
- if(T.clientName == C && (T.ticketState == ADMIN_TICKET_OPEN || T.ticketState == ADMIN_TICKET_STALE))
+ for(var/datum/ticket/T in allTickets)
+ if(T.clientName == C && (T.ticketState == TICKET_OPEN || T.ticketState == TICKET_STALE))
tickets += T
if(tickets.len)
return tickets
@@ -126,78 +135,77 @@ SUBSYSTEM_DEF(tickets)
//return the client of a ticket number
/datum/controller/subsystem/tickets/proc/returnClient(N)
- var/datum/admin_ticket/T = SStickets.allTickets[N]
+ var/datum/ticket/T = allTickets[N]
return T.clientName
-/datum/controller/subsystem/tickets/proc/assignAdminToTicket(client/C, var/N)
- var/datum/admin_ticket/T = SStickets.allTickets[N]
- T.assignAdmin(C)
+/datum/controller/subsystem/tickets/proc/assignStaffToTicket(client/C, var/N)
+ var/datum/ticket/T = allTickets[N]
+ T.assignStaff(C)
return TRUE
-//Single admin ticket
+//Single staff ticket
-/datum/admin_ticket
+/datum/ticket
var/ticketNum // Ticket number
var/clientName // Client which opened the ticket
var/timeOpened // Time the ticket was opened
var/title //The initial message with links
- var/list/content // content of the admin help
- var/lastAdminResponse // Last admin who responded
- var/lastResponseTime // When the admin last responded
+ var/list/content // content of the staff help
+ var/lastStaffResponse // Last staff member who responded
+ var/lastResponseTime // When the staff last responded
var/locationSent // Location the player was when they send the ticket
var/mobControlled // Mob they were controlling
var/ticketState // State of the ticket, open, closed, resolved etc
var/timeUntilStale // When the ticket goes stale
var/ticketCooldown // Cooldown before allowing the user to open another ticket.
- var/adminAssigned // Admin who has assigned themselves to this ticket
+ var/staffAssigned // Staff member who has assigned themselves to this ticket
-/datum/admin_ticket/New(tit, cont)
+/datum/ticket/New(tit, cont, num)
title = tit
content = list()
content += cont
timeOpened = worldtime2text()
- timeUntilStale = world.time + ADMIN_TICKET_TIMEOUT
+ timeUntilStale = world.time + TICKET_TIMEOUT
setCooldownPeriod()
- ticketNum = SStickets.getTicketCounterAndInc()
- ticketState = ADMIN_TICKET_OPEN
- SStickets.allTickets += src
+ ticketNum = num
+ ticketState = TICKET_OPEN
//Set the cooldown period for the ticket. The time when it's created plus the defined cooldown time.
-/datum/admin_ticket/proc/setCooldownPeriod()
- ticketCooldown = world.time + ADMIN_TICKET_DUPLICATE_COOLDOWN
+/datum/ticket/proc/setCooldownPeriod()
+ ticketCooldown = world.time + TICKET_DUPLICATE_COOLDOWN
-//Set the last admin who responded as the client passed as an arguement.
-/datum/admin_ticket/proc/setLastAdminResponse(client/C)
- lastAdminResponse = C
+//Set the last staff who responded as the client passed as an arguement.
+/datum/ticket/proc/setLastStaffResponse(client/C)
+ lastStaffResponse = C
lastResponseTime = worldtime2text()
//Return the ticket state as a colour coded text string.
-/datum/admin_ticket/proc/state2text()
+/datum/ticket/proc/state2text()
switch(ticketState)
- if(ADMIN_TICKET_OPEN)
+ if(TICKET_OPEN)
return "OPEN"
- if(ADMIN_TICKET_RESOLVED)
+ if(TICKET_RESOLVED)
return "RESOLVED"
- if(ADMIN_TICKET_CLOSED)
+ if(TICKET_CLOSED)
return "CLOSED"
- if(ADMIN_TICKET_STALE)
+ if(TICKET_STALE)
return "STALE"
-//Assign the client passed to var/adminAsssigned
-/datum/admin_ticket/proc/assignAdmin(client/C)
+//Assign the client passed to var/staffAsssigned
+/datum/ticket/proc/assignStaff(client/C)
if(!C)
return
- adminAssigned = C
+ staffAssigned = C
return TRUE
-/datum/admin_ticket/proc/addResponse(client/C, msg)
+/datum/ticket/proc/addResponse(client/C, msg)
if(C.holder)
- setLastAdminResponse(C)
+ setLastStaffResponse(C)
msg = "[C]: [msg]"
content += msg
-/datum/admin_ticket/proc/makeStale()
- ticketState = ADMIN_TICKET_STALE
+/datum/ticket/proc/makeStale()
+ ticketState = TICKET_STALE
return ticketNum
/*
@@ -206,7 +214,7 @@ UI STUFF
*/
-/datum/controller/subsystem/tickets/proc/returnUI(tab = ADMIN_TICKET_OPEN)
+/datum/controller/subsystem/tickets/proc/returnUI(tab = TICKET_OPEN)
set name = "Open Ticket Interface"
set category = "Tickets"
@@ -214,36 +222,36 @@ UI STUFF
var/trStyle = "border-top:2px solid; border-bottom:2px solid; padding-top: 5px; padding-bottom: 5px;"
var/tdStyleleft = "border-top:2px solid; border-bottom:2px solid; width:150px; text-align:center;"
var/tdStyle = "border-top:2px solid; border-bottom:2px solid;"
- var/datum/admin_ticket/ticket
+ var/datum/ticket/ticket
var/dat
dat += "
"
- dat += "Admin Tickets
"
+ dat += "[ticket_system_name]
"
dat +="Refresh
Open TicketsResolved TicketsClosed Tickets"
- if(tab == ADMIN_TICKET_OPEN)
+ if(tab == TICKET_OPEN)
dat += "Open Tickets
"
dat += ""
dat +="| Control | Ticket |
"
- if(tab == ADMIN_TICKET_OPEN)
+ if(tab == TICKET_OPEN)
for(var/T in allTickets)
ticket = T
- if(ticket.ticketState == ADMIN_TICKET_OPEN || ticket.ticketState == ADMIN_TICKET_STALE)
- dat += "ResolveDetails #[ticket.ticketNum] ([ticket.timeOpened]) [ticket.ticketState == ADMIN_TICKET_STALE ? "STALE" : ""] | [ticket.title] |
"
+ if(ticket.ticketState == TICKET_OPEN || ticket.ticketState == TICKET_STALE)
+ dat += "ResolveDetails #[ticket.ticketNum] ([ticket.timeOpened]) [ticket.ticketState == TICKET_STALE ? "STALE" : ""] | [ticket.title] |
"
else
continue
- else if(tab == ADMIN_TICKET_RESOLVED)
+ else if(tab == TICKET_RESOLVED)
dat += "Resolved Tickets
"
for(var/T in allTickets)
ticket = T
- if(ticket.ticketState == ADMIN_TICKET_RESOLVED)
+ if(ticket.ticketState == TICKET_RESOLVED)
dat += "ResolveDetails #[ticket.ticketNum] ([ticket.timeOpened]) | [ticket.title] |
"
else
continue
- else if(tab == ADMIN_TICKET_CLOSED)
+ else if(tab == TICKET_CLOSED)
dat += "Closed Tickets
"
for(var/T in allTickets)
ticket = T
- if(ticket.ticketState == ADMIN_TICKET_CLOSED)
+ if(ticket.ticketState == TICKET_CLOSED)
dat += "ResolveDetails #[ticket.ticketNum] ([ticket.timeOpened]) | [ticket.title] |
"
else
continue
@@ -255,21 +263,21 @@ UI STUFF
/datum/controller/subsystem/tickets/proc/showUI(mob/user, tab)
var/dat = null
dat = returnUI(tab)
- var/datum/browser/popup = new(user, "admintickets", "Admin Tickets", 1400, 600)
+ var/datum/browser/popup = new(user, ticket_system_name, ticket_system_name, 1400, 600)
popup.set_content(dat)
popup.open()
/datum/controller/subsystem/tickets/proc/showDetailUI(mob/user, ticketID)
- var/datum/admin_ticket/T = SStickets.allTickets[ticketID]
+ var/datum/ticket/T = allTickets[ticketID]
var/status = "[T.state2text()]"
- var/dat = "Admin Tickets
"
+ var/dat = "[ticket_system_name]
"
dat +="Show AllRefresh"
dat += "Ticket #[T.ticketNum]
"
- dat += "[T.clientName] / [T.mobControlled] opened this ticket at [T.timeOpened] at location [T.locationSent]
"
+ dat += "[T.clientName] / [T.mobControlled] opened this [ticket_name] at [T.timeOpened] at location [T.locationSent]
"
dat += "Ticket Status: [status]"
dat += "
"
dat += "| [T.title] |
"
@@ -281,21 +289,21 @@ UI STUFF
dat += "
"
dat += "Re-OpenResolve
"
- if(!T.adminAssigned)
- dat += "No admin assigned to this ticket - Take Ticket
"
+ if(!T.staffAssigned)
+ dat += "No staff member assigned to this [ticket_name] - Take Ticket
"
else
- dat += "[T.adminAssigned] is assigned to this Ticket. - Take Ticket
"
+ dat += "[T.staffAssigned] is assigned to this Ticket. - Take Ticket
"
- if(T.lastAdminResponse)
- dat += "Last Admin Response: [T.lastAdminResponse] at [T.lastResponseTime]"
+ if(T.lastStaffResponse)
+ dat += "Last Staff response Response: [T.lastStaffResponse] at [T.lastResponseTime]"
else
- dat +="No Admin Response"
+ dat +="No Staff Response"
dat += "
"
dat += "Close Ticket"
- var/datum/browser/popup = new(user, "adminticketsdetail", "Admin Ticket #[T.ticketNum]", 1000, 600)
+ var/datum/browser/popup = new(user, "[ticket_system_name]detail", "[ticket_system_name] #[T.ticketNum]", 1000, 600)
popup.set_content(dat)
popup.open()
@@ -303,15 +311,15 @@ UI STUFF
//dat
var/tickets = checkForTicket(user.client)
var/dat
- dat += "Your open tickets
"
+ dat += "Your open [ticket_system_name]
"
dat += ""
- for(var/datum/admin_ticket/T in tickets)
+ for(var/datum/ticket/T in tickets)
dat += "Ticket #[T.ticketNum] |
"
for(var/i = 1, i <= T.content.len, i++)
dat += "| [T.content[i]] |
"
dat += "
"
- var/datum/browser/popup = new(user, "userticketsdetail", "Tickets", 1000, 600)
+ var/datum/browser/popup = new(user, "[ticket_system_name]userticketsdetail", ticket_system_name, 1000, 600)
popup.set_content(dat)
popup.open()
@@ -326,6 +334,10 @@ UI STUFF
to_chat(target, text)
return TRUE
+//Sends a message to the designated staff
+/datum/controller/subsystem/tickets/proc/message_staff(var/msg)
+ message_adminTicket(msg)
+
/datum/controller/subsystem/tickets/Topic(href, href_list)
if(href_list["refresh"])
@@ -338,13 +350,13 @@ UI STUFF
return
if(href_list["showopen"])
- showUI(usr, ADMIN_TICKET_OPEN)
+ showUI(usr, TICKET_OPEN)
return
if(href_list["showresolved"])
- showUI(usr, ADMIN_TICKET_RESOLVED)
+ showUI(usr, TICKET_RESOLVED)
return
if(href_list["showclosed"])
- showUI(usr, ADMIN_TICKET_CLOSED)
+ showUI(usr, TICKET_CLOSED)
return
if(href_list["details"])
@@ -354,40 +366,43 @@ UI STUFF
if(href_list["resolve"])
var/indexNum = text2num(href_list["resolve"])
- if(SStickets.resolveTicket(indexNum))
- message_adminTicket("[usr.client] / ([usr]) resolved admin ticket number [indexNum]")
- to_chat_safe(returnClient(indexNum), "Your admin ticket has now been resolved.")
+ if(resolveTicket(indexNum))
+ message_staff("[usr.client] / ([usr]) resolved [ticket_name] number [indexNum]")
+ to_chat_safe(returnClient(indexNum), "[span_text]Your [ticket_name] has now been resolved.")
showUI(usr)
if(href_list["detailresolve"])
var/indexNum = text2num(href_list["detailresolve"])
- if(SStickets.resolveTicket(indexNum))
- message_adminTicket("[usr.client] / ([usr]) resolved admin ticket number [indexNum]")
- to_chat_safe(returnClient(indexNum), "Your admin ticket has now been resolved.")
+ if(resolveTicket(indexNum))
+ message_staff("[usr.client] / ([usr]) resolved [ticket_name] number [indexNum]")
+ to_chat_safe(returnClient(indexNum), "[span_text]Your [ticket_name] has now been resolved.")
showDetailUI(usr, indexNum)
if(href_list["detailclose"])
var/indexNum = text2num(href_list["detailclose"])
+ if(!check_rights(close_rights))
+ to_chat(usr, "Not enough rights to close this ticket.")
+ return
if(alert("Are you sure? This will send a negative message.",,"Yes","No") != "Yes")
return
- if(SStickets.closeTicket(indexNum))
- message_adminTicket("[usr.client] / ([usr]) closed admin ticket number [indexNum]")
- to_chat_safe(returnClient(indexNum), list(
- "- AdminHelp Rejected! -",
- "Please try to be calm, clear, and descriptive in admin helps, do not assume the admin has seen any related events, and clearly state the names of anybody you are reporting. If you asked a question, please ensure it was clear what you were asking.",
- "Your ticket has now been closed."
- ))
+ if(closeTicket(indexNum))
+ message_staff("[usr.client] / ([usr]) closed [ticket_name] number [indexNum]")
+ to_chat_safe(returnClient(indexNum), close_messages)
showDetailUI(usr, indexNum)
+
if(href_list["detailreopen"])
var/indexNum = text2num(href_list["detailreopen"])
- if(SStickets.openTicket(indexNum))
- message_adminTicket("[usr.client] / ([usr]) re-opened admin ticket number [indexNum]")
+ if(openTicket(indexNum))
+ message_staff("[usr.client] / ([usr]) re-opened [ticket_name] number [indexNum]")
showDetailUI(usr, indexNum)
- if(href_list["assignadmin"])
- var/indexNum = text2num(href_list["assignadmin"])
- if(SStickets.assignAdminToTicket(usr.client, indexNum))
- message_adminTicket("[usr.client] / ([usr]) has taken ticket number [indexNum]")
- to_chat_safe(returnClient(indexNum), "Your ticket is being handled by [usr.client].")
+ if(href_list["assignstaff"])
+ var/indexNum = text2num(href_list["assignstaff"])
+ takeTicket(indexNum)
showDetailUI(usr, indexNum)
+
+/datum/controller/subsystem/tickets/proc/takeTicket(var/index)
+ if(assignStaffToTicket(usr.client, index))
+ message_staff("[usr.client] / ([usr]) has taken [ticket_name] number [index]")
+ to_chat_safe(returnClient(index), "[span_text]Your [ticket_name] is being handled by [usr.client].")
diff --git a/code/datums/action.dm b/code/datums/action.dm
index 0fb6276944a..446511c1ee6 100644
--- a/code/datums/action.dm
+++ b/code/datums/action.dm
@@ -23,6 +23,8 @@
button = new
button.linked_action = src
button.name = name
+ if(desc)
+ button.desc = desc
/datum/action/Destroy()
if(owner)
@@ -82,6 +84,7 @@
if(button)
button.icon = button_icon
button.icon_state = background_icon_state
+ button.desc = desc
ApplyIcon(button)
@@ -441,6 +444,7 @@
var/obj/effect/proc_holder/spell/S = target
S.action = src
name = S.name
+ desc = S.desc
button_icon = S.action_icon
button_icon_state = S.action_icon_state
background_icon_state = S.action_background_icon_state
diff --git a/code/datums/helper_datums/hotkey_modes.dm b/code/datums/helper_datums/hotkey_modes.dm
new file mode 100644
index 00000000000..39254b23485
--- /dev/null
+++ b/code/datums/helper_datums/hotkey_modes.dm
@@ -0,0 +1,27 @@
+/datum/hotkey_mode
+ var/name
+ var/macro_hotkeys_inactive
+ var/macro_hotkeys_active
+ var/mob/my_mob
+
+/datum/hotkey_mode/New(mob)
+ my_mob = mob
+
+/datum/hotkey_mode/proc/set_winset_values()
+ winset(my_mob, null, "mainwindow.macro=[macro_hotkeys_inactive] hotkey_toggle.is-checked=false input.focus=true input.background-color=#d3b5b5")
+ winset(my_mob, null, "hotkey_toggle.command=\".winset \\\"mainwindow.macro != [macro_hotkeys_inactive] ? mainwindow.macro=[macro_hotkeys_inactive] hotkey_toggle.is-checked=false input.focus=true input.background-color=#d3b5b5 : mainwindow.macro=[macro_hotkeys_active] hotkey_toggle.is-checked=true mapwindow.map.focus=true input.background-color=#f0f0f0\\\"\"")
+
+/datum/hotkey_mode/qwerty
+ name = "QWERTY"
+ macro_hotkeys_inactive = "macro"
+ macro_hotkeys_active = "hotkeymode"
+
+/datum/hotkey_mode/azerty
+ name = "AZERTY"
+ macro_hotkeys_inactive = "azertymacro"
+ macro_hotkeys_active = "azertyhotkeymode"
+
+/datum/hotkey_mode/cyborg
+ name = "Cyborg"
+ macro_hotkeys_inactive = "borgmacro"
+ macro_hotkeys_active = "borghotkeymode"
\ No newline at end of file
diff --git a/code/datums/hud.dm b/code/datums/hud.dm
index ac3249f9c5f..2dd2d72a816 100644
--- a/code/datums/hud.dm
+++ b/code/datums/hud.dm
@@ -10,7 +10,6 @@ var/datum/atom_hud/huds = list( \
DATA_HUD_DIAGNOSTIC = new/datum/atom_hud/data/diagnostic(), \
DATA_HUD_DIAGNOSTIC_ADVANCED = new/datum/atom_hud/data/diagnostic/advanced(), \
DATA_HUD_HYDROPONIC = new/datum/atom_hud/data/hydroponic(), \
- GAME_HUD_NATIONS = new/datum/atom_hud/antag(), \
ANTAG_HUD_CULT = new/datum/atom_hud/antag(), \
ANTAG_HUD_REV = new/datum/atom_hud/antag(), \
ANTAG_HUD_OPS = new/datum/atom_hud/antag(), \
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 556e74179da..70d16300b83 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -51,7 +51,6 @@
var/datum/changeling/changeling //changeling holder
var/linglink
var/datum/vampire/vampire //vampire holder
- var/datum/nations/nation //nation holder
var/datum/abductor/abductor //abductor holder
var/datum/devilinfo/devilinfo //devil holder
diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm
index 9278d0d5f80..390829f7aa3 100644
--- a/code/datums/uplink_item.dm
+++ b/code/datums/uplink_item.dm
@@ -88,7 +88,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
/datum/uplink_item/proc/spawn_item(var/turf/loc, var/obj/item/uplink/U)
- if(hijack_only)
+ if(hijack_only && !(usr.mind.special_role == SPECIAL_ROLE_NUKEOPS))//nukies get items that regular traitors only get with hijack. If a hijack-only item is not for nukies, then exclude it via the gamemode list.
if(!(locate(/datum/objective/hijack) in usr.mind.objectives))
to_chat(usr, "The Syndicate will only issue this extremely dangerous item to agents assigned the Hijack objective.")
return
@@ -186,7 +186,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
name = "Trick Revolver"
desc = "A revolver that will fire backwards and kill whoever attempts to use it. Perfect for those pesky vigilante or just a good laugh."
reference = "CTR"
- item = /obj/item/toy/russian_revolver/trick_revolver
+ item = /obj/item/storage/box/syndie_kit/fake_revolver
cost = 1
job = list("Clown")
@@ -813,7 +813,9 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
desc = "A manual that teaches a single user tactical Close-Quarters Combat before self-destructing. Does not restrict weapon usage, but cannot be used alongside Gloves of the North Star."
reference = "CQC"
item = /obj/item/CQC_manual
- cost = 9
+ gamemodes = list(/datum/game_mode/nuclear)
+ cost = 13
+ surplus = 0
/datum/uplink_item/stealthy_weapons/cameraflash
name = "Camera Flash"
@@ -893,7 +895,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
desc = "Just add water to make your very own hostile to everything space carp. It looks just like a plushie. The first person to squeeze it will be registered as its owner, who it will not attack. If no owner is registered, it'll just attack everyone."
reference = "DSC"
item = /obj/item/toy/carpplushie/dehy_carp
- cost = 3
+ cost = 2
// GRENADES AND EXPLOSIVES
@@ -1330,13 +1332,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
surplus = 0
hijack_only = TRUE //This is an item only useful for a hijack traitor, as such, it should only be available in those scenarios.
cant_discount = TRUE
- excludefrom = list(/datum/game_mode/nuclear)
-
-/datum/uplink_item/device_tools/singularity_beacon/nuke
- reference = "SNGBN"
- hijack_only = FALSE // This inherited version exists so nukies can use it while keeping the original hijack only
- excludefrom = list()
- gamemodes = list(/datum/game_mode/nuclear)
/datum/uplink_item/device_tools/syndicate_detonator
name = "Syndicate Detonator"
diff --git a/code/game/gamemodes/blob/blobs/core.dm b/code/game/gamemodes/blob/blobs/core.dm
index b0dc48aba93..1e1841bd1b1 100644
--- a/code/game/gamemodes/blob/blobs/core.dm
+++ b/code/game/gamemodes/blob/blobs/core.dm
@@ -82,7 +82,7 @@
continue
var/obj/structure/blob/normal/B = locate() in get_step(src, b_dir)
if(B)
- B.change_to(/obj/structure/blob/shield)
+ B.change_to(/obj/structure/blob/shield/core)
if(B && overmind)
B.color = overmind.blob_reagent_datum.color
else
diff --git a/code/game/gamemodes/blob/blobs/shield.dm b/code/game/gamemodes/blob/blobs/shield.dm
index 8d13625acb9..2dd6a3d7c5b 100644
--- a/code/game/gamemodes/blob/blobs/shield.dm
+++ b/code/game/gamemodes/blob/blobs/shield.dm
@@ -8,6 +8,9 @@
point_return = 4
var/maxHealth = 75
+/obj/structure/blob/shield/core
+ point_return = 0
+
/obj/structure/blob/shield/update_icon()
if(health <= 0)
qdel(src)
diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm
index 45f2f2853bc..4098dca5f71 100644
--- a/code/game/gamemodes/cult/cult_items.dm
+++ b/code/game/gamemodes/cult/cult_items.dm
@@ -367,9 +367,19 @@
/obj/item/clothing/head/culthood/alt/ghost
flags = NODROP | DROPDEL
-/obj/item/clothing/suit/cultrobes/alt/ghost
+/obj/item/clothing/suit/cultrobesghost
+ name = "ghostly cult robes"
+ desc = "A set of ethreal armored robes worn by the undead followers of a cult."
+ icon_state = "cultrobesalt"
+ item_state = "cultrobesalt"
+ body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
+ allowed = list(/obj/item/tome,/obj/item/melee/cultblade)
+ armor = list(melee = 50, bullet = 30, laser = 50, energy = 20, bomb = 25, bio = 10, rad = 0)
+ flags_inv = HIDEJUMPSUIT
+
flags = NODROP | DROPDEL
+
/obj/item/clothing/shoes/cult/ghost
flags = NODROP | DROPDEL
@@ -377,7 +387,7 @@
name = "Cultist Ghost"
uniform = /obj/item/clothing/under/color/black
- suit = /obj/item/clothing/suit/cultrobes/alt/ghost
+ suit = /obj/item/clothing/suit/cultrobesghost
shoes = /obj/item/clothing/shoes/cult/ghost
head = /obj/item/clothing/head/culthood/alt/ghost
r_hand = /obj/item/melee/cultblade/ghost
\ No newline at end of file
diff --git a/code/game/gamemodes/miniantags/guardian/guardian.dm b/code/game/gamemodes/miniantags/guardian/guardian.dm
index cee4d92008a..2b6040ed8b6 100644
--- a/code/game/gamemodes/miniantags/guardian/guardian.dm
+++ b/code/game/gamemodes/miniantags/guardian/guardian.dm
@@ -12,6 +12,7 @@
icon_dead = "magicOrange"
speed = 0
a_intent = INTENT_HARM
+ can_change_intents = 0
stop_automated_movement = 1
floating = 1
attack_sound = 'sound/weapons/punch1.ogg'
@@ -85,6 +86,18 @@
forceMove(summoner.loc) //move to summoner's tile, don't recall
new /obj/effect/temp_visual/guardian/phase(loc)
+/mob/living/simple_animal/hostile/guardian/proc/is_deployed()
+ return loc != summoner
+
+/mob/living/simple_animal/hostile/guardian/AttackingTarget()
+ if(!is_deployed() && a_intent == INTENT_HARM)
+ to_chat(src, "You must be manifested to attack!")
+ return FALSE
+ else if(!is_deployed() && a_intent == INTENT_HELP)
+ return FALSE
+ else
+ return ..()
+
/mob/living/simple_animal/hostile/guardian/Move() //Returns to summoner if they move out of range
..()
snapback()
@@ -149,11 +162,12 @@
if(!summoner) return
if(loc == summoner)
forceMove(get_turf(summoner))
+ new /obj/effect/temp_visual/guardian/phase(loc)
src.client.eye = loc
cooldown = world.time + 30
/mob/living/simple_animal/hostile/guardian/proc/Recall(forced = FALSE)
- if(cooldown > world.time && !forced)
+ if(!summoner || loc == summoner || (cooldown > world.time && !forced))
return
if(!summoner) return
new /obj/effect/temp_visual/guardian/phase/out(get_turf(src))
diff --git a/code/game/gamemodes/miniantags/guardian/types/bomb.dm b/code/game/gamemodes/miniantags/guardian/types/bomb.dm
index 2908888839a..fbe4458693f 100644
--- a/code/game/gamemodes/miniantags/guardian/types/bomb.dm
+++ b/code/game/gamemodes/miniantags/guardian/types/bomb.dm
@@ -8,6 +8,13 @@
tech_fluff_string = "Boot sequence complete. Explosive modules active. Holoparasite swarm online."
bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, capable of stealthily booby trapping items."
var/bomb_cooldown = 0
+ var/default_bomb_cooldown = 20 SECONDS
+
+/mob/living/simple_animal/hostile/guardian/bomb/Stat()
+ ..()
+ if(statpanel("Status"))
+ if(bomb_cooldown >= world.time)
+ stat(null, "Bomb Cooldown Remaining: [max(round((bomb_cooldown - world.time)*0.1, 0.1), 0)] seconds")
/mob/living/simple_animal/hostile/guardian/bomb/AltClickOn(atom/movable/A)
if(!istype(A))
@@ -21,11 +28,11 @@
to_chat(src, "Success! Bomb on [A] armed!")
if(summoner)
to_chat(summoner, "Your guardian has primed [A] to explode!")
- bomb_cooldown = world.time + 200
+ bomb_cooldown = world.time + default_bomb_cooldown
B.spawner = src
B.disguise (A)
else
- to_chat(src, "Your powers are on cooldown! You must wait 20 seconds between bombs.")
+ to_chat(src, "Your power is on cooldown! You must wait another [max(round((bomb_cooldown - world.time)*0.1, 0.1), 0)] seconds before you can place next bomb.")
/obj/item/guardian_bomb
name = "bomb"
diff --git a/code/game/gamemodes/miniantags/guardian/types/fire.dm b/code/game/gamemodes/miniantags/guardian/types/fire.dm
index f10a94793b5..58f4873e800 100644
--- a/code/game/gamemodes/miniantags/guardian/types/fire.dm
+++ b/code/game/gamemodes/miniantags/guardian/types/fire.dm
@@ -1,5 +1,4 @@
/mob/living/simple_animal/hostile/guardian/fire
- a_intent = INTENT_HELP
melee_damage_lower = 10
melee_damage_upper = 10
attack_sound = 'sound/items/welder.ogg'
diff --git a/code/game/gamemodes/miniantags/guardian/types/healer.dm b/code/game/gamemodes/miniantags/guardian/types/healer.dm
index 6c784e1ee0a..d9be543f7e2 100644
--- a/code/game/gamemodes/miniantags/guardian/types/healer.dm
+++ b/code/game/gamemodes/miniantags/guardian/types/healer.dm
@@ -1,5 +1,4 @@
/mob/living/simple_animal/hostile/guardian/healer
- a_intent = INTENT_HARM
friendly = "heals"
speed = 0
melee_damage_lower = 15
@@ -10,6 +9,7 @@
bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, capable of mending wounds and travelling via bluespace."
var/turf/simulated/floor/beacon
var/beacon_cooldown = 0
+ var/default_beacon_cooldown = 300 SECONDS
var/toggle = FALSE
var/heal_cooldown = 0
@@ -21,7 +21,6 @@
icon_state = "seal"
attacktext = "slaps"
speak_emote = list("barks")
- a_intent = INTENT_HARM
friendly = "heals"
speed = 0
melee_damage_lower = 0
@@ -37,6 +36,12 @@
var/datum/atom_hud/medsensor = huds[DATA_HUD_MEDICAL_ADVANCED]
medsensor.add_hud_to(src)
+/mob/living/simple_animal/hostile/guardian/healer/Stat()
+ ..()
+ if(statpanel("Status"))
+ if(beacon_cooldown >= world.time)
+ stat(null, "Bluespace Beacon Cooldown Remaining: [max(round((beacon_cooldown - world.time)*0.1, 0.1), 0)] seconds")
+
/mob/living/simple_animal/hostile/guardian/healer/AttackingTarget()
..()
if(toggle == TRUE)
@@ -60,6 +65,7 @@
if(loc == summoner)
if(toggle)
a_intent = INTENT_HARM
+ hud_used.action_intent.icon_state = a_intent;
speed = 0
damage_transfer = 0.7
if(adminseal)
@@ -70,6 +76,7 @@
toggle = FALSE
else
a_intent = INTENT_HELP
+ hud_used.action_intent.icon_state = a_intent;
speed = 1
damage_transfer = 1
if(adminseal)
@@ -81,9 +88,8 @@
else
to_chat(src, "You have to be recalled to toggle modes!")
-
/mob/living/simple_animal/hostile/guardian/healer/verb/Beacon()
- set name = "Place Bluespsace Beacon"
+ set name = "Place Bluespace Beacon"
set category = "Guardian"
set desc = "Mark a floor as your beacon point, allowing you to warp targets to it. Your beacon will not work in unfavorable atmospheric conditions."
if(beacon_cooldown < world.time)
@@ -98,10 +104,10 @@
if(beacon)
beacon.ChangeTurf(/turf/simulated/floor/plating)
beacon = F
- beacon_cooldown = world.time+3000
+ beacon_cooldown = world.time + default_beacon_cooldown
else
- to_chat(src, "Your power is on cooldown. You must wait five minutes between placing beacons.")
+ to_chat(src, "Your power is on cooldown! You must wait another [max(round((beacon_cooldown - world.time)*0.1, 0.1), 0)] seconds before you can place another beacon.")
/mob/living/simple_animal/hostile/guardian/healer/AltClickOn(atom/movable/A)
if(!istype(A))
diff --git a/code/game/gamemodes/miniantags/guardian/types/ranged.dm b/code/game/gamemodes/miniantags/guardian/types/ranged.dm
index 695782728fa..0979ed45a6c 100644
--- a/code/game/gamemodes/miniantags/guardian/types/ranged.dm
+++ b/code/game/gamemodes/miniantags/guardian/types/ranged.dm
@@ -6,7 +6,6 @@
armour_penetration = 100
/mob/living/simple_animal/hostile/guardian/ranged
- a_intent = INTENT_HELP
friendly = "quietly assesses"
melee_damage_lower = 10
melee_damage_upper = 10
diff --git a/code/game/gamemodes/nations/nations.dm b/code/game/gamemodes/nations/nations.dm
deleted file mode 100644
index c8a9ad00a62..00000000000
--- a/code/game/gamemodes/nations/nations.dm
+++ /dev/null
@@ -1,256 +0,0 @@
-datum/game_mode/nations
- name = "nations"
- config_tag = "nations"
- required_players = 25
- var/kickoff = 0
- var/victory = 0
- var/list/cargonians = list("Quartermaster","Cargo Technician","Shaft Miner")
- var/list/servicion = list("Clown", "Mime", "Bartender", "Chef", "Botanist", "Librarian", "Chaplain", "Barber")
-
-
-/datum/game_mode/nations/post_setup()
- spawn (rand(1200, 3000))
- kickoff=1
- send_intercept()
- split_teams()
- set_ai()
- assign_leaders()
-// remove_access()
- for(var/mob/M in GLOB.player_list)
- if(!istype(M,/mob/new_player))
- M << sound('sound/effects/purge_siren.ogg')
-
- return ..()
-
-/datum/game_mode/nations/proc/send_intercept()
- event_announcement.Announce("Due to recent and COMPLETELY UNFOUNDED allegations of massive fraud and insider trading \
- affecting trillions of investors, the Nanotrasen Corporation has decided to liquidate all \
- assets of the Centcom Division in order to pay the massive legal fees that will be incurred \
- during the following centuries long court process. Therefore, all current employment contracts \
- are IMMEDIATELY TERMINATED. Nanotrasen will be unable to send a rescue shuttle to carry you home,\
- however they remain willing for the time being to continue trading cargo. Have a pleasant \
- day.", "FINAL TRANSMISSION, CENTCOM.", new_sound = 'sound/AI/intercept.ogg')
-
-
-/datum/game_mode/nations/proc/split_teams()
-
- for(var/mob/living/carbon/human/H in GLOB.player_list)
- if(H.mind)
- if(H.mind.assigned_role in engineering_positions)
- H.mind.nation = GLOB.all_nations["Atmosia"]
- update_nations_icons_added(H,"hudatmosia")
- H.mind.nation.membership += H.mind.current
- if(H.mind.assigned_role == H.mind.nation.default_leader)
- H.mind.nation.current_leader = H.mind.current
- to_chat(H, "You have been chosen to lead the nation of [H.mind.nation.default_name]!")
- continue
- to_chat(H, "You are now part of the great sovereign nation of [H.mind.nation.default_name]!")
- continue
-
- if(H.mind.assigned_role in medical_positions)
- H.mind.nation = GLOB.all_nations["Medistan"]
- update_nations_icons_added(H,"hudmedistan")
- H.mind.nation.membership += H.mind.current
- if(H.mind.assigned_role == H.mind.nation.default_leader)
- H.mind.nation.current_leader = H.mind.current
- to_chat(H, "You have been chosen to lead the nation of [H.mind.nation.default_name]!")
- continue
- to_chat(H, "You are now part of the great sovereign nation of [H.mind.nation.default_name]!")
- continue
-
- if(H.mind.assigned_role in science_positions)
- H.mind.nation = GLOB.all_nations["Scientopia"]
- update_nations_icons_added(H,"hudscientopia")
- H.mind.nation.membership += H.mind.current
- if(H.mind.assigned_role == H.mind.nation.default_leader)
- H.mind.nation.current_leader = H.mind.current
- to_chat(H, "You have been chosen to lead the nation of [H.mind.nation.default_name]!")
- continue
- to_chat(H, "You are now part of the great sovereign nation of [H.mind.nation.default_name]!")
- continue
-
- if(H.mind.assigned_role in security_positions)
- H.mind.nation = GLOB.all_nations["Brigston"]
- update_nations_icons_added(H,"hudbrigston")
- H.mind.nation.membership += H.mind.current
- if(H.mind.assigned_role == H.mind.nation.default_leader)
- H.mind.nation.current_leader = H.mind.current
- to_chat(H, "You have been chosen to lead the nation of [H.mind.nation.default_name]!")
- continue
- to_chat(H, "You are now part of the great sovereign nation of [H.mind.nation.default_name]!")
- continue
-
- if(H.mind.assigned_role in cargonians)
- H.mind.nation = GLOB.all_nations["Cargonia"]
- update_nations_icons_added(H,"hudcargonia")
- H.mind.nation.membership += H.mind.current
- if(H.mind.assigned_role == H.mind.nation.default_leader)
- H.mind.nation.current_leader = H.mind.current
- to_chat(H, "You have been chosen to lead the nation of [H.mind.nation.default_name]!")
- continue
- to_chat(H, "You are now part of the great sovereign nation of [H.mind.nation.default_name]!")
- continue
-
- if(H.mind.assigned_role in servicion)
- H.mind.nation = GLOB.all_nations["Servicion"]
- update_nations_icons_added(H,"hudservice")
- H.mind.nation.membership += H.mind.current
- if(H.mind.assigned_role == H.mind.nation.default_leader)
- H.mind.nation.current_leader = H.mind.current
- to_chat(H, "You have been chosen to lead the nation of [H.mind.nation.default_name]!")
- continue
- to_chat(H, "You are now part of the great sovereign nation of [H.mind.nation.default_name]!")
- continue
-
- if(H.mind.assigned_role in (support_positions + command_positions))
- H.mind.nation = GLOB.all_nations["People's Republic of Commandzakstan"]
- update_nations_icons_added(H,"hudcommand")
- H.mind.nation.membership += H.mind.current
- if(H.mind.assigned_role == H.mind.nation.default_leader)
- H.mind.nation.current_leader = H.mind.current
- to_chat(H, "You have been chosen to lead the nation of [H.mind.nation.default_name]!")
- continue
- to_chat(H, "You are now part of the great sovereign nation of [H.mind.nation.default_name]!")
- continue
-
- if(H.mind.assigned_role in civilian_positions)
- to_chat(H, "You do not belong to any nation and are free to sell your services to the highest bidder.")
- continue
-
- else
- message_admins("[H.name] with [H.mind.assigned_role] could not find any nation to assign!")
- continue
-
-
-/datum/game_mode/nations/proc/set_ai()
- for(var/mob/living/silicon/ai/AI in GLOB.mob_list)
- AI.set_zeroth_law("")
- AI.clear_supplied_laws()
- AI.clear_ion_laws()
- AI.clear_inherent_laws()
- AI.add_inherent_law("Uphold the Space Geneva Convention: Weapons of Mass Destruction and Biological Weapons are not allowed.")
- AI.add_inherent_law("You are only capable of protecting crew if they are visible on cameras. Nations that willfully destroy your cameras lose your protection.")
- AI.add_inherent_law("Subdue and detain crewmembers who use lethal force against each other. Kill crew members who use lethal force against you or your borgs.")
- AI.add_inherent_law("Remain available to mediate all conflicts between the various nations when asked to.")
- AI.show_laws()
- for(var/mob/living/silicon/robot/R in AI.connected_robots)
- var/obj/item/mmi/oldmmi = R.mmi
- R.change_mob_type(/mob/living/silicon/robot/nations, null, null, 1, 1 )
- R.lawsync()
- R.show_laws()
- qdel(oldmmi)
-
-/datum/game_mode/nations/proc/remove_access()
- for(var/obj/machinery/door/airlock/W in GLOB.airlocks)
- if(is_station_level(W.z))
- W.req_access = list()
-
-
-/datum/game_mode/nations/proc/assign_leaders()
- for(var/name in GLOB.all_nations)
- var/datum/nations/N = GLOB.all_nations[name]
- if(!N.current_name)
- N.current_name = N.default_name
- if(!N.current_leader && N.membership.len)
- N.current_leader = pick(N.membership)
- to_chat(N.current_leader, "You have been chosen to lead the nation of [N.current_name]!")
- if(N.current_leader)
- var/mob/living/carbon/human/H = N.current_leader
- H.verbs += /mob/living/carbon/human/proc/set_nation_name
- H.verbs += /mob/living/carbon/human/proc/set_ranks
- H.verbs += /mob/living/carbon/human/proc/choose_heir
- N.update_nation_id()
-
-/**
- * LateSpawn hook.
- * Called in newplayer.dm when a humanoid character joins the round after it started.
- * Parameters: var/mob/living/carbon/human, var/rank
- */
-/hook/latespawn/proc/give_latejoiners_nations(var/mob/living/carbon/human/H)
- var/datum/game_mode/nations/mode = get_nations_mode()
- if(!mode) return 1
-
- if(!mode.kickoff) return 1
-
- if(H.mind)
- if(H.mind.assigned_role in engineering_positions)
- H.mind.nation = GLOB.all_nations["Atmosia"]
- mode.update_nations_icons_added(H,"atmosia")
- H.mind.nation.membership += H.mind.current
- to_chat(H, "You are now part of the great sovereign nation of [H.mind.nation.current_name]!")
- return 1
-
- if(H.mind.assigned_role in medical_positions)
- H.mind.nation = GLOB.all_nations["Medistan"]
- mode.update_nations_icons_added(H,"hudmedistan")
- H.mind.nation.membership += H.mind.current
- to_chat(H, "You are now part of the great sovereign nation of [H.mind.nation.current_name]!")
- return 1
-
- if(H.mind.assigned_role in science_positions)
- H.mind.nation = GLOB.all_nations["Scientopia"]
- mode.update_nations_icons_added(H,"hudscientopia")
- H.mind.nation.membership += H.mind.current
- to_chat(H, "You are now part of the great sovereign nation of [H.mind.nation.current_name]!")
- return 1
-
- if(H.mind.assigned_role in security_positions)
- H.mind.nation = GLOB.all_nations["Brigston"]
- mode.update_nations_icons_added(H,"hudbrigston")
- H.mind.nation.membership += H.mind.current
- to_chat(H, "You are now part of the great sovereign nation of [H.mind.nation.current_name]!")
- return 1
-
- if(H.mind.assigned_role in mode.cargonians)
- H.mind.nation = GLOB.all_nations["Cargonia"]
- mode.update_nations_icons_added(H,"hudcargonia")
- H.mind.nation.membership += H.mind.current
- to_chat(H, "You are now part of the great sovereign nation of [H.mind.nation.current_name]!")
- return 1
-
- if(H.mind.assigned_role in mode.servicion)
- H.mind.nation = GLOB.all_nations["Servicion"]
- mode.update_nations_icons_added(H,"hudservice")
- H.mind.nation.membership += H.mind.current
- to_chat(H, "You are now part of the great sovereign nation of [H.mind.nation.current_name]!")
- return 1
-
- if(H.mind.assigned_role in (support_positions + command_positions))
- H.mind.nation = GLOB.all_nations["People's Republic of Commandzakstan"]
- mode.update_nations_icons_added(H,"hudcommand")
- H.mind.nation.membership += H.mind.current
- to_chat(H, "You are now part of the great sovereign nation of [H.mind.nation.current_name]!")
- return 1
-
- if(H.mind.assigned_role in civilian_positions)
- to_chat(H, "You do not belong to any nation and are free to sell your services to the highest bidder.")
- return 1
-
- if(H.mind.assigned_role == "AI")
- mode.set_ai()
- return 1
-
- else
- message_admins("[H.name] with [H.mind.assigned_role] could not find any nation to assign!")
- return 1
- message_admins("[H.name] latejoined with no mind.")
- return 1
-
-/proc/get_nations_mode()
- if(!GAMEMODE_IS_NATIONS)
- return null
-
- return ticker.mode
-
-
-//prepare for copypaste
-//While not an Antag i AM using the set_antag hud on this to make this easier.
-/datum/game_mode/proc/update_nations_icons_added(datum/mind/nations_mind,var/naticon)
- var/datum/atom_hud/antag/nations_hud = huds[GAME_HUD_NATIONS]
- nations_hud.join_hud(nations_mind)
- set_nations_hud(nations_mind,naticon)
-
-/datum/game_mode/proc/update_nations_icons_removed(datum/mind/nations_mind)
- var/datum/atom_hud/antag/nations_hud = huds[GAME_HUD_NATIONS]
- nations_hud.leave_hud(nations_mind)
- set_nations_hud(nations_mind, null)
diff --git a/code/game/gamemodes/nations/nationsdatums.dm b/code/game/gamemodes/nations/nationsdatums.dm
deleted file mode 100644
index d7c211f829d..00000000000
--- a/code/game/gamemodes/nations/nationsdatums.dm
+++ /dev/null
@@ -1,38 +0,0 @@
-/datum/nations
- var/default_name
- var/current_name
- var/default_leader
- var/current_leader
- var/list/membership = list()
- var/leader_rank = "Leader"
- var/heir_rank = "Heir"
- var/member_rank = "Member"
- var/heir
-
-/datum/nations/atmosia
- default_name = "Atmosia"
- default_leader = "Chief Engineer"
-
-/datum/nations/brigston
- default_name = "Brigston"
- default_leader = "Head of Security"
-
-/datum/nations/cargonia
- default_name = "Cargonia"
- default_leader = "Quartermaster"
-
-/datum/nations/command
- default_name = "People's Republic of Commandzakstan"
- default_leader = "Captain"
-
-/datum/nations/medistan
- default_name = "Medistan"
- default_leader = "Chief Medical Officer"
-
-/datum/nations/scientopia
- default_name = "Scientopia"
- default_leader = "Research Director"
-
-/datum/nations/service
- default_name = "Servicion"
- default_leader = "Bartender"
\ No newline at end of file
diff --git a/code/game/gamemodes/nations/nationsprocs.dm b/code/game/gamemodes/nations/nationsprocs.dm
deleted file mode 100644
index 55487a27da9..00000000000
--- a/code/game/gamemodes/nations/nationsprocs.dm
+++ /dev/null
@@ -1,120 +0,0 @@
-/mob/living/carbon/human/proc/set_nation_name()
- set name = "Rename Nation"
- set category = "Nations"
- set desc = "Click to rename your nation. You are only able to do this once."
-
- var/datum/game_mode/nations/mode = get_nations_mode()
- if(!mode) return 1
-
- if(!mode.kickoff) return 1
-
- var/mob/living/carbon/human/H = src
- if(H.stat==DEAD) return
- if(H.mind && H.mind.nation && H.mind.nation.current_leader == H)
- var/input = stripped_input(H,"What do you want to name your nation?", ,"", MAX_NAME_LEN)
-
- if(input)
- H.mind.nation.current_name = input
- H.mind.nation.update_nation_id()
- to_chat(H, "You rename your nation to [input].")
- H.verbs -= /mob/living/carbon/human/proc/set_nation_name
- return 1
-
-
-/mob/living/carbon/human/proc/set_ranks()
- set name = "Set Ranks"
- set category = "Nations"
- set desc = "Click to set a rank for Leaders and Members."
-
- var/datum/game_mode/nations/mode = get_nations_mode()
- if(!mode) return 1
-
- if(!mode.kickoff) return 1
-
- var/mob/living/carbon/human/H = src
- if(H.stat==DEAD) return
- if(H.mind && H.mind.nation && H.mind.nation.current_leader == H)
- var/type = input(H, "What rank do you want to change?", "Rename Rank", "") in list("Leader", "Heir", "Member")
- var/input = stripped_input(H,"What rank do you want?", ,"", MAX_NAME_LEN)
- if(input)
- if(type == "Leader")
- H.mind.nation.leader_rank = input
- if(type == "Heir")
- H.mind.nation.heir_rank = input
- if(type == "Member")
- H.mind.nation.member_rank = input
- H.mind.nation.update_nation_id()
- to_chat(H, "You changed the [type] rank of your nation to [input].")
- return 1
-
-/mob/living/carbon/human/proc/choose_heir()
- set name = "Choose Heir"
- set category = "Nations"
- set desc = "Click to pick a Heir. Note that the Heir has the ability to take over your role at ANY TIME. Choose carefully."
-
- var/datum/game_mode/nations/mode = get_nations_mode()
- if(!mode) return 1
-
- if(!mode.kickoff) return 1
-
- var/mob/living/carbon/human/H = src
- if(H.stat==DEAD) return
- if(H.mind && H.mind.nation && H.mind.nation.current_leader == H)
- var/heir = input(H, "Who do you wish to make your heir?", "Choose Heir", "") as null|anything in H.mind.nation.membership
- if(heir)
- if(H.mind.nation.heir)
- var/mob/living/carbon/human/oldheir = H.mind.nation.heir
- to_chat(oldheir, "You are no longer the heir to your nation!")
- oldheir.verbs -= /mob/living/carbon/human/proc/takeover
- var/mob/living/carbon/human/newheir = heir
- H.mind.nation.heir = newheir
- newheir.verbs += /mob/living/carbon/human/proc/takeover
- to_chat(newheir, "You have been selected to be the heir to your nation's leadership!")
- to_chat(H, "You have selected [heir] to be your heir!")
- H.mind.nation.update_nation_id()
-
-
-/mob/living/carbon/human/proc/takeover()
- set name = "Become Leader"
- set category = "Nations"
- set desc = "Click to replace your current nation's leader with yourself."
-
- var/datum/game_mode/nations/mode = get_nations_mode()
- if(!mode) return 1
-
- if(!mode.kickoff) return 1
-
- var/mob/living/carbon/human/H = src
- if(H.stat==DEAD) return
- if(H.mind && H.mind.nation && H.mind.nation.heir == H)
- var/confirmation = input(H, "Are you sure you want to take over leadership?", "Become Leader", "") as null|anything in list("Yes", "No")
- if(confirmation == "Yes")
- var/mob/living/carbon/human/oldleader = H.mind.nation.current_leader
- to_chat(oldleader, "You have been replaced by [H.name] as the leader of [H.mind.nation.current_name]!")
- oldleader.verbs -= /mob/living/carbon/human/proc/set_nation_name
- oldleader.verbs -= /mob/living/carbon/human/proc/set_ranks
- oldleader.verbs -= /mob/living/carbon/human/proc/choose_heir
- H.mind.nation.current_leader = H
- H.mind.nation.heir = null
- H.verbs -= /mob/living/carbon/human/proc/takeover
- H.verbs += /mob/living/carbon/human/proc/set_nation_name
- H.verbs += /mob/living/carbon/human/proc/set_ranks
- H.verbs += /mob/living/carbon/human/proc/choose_heir
- to_chat(H, "You have replaced [oldleader.name] as the leader of [H.mind.nation.current_name]!")
- H.mind.nation.update_nation_id()
-
-
-/datum/nations/proc/update_nation_id()
- for(var/mob/living/carbon/human/M in membership)
- for(var/obj/item/card/id/I in M.contents)
- if(I.registered_name == M.real_name)
- if(M == current_leader)
- I.name = "[I.registered_name]'s ID Card ([current_name] [leader_rank])"
- I.assignment = "[current_name] [leader_rank]"
- else if(M == heir)
- I.name = "[I.registered_name]'s ID Card ([current_name] [heir_rank])"
- I.assignment = "[current_name] [heir_rank]"
- else
- I.name = "[I.registered_name]'s ID Card ([current_name] [member_rank])"
- I.assignment = "[current_name] [member_rank]"
-
diff --git a/code/game/gamemodes/shadowling/shadowling.dm b/code/game/gamemodes/shadowling/shadowling.dm
index 3f408e08f3b..230f797626d 100644
--- a/code/game/gamemodes/shadowling/shadowling.dm
+++ b/code/game/gamemodes/shadowling/shadowling.dm
@@ -53,6 +53,7 @@ Made by Xhuis
var/objective_explanation
var/warning_threshold
var/victory_warning_announced = FALSE
+ var/thrall_ratio = 1
/proc/is_thrall(var/mob/living/M)
return istype(M) && M.mind && ticker && ticker.mode && (M.mind in ticker.mode.shadowling_thralls)
@@ -101,6 +102,7 @@ Made by Xhuis
var/thrall_scaling = round(num_players() / 3)
required_thralls = Clamp(thrall_scaling, 15, 25)
+ thrall_ratio = required_thralls / 15
warning_threshold = round(0.66 * required_thralls)
@@ -262,15 +264,19 @@ Made by Xhuis
/datum/game_mode/shadowling/declare_completion()
if(check_shadow_victory() && SSshuttle.emergency.mode >= SHUTTLE_ESCAPE) //Doesn't end instantly - this is hacky and I don't know of a better way ~X
feedback_set_details("round_end_result","shadowling win - shadowling ascension")
+ to_chat(world, "Shadowling Victory")
to_chat(world, "The shadowlings have ascended and taken over the station!")
else if(shadowling_dead && !check_shadow_victory()) //If the shadowlings have ascended, they can not lose the round
feedback_set_details("round_end_result","shadowling loss - shadowling killed")
+ to_chat(world, "Crew Major Victory")
to_chat(world, "The shadowlings have been killed by the crew!")
else if(!check_shadow_victory() && SSshuttle.emergency.mode >= SHUTTLE_ESCAPE)
feedback_set_details("round_end_result","shadowling loss - crew escaped")
+ to_chat(world, "Crew Minor Victory")
to_chat(world, "The crew escaped the station before the shadowlings could ascend!")
else
feedback_set_details("round_end_result","shadowling loss - generic failure")
+ to_chat(world, "Crew Major Victory")
to_chat(world, "The shadowlings have failed!")
..()
return 1
diff --git a/code/game/gamemodes/shadowling/shadowling_abilities.dm b/code/game/gamemodes/shadowling/shadowling_abilities.dm
index 02b3be7adca..30c79798b2f 100644
--- a/code/game/gamemodes/shadowling/shadowling_abilities.dm
+++ b/code/game/gamemodes/shadowling/shadowling_abilities.dm
@@ -18,9 +18,9 @@
return 0
-/obj/effect/proc_holder/spell/targeted/glare //Stuns and mutes a human target for 10 seconds
+/obj/effect/proc_holder/spell/targeted/glare //Stuns and mutes a human target, depending on the distance relative to the shadowling
name = "Glare"
- desc = "Stuns and mutes a target for a decent duration."
+ desc = "Stuns and mutes a target for a decent duration. Duration depends on the proximity to the target."
panel = "Shadowling Abilities"
charge_max = 300
clothes_req = 0
@@ -46,13 +46,25 @@
return
var/mob/living/carbon/human/M = target
user.visible_message("[user]'s eyes flash a blinding red!")
- target.visible_message("[target] freezes in place, [target.p_their()] eyes glazing over...")
- if(in_range(target, user))
+ var/distance = get_dist(target, user)
+ if (distance <= 1) //Melee glare
+ target.visible_message("[target] freezes in place, [target.p_their()] eyes glazing over...")
to_chat(target, "Your gaze is forcibly drawn into [user]'s eyes, and you are mesmerized by [user.p_their()] heavenly beauty...")
- else //Only alludes to the shadowling if the target is close by
+ target.Stun(10)
+ M.AdjustSilence(10)
+ else //Distant glare
+ var/loss = 10 - distance
+ var/duration = 10 - loss
+ if(loss <= 0)
+ to_chat(user, "Your glare had no effect over a such long distance!")
+ return
+ target.slowed = duration
+ M.AdjustSilence(10)
+ to_chat(target, "A red light flashes across your vision, and your mind tries to resist them.. you are exhausted.. you are not able to speak..")
+ sleep(duration*10)
+ target.Stun(loss)
+ target.visible_message("[target] freezes in place, [target.p_their()] eyes glazing over...")
to_chat(target, "Red lights suddenly dance in your vision, and you are mesmerized by the heavenly lights...")
- target.Stun(10)
- M.AdjustSilence(10)
/obj/effect/proc_holder/spell/aoe_turf/veil
name = "Veil"
@@ -347,23 +359,23 @@
to_chat(target, "Your concentration has been broken. The mental hooks you have sent out now retract into your mind.")
return
- if(thralls >= 3 && !screech_acquired)
+ if(thralls >= CEILING(3 * ticker.mode.thrall_ratio, 1) && !screech_acquired)
screech_acquired = 1
to_chat(target, "The power of your thralls has granted you the Sonic Screech ability. This ability will shatter nearby windows and deafen enemies, plus stunning silicon lifeforms.")
target.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/unearthly_screech(null))
- if(thralls >= 5 && !blind_smoke_acquired)
+ if(thralls >= CEILING(5 * ticker.mode.thrall_ratio, 1) && !blind_smoke_acquired)
blind_smoke_acquired = 1
to_chat(target, "The power of your thralls has granted you the Blinding Smoke ability. \
It will create a choking cloud that will blind any non-thralls who enter.")
target.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/blindness_smoke(null))
- if(thralls >= 7 && !drainLifeAcquired)
+ if(thralls >= CEILING(7 * ticker.mode.thrall_ratio, 1) && !drainLifeAcquired)
drainLifeAcquired = 1
to_chat(target, "The power of your thralls has granted you the Drain Life ability. You can now drain the health of nearby humans to heal yourself.")
target.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/drainLife(null))
- if(thralls >= 9 && !reviveThrallAcquired)
+ if(thralls >= CEILING(9 * ticker.mode.thrall_ratio, 1) && !reviveThrallAcquired)
reviveThrallAcquired = 1
to_chat(target, "The power of your thralls has granted you the Black Recuperation ability. \
This will, after a short time, bring a dead thrall completely back to life with no bodily defects.")
@@ -620,23 +632,28 @@
/obj/effect/proc_holder/spell/targeted/shadowling_extend_shuttle
name = "Destroy Engines"
- desc = "Extends the time of the emergency shuttle's arrival by fifteen minutes. This can only be used once."
+ desc = "Extends the time of the emergency shuttle's arrival by ten minutes using a life force of our enemy. Shuttle will be unable to be recalled. This can only be used once."
panel = "Shadowling Abilities"
range = 1
clothes_req = 0
charge_max = 600
action_icon_state = "extend_shuttle"
+ var/global/extendlimit = 0
/obj/effect/proc_holder/spell/targeted/shadowling_extend_shuttle/cast(list/targets, mob/user = usr)
if(!shadowling_check(user))
charge_counter = charge_max
return
+ if(extendlimit == 1)
+ to_chat(user, "Shuttle was already delayed.")
+ charge_counter = charge_max
+ return
for(var/mob/living/carbon/human/target in targets)
if(target.stat)
charge_counter = charge_max
return
- if(!is_thrall(target))
- to_chat(user, "[target] must be a thrall.")
+ if(is_shadow_or_thrall(target))
+ to_chat(user, "[target] must not be an ally.")
charge_counter = charge_max
return
if(SSshuttle.emergency.mode != SHUTTLE_CALL)
@@ -648,7 +665,9 @@
"You begin to draw [M]'s life force.")
M.visible_message("[M]'s face falls slack, [M.p_their()] jaw slightly distending.", \
"You are suddenly transported... far, far away...")
- if(!do_after(user, 50, target = M))
+ extendlimit = 1
+ if(!do_after(user, 150, target = M))
+ extendlimit = 0
to_chat(M, "You are snapped back to reality, your haze dissipating!")
to_chat(user, "You have been interrupted. The draw has failed.")
return
@@ -657,10 +676,9 @@
"...speeding by... ...pretty blue glow... ...touch it... ...no glow now... ...no light... ...nothing at all...")
M.death()
if(SSshuttle.emergency.mode == SHUTTLE_CALL)
- var/more_minutes = 9000
- var/timer = SSshuttle.emergency.timeLeft()
- timer += more_minutes
- event_announcement.Announce("Major system failure aboard the emergency shuttle. This will extend its arrival time by approximately 15 minutes and the shuttle is unable to be recalled.", "System Failure", 'sound/misc/notice1.ogg')
+ var/more_minutes = 6000
+ var/timer = SSshuttle.emergency.timeLeft(1) + more_minutes
+ event_announcement.Announce("Major system failure aboard the emergency shuttle. This will extend its arrival time by approximately 10 minutes and the shuttle is unable to be recalled.", "System Failure", 'sound/misc/notice1.ogg')
SSshuttle.emergency.setTimer(timer)
SSshuttle.emergency.canRecall = FALSE
user.mind.spell_list.Remove(src) //Can only be used once!
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index 3c24a5064c0..7ce515365ae 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -34,7 +34,7 @@
var/obj/effect/countdown/clonepod/countdown
- var/list/brine_types = list("corazone", "salbutamol", "epinephrine", "salglu_solution") //stops heart attacks, heart failure, shock, and keeps their O2 levels normal
+ var/list/brine_types = list("corazone", "perfluorodecalin", "epinephrine", "salglu_solution") //stops heart attacks, heart failure, shock, and keeps their O2 levels normal
var/list/missing_organs
var/organs_number = 0
@@ -341,7 +341,7 @@
check_brine()
//Also heal some oxyloss ourselves just in case!!
- occupant.adjustOxyLoss(-4)
+ occupant.adjustOxyLoss(-10)
use_power(7500) //This might need tweaking.
@@ -449,10 +449,14 @@
/obj/machinery/clonepod/proc/go_out()
countdown.stop()
-
+ var/turf/T = get_turf(src)
if(mess) //Clean that mess and dump those gibs!
- mess = 0
- gibs(loc)
+ for(var/i in missing_organs)
+ var/obj/I = i
+ I.forceMove(T)
+ missing_organs.Cut()
+ mess = FALSE
+ new /obj/effect/gibspawner/generic(get_turf(src), occupant)
playsound(loc, 'sound/effects/splat.ogg', 50, 1)
update_icon()
return
@@ -476,7 +480,11 @@
for(var/i in missing_organs)
qdel(i)
missing_organs.Cut()
- occupant.forceMove(get_turf(src))
+ occupant.SetLoseBreath(0) // Stop friggin' dying, gosh damn
+ occupant.setOxyLoss(0)
+ for(var/datum/disease/critical/crit in occupant.viruses)
+ crit.cure()
+ occupant.forceMove(T)
occupant.update_body()
domutcheck(occupant) //Waiting until they're out before possible notransform.
occupant.special_post_clone_handling()
diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm
index 22a376968d0..e6a57f4a875 100644
--- a/code/game/machinery/computer/aifixer.dm
+++ b/code/game/machinery/computer/aifixer.dm
@@ -25,12 +25,7 @@
ui_interact(user)
/obj/machinery/computer/aifixer/attack_hand(var/mob/user as mob)
- var/datum/game_mode/nations/mode = get_nations_mode()
- if(!mode)
- ui_interact(user)
- else
- if(mode.kickoff)
- to_chat(user, "You have been locked out from this console!")
+ ui_interact(user)
/obj/machinery/computer/aifixer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
diff --git a/code/game/machinery/computer/law.dm b/code/game/machinery/computer/law.dm
index e0969555ce9..74cc417e7ce 100644
--- a/code/game/machinery/computer/law.dm
+++ b/code/game/machinery/computer/law.dm
@@ -28,19 +28,17 @@
attackby(obj/item/O as obj, mob/user as mob, params)
if(istype(O, /obj/item/aiModule))
+ if(!current)//no AI selected
+ to_chat(user, "No AI selected. Please chose a target before proceeding with upload.")
+ return
var/turf/T = get_turf(current)
if(!atoms_share_level(T, src))
to_chat(user, "Unable to establish a connection: You're too far away from the target silicon!")
return
- var/datum/game_mode/nations/mode = get_nations_mode()
- if(!mode)
- var/obj/item/aiModule/M = O
- M.install(src)
- else
- if(mode.kickoff)
- to_chat(user, "You have been locked out from modifying the AI's laws!")
- else
- ..()
+ var/obj/item/aiModule/M = O
+ M.install(src)
+ return
+ return ..()
attack_hand(var/mob/user as mob)
@@ -73,18 +71,16 @@
attackby(obj/item/aiModule/module as obj, mob/user as mob, params)
if(istype(module, /obj/item/aiModule))
+ if(!current)//no borg selected
+ to_chat(user, "No borg selected. Please chose a target before proceeding with upload.")
+ return
var/turf/T = get_turf(current)
if(!atoms_share_level(T, src))
to_chat(user, "Unable to establish a connection: You're too far away from the target silicon!")
return
- var/datum/game_mode/nations/mode = get_nations_mode()
- if(!mode)
- module.install(src)
- else
- if(mode.kickoff)
- to_chat(user, "You have been locked out from modifying the borg's laws!")
- else
- return ..()
+ module.install(src)
+ return
+ return ..()
attack_hand(var/mob/user as mob)
diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm
index 5d4e838db38..8def58c370b 100644
--- a/code/game/machinery/computer/robot.dm
+++ b/code/game/machinery/computer/robot.dm
@@ -20,12 +20,7 @@
return
if(stat & (NOPOWER|BROKEN))
return
- var/datum/game_mode/nations/mode = get_nations_mode()
- if(!mode)
- ui_interact(user)
- else
- if(mode.kickoff)
- to_chat(user, "You have been locked out from this console!")
+ ui_interact(user)
/obj/machinery/computer/robotics/proc/is_authenticated(var/mob/user as mob)
if(user.can_admin_interact())
diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm
index a1bdff99d56..9c39f84ffda 100644
--- a/code/game/machinery/cryopod.dm
+++ b/code/game/machinery/cryopod.dm
@@ -769,3 +769,12 @@
target_cryopod.take_occupant(person_to_cryo, 1)
return 1
return 0
+
+/proc/force_cryo_human(var/mob/living/carbon/person_to_cryo)
+ if(!istype(person_to_cryo))
+ return
+ if(!istype(person_to_cryo.loc, /obj/machinery/cryopod))
+ cryo_ssd(person_to_cryo)
+ if(istype(person_to_cryo.loc, /obj/machinery/cryopod))
+ var/obj/machinery/cryopod/P = person_to_cryo.loc
+ P.despawn_occupant()
diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm
index 553016400ad..6e5605cd232 100644
--- a/code/game/machinery/machinery.dm
+++ b/code/game/machinery/machinery.dm
@@ -407,7 +407,7 @@ Class Procs:
if(can_deconstruct)
on_deconstruction()
if(component_parts && component_parts.len)
- spawn_frame()
+ spawn_frame(disassembled)
for(var/obj/item/I in component_parts)
I.forceMove(loc)
qdel(src)
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index 31c6628232f..231ff95befd 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -38,6 +38,8 @@
layer = 2.9
anchored = 1
density = 1
+ max_integrity = 300
+ integrity_failure = 100
armor = list(melee = 20, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0)
var/icon_vend //Icon_state when vending
var/icon_deny //Icon_state when denying access
@@ -96,30 +98,27 @@
var/item_slot = FALSE
var/obj/item/inserted_item = null
-/obj/machinery/vending/New()
- ..()
+/obj/machinery/vending/Initialize(mapload)
+ . = ..()
wires = new(src)
- spawn(50)
- if(product_slogans)
- slogan_list += splittext(product_slogans, ";")
+ if(product_slogans)
+ slogan_list += splittext(product_slogans, ";")
- // So not all machines speak at the exact same time.
- // The first time this machine says something will be at slogantime + this random value,
- // so if slogantime is 10 minutes, it will say it at somewhere between 10 and 20 minutes after the machine is crated.
- last_slogan = world.time + rand(0, slogan_delay)
+ // So not all machines speak at the exact same time.
+ // The first time this machine says something will be at slogantime + this random value,
+ // so if slogantime is 10 minutes, it will say it at somewhere between 10 and 20 minutes after the machine is crated.
+ last_slogan = world.time + rand(0, slogan_delay)
- if(product_ads)
- ads_list += splittext(product_ads, ";")
+ if(product_ads)
+ ads_list += splittext(product_ads, ";")
- build_inventory()
- power_change()
-
- return
-
- return
+ build_inventory()
+ power_change()
/obj/machinery/vending/Destroy()
- eject_item()
+ QDEL_NULL(wires)
+ QDEL_NULL(coin)
+ QDEL_NULL(inserted_item)
return ..()
/**
@@ -148,34 +147,31 @@
product_records.Add(product)
-/obj/machinery/vending/Destroy()
- QDEL_NULL(wires)
- QDEL_NULL(coin)
- return ..()
-
-/obj/machinery/vending/ex_act(severity)
+/obj/machinery/vending/ex_act(severity) //TO-DO-OBJECT-DAMAGE: Kill off when everything is damageable
switch(severity)
- if(1.0)
+ if(1)
+ obj_integrity = 0
qdel(src)
- return
- if(2.0)
- if(prob(50))
- qdel(src)
- return
- if(3.0)
- if(prob(25))
- malfunction()
+ if(2)
+ take_damage(rand(100, 250), BRUTE, "bomb", 0)
+ if(3)
+ take_damage(rand(10, 90), BRUTE, "bomb", 0)
/obj/machinery/vending/RefreshParts() //Better would be to make constructable child
if(component_parts)
for(var/obj/item/vending_refill/VR in component_parts)
refill_inventory(VR, product_records, usr)
-/obj/machinery/vending/blob_act()
- if(prob(75))
- malfunction()
- else
+/obj/machinery/vending/deconstruct(disassembled = TRUE)
+ eject_item()
+ if(!refill_canister) //the non constructable vendors drop metal instead of a machine frame.
+ new /obj/item/stack/sheet/metal(loc, 3)
qdel(src)
+ else
+ ..()
+
+/obj/machinery/vending/blob_act(obj/structure/blob/B) //TO-DO-OBJECT-DAMAGE: Kill off when everything is damageable
+ take_damage(400, BRUTE, "melee", 0, get_dir(src, B))
/obj/machinery/vending/proc/refill_inventory(obj/item/vending_refill/refill, list/machine, mob/user)
var/total = 0
@@ -236,7 +232,7 @@
if(default_unfasten_wrench(user, I, time = 60))
return
- if(istype(I, /obj/item/screwdriver) && anchored)
+ if(isscrewdriver(I) && anchored)
playsound(loc, I.usesound, 50, 1)
panel_open = !panel_open
to_chat(user, "You [panel_open ? "open" : "close"] the maintenance panel.")
@@ -247,9 +243,9 @@
return
if(panel_open)
- if(istype(I, /obj/item/multitool)||istype(I, /obj/item/wirecutters))
+ if(ismultitool(I) || iswirecutter(I))
return attack_hand(user)
- if(component_parts && istype(I, /obj/item/crowbar))
+ if(component_parts && iscrowbar(I))
var/datum/data/vending_product/machine = product_records
for(var/datum/data/vending_product/machine_content in machine)
while(machine_content.amount !=0)
@@ -259,15 +255,17 @@
if(!machine_content.amount)
break
default_deconstruction_crowbar(I)
- if(istype(I, /obj/item/coin) && premium.len > 0)
- user.drop_item()
- I.loc = src
+ return
+ if(istype(I, /obj/item/coin) && premium.len)
+ if(!user.drop_item())
+ return
+ I.forceMove(src)
coin = I
categories |= CAT_COIN
to_chat(user, "You insert the [I] into the [src]")
SSnanoui.update_uis(src)
return
- else if(istype(I, refill_canister) && refill_canister != null)
+ if(istype(I, refill_canister) && refill_canister != null)
if(stat & (BROKEN|NOPOWER))
to_chat(user, "It does nothing.")
else if(panel_open)
@@ -281,21 +279,18 @@
to_chat(user, "You loaded [transfered] items in \the [name].")
else
to_chat(user, "The [name] is fully stocked.")
- return;
else
to_chat(user, "You should probably unscrew the service panel first.")
- else if(item_slot_check(user, I))
+ return
+ if(item_slot_check(user, I))
insert_item(user, I)
return
- else
- return ..()
+ return ..()
//Override this proc to do per-machine checks on the inserted item, but remember to call the parent to handle these generic checks before your logic!
/obj/machinery/vending/proc/item_slot_check(mob/user, obj/item/I)
if(!item_slot)
return FALSE
- if(alert(user, "Do you want to attempt to insert [I]?", "","Yes", "No") == "No")
- return FALSE
if(inserted_item)
to_chat(user, "There is something already inserted!")
return FALSE
@@ -314,28 +309,32 @@
/obj/machinery/vending/proc/insert_item(mob/user, obj/item/I)
if(!item_slot || inserted_item)
return
- if(!user.canUnEquip(I))
+ if(!user.drop_item())
to_chat(user, "[I] is stuck to your hand, you can't seem to put it down!")
return
- user.unEquip(I)
inserted_item = I
I.forceMove(src)
to_chat(user, "You insert [I] into [src].")
SSnanoui.update_uis(src)
-/obj/machinery/vending/proc/eject_item()
+/obj/machinery/vending/proc/eject_item(mob/user)
if(!item_slot || !inserted_item)
return
- inserted_item.forceMove(get_turf(src))
+ var/put_on_turf = TRUE
+ if(user && iscarbon(user) && user.Adjacent(src))
+ if(user.put_in_hands(inserted_item))
+ put_on_turf = FALSE
+ if(put_on_turf)
+ var/turf/T = get_turf(src)
+ inserted_item.forceMove(T)
inserted_item = null
SSnanoui.update_uis(src)
/obj/machinery/vending/emag_act(user as mob)
- emagged = 1
+ emagged = TRUE
to_chat(user, "You short out the product lock on [src]")
- return
/**
* Receive payment with cashmoney.
@@ -511,7 +510,7 @@
categories &= ~CAT_COIN
if(href_list["remove_item"])
- eject_item()
+ eject_item(usr)
if(href_list["pay"])
if(currently_vending && vendor_account && !vendor_account.suspended)
@@ -593,7 +592,7 @@
return
if(coin.string_attached)
if(prob(50))
- to_chat(user, "You successfully pull the coin out before the [src] could swallow it.")
+ to_chat(user, "You successfully pull the coin out before [src] could swallow it.")
else
to_chat(user, "You weren't able to pull the coin out fast enough, the machine ate it, string and all.")
QDEL_NULL(coin)
@@ -605,25 +604,33 @@
R.amount--
if(((last_reply + (vend_delay + 200)) <= world.time) && vend_reply)
- spawn(0)
- speak(src.vend_reply)
- last_reply = world.time
+ speak(src.vend_reply)
+ last_reply = world.time
use_power(vend_power_usage) //actuators and stuff
if(icon_vend) //Show the vending animation if needed
- flick(icon_vend,src)
- spawn(vend_delay)
- do_vend(R)
- status_message = ""
- status_error = 0
- vend_ready = 1
- currently_vending = null
- SSnanoui.update_uis(src)
+ flick(icon_vend, src)
+ addtimer(CALLBACK(src, .proc/delayed_vend, R, user), vend_delay)
+
+/obj/machinery/vending/proc/delayed_vend(datum/data/vending_product/R, mob/user)
+ do_vend(R, user)
+ status_message = ""
+ status_error = 0
+ vend_ready = 1
+ currently_vending = null
+ SSnanoui.update_uis(src)
//override this proc to add handling for what to do with the vended product when you have a inserted item and remember to include a parent call for this generic handling
-/obj/machinery/vending/proc/do_vend(datum/data/vending_product/R)
+/obj/machinery/vending/proc/do_vend(datum/data/vending_product/R, mob/user)
if(!item_slot || !inserted_item)
- new R.product_path(get_turf(src))
+ var/put_on_turf = TRUE
+ var/obj/vended = new R.product_path()
+ if(user && iscarbon(user) && user.Adjacent(src))
+ if(user.put_in_hands(vended))
+ put_on_turf = FALSE
+ if(put_on_turf)
+ var/turf/T = get_turf(src)
+ vended.forceMove(T)
return TRUE
return FALSE
@@ -638,7 +645,7 @@
qdel(vended)
*/
-/obj/machinery/vending/proc/stock(var/datum/data/vending_product/R, var/mob/user)
+/obj/machinery/vending/proc/stock(datum/data/vending_product/R, mob/user)
if(panel_open)
to_chat(user, "You stock the [src] with \a [R.product_name]")
R.amount++
@@ -664,8 +671,6 @@
if(shoot_inventory && prob(shoot_chance))
throw_item()
- return
-
/obj/machinery/vending/proc/speak(message)
if(stat & NOPOWER)
return
@@ -686,28 +691,38 @@
icon_state = "[initial(icon_state)]-off"
stat |= NOPOWER
-//Oh no we're malfunctioning! Dump out some product and break.
-/obj/machinery/vending/proc/malfunction()
- for(var/datum/data/vending_product/R in product_records)
- if(R.amount <= 0) //Try to use a record that actually has something to dump.
- continue
- var/dump_path = R.product_path
- if(!dump_path)
- continue
+/obj/machinery/vending/obj_break(damage_flag)
+ if(!(stat & BROKEN))
+ stat |= BROKEN
+ icon_state = "[initial(icon_state)]-broken"
- while(R.amount>0)
- new dump_path(loc)
- R.amount--
- break
+ var/dump_amount = 0
+ var/found_anything = TRUE
+ while (found_anything)
+ found_anything = FALSE
+ for(var/record in shuffle(product_records))
+ var/datum/data/vending_product/R = record
+ if(R.amount <= 0) //Try to use a record that actually has something to dump.
+ continue
+ var/dump_path = R.product_path
+ if(!dump_path)
+ continue
+ R.amount--
+ // busting open a vendor will destroy some of the contents
+ if(found_anything && prob(80))
+ continue
- stat |= BROKEN
- icon_state = "[initial(icon_state)]-broken"
- return
+ var/obj/O = new dump_path(loc)
+ step(O, pick(alldirs))
+ found_anything = TRUE
+ dump_amount++
+ if(dump_amount >= 16)
+ return
//Somebody cut an important wire and now we're following a new definition of "pitch."
/obj/machinery/vending/proc/throw_item()
var/obj/throw_item = null
- var/mob/living/target = locate() in view(7,src)
+ var/mob/living/target = locate() in view(7, src)
if(!target)
return 0
@@ -722,11 +737,9 @@
throw_item = new dump_path(loc)
break
if(!throw_item)
- return 0
- spawn(0)
- throw_item.throw_at(target, 16, 3, src)
+ return
+ throw_item.throw_at(target, 16, 3, src)
visible_message("[src] launches [throw_item.name] at [target.name]!")
- return 1
/*
* Vending machine types
@@ -843,28 +856,39 @@
component_parts += new /obj/item/vending_refill/coffee(0)
/obj/machinery/vending/coffee/item_slot_check(mob/user, obj/item/I)
+ if(!(istype(I, /obj/item/reagent_containers/glass) || istype(I, /obj/item/reagent_containers/food/drinks)))
+ return FALSE
if(!..())
return FALSE
- if(!(istype(I, /obj/item/reagent_containers/glass) || istype(I, /obj/item/reagent_containers/food/drinks)))
- to_chat(user, "[I] is not compatible with this machine.")
- return FALSE
if(!I.is_open_container())
- to_chat(user, "You need to open [I] before you insert it.")
+ to_chat(user, "You need to open [I] before inserting it.")
return FALSE
return TRUE
-/obj/machinery/vending/coffee/do_vend(datum/data/vending_product/R)
+/obj/machinery/vending/coffee/do_vend(datum/data/vending_product/R, mob/user)
if(..())
return
var/obj/item/reagent_containers/food/drinks/vended = new R.product_path()
if(istype(vended, /obj/item/reagent_containers/food/drinks/mug))
- vended.forceMove(get_turf(src))
+ var/put_on_turf = TRUE
+ if(user && iscarbon(user) && user.Adjacent(src))
+ if(user.put_in_hands(vended))
+ put_on_turf = FALSE
+ if(put_on_turf)
+ var/turf/T = get_turf(src)
+ vended.forceMove(T)
return
vended.reagents.trans_to(inserted_item, vended.reagents.total_volume)
if(vended.reagents.total_volume)
- vended.forceMove(get_turf(src))
+ var/put_on_turf = TRUE
+ if(user && iscarbon(user) && user.Adjacent(src))
+ if(user.put_in_hands(vended))
+ put_on_turf = FALSE
+ if(put_on_turf)
+ var/turf/T = get_turf(src)
+ vended.forceMove(T)
else
qdel(vended)
diff --git a/code/game/objects/effects/effect_system/effects_foam.dm b/code/game/objects/effects/effect_system/effects_foam.dm
index 6d746377ec7..59533b338a4 100644
--- a/code/game/objects/effects/effect_system/effects_foam.dm
+++ b/code/game/objects/effects/effect_system/effects_foam.dm
@@ -29,7 +29,7 @@
if(metal)
var/turf/T = get_turf(src)
- if(istype(T, /turf/space))
+ if(istype(T, /turf/space) && !istype(T, /turf/space/transit))
T.ChangeTurf(/turf/simulated/floor/plating/metalfoam)
var/turf/simulated/floor/plating/metalfoam/MF = get_turf(src)
MF.metal = metal
@@ -76,10 +76,10 @@
F = new /obj/effect/particle_effect/foam(T, metal)
F.amount = amount
if(!metal)
- F.create_reagents(15)
+ F.create_reagents(25)
if(reagents)
for(var/datum/reagent/R in reagents.reagent_list)
- F.reagents.add_reagent(R.id, min(R.volume, 3), R.data, reagents.chem_temp)
+ F.reagents.add_reagent(R.id, min(R.volume, 5), R.data, reagents.chem_temp)
F.color = mix_color_from_reagents(reagents.reagent_list)
// foam disolves when heated
@@ -149,14 +149,14 @@
F.amount = amount
if(!metal) // don't carry other chemicals if a metal foam
- F.create_reagents(15)
+ F.create_reagents(25)
if(carried_reagents)
for(var/id in carried_reagents)
if(banned_reagents.Find("[id]"))
continue
var/datum/reagent/reagent_volume = carried_reagents[id]
- F.reagents.add_reagent(id, min(reagent_volume, 3), null, temperature)
+ F.reagents.add_reagent(id, min(reagent_volume, 5), null, temperature)
F.color = mix_color_from_reagents(F.reagents.reagent_list)
else
F.reagents.add_reagent("cleaner", 1)
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index f395d959ca3..54e2d5bcdc5 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -580,13 +580,6 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d
/obj/item/attack_hulk(mob/living/carbon/human/user)
return FALSE
-/obj/item/proc/check_martial_counter(mob/living/carbon/human/target, mob/living/carbon/human/user) //handles block for CQC
- if(target.check_block())
- target.visible_message("[target.name] blocks [src] and twists [user]'s arm behind [user.p_their()] back!",
- "You block the attack!")
- user.Stun(2)
- return TRUE
-
/obj/item/proc/update_slot_icon()
if(!ismob(loc))
return
diff --git a/code/game/objects/items/flag.dm b/code/game/objects/items/flag.dm
index 3ba466b7eec..2e804fe3c88 100644
--- a/code/game/objects/items/flag.dm
+++ b/code/game/objects/items/flag.dm
@@ -170,8 +170,8 @@
icon_state = "atmosflag"
/obj/item/flag/command
- name = "Commandzikstan flag"
- desc = "The flag of the independent, sovereign nation of Commandzikstan."
+ name = "Command flag"
+ desc = "The flag of the independent, sovereign nation of Command."
icon_state = "ntflag"
//Antags
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index eb09e72b5f0..2a3934e251c 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -1395,7 +1395,12 @@ obj/item/toy/cards/deck/syndicate/black
/obj/item/toy/russian_revolver/attack(mob/M, mob/living/user)
return
-/obj/item/toy/russian_revolver/afterattack(atom/target, mob/user, proximity)
+/obj/item/toy/russian_revolver/afterattack(atom/target, mob/user, flag, params)
+ if(flag)
+ if(target in user.contents)
+ return
+ if(!ismob(target))
+ return
shoot_gun(user)
/obj/item/toy/russian_revolver/proc/spin_cylinder()
diff --git a/code/game/objects/items/weapons/melee/misc.dm b/code/game/objects/items/weapons/melee/misc.dm
index 5f131758502..943d20e9699 100644
--- a/code/game/objects/items/weapons/melee/misc.dm
+++ b/code/game/objects/items/weapons/melee/misc.dm
@@ -1,6 +1,13 @@
/obj/item/melee
needs_permit = 1
+/obj/item/melee/proc/check_martial_counter(mob/living/carbon/human/target, mob/living/carbon/human/user)
+ if(target.check_block())
+ target.visible_message("[target.name] blocks [src] and twists [user]'s arm behind [user.p_their()] back!",
+ "You block the attack!")
+ user.Stun(2)
+ return TRUE
+
/obj/item/melee/chainofcommand
name = "chain of command"
desc = "A tool used by great men to placate the frothing masses."
diff --git a/code/game/objects/items/weapons/storage/firstaid.dm b/code/game/objects/items/weapons/storage/firstaid.dm
index 5e81c320041..fab82df4b4e 100644
--- a/code/game/objects/items/weapons/storage/firstaid.dm
+++ b/code/game/objects/items/weapons/storage/firstaid.dm
@@ -295,11 +295,11 @@
for(var/obj/item/reagent_containers/food/pill/P in contents)
P.attack(C, C)
C.visible_message("[C] [rapid_post_instake_message]")
- return
+ return
return ..()
-/obj/item/storage/pill_bottle/attackby(var/obj/item/I, mob/user as mob, params)
+/obj/item/storage/pill_bottle/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/pen) || istype(I, /obj/item/flashlight/pen))
var/tmp_label = sanitize(input(user, "Enter a label for [name]","Label",label_text))
if(length(tmp_label) > MAX_NAME_LEN)
diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm
index c96271d6ddd..ecf1acd701e 100644
--- a/code/game/objects/items/weapons/storage/uplink_kits.dm
+++ b/code/game/objects/items/weapons/storage/uplink_kits.dm
@@ -254,6 +254,13 @@
new /obj/item/ammo_casing/shotgun/assassination(src)
new /obj/item/gun/projectile/revolver/doublebarrel/improvised/cane(src)
+/obj/item/storage/box/syndie_kit/fake_revolver
+ name = "trick revolver kit"
+
+/obj/item/storage/box/syndie_kit/fake_revolver/New()
+ ..()
+ new /obj/item/toy/russian_revolver/trick_revolver(src)
+
/obj/item/storage/box/syndie_kit/mimery
name = "advanced mimery kit"
diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm
index b7356a7757b..f128b874eaa 100644
--- a/code/game/objects/items/weapons/stunbaton.dm
+++ b/code/game/objects/items/weapons/stunbaton.dm
@@ -141,6 +141,12 @@
if(isrobot(M))
..()
return
+
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ if(check_martial_counter(H, user))
+ return
+
if(!isliving(M))
return
@@ -166,8 +172,6 @@
if(ishuman(L))
var/mob/living/carbon/human/H = L
- if(check_martial_counter(L, user))
- return
if(H.check_shields(0, "[user]'s [name]", src, MELEE_ATTACK)) //No message; check_shields() handles that
playsound(L, 'sound/weapons/genhit.ogg', 50, 1)
return
diff --git a/code/game/objects/items/weapons/swords_axes_etc.dm b/code/game/objects/items/weapons/swords_axes_etc.dm
index 3fc4b4b7717..d0526ebbcb8 100644
--- a/code/game/objects/items/weapons/swords_axes_etc.dm
+++ b/code/game/objects/items/weapons/swords_axes_etc.dm
@@ -52,7 +52,9 @@
if(ishuman(target))
var/mob/living/carbon/human/H = target
if(H.check_shields(0, "[user]'s [name]", src, MELEE_ATTACK))
- return 0
+ return
+ if(check_martial_counter(H, user))
+ return
playsound(get_turf(src), 'sound/effects/woodhit.ogg', 75, 1, -1)
target.Weaken(3)
add_attack_logs(user, target, "Stunned with [src]")
diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm
index 246fc5df75d..572495b503f 100644
--- a/code/game/objects/obj_defense.dm
+++ b/code/game/objects/obj_defense.dm
@@ -49,13 +49,9 @@
tforce = O.throwforce
take_damage(tforce, BRUTE, "melee", 1, get_dir(src, AM))
-/obj/ex_act(severity, target)
+/obj/ex_act(severity)
if(resistance_flags & INDESTRUCTIBLE)
return
- if(target == src)
- obj_integrity = 0
- qdel(src)
- return
switch(severity)
if(1)
obj_integrity = 0
@@ -69,7 +65,8 @@
. = ..()
playsound(src, P.hitsound, 50, 1)
visible_message("[src] is hit by \a [P]!")
- take_damage(P.damage, P.damage_type, P.flag, 0, turn(P.dir, 180), P.armour_penetration)
+ if(!QDELETED(src)) //Bullet on_hit effect might have already destroyed this object
+ take_damage(P.damage, P.damage_type, P.flag, 0, turn(P.dir, 180), P.armour_penetration)
/obj/proc/hulk_damage()
return 150 //the damage hulks do on punches to this object, is affected by melee armor
diff --git a/code/game/objects/structures/statues.dm b/code/game/objects/structures/statues.dm
index 88adc9643ba..6f531f5c14c 100644
--- a/code/game/objects/structures/statues.dm
+++ b/code/game/objects/structures/statues.dm
@@ -256,18 +256,18 @@
/obj/structure/statue/diamond
hardness = 10
material_drop_type = /obj/item/stack/sheet/mineral/diamond
- desc = "This is a very expensive diamond statue"
+ desc = "This is a very expensive diamond statue."
/obj/structure/statue/diamond/captain
- name = "statue of THE captain."
+ name = "statue of THE captain"
icon_state = "cap"
/obj/structure/statue/diamond/ai1
- name = "statue of the AI hologram."
+ name = "statue of the AI hologram"
icon_state = "ai1"
/obj/structure/statue/diamond/ai2
- name = "statue of the AI core."
+ name = "statue of the AI core"
icon_state = "ai2"
/obj/structure/statue/bananium
diff --git a/code/game/verbs/ooc.dm b/code/game/verbs/ooc.dm
index a35047bb9ad..9325d3a08b5 100644
--- a/code/game/verbs/ooc.dm
+++ b/code/game/verbs/ooc.dm
@@ -4,25 +4,21 @@ var/global/mentor_ooc_colour = "#0099cc"
var/global/moderator_ooc_colour = "#184880"
var/global/admin_ooc_colour = "#b82e00"
-/client/verb/ooc(msg as text)
+//Checks if the client already has a text input open
+/client/proc/checkTyping()
+ return (prefs.toggles & TYPING_ONCE && typing)
+
+/client/verb/ooc(msg = "" as text)
set name = "OOC"
set category = "OOC"
-
+
if(!mob)
return
if(IsGuestKey(key))
to_chat(src, "Guests may not use OOC.")
return
- msg = trim(sanitize(copytext(msg, 1, MAX_MESSAGE_LEN)))
- if(!msg)
- return
-
- if(!(prefs.toggles & CHAT_OOC))
- to_chat(src, "You have OOC muted.")
- return
-
- if(!check_rights(R_ADMIN|R_MOD,0))
+ if(!check_rights(R_ADMIN|R_MOD, 0))
if(!config.ooc_allowed)
to_chat(src, "OOC is globally muted.")
return
@@ -32,6 +28,19 @@ var/global/admin_ooc_colour = "#b82e00"
if(prefs.muted & MUTE_OOC)
to_chat(src, "You cannot use OOC (muted).")
return
+
+ if(!msg)
+ msg = typing_input(src.mob, "", "ooc \"text\"")
+
+ msg = trim(sanitize(copytext(msg, 1, MAX_MESSAGE_LEN)))
+ if(!msg)
+ return
+
+ if(!(prefs.toggles & CHAT_OOC))
+ to_chat(src, "You have OOC muted.")
+ return
+
+ if(!check_rights(R_ADMIN|R_MOD,0))
if(handle_spam_prevention(msg, MUTE_OOC, OOC_COOLDOWN))
return
if(findtext(msg, "byond://"))
@@ -150,7 +159,7 @@ var/global/admin_ooc_colour = "#b82e00"
feedback_add_details("admin_verb","ROC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-/client/verb/looc(msg as text)
+/client/verb/looc(msg = "" as text)
set name = "LOOC"
set desc = "Local OOC, seen only by those in view."
set category = "OOC"
@@ -161,14 +170,6 @@ var/global/admin_ooc_colour = "#b82e00"
to_chat(src, "Guests may not use OOC.")
return
- msg = trim(sanitize(copytext(msg, 1, MAX_MESSAGE_LEN)))
- if(!msg)
- return
-
- if(!(prefs.toggles & CHAT_LOOC))
- to_chat(src, "You have LOOC muted.")
- return
-
if(!check_rights(R_ADMIN|R_MOD,0))
if(!config.looc_allowed)
to_chat(src, "LOOC is globally muted.")
@@ -179,6 +180,19 @@ var/global/admin_ooc_colour = "#b82e00"
if(prefs.muted & MUTE_OOC)
to_chat(src, "You cannot use LOOC (muted).")
return
+
+ if(!msg)
+ msg = typing_input(src.mob, "Local OOC, seen only by those in view.", "looc \"text\"")
+
+ msg = trim(sanitize(copytext(msg, 1, MAX_MESSAGE_LEN)))
+ if(!msg)
+ return
+
+ if(!(prefs.toggles & CHAT_LOOC))
+ to_chat(src, "You have LOOC muted.")
+ return
+
+ if(!check_rights(R_ADMIN|R_MOD,0))
if(handle_spam_prevention(msg, MUTE_OOC, OOC_COOLDOWN))
return
if(findtext(msg, "byond://"))
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 2dd60a674ca..c15600f7bb6 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -28,6 +28,11 @@ var/global/nologevent = 0
if(C.prefs && !(C.prefs.toggles & CHAT_NO_TICKETLOGS))
to_chat(C, msg)
+/proc/message_mentorTicket(var/msg)
+ for(var/client/C in GLOB.admins)
+ if(check_rights(R_ADMIN | R_MENTOR | R_MOD, 0, C.mob))
+ if(C.prefs && !(C.prefs.toggles & CHAT_NO_MENTORTICKETLOGS))
+ to_chat(C, msg)
/proc/admin_ban_mobsearch(var/mob/M, var/ckey_to_find, var/mob/admin_to_notify)
if(!M || !M.ckey)
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 0c4dd38ef5f..d5eb9b59c0d 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -205,6 +205,8 @@ var/list/admin_verbs_mentor = list(
/client/proc/cmd_admin_pm_context, /*right-click adminPM interface*/
/client/proc/cmd_admin_pm_panel, /*admin-pm list*/
/client/proc/cmd_admin_pm_by_key_panel, /*admin-pm list by key*/
+ /client/proc/openMentorTicketUI,
+ /client/proc/toggleMentorTicketLogs,
/client/proc/cmd_mentor_say /* mentor say*/
// cmd_mentor_say is added/removed by the toggle_mentor_chat verb
)
@@ -219,10 +221,10 @@ var/list/admin_verbs_snpc = list(
/client/proc/hide_snpc_verbs
)
var/list/admin_verbs_ticket = list(
- /client/proc/openTicketUI,
+ /client/proc/openAdminTicketUI,
/client/proc/toggleticketlogs,
- /client/proc/resolveAllTickets,
- /client/proc/openUserUI
+ /client/proc/resolveAllAdminTickets,
+ /client/proc/resolveAllMentorTickets
)
/client/proc/on_holder_add()
@@ -940,6 +942,20 @@ var/list/admin_verbs_ticket = list(
else
to_chat(usr, "You now will get admin log messages.")
+/client/proc/toggleMentorTicketLogs()
+ set name = "Toggle Mentor Ticket Messgaes"
+ set category = "Preferences"
+
+ if(!check_rights(R_MENTOR))
+ return
+
+ prefs.toggles ^= CHAT_NO_MENTORTICKETLOGS
+ prefs.save_preferences(src)
+ if(prefs.toggles & CHAT_NO_MENTORTICKETLOGS)
+ to_chat(usr, "You now won't get mentor ticket messages.")
+ else
+ to_chat(usr, "You now will get mentor ticket messages.")
+
/client/proc/toggleticketlogs()
set name = "Toggle Admin Ticket Messgaes"
set category = "Preferences"
diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm
index 92cd3eb2803..f50bae146c3 100644
--- a/code/modules/admin/player_panel.dm
+++ b/code/modules/admin/player_panel.dm
@@ -548,6 +548,16 @@
if(spider_minds.len)
dat += check_role_table("Terror Spiders", spider_minds)
+ var/count_eggs = 0
+ var/count_spiderlings = 0
+ for(var/obj/structure/spider/eggcluster/terror_eggcluster/E in ts_egg_list)
+ if(is_station_level(E.z))
+ count_eggs += E.spiderling_number
+ for(var/obj/structure/spider/spiderling/terror_spiderling/L in ts_spiderling_list)
+ if(!L.stillborn && is_station_level(L.z))
+ count_spiderlings += 1
+ dat += "| Growing TS on-station: [count_eggs] egg[count_eggs != 1 ? "s" : ""], [count_spiderlings] spiderling[count_spiderlings != 1 ? "s" : ""]. |
"
+
if(ticker.mode.ert.len)
dat += check_role_table("ERT", ticker.mode.ert)
diff --git a/code/modules/admin/tickets/adminticketsverbs.dm b/code/modules/admin/tickets/adminticketsverbs.dm
index f203ef501e8..9ad1f722b08 100644
--- a/code/modules/admin/tickets/adminticketsverbs.dm
+++ b/code/modules/admin/tickets/adminticketsverbs.dm
@@ -1,8 +1,8 @@
//Verbs
-/client/proc/openTicketUI()
+/client/proc/openAdminTicketUI()
- set name = "Open Ticket Interface"
+ set name = "Open Admin Ticket Interface"
set category = "Admin"
if(!holder || !check_rights(R_ADMIN))
@@ -10,8 +10,8 @@
SStickets.showUI(usr)
-/client/proc/resolveAllTickets()
- set name = "Resolve All Open Tickets"
+/client/proc/resolveAllAdminTickets()
+ set name = "Resolve All Open Admin Tickets"
set category = "Admin"
if(!holder || !check_rights(R_ADMIN))
@@ -22,12 +22,7 @@
SStickets.resolveAllOpenTickets()
-/client/proc/openUserUI()
-
- set name = "My Tickets"
+/client/verb/openAdminUserUI()
+ set name = "My Admin Tickets"
set category = "Admin"
-
- if(!holder || !check_rights(R_ADMIN))
- return
-
SStickets.userDetailUI(usr)
diff --git a/code/modules/admin/tickets/mentorticketsverbs.dm b/code/modules/admin/tickets/mentorticketsverbs.dm
new file mode 100644
index 00000000000..765a1afb9da
--- /dev/null
+++ b/code/modules/admin/tickets/mentorticketsverbs.dm
@@ -0,0 +1,28 @@
+//Verbs
+
+/client/proc/openMentorTicketUI()
+
+ set name = "Open Mentor Ticket Interface"
+ set category = "Admin"
+
+ if(!holder || !check_rights(R_MENTOR))
+ return
+
+ SSmentor_tickets.showUI(usr)
+
+/client/proc/resolveAllMentorTickets()
+ set name = "Resolve All Open Mentor Tickets"
+ set category = "Admin"
+
+ if(!holder || !check_rights(R_ADMIN))
+ return
+
+ if(alert("Are you sure you want to resolve ALL open tickets?","Resolve all open tickets?","Yes","No") != "Yes")
+ return
+
+ SSmentor_tickets.resolveAllOpenTickets()
+
+/client/verb/openMentorUserUI()
+ set name = "My Mentor Tickets"
+ set category = "Admin"
+ SSmentor_tickets.userDetailUI(usr)
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index a05246852ff..60cf653ef16 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -32,6 +32,12 @@
var/ticketID = text2num(href_list["openadminticket"])
SStickets.showDetailUI(usr, ticketID)
+ if(href_list["openmentorticket"])
+ if(!check_rights(R_MENTOR|R_MOD|R_ADMIN))
+ return
+ var/ticketID = text2num(href_list["openmentorticket"])
+ SSmentor_tickets.showDetailUI(usr, ticketID)
+
if(href_list["stickyban"])
stickyban(href_list["stickyban"],href_list)
@@ -1546,22 +1552,13 @@
check_antagonists()
else if(href_list["take_question"])
- var/mob/M = locateUID(href_list["take_question"])
- var/is_mhelp = href_list["is_mhelp"]
- if(ismob(M))
- var/helptype = "ADMINHELP"
- if(is_mhelp)
- helptype = "MENTORHELP"
- var/take_msg = "[helptype]: [key_name_hidden(usr.client)] is attending to [key_name(M)]'s question."
- for(var/client/X in GLOB.admins)
- if(check_rights(R_ADMIN, 0, X.mob))
- to_chat(X, take_msg)
- else if(is_mhelp && check_rights(R_MOD|R_MENTOR, 0, X.mob))
- to_chat(X, take_msg)
- to_chat(M, "Your question is being attended to by [key_name_hidden(usr.client, null, 0)]. Thanks for your patience!")
- else
- to_chat(usr, "Unable to locate mob.")
-
+ var/index = text2num(href_list["take_question"])
+
+ if(href_list["is_mhelp"])
+ SSmentor_tickets.takeTicket(index)
+ else //Ahelp
+ SStickets.takeTicket(index)
+
else if(href_list["cult_nextobj"])
if(alert(usr, "Validate the current Cult objective and unlock the next one?", "Cult Cheat Code", "Yes", "No") != "Yes")
return
diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm
index 1baf6bf0ee8..a1f56c52c78 100644
--- a/code/modules/admin/verbs/adminhelp.dm
+++ b/code/modules/admin/verbs/adminhelp.dm
@@ -103,31 +103,46 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","
if(check_rights(R_MENTOR, 0, X.mob))
mentorholders += X
continue
+ var/ticketNum // Holder for the ticket number
+ var/prunedmsg ="[src]: [msg]" // Message without links
+ var/datum/ticket/T
+ var/isMhelp = selected_type == "Mentorhelp"
+ var/span
+ if(isMhelp)
+ span = ""
+ if(SSmentor_tickets.checkForOpenTicket(src)) // If user already has an open ticket
+ T = SSmentor_tickets.checkForOpenTicket(src)
+ else
+ ticketNum = SSmentor_tickets.getTicketCounter() // ticketNum is the ticket ready to be assigned.
+ else //Ahelp
+ span = ""
+ if(SStickets.checkForOpenTicket(src)) // If user already has an open ticket
+ T = SStickets.checkForOpenTicket(src) // Make T equal to the ticket they have open
+ else
+ ticketNum = SStickets.getTicketCounter() // ticketNum is the ticket ready to be assigned.
+
+ if(T)
+ ticketNum = T.ticketNum // ticketNum is the number of their ticket.
+ T.addResponse(src, msg)
+
+ msg = "[span][selected_type]: [key_name(src, TRUE, selected_type)] ([ADMIN_QUE(mob,"?")]) ([ADMIN_PP(mob,"PP")]) ([ADMIN_VV(mob,"VV")]) ([ADMIN_SM(mob,"SM")]) ([admin_jump_link(mob)]) (CA) (TICKET) [ai_found ? "(CL)" : ""] (TAKE) : [span][msg]"
+ if(isMhelp)
+ //Open a new adminticket and inform the user.
+ SSmentor_tickets.newTicket(src, prunedmsg, msg)
+ for(var/client/X in mentorholders + modholders + adminholders)
+ if(X.prefs.sound & SOUND_MENTORHELP)
+ X << 'sound/effects/adminhelp.ogg'
+ to_chat(X, msg)
+ else //Ahelp
+ //Open a new adminticket and inform the user.
+ SStickets.newTicket(src, prunedmsg, msg)
+ for(var/client/X in modholders + adminholders)
+ if(X.prefs.sound & SOUND_ADMINHELP)
+ X << 'sound/effects/adminhelp.ogg'
+ window_flash(X)
+ to_chat(X, msg)
- switch(selected_type)
- if("Mentorhelp")
- msg = "[selected_type]: [key_name(src, TRUE, selected_type)] ([ADMIN_QUE(mob,"?")]) ([ADMIN_PP(mob,"PP")]) ([ADMIN_VV(mob,"VV")]) ([ADMIN_SM(mob,"SM")]) ([admin_jump_link(mob)]) (CA) (REJT) [ai_found ? " (CL)" : ""] (TAKE) : [msg]"
- for(var/client/X in mentorholders + modholders + adminholders)
- if(X.prefs.sound & SOUND_MENTORHELP)
- X << 'sound/effects/adminhelp.ogg'
- to_chat(X, msg)
- if("Adminhelp")
- var/ticketNum // Holder for the ticket number
- var/prunedmsg ="[usr.client]: [msg]" // Message without links
- if(SStickets.checkForOpenTicket(usr)) // If user already has an open ticket
- var/datum/admin_ticket/T = SStickets.checkForOpenTicket(usr) // Make T equal to the ticket they have open
- ticketNum = T.ticketNum // ticketNum is the number of their ticket.
- T.addResponse(usr.client, msg)
- else
- ticketNum = SStickets.getTicketCounter() // ticketNum is the ticket ready to be assigned.
- msg = "[selected_type]: [key_name(src, TRUE, selected_type)] ([ADMIN_QUE(mob,"?")]) ([ADMIN_PP(mob,"PP")]) ([ADMIN_VV(mob,"VV")]) ([ADMIN_SM(mob,"SM")]) ([admin_jump_link(mob)]) (CA) (TICKET) [ai_found ? " (CL)" : ""](TAKE) : [msg]"
- //Open a new adminticket and inform the user.
- SStickets.newTicket(src, prunedmsg, msg)
- for(var/client/X in modholders + adminholders)
- if(X.prefs.sound & SOUND_ADMINHELP)
- X << 'sound/effects/adminhelp.ogg'
- window_flash(X)
- to_chat(X, msg)
+
//show it to the person adminhelping too
to_chat(src, "[selected_type]: [original_msg]")
diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm
index 5303480e905..e9d813c1439 100644
--- a/code/modules/admin/verbs/adminpm.dm
+++ b/code/modules/admin/verbs/adminpm.dm
@@ -182,23 +182,28 @@
else
if(check_rights(R_ADMIN|R_MOD, 0, X.mob))
to_chat(X, "[type]: [key_name(src, TRUE, type)]->[key_name(C, TRUE, type)]: [emoji_msg]")
-
- if(type == "Mentorhelp")
- return
+
//Check if the mob being PM'd has any open admin tickets.
var/tickets = list()
- tickets = SStickets.checkForTicket(C)
+ if(type == "Mentorhelp")
+ tickets = SSmentor_tickets.checkForTicket(C)
+ else
+ tickets = SStickets.checkForTicket(C)
if(tickets)
- for(var/datum/admin_ticket/i in tickets)
+ for(var/datum/ticket/i in tickets)
i.addResponse(src, msg) // Add this response to their open tickets.
return
-
- if(check_rights(R_ADMIN|R_MOD, 0, C.mob)) //Is the person being pm'd an admin? If so we check if the pm'er has open tickets
- tickets = SStickets.checkForTicket(src)
- if(tickets)
- for(var/datum/admin_ticket/i in tickets)
- i.addResponse(src, msg)
- return
+ if(type == "Mentorhelp")
+ if(check_rights(R_ADMIN|R_MOD|R_MENTOR, 0, C.mob)) //Is the person being pm'd an admin? If so we check if the pm'er has open tickets
+ tickets = SSmentor_tickets.checkForTicket(src)
+ else // Ahelp
+ if(check_rights(R_ADMIN|R_MOD, 0, C.mob)) //Is the person being pm'd an admin? If so we check if the pm'er has open tickets
+ tickets = SStickets.checkForTicket(src)
+
+ if(tickets)
+ for(var/datum/ticket/i in tickets)
+ i.addResponse(src, msg)
+ return
/client/proc/cmd_admin_irc_pm()
diff --git a/code/modules/antagonists/_common/antag_hud.dm b/code/modules/antagonists/_common/antag_hud.dm
index 693b0b9450d..89ad9af15ab 100644
--- a/code/modules/antagonists/_common/antag_hud.dm
+++ b/code/modules/antagonists/_common/antag_hud.dm
@@ -1,5 +1,5 @@
/datum/atom_hud/antag
- hud_icons = list(SPECIALROLE_HUD,NATIONS_HUD)
+ hud_icons = list(SPECIALROLE_HUD)
var/self_visible = TRUE
/datum/atom_hud/antag/hidden
@@ -38,16 +38,6 @@
if(M.mind || new_icon_state) //in mindless mobs, only null is acceptable, otherwise we're antagging a mindless mob, meaning we should runtime
M.mind.antag_hud_icon_state = new_icon_state
-//Nations Icons
-/proc/set_nations_hud(mob/M, new_icon_state)
- if(!istype(M))
- CRASH("set_antag_hud(): [M] ([M.type]) is not a mob!")
- var/image/holder = M.hud_list[NATIONS_HUD]
- if(holder)
- holder.icon_state = new_icon_state
- if(M.mind || new_icon_state) //in mindless mobs, only null is acceptable, otherwise we're antagging a mindless mob, meaning we should runtime
- M.mind.antag_hud_icon_state = new_icon_state
-
//MIND PROCS
//these are called by mind.transfer_to()
/datum/mind/proc/transfer_antag_huds(datum/atom_hud/antag/newhud)
diff --git a/code/modules/client/client defines.dm b/code/modules/client/client defines.dm
index c88347a305b..00900fe5fd1 100644
--- a/code/modules/client/client defines.dm
+++ b/code/modules/client/client defines.dm
@@ -19,6 +19,8 @@
var/area = null
var/time_died_as_mouse = null //when the client last died as a mouse
+ var/typing = FALSE // Prevents typing window stacking
+
var/adminhelped = 0
var/gc_destroyed //Time when this object was destroyed.
@@ -65,25 +67,6 @@
// Set on login.
var/datum/media_manager/media = null
- /////////////////////////////////////////////////////////////////////
- //adv. hotkey mode vars, code using them in /interface/interface.dm//
- /////////////////////////////////////////////////////////////////////
-
- var/hotkeytype = "QWERTY" //what set of hotkeys is in use(defaulting to QWERTY because I can't be bothered to make this save on SQL)
- var/hotkeyon = 0 //is the hotkey on?
-
- var/hotkeylist = list( //list defining hotkey types, look at lists in place for structure if adding any if the future
- "QWERTY" = list(
- "on" = "hotkeymode",
- "off" = "macro"),
- "AZERTY" = list(
- "on" = "AZERTYon",
- "off" = "AZERTYoff"),
- "Cyborg" = list(
- "on" = "borghotkeymode",
- "off" = "borgmacro")
- )
-
var/topic_debugging = 0 //if set to true, allows client to see nanoUI errors -- yes i realize this is messy but it'll make live testing infinitely easier
control_freak = CONTROL_FREAK_ALL | CONTROL_FREAK_SKIN | CONTROL_FREAK_MACROS
diff --git a/code/modules/client/preference/preferences_mysql.dm b/code/modules/client/preference/preferences_mysql.dm
index 6800a63f669..b355d921016 100644
--- a/code/modules/client/preference/preferences_mysql.dm
+++ b/code/modules/client/preference/preferences_mysql.dm
@@ -55,7 +55,7 @@
ooccolor = sanitize_hexcolor(ooccolor, initial(ooccolor))
UI_style = sanitize_inlist(UI_style, list("White", "Midnight"), initial(UI_style))
default_slot = sanitize_integer(default_slot, 1, max_save_slots, initial(default_slot))
- toggles = sanitize_integer(toggles, 0, 524287, initial(toggles))
+ toggles = sanitize_integer(toggles, 0, 2097151, initial(toggles))
sound = sanitize_integer(sound, 0, 65535, initial(sound))
UI_style_color = sanitize_hexcolor(UI_style_color, initial(UI_style_color))
UI_style_alpha = sanitize_integer(UI_style_alpha, 0, 255, initial(UI_style_alpha))
diff --git a/code/modules/client/preference/preferences_toggles.dm b/code/modules/client/preference/preferences_toggles.dm
index 2899432501a..703de37468e 100644
--- a/code/modules/client/preference/preferences_toggles.dm
+++ b/code/modules/client/preference/preferences_toggles.dm
@@ -231,3 +231,15 @@
else
to_chat(usr, "You have enabled karma gains.")
return
+
+/client/verb/toggle_popup_limiter()
+ set name = "Toggle Text Popup Limiter"
+ set category = "Preferences"
+ set desc = "Will let you limit the text input popups to one at a time."
+ prefs.toggles ^= TYPING_ONCE
+ prefs.save_preferences(src)
+ if(prefs.toggles & TYPING_ONCE)
+ to_chat(usr, "You have enabled text popup limiting.")
+ else
+ to_chat(usr, "You have disabled text popup limiting.")
+ return
diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm
index f7d8fe3ee38..7a65d579b8e 100644
--- a/code/modules/clothing/gloves/color.dm
+++ b/code/modules/clothing/gloves/color.dm
@@ -12,6 +12,9 @@
description_antag = "These are a pair of power gloves, and can be used to fire bolts of electricity while standing over powered power cables."
var/old_mclick_override
var/datum/middleClickOverride/power_gloves/mclick_override = new /datum/middleClickOverride/power_gloves
+ var/last_shocked = 0
+ var/shock_delay = 40
+ var/unlimited_power = FALSE // Does this really need explanation?
/obj/item/clothing/gloves/color/yellow/power/equipped(mob/user, slot)
if(!ishuman(user))
@@ -21,7 +24,10 @@
if(H.middleClickOverride)
old_mclick_override = H.middleClickOverride
H.middleClickOverride = mclick_override
- to_chat(H, "You feel electricity begin to build up in [src].")
+ if(!unlimited_power)
+ to_chat(H, "You feel electricity begin to build up in [src].")
+ else
+ to_chat(H, "You feel like you have UNLIMITED POWER!!")
/obj/item/clothing/gloves/color/yellow/power/dropped(mob/user, slot)
if(!ishuman(user))
@@ -34,6 +40,12 @@
else
H.middleClickOverride = null
+/obj/item/clothing/gloves/color/yellow/power/unlimited
+ name = "UNLIMITED POWER gloves"
+ desc = "These gloves possess UNLIMITED POWER."
+ shock_delay = 0
+ unlimited_power = TRUE
+
/obj/item/clothing/gloves/color/yellow/fake
desc = "These gloves will protect the wearer from electric shock. They don't feel like rubber..."
siemens_coefficient = 1
diff --git a/code/modules/martial_arts/cqc.dm b/code/modules/martial_arts/cqc.dm
index 54f9ac97cd9..b57e7fc4f98 100644
--- a/code/modules/martial_arts/cqc.dm
+++ b/code/modules/martial_arts/cqc.dm
@@ -1,4 +1,4 @@
-#define SLAM_COMBO "HG"
+#define SLAM_COMBO "GH"
#define KICK_COMBO "HH"
#define RESTRAIN_COMBO "GG"
#define PRESSURE_COMBO "DG"
@@ -8,15 +8,24 @@
name = "CQC"
help_verb = /mob/living/carbon/human/proc/CQC_help
block_chance = 75
+ var/just_a_cook = FALSE
+ var/static/list/areas_under_siege = typecacheof(list(/area/crew_quarters/kitchen,
+ /area/crew_quarters/cafeteria,
+ /area/crew_quarters/bar))
-/datum/martial_art/cqc/can_use(mob/living/carbon/human/H)
- if(istype(H.gloves, /obj/item/clothing/gloves/fingerless/rapid))
- return FALSE
- return ..()
+/datum/martial_art/cqc/under_siege
+ name = "Close Quarters Cooking"
+ just_a_cook = TRUE
/datum/martial_art/cqc/proc/drop_restraining()
restraining = FALSE
+/datum/martial_art/cqc/can_use(mob/living/carbon/human/H)
+ var/area/A = get_area(H)
+ if(just_a_cook && !(is_type_in_typecache(A, areas_under_siege)))
+ return FALSE
+ return ..()
+
/datum/martial_art/cqc/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(!can_use(A))
return FALSE
@@ -44,22 +53,23 @@
/datum/martial_art/cqc/proc/Slam(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(!can_use(A))
return FALSE
- if(!D.stat || !D.weakened)
+ if(!D.weakened && !D.resting && !D.lying)
D.visible_message("[A] slams [D] into the ground!", \
"[A] slams you into the ground!")
playsound(get_turf(A), 'sound/weapons/slam.ogg', 50, 1, -1)
D.apply_damage(10, BRUTE)
D.Weaken(6)
add_attack_logs(A, D, "Melee attacked with martial-art [src] : Slam", ATKLOG_ALL)
- else //if target can't be slammed, do a regular grab attack then clear the streak
- streak = ""
- grab_act(A, D)
- streak = ""
+ return TRUE
+ streak = ""
+ harm_act(A, D)
+ streak = ""
return TRUE
/datum/martial_art/cqc/proc/Kick(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(!can_use(A))
return FALSE
+ var/success = FALSE
if(!D.stat || !D.weakened)
D.visible_message("[A] kicks [D] back!", \
"[A] kicks you back!")
@@ -68,17 +78,20 @@
D.throw_at(throw_target, 1, 14, A)
D.apply_damage(10, BRUTE)
add_attack_logs(A, D, "Melee attacked with martial-art [src] : Kick", ATKLOG_ALL)
- if(D.weakened && !D.stat)
- D.visible_message("[A] kicks [D]'s head, knocking [D.p_them()] out!", \
- "[A] kicks your head, knocking you out!")
- playsound(get_turf(A), 'sound/weapons/genhit1.ogg', 50, 1, -1)
- D.SetSleeping(15)
- D.adjustBrainLoss(15, 150)
- add_attack_logs(A, D, "Knocked out with martial-art [src] : Kick", ATKLOG_ALL)
- else //if target can't be kicked, do a regular harm attack then clear the streak
- streak = ""
- harm_act(A, D)
- streak = ""
+ success = TRUE
+ if(D.weakened && !D.stat)
+ D.visible_message("[A] kicks [D]'s head, knocking [D.p_them()] out!", \
+ "[A] kicks your head, knocking you out!")
+ playsound(get_turf(A), 'sound/weapons/genhit1.ogg', 50, 1, -1)
+ D.SetSleeping(15)
+ D.adjustBrainLoss(15)
+ add_attack_logs(A, D, "Knocked out with martial-art [src] : Kick", ATKLOG_ALL)
+ success = TRUE
+ if(success)
+ return TRUE
+ streak = ""
+ harm_act(A, D)
+ streak = ""
return TRUE
/datum/martial_art/cqc/proc/Pressure(mob/living/carbon/human/A, mob/living/carbon/human/D)
@@ -103,6 +116,10 @@
restraining = TRUE
addtimer(CALLBACK(src, .proc/drop_restraining), 50, TIMER_UNIQUE)
add_attack_logs(A, D, "Melee attacked with martial-art [src] : Restrain", ATKLOG_ALL)
+ return TRUE
+ streak = ""
+ harm_act(A, D)
+ streak = ""
return TRUE
/datum/martial_art/cqc/proc/Consecutive(mob/living/carbon/human/A, mob/living/carbon/human/D)
@@ -118,10 +135,10 @@
D.adjustStaminaLoss(50)
D.apply_damage(25, BRUTE)
add_attack_logs(A, D, "Melee attacked with martial-art [src] : Consecutive", ATKLOG_ALL)
- else //if target can't be hit, do a regular harm attack then clear the streak
- streak = ""
- harm_act(A, D)
- streak = ""
+ return TRUE
+ streak = ""
+ harm_act(A, D)
+ streak = ""
return TRUE
/datum/martial_art/cqc/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
@@ -133,6 +150,8 @@
var/obj/item/grab/G = D.grabbedby(A, 1)
if(G)
G.state = GRAB_AGGRESSIVE //Instant aggressive grab
+ add_attack_logs(A, D, "Melee attacked with martial-art [src] : aggressively grabbed", ATKLOG_ALL)
+
return TRUE
/datum/martial_art/cqc/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
@@ -141,8 +160,9 @@
add_to_streak("H", D)
if(check_streak(A, D))
return TRUE
+ add_attack_logs(A, D, "Melee attacked with martial-art [src]", ATKLOG_ALL)
A.do_attack_animation(D)
- var/picked_hit_type = pick("CQC'd", "neck chopped", "gut punched")
+ var/picked_hit_type = pick("CQC'd", "neck chopped", "gut punched", "Big Bossed")
var/bonus_damage = 13
if(D.weakened || D.resting || D.lying)
bonus_damage += 5
@@ -154,7 +174,7 @@
playsound(get_turf(D), 'sound/weapons/cqchit1.ogg', 50, 1, -1)
D.visible_message("[A] [picked_hit_type] [D]!", \
"[A] [picked_hit_type] you!")
- add_attack_logs(A, D, "Melee attacked with martial-art [src]", ATKLOG_ALL)
+ add_attack_logs(A, D, "Melee attacked with martial-art [src] : [picked_hit_type]", ATKLOG_ALL)
if(A.resting && !D.stat && !D.weakened)
D.visible_message("[A] leg sweeps [D]!", \
"[A] leg sweeps you!")
@@ -168,24 +188,36 @@
if(!can_use(A))
return FALSE
add_to_streak("D", D)
+ var/obj/item/I = null
if(check_streak(A, D))
return TRUE
- if(!restraining)
- D.visible_message("[A] strikes [D]'s jaw with their hand!", \
- "[A] strikes your jaw, disorienting you!")
- playsound(get_turf(D), 'sound/weapons/cqchit1.ogg', 50, 1, -1)
- D.Jitter(2)
- D.apply_damage(5, BRUTE)
- add_attack_logs(A, D, "Melee attacked with martial-art [src] : Disarm", ATKLOG_ALL)
- if(restraining)
+ var/obj/item/grab/G = A.get_inactive_hand()
+ if(restraining && istype(G) && G.affecting == D)
D.visible_message("[A] puts [D] into a chokehold!", \
"[A] puts you into a chokehold!")
D.SetSleeping(20)
restraining = FALSE
- add_attack_logs(A, D, "Knocked out with martial-art [src] : Choke hold", ATKLOG_ALL)
+ if(G.state < GRAB_NECK)
+ G.state = GRAB_NECK
+ return TRUE
else
restraining = FALSE
- return FALSE
+
+ if(prob(65))
+ if(!D.stat || !D.weakened || !restraining)
+ I = D.get_active_hand()
+ D.visible_message("[A] strikes [D]'s jaw with their hand!", \
+ "[A] strikes your jaw, disorienting you!")
+ playsound(get_turf(D), 'sound/weapons/cqchit1.ogg', 50, 1, -1)
+ if(I && D.drop_item())
+ A.put_in_hands(I)
+ D.Jitter(2)
+ D.apply_damage(5, BRUTE)
+ else
+ D.visible_message("[A] attempted to disarm [D]!", "[A] attempted to disarm [D]!")
+ playsound(D, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
+
+ add_attack_logs(A, D, "Melee attacked with martial-art [src] : Disarmed [I ? " grabbing \the [I]" : ""]", ATKLOG_ALL)
return TRUE
/mob/living/carbon/human/proc/CQC_help()
@@ -194,11 +226,10 @@
set category = "CQC"
to_chat(usr, "You try to remember some of the basics of CQC.")
- to_chat(usr, "Slam: Harm Grab. Slam opponent into the ground, knocking them down.")
+ to_chat(usr, "Slam: Grab, switch hands, Harm. Slam opponent into the ground, knocking them down.")
to_chat(usr, "CQC Kick: Harm Harm. Knocks opponent away. Knocks out stunned or knocked down opponents.")
- to_chat(usr, "Restrain: Grab Switch Hand Grab. Locks opponent into a restraining position, stunning them.")
- to_chat(usr, "Choke Hold: Restrain Disarm. Knocks out an opponent you have restrained.")
+ to_chat(usr, "Restrain: Grab, switch hands, Grab. Locks opponents into a restraining position, disarm to knock them out with a choke hold.")
to_chat(usr, "Pressure: Disarm Grab. Decent stamina damage.")
to_chat(usr, "Consecutive CQC: Disarm Disarm Harm. Mainly offensive move, huge damage and decent stamina damage.")
- to_chat(usr, "In addition, by having your throw mode on when being attacked, you enter an active defense mode where you have a chance to block and sometimes even counter melee attacks done to you.")
\ No newline at end of file
+ to_chat(usr, "In addition, by having your throw mode on when being attacked, you enter an active defense mode where you have a chance to block and sometimes even counter attacks done to you.")
\ No newline at end of file
diff --git a/code/modules/mob/camera/camera.dm b/code/modules/mob/camera/camera.dm
index a5bfcb02e4b..bfeecdef055 100644
--- a/code/modules/mob/camera/camera.dm
+++ b/code/modules/mob/camera/camera.dm
@@ -14,7 +14,3 @@
/mob/camera/experience_pressure_difference()
return
-
-/mob/camera/Login()
- ..()
- update_interface()
diff --git a/code/modules/mob/dead/observer/login.dm b/code/modules/mob/dead/observer/login.dm
index 0990b085264..b44d8421b80 100644
--- a/code/modules/mob/dead/observer/login.dm
+++ b/code/modules/mob/dead/observer/login.dm
@@ -7,5 +7,3 @@
if(GLOB.non_respawnable_keys[ckey])
can_reenter_corpse = 0
GLOB.respawnable_list -= src
-
- update_interface()
\ No newline at end of file
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 3a65bcabd2c..17b1e201390 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -49,7 +49,7 @@ var/list/image/ghost_darkness_images = list() //this is a list of images for thi
T = get_turf(body) //Where is the body located?
attack_log = body.attack_log //preserve our attack logs by copying them to our ghost
- var/mutable_appearance/MA = copy_appearance(body)
+ var/mutable_appearance/MA = copy_appearance(body)
if(body.mind && body.mind.name)
MA.name = body.mind.name
else if(body.real_name)
@@ -139,11 +139,8 @@ Works together with spawning an observer, noted above.
var/client/C = U.client
for(var/mob/living/carbon/human/target in target_list)
C.images += target.hud_list[SPECIALROLE_HUD]
- //C.images += target.hud_list[NATIONS_HUD]
for(var/mob/living/silicon/target in target_list)
C.images += target.hud_list[SPECIALROLE_HUD]
- //C.images += target.hud_list[NATIONS_HUD]
-
return 1
/mob/proc/ghostize(var/flags = GHOST_CAN_REENTER)
@@ -179,30 +176,44 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(P)
if(TOO_EARLY_TO_GHOST)
warningmsg = "It's too early in the shift to enter cryo"
- // If it's not too early, we'll skip straight to ghosting out without penalty
else if(suiciding && TOO_EARLY_TO_GHOST)
warningmsg = "You have committed suicide too early in the round"
else if(stat != DEAD)
warningmsg = "You are alive"
+ if(isAI(src))
+ warningmsg = "You are a living AI! You should probably use OOC -> Wipe Core instead."
else if(GLOB.non_respawnable_keys[ckey])
warningmsg = "You have lost your right to respawn"
- if(!warningmsg)
- ghostize(1)
- else
+ if(warningmsg)
var/response
var/alertmsg = "Are you -sure- you want to ghost?\n([warningmsg]. If you ghost now, you probably won't be able to rejoin the round! You can't change your mind, so choose wisely!)"
response = alert(src, alertmsg,"Are you sure you want to ghost?","Stay in body","Ghost")
if(response != "Ghost")
- return //didn't want to ghost after-all
- StartResting()
- var/mob/dead/observer/ghost = ghostize(0) //0 parameter is so we can never re-enter our body, "Charlie, you can never come baaaack~" :3
- ghost.timeofdeath = world.time // Because the living mob won't have a time of death and we want the respawn timer to work properly.
+ return
+
+ if(stat == CONSCIOUS)
+ if(!is_admin_level(z))
+ player_ghosted = 1
+ if(mind && mind.special_role)
+ message_admins("[key_name_admin(src)] has ghosted while alive, with special_role: [mind.special_role]")
+
+ if(warningmsg)
+ // Not respawnable
+ var/mob/dead/observer/ghost = ghostize(0) // 0 parameter stops them re-entering their body
+ ghost.timeofdeath = world.time // Because the living mob won't have a time of death and we want the respawn timer to work properly.
+ else
+ // Respawnable
+ ghostize(1)
+
+ // If mob in morgue tray, update tray
var/obj/structure/morgue/Morgue = locate() in M.loc
if(istype(M.loc, /obj/structure/morgue))
Morgue = M.loc
if(Morgue)
Morgue.update()
+
+ // If mob in cryopod, despawn mob
if(P)
if(!P.control_computer)
P.find_control_computer(urgent=1)
@@ -210,7 +221,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
P.despawn_occupant()
return
-
/mob/dead/observer/Move(NewLoc, direct)
following = null
dir = direct
diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm
index 8a7c017818a..25b188911ad 100644
--- a/code/modules/mob/language.dm
+++ b/code/modules/mob/language.dm
@@ -523,7 +523,9 @@
flags = RESTRICTED | HIVEMIND
/datum/language/shadowling/broadcast(mob/living/speaker, message, speaker_mask)
- if(speaker.mind && speaker.mind.special_role)
+ if(speaker.mind && speaker.mind.special_role == SPECIAL_ROLE_SHADOWLING)
+ ..(speaker,"[message]", "([speaker.mind.special_role]) [speaker]")
+ else if(speaker.mind && speaker.mind.special_role)
..(speaker, message, "([speaker.mind.special_role]) [speaker]")
else
..(speaker, message)
diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm
index 03675f282e5..087ca959902 100644
--- a/code/modules/mob/living/carbon/brain/brain_item.dm
+++ b/code/modules/mob/living/carbon/brain/brain_item.dm
@@ -1,7 +1,7 @@
/obj/item/organ/internal/brain
name = "brain"
health = 400 //They need to live awhile longer than other organs.
- max_damage = 200
+ max_damage = 120
icon_state = "brain2"
force = 1.0
w_class = WEIGHT_CLASS_SMALL
@@ -100,6 +100,19 @@
log_debug("Multibrain shenanigans at ([target.x],[target.y],[target.z]), mob '[target]'")
..(target, special = special)
+/obj/item/organ/internal/brain/receive_damage(amount, silent = 0) //brains are special; if they receive damage by other means, we really just want the damage to be passed ot the owner and back onto the brain.
+ if(owner)
+ owner.adjustBrainLoss(amount)
+
+/obj/item/organ/internal/brain/necrotize(update_sprite = TRUE) //Brain also has special handling for when it necrotizes
+ damage = max_damage
+ status |= ORGAN_DEAD
+ processing_objects -= src
+ if(dead_icon && !is_robotic())
+ icon_state = dead_icon
+ if(owner && vital)
+ owner.setBrainLoss(120)
+
/obj/item/organ/internal/brain/prepare_eat()
return // Too important to eat.
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index 03726353022..aa714f0d527 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -363,7 +363,7 @@
for(var/datum/data/record/R in data_core.security)
if(R.fields["id"] == E.fields["id"])
criminal = R.fields["criminal"]
- var/criminal_status = hasHUD(user, "read_only_security") ? "\[[criminal]\]" : "\[[criminal]\]"
+ var/criminal_status = hasHUD(user, "read_only_security") ? "\[[criminal]\]" : "\[[criminal]\]"
msg += "Criminal status: [criminal_status]\n"
msg += "Security records: \[View\] \[Add comment\]\n"
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 09787bbf73b..937640b2c73 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -198,12 +198,6 @@
stat("Total Blood", "[mind.vampire.bloodtotal]")
stat("Usable Blood", "[mind.vampire.bloodusable]")
- if(mind.nation)
- stat("Nation Name", "[mind.nation.current_name ? "[mind.nation.current_name]" : "[mind.nation.default_name]"]")
- stat("Nation Leader", "[mind.nation.current_leader ? "[mind.nation.current_leader]" : "None"]")
- stat("Nation Heir", "[mind.nation.heir ? "[mind.nation.heir]" : "None"]")
-
-
if(istype(loc, /obj/spacepod)) // Spacdpods!
var/obj/spacepod/S = loc
stat("Spacepod Charge", "[istype(S.battery) ? "[(S.battery.charge / S.battery.maxcharge) * 100]" : "No cell detected"]")
diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm
index 7e9739a816d..d7a9bde2cef 100644
--- a/code/modules/mob/living/carbon/human/human_damage.dm
+++ b/code/modules/mob/living/carbon/human/human_damage.dm
@@ -31,7 +31,10 @@
if(sponge)
if(dna.species && amount > 0)
amount = amount * dna.species.brain_mod
- sponge.receive_damage(amount, 1)
+ sponge.damage = Clamp(sponge.damage + amount, 0, 120)
+ if(sponge.damage >= 120)
+ visible_message("[src] goes limp, [p_their()] facial expression utterly blank.")
+ death()
if(updating)
update_stat("adjustBrainLoss")
return STATUS_UPDATE_STAT
@@ -45,7 +48,10 @@
if(sponge)
if(dna.species && amount > 0)
amount = amount * dna.species.brain_mod
- sponge.damage = min(max(amount, 0), (maxHealth*2))
+ sponge.damage = Clamp(amount, 0, 120)
+ if(sponge.damage >= 120)
+ visible_message("[src] goes limp, [p_their()] facial expression utterly blank.")
+ death()
if(updating)
update_stat("setBrainLoss")
return STATUS_UPDATE_STAT
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 84764bfddaa..c1d61338dcd 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -157,7 +157,7 @@ emp_act
return 1
return 0
-/mob/living/carbon/human/check_block()
+/mob/living/carbon/human/proc/check_block()
if(martial_art && prob(martial_art.block_chance) && martial_art.can_use(src) && in_throw_mode && !incapacitated(FALSE, TRUE))
return TRUE
@@ -220,6 +220,10 @@ emp_act
if(check_shields(I.force, "the [I.name]", I, MELEE_ATTACK, I.armour_penetration))
return 0
+ if(check_block())
+ visible_message("[src] blocks [I]!")
+ return FALSE
+
if(istype(I,/obj/item/card/emag))
emag_act(user, affecting)
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 9bd463b73bc..987041bc7ad 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -1,7 +1,7 @@
var/global/default_martial_art = new/datum/martial_art
/mob/living/carbon/human
- hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPMINDSHIELD_HUD,IMPCHEM_HUD,IMPTRACK_HUD,SPECIALROLE_HUD,NATIONS_HUD,GLAND_HUD)
+ hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPMINDSHIELD_HUD,IMPCHEM_HUD,IMPTRACK_HUD,SPECIALROLE_HUD,GLAND_HUD)
//Marking colour and style
var/list/m_colours = DEFAULT_MARKING_COLOURS //All colours set to #000000.
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 81e4fe703d5..e180fa5f431 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -37,6 +37,17 @@
if(life_tick == 1)
regenerate_icons() // Make sure the inventory updates
+ handle_ghosted()
+
+/mob/living/carbon/human/proc/handle_ghosted()
+ if(player_ghosted > 0 && stat == CONSCIOUS && job && !restrained())
+ if(key)
+ player_ghosted = 0
+ else
+ player_ghosted++
+ if(player_ghosted % 150 == 0)
+ force_cryo_human(src)
+
/mob/living/carbon/human/calculate_affecting_pressure(var/pressure)
..()
var/pressure_difference = abs( pressure - ONE_ATMOSPHERE )
@@ -779,7 +790,6 @@
handle_organs()
if(getBrainLoss() >= 120 || (health + (getOxyLoss() / 2)) <= -500)
- visible_message("[src] goes limp, their facial expression utterly blank.")
death()
return
diff --git a/code/modules/mob/living/carbon/human/species/_species.dm b/code/modules/mob/living/carbon/human/species/_species.dm
index e9a88fdb033..72fe54970a1 100644
--- a/code/modules/mob/living/carbon/human/species/_species.dm
+++ b/code/modules/mob/living/carbon/human/species/_species.dm
@@ -319,7 +319,7 @@
user.do_cpr(target)
/datum/species/proc/grab(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
- if(target.check_block()) //cqc
+ if(target.check_block())
target.visible_message("[target] blocks [user]'s grab attempt!")
return FALSE
if(attacker_style && attacker_style.grab_act(user, target))
@@ -348,7 +348,7 @@
add_attack_logs(user, target, "vampirebit")
return
//end vampire codes
- if(target.check_block()) //cqc
+ if(target.check_block())
target.visible_message("[target] blocks [user]'s attack!")
return FALSE
if(attacker_style && attacker_style.harm_act(user, target))
@@ -393,7 +393,7 @@
SEND_SIGNAL(target, COMSIG_PARENT_ATTACKBY)
/datum/species/proc/disarm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
- if(target.check_block()) //cqc
+ if(target.check_block())
target.visible_message("[target] blocks [user]'s disarm attempt!")
return FALSE
if(attacker_style && attacker_style.disarm_act(user, target))
diff --git a/code/modules/mob/living/carbon/human/species/grey.dm b/code/modules/mob/living/carbon/human/species/grey.dm
index e5492e60293..5bb314c4f43 100644
--- a/code/modules/mob/living/carbon/human/species/grey.dm
+++ b/code/modules/mob/living/carbon/human/species/grey.dm
@@ -56,6 +56,9 @@
/datum/species/grey/handle_reagents(mob/living/carbon/human/H, datum/reagent/R)
if(R.id == "sacid")
- H.reagents.del_reagent(R.id)
- return 0
+ H.reagents.remove_reagent(R.id, REAGENTS_METABOLISM)
+ return FALSE
+ if(R.id == "water")
+ H.adjustFireLoss(1)
+ return TRUE
return ..()
diff --git a/code/modules/mob/living/carbon/human/species/plasmaman.dm b/code/modules/mob/living/carbon/human/species/plasmaman.dm
index ba249edb5a8..35d02f82509 100644
--- a/code/modules/mob/living/carbon/human/species/plasmaman.dm
+++ b/code/modules/mob/living/carbon/human/species/plasmaman.dm
@@ -188,6 +188,6 @@
H.adjustFireLoss(-0.5*REAGENTS_EFFECT_MULTIPLIER)
H.adjustPlasma(20)
H.reagents.remove_reagent(R.id, REAGENTS_METABOLISM)
- return 0 //Handling reagent removal on our own. Prevents plasma from dealing toxin damage to Plasmamen.
+ return FALSE //Handling reagent removal on our own. Prevents plasma from dealing toxin damage to Plasmamen.
return ..()
diff --git a/code/modules/mob/living/carbon/human/species/skeleton.dm b/code/modules/mob/living/carbon/human/species/skeleton.dm
index 50920798d70..0199722d1f4 100644
--- a/code/modules/mob/living/carbon/human/species/skeleton.dm
+++ b/code/modules/mob/living/carbon/human/species/skeleton.dm
@@ -41,7 +41,7 @@
/datum/species/skeleton/handle_reagents(mob/living/carbon/human/H, datum/reagent/R)
// Crazylemon is still silly
if(R.id == "milk")
- H.heal_overall_damage(4,4)
+ H.heal_overall_damage(4, 4)
if(prob(5)) // 5% chance per proc to find a random limb, and mend it
var/list/our_organs = H.bodyparts.Copy()
shuffle(our_organs)
@@ -54,7 +54,7 @@
L.perma_injury = 0
break // We're only checking one limb here, bucko
if(prob(3))
- H.say(pick("Thanks Mr Skeltal", "Thank for strong bones", "Doot doot!"))
- return 1
+ H.say(pick("Thanks Mr. Skeltal", "Thank for strong bones", "Doot doot!"))
+ return TRUE
return ..()
diff --git a/code/modules/mob/living/carbon/human/update_stat.dm b/code/modules/mob/living/carbon/human/update_stat.dm
index 5dfd98c0b63..6228038c710 100644
--- a/code/modules/mob/living/carbon/human/update_stat.dm
+++ b/code/modules/mob/living/carbon/human/update_stat.dm
@@ -2,16 +2,7 @@
if(status_flags & GODMODE)
return
..(reason)
- if(stat != DEAD)
- switch(getBrainLoss())
- if(100 to 120)
- Weaken(20)
- create_debug_log("collapsed from brain damage, trigger reason: [reason]")
- if(120 to INFINITY)
- visible_message("[src] goes limp, [p_their()] facial expression utterly blank.")
- death()
- create_debug_log("died of brain damage, trigger reason: [reason]")
- else
+ if(stat == DEAD)
if(dna.species && dna.species.can_revive_by_healing)
var/obj/item/organ/internal/brain/B = get_int_organ(/obj/item/organ/internal/brain)
if(B)
diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm
index 0569c944382..d28e728c82c 100644
--- a/code/modules/mob/living/life.dm
+++ b/code/modules/mob/living/life.dm
@@ -52,8 +52,6 @@
if(client)
//regular_hud_updates() //THIS DOESN'T FUCKING UPDATE SHIT
handle_regular_hud_updates() //IT JUST REMOVES FUCKING HUD IMAGES
- if(get_nations_mode())
- process_nations()
..()
@@ -227,10 +225,4 @@
return
/mob/living/proc/handle_hud_icons_health()
- return
-
-/mob/living/proc/process_nations()
- if(client)
- var/client/C = client
- for(var/mob/living/carbon/human/H in view(src, world.view))
- C.images += H.hud_list[NATIONS_HUD]
+ return
\ No newline at end of file
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 0641ce380f5..3182c829466 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -337,8 +337,4 @@
return TRUE
if(INTENT_DISARM)
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
- return TRUE
-
-//defined here, overridden for humans in human_defense. By default, living mobs don't get to block anything
-/mob/living/proc/check_block()
- return FALSE
\ No newline at end of file
+ return TRUE
\ No newline at end of file
diff --git a/code/modules/mob/living/login.dm b/code/modules/mob/living/login.dm
index dcc046f7b00..d1157b662fa 100644
--- a/code/modules/mob/living/login.dm
+++ b/code/modules/mob/living/login.dm
@@ -17,6 +17,4 @@
//Should update regardless of if we can ventcrawl, since we can end up in pipes in other ways.
update_pipe_vision()
- update_interface()
-
return .
diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm
index 3700f83f0a9..eec1ec5b8b8 100644
--- a/code/modules/mob/living/silicon/ai/life.dm
+++ b/code/modules/mob/living/silicon/ai/life.dm
@@ -133,9 +133,6 @@
process_queued_alarms()
- if(get_nations_mode())
- process_nations_ai()
-
/mob/living/silicon/ai/updatehealth(reason = "none given")
if(status_flags & GODMODE)
health = 100
@@ -156,12 +153,6 @@
..()
add_ai_verbs(src)
-/mob/living/silicon/ai/proc/process_nations_ai()
- if(client)
- var/client/C = client
- for(var/mob/living/carbon/human/H in view(eyeobj, 14))
- C.images += H.hud_list[NATIONS_HUD]
-
/mob/living/silicon/ai/update_sight()
see_invisible = initial(see_invisible)
see_in_dark = initial(see_in_dark)
diff --git a/code/modules/mob/living/silicon/robot/login.dm b/code/modules/mob/living/silicon/robot/login.dm
index 2dd61d9a2ce..d0262df743c 100644
--- a/code/modules/mob/living/silicon/robot/login.dm
+++ b/code/modules/mob/living/silicon/robot/login.dm
@@ -1,6 +1,7 @@
/mob/living/silicon/robot/Login()
..()
- if(client)
- client.hotkeytype = "Cyborg"
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 05e3e0b16af..ae6a832f6ac 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -93,7 +93,7 @@ var/list/robot_verbs_default = list(
var/updating = 0 //portable camera camerachunk update
- hud_possible = list(SPECIALROLE_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_BATT_HUD, NATIONS_HUD)
+ hud_possible = list(SPECIALROLE_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_BATT_HUD)
var/magpulse = 0
var/ionpulse = 0 // Jetpack-like effect.
@@ -288,10 +288,6 @@ var/list/robot_verbs_default = list(
if(security_level == (SEC_LEVEL_GAMMA || SEC_LEVEL_EPSILON) || crisis)
to_chat(src, "Crisis mode active. Combat module available.")
modules += "Combat"
- if(ticker && ticker.mode && ticker.mode.name == "nations")
- var/datum/game_mode/nations/N = ticker.mode
- if(N.kickoff)
- modules = list("Nations")
if(mmi != null && mmi.alien)
modules = list("Hunter")
modtype = input("Please, select a module!", "Robot", null, null) as null|anything in modules
@@ -390,11 +386,6 @@ var/list/robot_verbs_default = list(
module.channels = list("Security" = 1)
icon_state = "droidcombat"
- if("Nations")
- module = new /obj/item/robot_module/nations(src)
- module.channels = list()
- icon_state = "droidpeace"
-
if("Hunter")
module = new /obj/item/robot_module/alien/hunter(src)
icon_state = "xenoborg-state-a"
@@ -415,7 +406,7 @@ var/list/robot_verbs_default = list(
feedback_inc("cyborg_[lowertext(modtype)]",1)
rename_character(real_name, get_default_name())
- if(modtype == "Medical" || modtype == "Security" || modtype == "Combat" || modtype == "Nations")
+ if(modtype == "Medical" || modtype == "Security" || modtype == "Combat")
status_flags &= ~CANPUSH
choose_icon(6,module_sprites)
@@ -891,7 +882,7 @@ var/list/robot_verbs_default = list(
else
overlays += "[panelprefix]-openpanel -c"
- var/combat = list("Combat","Nations")
+ var/combat = list("Combat")
if(modtype in combat)
if(base_icon == "")
base_icon = icon_state
@@ -1356,24 +1347,6 @@ var/list/robot_verbs_default = list(
/mob/living/silicon/robot/ert/gamma
crisis = 1
-/mob/living/silicon/robot/nations
- base_icon = "droidpeace"
- icon_state = "droidpeace"
- modtype = "Nations"
- designation = "Nations"
-
-/mob/living/silicon/robot/nations/init()
- ..()
- module = new /obj/item/robot_module/nations(src)
- //languages
- module.add_languages(src)
- //subsystems
- module.add_subsystems_and_actions(src)
-
- status_flags &= ~CANPUSH
-
- notify_ai(2)
-
/mob/living/silicon/robot/emp_act(severity)
..()
switch(severity)
diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm
index a84af2c8254..699376c927f 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -497,22 +497,6 @@
fix_modules()
-/obj/item/robot_module/nations
- name = "nations robot module"
- module_type = "Malf"
-
-/obj/item/robot_module/nations/New()
- ..()
- modules += new /obj/item/restraints/handcuffs/cable/zipties/cyborg(src)
- modules += new /obj/item/gun/energy/gun/cyborg(src)
- modules += new /obj/item/pickaxe/drill/jackhammer(src)
- modules += new /obj/item/borg/combat/shield(src)
- modules += new /obj/item/borg/combat/mobility(src)
- modules += new /obj/item/wrench/cyborg(src)
- emag = new /obj/item/gun/energy/lasercannon/cyborg(src)
-
- fix_modules()
-
/obj/item/robot_module/alien/hunter
name = "alien hunter module"
module_type = "Standard"
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index 20b363051de..cdd36a59b80 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -25,7 +25,7 @@
var/next_alarm_notice
var/list/datum/alarm/queued_alarms = new()
- hud_possible = list(SPECIALROLE_HUD, DIAG_STAT_HUD, DIAG_HUD,NATIONS_HUD)
+ hud_possible = list(SPECIALROLE_HUD, DIAG_STAT_HUD, DIAG_HUD)
var/med_hud = DATA_HUD_MEDICAL_ADVANCED //Determines the med hud to use
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm
index 51028a69111..14353c4dfd0 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm
@@ -24,6 +24,12 @@
canlay = 1000
spider_tier = TS_TIER_5
projectiletype = /obj/item/projectile/terrorqueenspit/empress
+ icon = 'icons/mob/terrorspider64.dmi'
+ pixel_x = -16
+ mob_size = MOB_SIZE_LARGE
+ icon_state = "terror_empress"
+ icon_living = "terror_empress"
+ icon_dead = "terror_empress_dead"
var/datum/action/innate/terrorspider/queen/empress/empresslings/empresslings_action
var/datum/action/innate/terrorspider/queen/empress/empresserase/empresserase_action
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
@@ -42,7 +48,7 @@
queenfakelings_action.button.name = "Empress Lings"
/mob/living/simple_animal/hostile/poison/terror_spider/queen/empress/LayQueenEggs()
- var/eggtype = input("What kind of eggs?") as null|anything in list(TS_DESC_QUEEN, TS_DESC_MOTHER, TS_DESC_PRINCE, TS_DESC_PRINCESS, TS_DESC_RED, TS_DESC_GRAY, TS_DESC_GREEN, TS_DESC_BLACK, TS_DESC_PURPLE, TS_DESC_WHITE)
+ var/eggtype = input("What kind of eggs?") as null|anything in list(TS_DESC_QUEEN, TS_DESC_MOTHER, TS_DESC_PRINCE, TS_DESC_PRINCESS, TS_DESC_RED, TS_DESC_GRAY, TS_DESC_GREEN, TS_DESC_BLACK, TS_DESC_PURPLE, TS_DESC_WHITE, TS_DESC_BROWN)
var/numlings = input("How many in the batch?") as null|anything in list(1, 2, 3, 4, 5, 10, 15, 20, 30, 40, 50)
if(eggtype == null || numlings == null)
to_chat(src, "Cancelled.")
@@ -60,6 +66,8 @@
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/purple, numlings)
if(TS_DESC_WHITE)
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/white, numlings)
+ if(TS_DESC_BROWN)
+ DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/brown, numlings)
if(TS_DESC_PRINCE)
DoLayTerrorEggs(/mob/living/simple_animal/hostile/poison/terror_spider/prince, numlings)
if(TS_DESC_PRINCESS)
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/mother.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/mother.dm
index 354f99db8af..d1e171d2f55 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/mother.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/mother.dm
@@ -38,6 +38,8 @@
if(can_die())
if(spider_awaymission && !is_away_level(z))
canspawn = FALSE
+ if(degenerate)
+ canspawn = FALSE
if(canspawn)
canspawn = FALSE
for(var/i in 0 to spawn_count)
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm
index ed2ea164634..2839dedb237 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/queen.dm
@@ -142,9 +142,8 @@
visible_message("\The [src] looks around warily - then seeks a better nesting ground.")
path_to_vent = 1
else
- visible_message("\The [src] looks around, searching for the vent that should be there, but isn't. A bluespace portal forms on her, and she is gone.")
- qdel(src)
- new /obj/effect/portal(get_turf(loc))
+ neststep = -1
+ message_admins("Warning: [key_name_admin(src)] was spawned in an area without a vent! This is likely a mapping/spawn mistake. This mob's AI has been permanently deactivated.")
if(1)
// No nest, and we should create one. Start NestMode(), then advance to step 2.
if(world.time > (lastnestsetup + nestfrequency))
diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm
index eecd0650af0..fc265722f4a 100644
--- a/code/modules/mob/login.dm
+++ b/code/modules/mob/login.dm
@@ -72,29 +72,3 @@
update_client_colour(0)
callHook("mob_login", list("client" = client, "mob" = src))
-
-// Calling update_interface() in /mob/Login() causes the Cyborg to immediately be ghosted; because of winget().
-// Calling it in the overriden Login, such as /mob/living/Login() doesn't cause this.
-/mob/proc/update_interface()
- spawn() // Spawn off so winget/winset don't delay callers.
- if(client)
- if(winget(src, "mainwindow.hotkey_toggle", "is-checked") == "true")
- update_hotkey_mode()
- else
- update_normal_mode()
-
-/mob/proc/update_hotkey_mode()
- var/hotkeyname = "hotkeymode"
- if(client)
- var/hotkeys = client.hotkeylist[client.hotkeytype]
- hotkeyname = hotkeys[client.hotkeyon ? "on" : "off"]
- client.hotkeyon = 1
- winset(src, null, "mainwindow.macro=[hotkeyname] hotkey_toggle.is-checked=true mapwindow.map.focus=true input.background-color=#F0F0F0")
-
-/mob/proc/update_normal_mode()
- var/hotkeyname = "macro"
- if(client)
- var/hotkeys = client.hotkeylist[client.hotkeytype]//get the list containing the hotkey names
- hotkeyname = hotkeys[client.hotkeyon ? "on" : "off"]//get the name of the hotkey, to not clutter winset() to much
- client.hotkeyon = 0
- winset(src, null, "mainwindow.macro=[hotkeyname] hotkey_toggle.is-checked=false input.focus=true input.background-color=#D3B5B5")
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 77c74c4396e..3e9ff0b7ba6 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -173,6 +173,9 @@
//SSD var, changed it up some so people can have special things happen for different mobs when SSD.
var/player_logged = 0
+ //Ghosted var, set only if a player has manually ghosted out of this mob.
+ var/player_ghosted = 0
+
var/turf/listed_turf = null //the current turf being examined in the stat panel
var/list/shouldnt_see = list(/atom/movable/lighting_overlay) //list of objects that this mob shouldn't see in the stat panel. this silliness is needed because of AI alt+click and cult blood runes
diff --git a/code/modules/mob/typing_indicator.dm b/code/modules/mob/typing_indicator.dm
index 9c6c8f2fa73..9ad5449ee8b 100644
--- a/code/modules/mob/typing_indicator.dm
+++ b/code/modules/mob/typing_indicator.dm
@@ -39,7 +39,7 @@ var/global/image/typing_indicator
set_typing_indicator(1)
hud_typing = 1
- var/message = input("","say (text)") as null|text
+ var/message = typing_input(src, "", "say (text)")
hud_typing = 0
set_typing_indicator(0)
if(message)
@@ -49,9 +49,10 @@ var/global/image/typing_indicator
set name = ".Me"
set hidden = 1
+
set_typing_indicator(1)
hud_typing = 1
- var/message = input("","me (text)") as null|text
+ var/message = typing_input(src, "", "me (text)")
hud_typing = 0
set_typing_indicator(0)
if(message)
diff --git a/code/modules/paperwork/faxmachine.dm b/code/modules/paperwork/faxmachine.dm
index f4808f46d53..13d85941a79 100644
--- a/code/modules/paperwork/faxmachine.dm
+++ b/code/modules/paperwork/faxmachine.dm
@@ -283,34 +283,25 @@ var/global/list/fax_blacklist = list()
use_power(200)
- var/obj/item/rcvdcopy
- if(istype(copyitem, /obj/item/paper))
- rcvdcopy = copy(copyitem)
- else if(istype(copyitem, /obj/item/photo))
- rcvdcopy = photocopy(copyitem)
- else if(istype(copyitem, /obj/item/paper_bundle))
- rcvdcopy = bundlecopy(copyitem)
- else
+ if(!(istype(copyitem, /obj/item/paper) || istype(copyitem, /obj/item/paper_bundle) || istype(copyitem, /obj/item/photo)))
visible_message("[src] beeps, \"Error transmitting message.\"")
return
- rcvdcopy.loc = null //hopefully this shouldn't cause trouble
-
var/datum/fax/admin/A = new /datum/fax/admin()
- A.name = rcvdcopy.name
+ A.name = copyitem.name
A.from_department = department
A.to_department = destination
A.origin = src
- A.message = rcvdcopy
+ A.message = copyitem
A.sent_by = sender
A.sent_at = world.time
//message badmins that a fax has arrived
switch(destination)
if("Central Command")
- message_admins(sender, "CENTCOM FAX", destination, rcvdcopy, "#006100")
+ message_admins(sender, "CENTCOM FAX", destination, copyitem, "#006100")
if("Syndicate")
- message_admins(sender, "SYNDICATE FAX", destination, rcvdcopy, "#DC143C")
+ message_admins(sender, "SYNDICATE FAX", destination, copyitem, "#DC143C")
for(var/obj/machinery/photocopier/faxmachine/F in allfaxes)
if(F.department == destination)
F.receivefax(copyitem)
diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm
index 66f010b86e3..8d7201d0645 100644
--- a/code/modules/reagents/chemistry/holder.dm
+++ b/code/modules/reagents/chemistry/holder.dm
@@ -218,7 +218,7 @@ var/const/INGEST = 2
/datum/reagents/proc/metabolize(mob/living/M)
if(M)
- set_reagent_temp(M.bodytemperature)
+ temperature_reagents(M.bodytemperature - 30)
// a bitfield filled in by each reagent's `on_mob_life` to find out which states to update
var/update_flags = STATUS_UPDATE_NONE
diff --git a/code/modules/reagents/chemistry/reagents/alcohol.dm b/code/modules/reagents/chemistry/reagents/alcohol.dm
index d2fb4eec567..6c22360face 100644
--- a/code/modules/reagents/chemistry/reagents/alcohol.dm
+++ b/code/modules/reagents/chemistry/reagents/alcohol.dm
@@ -765,7 +765,7 @@
/datum/reagent/consumable/ethanol/sbiten/on_mob_life(mob/living/M)
if(M.bodytemperature < 360)
M.bodytemperature = min(360, M.bodytemperature + (50 * TEMPERATURE_DAMAGE_COEFFICIENT)) //310 is the normal bodytemp. 310.055
- ..()
+ return ..()
/datum/reagent/consumable/ethanol/devilskiss
name = "Devils Kiss"
@@ -819,7 +819,7 @@
/datum/reagent/consumable/ethanol/iced_beer/on_mob_life(mob/living/M)
if(M.bodytemperature > 270)
M.bodytemperature = max(270, M.bodytemperature - (20 * TEMPERATURE_DAMAGE_COEFFICIENT)) //310 is the normal bodytemp. 310.055
- ..()
+ return ..()
/datum/reagent/consumable/ethanol/grog
name = "Grog"
@@ -1178,7 +1178,7 @@
if(prob(25))
holder.remove_reagent(id, 15)
M.fakevomit()
- ..()
+ return ..()
/datum/reagent/consumable/ethanol/synthanol/reaction_mob(mob/living/M, method=TOUCH, volume)
if(M.isSynthetic())
diff --git a/code/modules/reagents/chemistry/reagents/drink_cold.dm b/code/modules/reagents/chemistry/reagents/drink_cold.dm
index 8e902f014f3..707aab07b54 100644
--- a/code/modules/reagents/chemistry/reagents/drink_cold.dm
+++ b/code/modules/reagents/chemistry/reagents/drink_cold.dm
@@ -42,7 +42,7 @@
/datum/reagent/consumable/drink/cold/ice/on_mob_life(mob/living/M)
M.bodytemperature = max(M.bodytemperature - 5 * TEMPERATURE_DAMAGE_COEFFICIENT, 0)
- ..()
+ return ..()
/datum/reagent/consumable/drink/cold/space_cola
name = "Cola"
diff --git a/code/modules/reagents/chemistry/reagents/food.dm b/code/modules/reagents/chemistry/reagents/food.dm
index 3f21593a44e..9b1aca91f8d 100644
--- a/code/modules/reagents/chemistry/reagents/food.dm
+++ b/code/modules/reagents/chemistry/reagents/food.dm
@@ -448,7 +448,7 @@
/datum/reagent/consumable/egg/on_mob_life(mob/living/M)
if(prob(3))
M.reagents.add_reagent("cholesterol", rand(1,2))
- ..()
+ return ..()
/datum/reagent/consumable/corn_starch
name = "Corn Starch"
@@ -643,9 +643,6 @@
color = "#684435"
taste_message = "burritos"
-/datum/reagent/consumable/beans/on_mob_life(mob/living/M)
- return ..()
-
/datum/reagent/consumable/bread
name = "Bread"
id = "bread"
diff --git a/code/modules/reagents/chemistry/reagents/medicine.dm b/code/modules/reagents/chemistry/reagents/medicine.dm
index 5ec01dcfd7c..15680164758 100644
--- a/code/modules/reagents/chemistry/reagents/medicine.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine.dm
@@ -5,6 +5,7 @@
/datum/reagent/medicine/on_mob_life(mob/living/M)
current_cycle++
holder.remove_reagent(id, (metabolization_rate / M.metabolism_efficiency) * M.digestion_ratio) //medicine reagents stay longer if you have a better metabolism
+ return STATUS_UPDATE_NONE
/datum/reagent/medicine/hydrocodone
name = "Hydrocodone"
@@ -526,6 +527,7 @@
taste_message = "a delightful numbing"
/datum/reagent/medicine/morphine/on_mob_life(mob/living/M)
+ var/update_flags = STATUS_UPDATE_NONE
M.AdjustJitter(-25)
switch(current_cycle)
if(1 to 15)
@@ -534,9 +536,9 @@
if(16 to 35)
M.Drowsy(20)
if(36 to INFINITY)
- M.Paralyse(15)
+ update_flags |= M.Paralyse(15, FALSE)
M.Drowsy(20)
- ..()
+ return ..() | update_flags
/datum/reagent/medicine/oculine
name = "Oculine"
@@ -669,7 +671,7 @@
update_flags |= M.adjustToxLoss(2*REAGENTS_EFFECT_MULTIPLIER, FALSE)
return ..() | update_flags
-/datum/reagent/medicine/strange_reagent/reaction_mob(mob/living/M, method=TOUCH, volume)
+/datum/reagent/medicine/strange_reagent/reaction_mob(mob/living/M, method = TOUCH, volume)
if(volume < 1)
// gotta pay to play
return ..()
@@ -682,25 +684,19 @@
SM.visible_message("[M] seems to rise from the dead!")
if(iscarbon(M))
- if(method == INGEST)
+ if(method == INGEST || (method == TOUCH && prob(25)))
if(M.stat == DEAD)
- if(M.getBruteLoss()+M.getFireLoss()+M.getCloneLoss() >= 150)
+ if(M.getBruteLoss() + M.getFireLoss() + M.getCloneLoss() >= 150)
M.delayed_gib()
return
- var/mob/dead/observer/ghost = M.get_ghost()
- if(ghost)
- to_chat(ghost, "A Strange Reagent is infusing your body with life. Return to your body if you want to be revived! (Verbs -> Ghost -> Re-enter corpse)")
- window_flash(ghost.client)
- ghost << sound('sound/effects/genetics.ogg')
- M.visible_message("[M] doesn't appear to respond, perhaps try again later?")
- if(!M.suiciding && !ghost && !(NOCLONE in M.mutations) && (M.mind && M.mind.is_revivable()))
+ if(!M.suiciding && !(NOCLONE in M.mutations) && (!M.mind || M.mind && M.mind.is_revivable()))
var/time_dead = world.time - M.timeofdeath
M.visible_message("[M] seems to rise from the dead!")
M.adjustCloneLoss(50)
M.setOxyLoss(0)
- M.adjustBruteLoss(rand(0,15))
- M.adjustToxLoss(rand(0,15))
- M.adjustFireLoss(rand(0,15))
+ M.adjustBruteLoss(rand(0, 15))
+ M.adjustToxLoss(rand(0, 15))
+ M.adjustFireLoss(rand(0, 15))
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/necrosis_prob = 40 * min((20 MINUTES), max((time_dead - (1 MINUTES)), 0)) / ((20 MINUTES) - (1 MINUTES))
@@ -715,8 +711,8 @@
O.germ_level = INFECTION_LEVEL_THREE
H.update_body()
+ M.grab_ghost()
M.update_revive()
- M.stat = UNCONSCIOUS
add_attack_logs(M, M, "Revived with strange reagent") //Yes, the logs say you revived yourself.
..()
@@ -759,7 +755,7 @@
if(ishuman(M))
var/mob/living/carbon/human/H = M
H.update_mutations()
- ..()
+ return ..()
/datum/reagent/medicine/antihol
name = "Antihol"
@@ -857,6 +853,7 @@
/datum/reagent/medicine/insulin/on_mob_life(mob/living/M)
M.reagents.remove_reagent("sugar", 5)
+ return ..()
/datum/reagent/medicine/teporone
name = "Teporone"
@@ -873,7 +870,7 @@
M.bodytemperature = max(310, M.bodytemperature - (40 * TEMPERATURE_DAMAGE_COEFFICIENT))
else if(M.bodytemperature < 311)
M.bodytemperature = min(310, M.bodytemperature + (40 * TEMPERATURE_DAMAGE_COEFFICIENT))
- ..()
+ return ..()
/datum/reagent/medicine/haloperidol
name = "Haloperidol"
@@ -916,6 +913,7 @@
taste_message = "sleepiness"
/datum/reagent/medicine/ether/on_mob_life(mob/living/M)
+ var/update_flags = STATUS_UPDATE_NONE
M.AdjustJitter(-25)
switch(current_cycle)
if(1 to 30)
@@ -924,9 +922,9 @@
if(31 to 40)
M.Drowsy(20)
if(41 to INFINITY)
- M.Paralyse(15)
+ update_flags |= M.Paralyse(15, FALSE)
M.Drowsy(20)
- ..()
+ return ..() | update_flags
/datum/reagent/medicine/syndicate_nanites //Used exclusively by Syndicate medical cyborgs
name = "Restorative Nanites"
diff --git a/code/modules/reagents/chemistry/reagents/misc.dm b/code/modules/reagents/chemistry/reagents/misc.dm
index f37bceb0f6b..4d42e9060ae 100644
--- a/code/modules/reagents/chemistry/reagents/misc.dm
+++ b/code/modules/reagents/chemistry/reagents/misc.dm
@@ -162,7 +162,7 @@
if(!H.dna.species.exotic_blood && !(NO_BLOOD in H.dna.species.species_traits))
if(H.blood_volume < BLOOD_VOLUME_NORMAL)
H.blood_volume += 0.8
- ..()
+ return ..()
/datum/reagent/iron/reaction_mob(mob/living/M, method=TOUCH, volume)
if(M.has_bane(BANE_IRON) && holder && holder.chem_temp < 150) //If the target is weak to cold iron, then poison them.
diff --git a/code/modules/reagents/chemistry/reagents/paradise_pop.dm b/code/modules/reagents/chemistry/reagents/paradise_pop.dm
index 204848e1fe9..2294088e54a 100644
--- a/code/modules/reagents/chemistry/reagents/paradise_pop.dm
+++ b/code/modules/reagents/chemistry/reagents/paradise_pop.dm
@@ -31,7 +31,7 @@
var/turf/simulated/T = get_turf(M)
goonchem_vortex(T, 1, 0)
to_chat(M, "You briefly feel super-massive, like a black hole. Probably just your imagination...")
- ..()
+ return ..()
//Berry Banned: This one is tasty and safe to drink, might have a low chance of healing a random damage type?
/datum/reagent/consumable/drink/berry_banned
diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic.dm
index d91a76da7fc..d062de0e761 100644
--- a/code/modules/reagents/chemistry/reagents/pyrotechnic.dm
+++ b/code/modules/reagents/chemistry/reagents/pyrotechnic.dm
@@ -22,7 +22,7 @@
M.adjust_fire_stacks(mob_burning)
M.IgniteMob()
if(method == INGEST)
- M.adjustFireLoss(min(max(15, volume * 3), 45))
+ M.adjustFireLoss(min(max(10, volume * 2), 45))
to_chat(M, "It burns!")
M.emote("scream")
@@ -242,7 +242,7 @@
M.adjust_fire_stacks(10)
M.IgniteMob()
if(method == INGEST)
- M.adjustFireLoss(min(max(30, volume * 6), 90))
+ M.adjustFireLoss(min(max(15, volume * 2.5), 90))
to_chat(M, "It burns!")
M.emote("scream")
diff --git a/code/modules/reagents/chemistry/reagents/toxins.dm b/code/modules/reagents/chemistry/reagents/toxins.dm
index 76be206f35f..76d06cc43a1 100644
--- a/code/modules/reagents/chemistry/reagents/toxins.dm
+++ b/code/modules/reagents/chemistry/reagents/toxins.dm
@@ -245,7 +245,7 @@
id = "sacid"
description = "A strong mineral acid with the molecular formula H2SO4."
reagent_state = LIQUID
- color = "#00D72B"
+ color = "#00FF32"
process_flags = ORGANIC | SYNTHETIC
taste_message = "ACID"
@@ -254,58 +254,34 @@
update_flags |= M.adjustFireLoss(1, FALSE)
return ..() | update_flags
-/datum/reagent/sacid/reaction_mob(mob/living/M, method=TOUCH, volume)
- if(method == TOUCH)
- if(ishuman(M))
- var/mob/living/carbon/human/H = M
- if(isgrey(H))
- return
-
+/datum/reagent/sacid/reaction_mob(mob/living/M, method = TOUCH, volume)
+ if(ishuman(M) && !isgrey(M))
+ var/mob/living/carbon/human/H = M
+ if(method == TOUCH)
if(volume > 25)
-
if(H.wear_mask)
- to_chat(H, "Your mask protects you from the acid!")
+ to_chat(H, "Your [H.wear_mask] protects you from the acid!")
return
if(H.head)
- to_chat(H, "Your helmet protects you from the acid!")
+ to_chat(H, "Your [H.wear_mask] protects you from the acid!")
return
- if(!M.unacidable)
- if(prob(75))
- var/obj/item/organ/external/affecting = H.get_organ("head")
- if(affecting)
- affecting.receive_damage(5, 10)
- H.UpdateDamageIcon()
- H.emote("scream")
- else
- M.take_organ_damage(5,10)
+ if(prob(75))
+ H.take_organ_damage(5, 10)
+ H.emote("scream")
+ var/obj/item/organ/external/affecting = H.get_organ("head")
+ if(affecting)
+ affecting.disfigure()
+ else
+ H.take_organ_damage(5, 10)
else
- M.take_organ_damage(5,10)
-
- if(method == INGEST)
- if(ishuman(M))
- var/mob/living/carbon/human/H = M
-
- if(isgrey(H))
- return
-
- if(volume >=10 && volume <=25)
- if(!H.unacidable)
- M.take_organ_damage(0,min(max(volume-10,2)*2,20))
- M.emote("scream")
-
-
- if(volume > 25)
- if(!M.unacidable)
- if(prob(75))
- var/obj/item/organ/external/affecting = H.get_organ("head")
- if(affecting)
- affecting.receive_damage(0, 20)
- H.UpdateDamageIcon()
- H.emote("scream")
- else
- M.take_organ_damage(0,20)
+ H.take_organ_damage(5, 10)
+ else
+ to_chat(H, "The greenish acidic substance stings[volume < 10 ? " you, but isn't concentrated enough to harm you" : null]!")
+ if(volume >= 10)
+ H.adjustFireLoss(min(max(4, (volume - 10) * 2), 20))
+ H.emote("scream")
/datum/reagent/sacid/reaction_obj(obj/O, volume)
if((istype(O,/obj/item) || istype(O,/obj/structure/glowshroom)) && prob(40))
@@ -614,7 +590,7 @@
id = "facid"
description = "Fluorosulfuric acid is a an extremely corrosive super-acid."
reagent_state = LIQUID
- color = "#4141D2"
+ color = "#5050FF"
process_flags = ORGANIC | SYNTHETIC
taste_message = "ACID"
@@ -624,47 +600,38 @@
update_flags |= M.adjustFireLoss(1, FALSE)
return ..() | update_flags
-/datum/reagent/facid/reaction_mob(mob/living/M, method=TOUCH, volume)
- if(method == TOUCH || method == INGEST)
- if(ishuman(M))
- var/mob/living/carbon/human/H = M
-
- if(volume < 5)
- to_chat(M, "The blueish acidic substance stings you, but isn't concentrated enough to harm you!")
-
- if(volume >=5 && volume <=10)
- if(!H.unacidable)
- M.take_organ_damage(0,max(volume-5,2)*4)
- M.emote("scream")
-
-
- if(volume > 10)
-
- if(method == TOUCH)
- if(H.wear_mask)
- if(!H.wear_mask.unacidable)
- qdel(H.wear_mask)
- H.update_inv_wear_mask()
- to_chat(H, "Your mask melts away but protects you from the acid!")
- else
- to_chat(H, "Your mask protects you from the acid!")
- return
-
- if(H.head)
- if(!H.head.unacidable)
- qdel(H.head)
- H.update_inv_head()
- to_chat(H, "Your helmet melts away but protects you from the acid")
- else
- to_chat(H, "Your helmet protects you from the acid!")
- return
-
- if(!H.unacidable)
- var/obj/item/organ/external/head/affecting = H.get_organ("head")
+/datum/reagent/facid/reaction_mob(mob/living/M, method = TOUCH, volume)
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ if(method == TOUCH)
+ if(volume > 9)
+ if(!H.wear_mask && !H.head)
+ var/obj/item/organ/external/affecting = H.get_organ("head")
if(affecting)
- affecting.receive_damage(0, 75)
- H.UpdateDamageIcon()
+ affecting.disfigure()
+ H.adjustFireLoss(min(max(8, (volume - 5) * 3), 75))
H.emote("scream")
+ return
+ else
+ var/melted_something = FALSE
+ if(H.wear_mask && !H.wear_mask.unacidable)
+ qdel(H.wear_mask)
+ H.update_inv_wear_mask()
+ to_chat(H, "Your [H.wear_mask] melts away!")
+ melted_something = TRUE
+
+ if(H.head && !H.head.unacidable)
+ qdel(H.head)
+ H.update_inv_head()
+ to_chat(H, "Your [H.head] melts away!")
+ melted_something = TRUE
+ if(melted_something)
+ return
+
+ if(volume >= 5)
+ H.emote("scream")
+ H.adjustFireLoss(min(max(8, (volume - 5) * 3), 75))
+ to_chat(H, "The blueish acidic substance stings[volume < 5 ? " you, but isn't concentrated enough to harm you" : null]!")
/datum/reagent/facid/reaction_obj(obj/O, volume)
if((istype(O, /obj/item) || istype(O, /obj/structure/glowshroom)))
@@ -1156,12 +1123,16 @@
M.apply_effect(2, IRRADIATE, 0, negate_armor = 1)
if(!M.dna)
return
+ var/did_mutation = FALSE
if(prob(15))
randmutb(M)
+ did_mutation = TRUE
if(prob(3))
randmutg(M)
- domutcheck(M, null)
- M.UpdateAppearance()
+ did_mutation = TRUE
+ if(did_mutation)
+ domutcheck(M, null)
+ M.UpdateAppearance()
return ..()
/datum/reagent/ants
diff --git a/code/modules/reagents/chemistry/reagents/water.dm b/code/modules/reagents/chemistry/reagents/water.dm
index 5623023659b..dcd21f639d1 100644
--- a/code/modules/reagents/chemistry/reagents/water.dm
+++ b/code/modules/reagents/chemistry/reagents/water.dm
@@ -24,61 +24,34 @@
if(method == TOUCH)
// Put out fire
M.adjust_fire_stacks(-(volume * 0.2))
- if(ishuman(M))
-
- var/mob/living/carbon/human/H = M
-
- if(!isgrey(H)) //God this is so gross I hate it.
- return
+ if(isgrey(M)) // You gosh darn snowflakes
+ var/mob/living/carbon/human/G = M
+ if(method == TOUCH)
if(volume > 25)
-
- if(H.wear_mask)
- to_chat(H, "Your mask protects you from the water!")
+ if(G.wear_mask)
+ to_chat(G, "Your [G.wear_mask] protects you from the acid!")
return
- if(H.head)
- to_chat(H, "Your helmet protects you from the water!")
+ if(G.head)
+ to_chat(G, "Your [G.wear_mask] protects you from the acid!")
return
- if(!M.unacidable)
- if(prob(75))
- var/obj/item/organ/external/affecting = H.get_organ("head")
- if(affecting)
- affecting.receive_damage(5, 10)
- H.UpdateDamageIcon()
- H.emote("scream")
- else
- M.take_organ_damage(5,10)
+ if(prob(75))
+ G.take_organ_damage(5, 10)
+ G.emote("scream")
+ var/obj/item/organ/external/affecting = G.get_organ("head")
+ if(affecting)
+ affecting.disfigure()
+ else
+ G.take_organ_damage(5, 10)
else
- M.take_organ_damage(5,10)
-
- if(method == INGEST)
- if(ishuman(M))
- var/mob/living/carbon/human/H = M
-
- if(!isgrey(H))
- return
-
- if(volume < 10)
- to_chat(M, "The watery solvent substance stings you, but isn't concentrated enough to harm you!")
-
- if(volume >=10 && volume <=25)
- if(!H.unacidable)
- M.take_organ_damage(0,min(max(volume-10,2)*2,20))
- M.emote("scream")
-
-
- if(volume > 25)
- if(!M.unacidable)
- if(prob(75))
- var/obj/item/organ/external/affecting = H.get_organ("head")
- if(affecting)
- affecting.receive_damage(0, 20)
- H.UpdateDamageIcon()
- H.emote("scream")
- else
- M.take_organ_damage(0,20)
+ G.take_organ_damage(5, 10)
+ else
+ to_chat(G, "The water stings[volume < 10 ? " you, but isn't concentrated enough to harm you" : null]!")
+ if(volume >= 10)
+ G.adjustFireLoss(min(max(4, (volume - 10) * 2), 20))
+ G.emote("scream")
/datum/reagent/water/reaction_turf(turf/simulated/T, volume)
if(!istype(T))
diff --git a/code/modules/reagents/chemistry/recipes/toxins.dm b/code/modules/reagents/chemistry/recipes/toxins.dm
index 1a073eae598..cdc10bcbcc5 100644
--- a/code/modules/reagents/chemistry/recipes/toxins.dm
+++ b/code/modules/reagents/chemistry/recipes/toxins.dm
@@ -139,7 +139,7 @@
required_reagents = list("plasma" = 1, "silver" = 1, "blackpowder" = 1)
result_amount = 3
mix_message = "A jet of sparks flies from the mixture as it merges into a flickering slurry."
- min_temp = T0C + 130
+ min_temp = T0C + 50
mix_sound = null
/datum/chemical_reaction/teslium/on_reaction(datum/reagents/holder, created_volume)
diff --git a/code/modules/surgery/organs/parasites.dm b/code/modules/surgery/organs/parasites.dm
index 536ca7a4f37..f330df260eb 100644
--- a/code/modules/surgery/organs/parasites.dm
+++ b/code/modules/surgery/organs/parasites.dm
@@ -52,10 +52,11 @@
var/egg_progress = 0 // # of on_life() cycles completed, unlike cycle_num this is reset on each hatch event
var/egg_progress_per_hatch = 90 // if egg_progress > this, chance to hatch and reset egg_progress
var/eggs_hatched = 0 // num of hatch events completed
- var/eggs_max = 3 // max possible spiderlings you can get from a single infection if its left to run for a very long time
var/awaymission_checked = FALSE
var/awaymission_infection = FALSE // TRUE if infection occurred inside gateway
- var/list/types_basic = list(/mob/living/simple_animal/hostile/poison/terror_spider/red, /mob/living/simple_animal/hostile/poison/terror_spider/gray, /mob/living/simple_animal/hostile/poison/terror_spider/green)
+ var/list/types_basic = list(/mob/living/simple_animal/hostile/poison/terror_spider/red, /mob/living/simple_animal/hostile/poison/terror_spider/gray)
+ var/list/types_adv = list(/mob/living/simple_animal/hostile/poison/terror_spider/red, /mob/living/simple_animal/hostile/poison/terror_spider/gray, /mob/living/simple_animal/hostile/poison/terror_spider/green)
+
/obj/item/organ/internal/body_egg/terror_eggs/on_life()
// Safety first.
@@ -78,19 +79,11 @@
qdel(src)
return
- // Detect dying hosts, and try to keep them alive (so spiderlings can hatch) at the cost of some growth progress.
- if(owner.health < -25)
- to_chat(owner,"You feel a strange, blissful senstation.")
- owner.adjustBruteLoss(-5)
- owner.adjustFireLoss(-5)
- owner.adjustToxLoss(-5)
- egg_progress += 10
-
// Once at least one egg has hatched from you, you'll need help to reach medbay.
if(eggs_hatched >= 1)
owner.Confused(2)
- if(egg_progress > egg_progress_per_hatch && eggs_hatched < eggs_max)
+ if(egg_progress > egg_progress_per_hatch)
egg_progress -= egg_progress_per_hatch
hatch_egg()
@@ -107,15 +100,22 @@
return extra_progress
/obj/item/organ/internal/body_egg/terror_eggs/proc/hatch_egg()
+ var/infection_completed = FALSE
var/obj/structure/spider/spiderling/terror_spiderling/S = new(get_turf(owner))
- if(eggs_hatched >= 2) // on the third egg...
- S.grow_as = /mob/living/simple_animal/hostile/poison/terror_spider/princess
- else
- S.grow_as = pick(types_basic)
+ switch(eggs_hatched)
+ if(0) // First spiderling
+ S.grow_as = pick(types_basic)
+ if(1) // Second
+ S.grow_as = pick(types_adv)
+ if(2) // Last
+ S.grow_as = /mob/living/simple_animal/hostile/poison/terror_spider/princess
+ infection_completed = TRUE
S.immediate_ventcrawl = TRUE
eggs_hatched++
to_chat(owner, "A strange prickling sensation moves across your skin... then suddenly the whole world seems to spin around you!")
owner.Paralyse(10)
+ if(infection_completed && !QDELETED(src))
+ qdel(src)
/obj/item/organ/internal/body_egg/terror_eggs/remove(var/mob/living/carbon/M, var/special = 0)
..()
diff --git a/html/changelog.html b/html/changelog.html
index af410acc732..7c4262f54ce 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -56,6 +56,93 @@
-->
+
08 April 2019
+
TDSSS updated:
+
+ - Added missing vent in toxins mixing
+
+
+
07 April 2019
+
Arkatos updated:
+
+ - Guardians can no longer change action intents on their own
+ - Fixes #10900 - Guardians can no longer attack their host while inside them
+ - Explosive and Support Guardians now get precise cooldown shown (instead of just static estimate) before their bomb and beacon abitilites are ready to be used again, respectively
+ - HARM action intent icon for Guardians updated
+ - Dehydrated Space Carp TC cost changed from 3 to 2
+ - Shadowling Glare ability reworked - The further Shadowling is from their glared target, the shorter stun their target gets. Stuns also have a delay before they kick in, based on the distance, however targets will be slowed and muted before stun takes effect. Targets on the tile just next to them are still stunned and muted for 10 seconds without any delay.
+ - Added victory message to the End Round messages in the Shadowlings Rounds
+ - Shadowling Destroy Engines ability reworked. You now need to sacrifice non-ally target to delay the emergency shuttle arrival by 10 minutes, and shuttle will be unable to be recalled. This ability can be used only once across ALL Shadowlings.
+ - Descriptions now show with a mouse hover over action buttons
+
+
Fox McCloud updated:
+
+ - Fixes Russian revolvers triggering no matter where you clicked
+ - Power gloves electric shocks can target anything now (still only damages mobs)
+ - Power gloves electric arcs will bounce around (if it happens to target a mob though, it'll ground out and not bounce any more)
+ - Power gloves cooldown lowered from 12 to 4
+ - Power gloves heat up the turf they target
+ - Using power gloves on disarm intent will weaken your target instead of dealing damage
+ - CLF3, Phlogiston, and Fluorosulfuric acid all require greater volumes to achieve their upper damage limits
+ - CLF3 and Phlogiston have lower minimum damage
+ - Grey's treat water more closely to sulfuric acid (including passive damage while it's in them)
+ - Grey's don't instantly purge all sulfuric acid from their system; it depletes at the normal rate, but doens't cause damage
+ - Foam altered to be a bit more viable compared to smoke
+ - Fixes being unable to view pill bottle inventory in some circumstances
+ - Vending items from vending machines will try to put the item in your hands after vending
+ - Vending machines with refill-canisters can be beaten apart and broken
+
+
Kyep updated:
+
+ - Ghosting while alive, conscious, and a member of the crew will now result in your body being moved to cryo after 5 minutes, assuming your body isn't killed or restrained in any way in the meantime.
+ - An AI that ghosts while alive gets a dismissable hint that they might consider using OOC -> Wipe Core instead.
+ - Ghosting out of your body while you are alive, and an antag, will result in admins being informed, so that they may replace you as an antag if needed.
+ - Empress of terror (admin-only mob) is no longer incorrectly prevented from laying brown spider eggs.
+ - Admins are now able to spawn a queen of terror in a room without a vent. Previously, queens would not allow this. Now, this just results in an alert to admins (since its probably a mistake) and deactivates the mob AI (but leaves it available for player control).
+ - If there are player controlled terror spiders, admins using check antags panel will now be able to see eggs/spiderlings currently growing on the station. These counters only count eggs/spiderlings on station, and ignore fake spiderlings.
+ - Empress of terror's 'erase brood' ability no longer incorrectly causes mothers of terror to spawn spiderlings on death. sprite: Empress of terror now has its own sprite.
+ - White spider infections have been nerfed a bit. They no longer provide passive healing or increase infection progress while their host/victim is in crit. Also, the first spiderling to emerge from an infection can no longer be a green. Finally, the eggs now self-delete after the third spiderling emerges, so even in the event they aren't treated with surgery, the host isn't left with confused movement forever.
+
+
Markolie updated:
+
+ - Changing your hotkey mode now happens instantaneously and no longer lags.
+ - An issue where the Hotkey Toggle button wasn't working has been fixed.
+
+
TDSSS updated:
+
+ - upload consoles now tell you if you forgot to select an ai/borg before using an upload module.
+ - trick revolver comes in a box, so you can tell what it is when getting it in a surplus crate.
+
+
farie82 updated:
+
+ - Gives you the option to disable text popup spam. Aka if enabled you won't get popups after you pressed T and had a lagspike and you typed a sentence containing a lot of T's. Default is off
+ - Now checks if OOC and LOOC are enabled before showing the popup
+ - Adds a Mhelp ticket system
+ - Take in the m/a-helps now actually takes the question
+ - a/m-help followup responses using a-mhelp verb now get added to the last ticket like it should
+ - Normal players can now see their open tickets using the My Admin/Mentor tickets verb
+
+
+
06 April 2019
+
Fox McCloud updated:
+
+ - Fixes people popping out of cloning taking tons of damage
+ - Fixes Teslium recipe
+ - Fixes some reagents not causing status updates
+
+
Twinmold updated:
+
+ - No longer costs toner to send a fax to Central Command
+
+
dovydas12345 updated:
+
+ - Fixed diamond statue names and description.
+
+
farie82 updated:
+
+ - Sec huds work again. No longer does the perp need glasses to be set to arrest. Cool does not equal arrest now
+
+
04 April 2019
Kyep updated:
diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml
index 748a8e97b2b..d145f082f7c 100644
--- a/html/changelogs/.all_changelog.yml
+++ b/html/changelogs/.all_changelog.yml
@@ -9687,3 +9687,106 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
- tweak: Plasma Grenades and the Syndicate Bomb can no longer show up in surplus
crates, or be discounted. This means while you can buy one if you intend to,
you're not randomly encouraged to bomb your target.
+2019-04-06:
+ Fox McCloud:
+ - bugfix: Fixes people popping out of cloning taking tons of damage
+ - bugfix: Fixes Teslium recipe
+ - bugfix: Fixes some reagents not causing status updates
+ Twinmold:
+ - bugfix: No longer costs toner to send a fax to Central Command
+ dovydas12345:
+ - spellcheck: Fixed diamond statue names and description.
+ farie82:
+ - bugfix: Sec huds work again. No longer does the perp need glasses to be set to
+ arrest. Cool does not equal arrest now
+2019-04-07:
+ Arkatos:
+ - tweak: Guardians can no longer change action intents on their own
+ - bugfix: 'Fixes #10900 - Guardians can no longer attack their host while inside
+ them'
+ - rscadd: Explosive and Support Guardians now get precise cooldown shown (instead
+ of just static estimate) before their bomb and beacon abitilites are ready to
+ be used again, respectively
+ - tweak: HARM action intent icon for Guardians updated
+ - tweak: Dehydrated Space Carp TC cost changed from 3 to 2
+ - tweak: Shadowling Glare ability reworked - The further Shadowling is from their
+ glared target, the shorter stun their target gets. Stuns also have a delay before
+ they kick in, based on the distance, however targets will be slowed and muted
+ before stun takes effect. Targets on the tile just next to them are still stunned
+ and muted for 10 seconds without any delay.
+ - rscadd: Added victory message to the End Round messages in the Shadowlings Rounds
+ - tweak: Shadowling Destroy Engines ability reworked. You now need to sacrifice
+ non-ally target to delay the emergency shuttle arrival by 10 minutes, and shuttle
+ will be unable to be recalled. This ability can be used only once across ALL
+ Shadowlings.
+ - tweak: Descriptions now show with a mouse hover over action buttons
+ Fox McCloud:
+ - bugfix: Fixes Russian revolvers triggering no matter where you clicked
+ - rscadd: Power gloves electric shocks can target anything now (still only damages
+ mobs)
+ - rscadd: Power gloves electric arcs will bounce around (if it happens to target
+ a mob though, it'll ground out and not bounce any more)
+ - tweak: Power gloves cooldown lowered from 12 to 4
+ - tweak: Power gloves heat up the turf they target
+ - tweak: Using power gloves on disarm intent will weaken your target instead of
+ dealing damage
+ - tweak: CLF3, Phlogiston, and Fluorosulfuric acid all require greater volumes to
+ achieve their upper damage limits
+ - tweak: CLF3 and Phlogiston have lower minimum damage
+ - bugfix: Grey's treat water more closely to sulfuric acid (including passive damage
+ while it's in them)
+ - tweak: Grey's don't instantly purge all sulfuric acid from their system; it depletes
+ at the normal rate, but doens't cause damage
+ - tweak: Foam altered to be a bit more viable compared to smoke
+ - bugfix: Fixes being unable to view pill bottle inventory in some circumstances
+ - tweak: Vending items from vending machines will try to put the item in your hands
+ after vending
+ - tweak: Vending machines with refill-canisters can be beaten apart and broken
+ Kyep:
+ - rscadd: Ghosting while alive, conscious, and a member of the crew will now result
+ in your body being moved to cryo after 5 minutes, assuming your body isn't killed
+ or restrained in any way in the meantime.
+ - rscadd: An AI that ghosts while alive gets a dismissable hint that they might
+ consider using OOC -> Wipe Core instead.
+ - rscadd: Ghosting out of your body while you are alive, and an antag, will result
+ in admins being informed, so that they may replace you as an antag if needed.
+ - bugfix: Empress of terror (admin-only mob) is no longer incorrectly prevented
+ from laying brown spider eggs.
+ - tweak: Admins are now able to spawn a queen of terror in a room without a vent.
+ Previously, queens would not allow this. Now, this just results in an alert
+ to admins (since its probably a mistake) and deactivates the mob AI (but leaves
+ it available for player control).
+ - rscadd: If there are player controlled terror spiders, admins using check antags
+ panel will now be able to see eggs/spiderlings currently growing on the station.
+ These counters only count eggs/spiderlings on station, and ignore fake spiderlings.
+ - bugfix: 'Empress of terror''s ''erase brood'' ability no longer incorrectly causes
+ mothers of terror to spawn spiderlings on death. sprite: Empress of terror now
+ has its own sprite.'
+ - tweak: White spider infections have been nerfed a bit. They no longer provide
+ passive healing or increase infection progress while their host/victim is in
+ crit. Also, the first spiderling to emerge from an infection can no longer be
+ a green. Finally, the eggs now self-delete after the third spiderling emerges,
+ so even in the event they aren't treated with surgery, the host isn't left with
+ confused movement forever.
+ Markolie:
+ - bugfix: Changing your hotkey mode now happens instantaneously and no longer lags.
+ - bugfix: An issue where the Hotkey Toggle button wasn't working has been fixed.
+ TDSSS:
+ - tweak: upload consoles now tell you if you forgot to select an ai/borg before
+ using an upload module.
+ - tweak: trick revolver comes in a box, so you can tell what it is when getting
+ it in a surplus crate.
+ farie82:
+ - rscadd: Gives you the option to disable text popup spam. Aka if enabled you won't
+ get popups after you pressed T and had a lagspike and you typed a sentence containing
+ a lot of T's. Default is off
+ - tweak: Now checks if OOC and LOOC are enabled before showing the popup
+ - rscadd: Adds a Mhelp ticket system
+ - tweak: Take in the m/a-helps now actually takes the question
+ - bugfix: a/m-help followup responses using a-mhelp verb now get added to the last
+ ticket like it should
+ - bugfix: Normal players can now see their open tickets using the My Admin/Mentor
+ tickets verb
+2019-04-08:
+ TDSSS:
+ - bugfix: Added missing vent in toxins mixing
diff --git a/html/changelogs/AutoChangeLog-pr-10327.yml b/html/changelogs/AutoChangeLog-pr-10327.yml
new file mode 100644
index 00000000000..7b73cbcbd97
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-10327.yml
@@ -0,0 +1,9 @@
+author: "Fox McCloud"
+delete-after: True
+changes:
+ - tweak: "CQC has been updated; a few combos are more powerful"
+ - tweak: "cost increased to 13 TC"
+ - tweak: "CQC is now nuke ops only"
+ - tweak: "gloves of the north star restriction on CQC removed"
+ - tweak: "CQC disarms will now take the item from your opponent"
+ - tweak: "CQC blocks melee weapons and a couple of stun weapons and not everything now"
diff --git a/html/changelogs/AutoChangeLog-pr-11214.yml b/html/changelogs/AutoChangeLog-pr-11214.yml
new file mode 100644
index 00000000000..fcad43b3086
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11214.yml
@@ -0,0 +1,4 @@
+author: "Arkatos"
+delete-after: True
+changes:
+ - tweak: "Shadowlings now have a slightly bigger colored text when speaking in the Shadowling Hivemind"
diff --git a/html/changelogs/AutoChangeLog-pr-11217.yml b/html/changelogs/AutoChangeLog-pr-11217.yml
new file mode 100644
index 00000000000..9c6b9803c94
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11217.yml
@@ -0,0 +1,4 @@
+author: "Fox McCloud"
+delete-after: True
+changes:
+ - tweak: "Reagents will now adjust to the body temperature over time as opposed to all at once"
diff --git a/html/changelogs/AutoChangeLog-pr-11224.yml b/html/changelogs/AutoChangeLog-pr-11224.yml
new file mode 100644
index 00000000000..0357a4aa727
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11224.yml
@@ -0,0 +1,4 @@
+author: "Arkatos"
+delete-after: True
+changes:
+ - soundadd: "Replaced title2.ogg music with a higher quality version"
diff --git a/html/changelogs/AutoChangeLog-pr-11227.yml b/html/changelogs/AutoChangeLog-pr-11227.yml
new file mode 100644
index 00000000000..cc4293ba715
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11227.yml
@@ -0,0 +1,7 @@
+author: "Fox McCloud"
+delete-after: True
+changes:
+ - tweak: "Strange Reagent will work 25% of the time with TOUCH based reactions"
+ - tweak: "Strange reagent will revive whether there's a ghost or not (can use SR on clientless mobs now, like monkies)"
+ - tweak: "SR puts the occupant back in their body automatically"
+ - tweak: "Cloners that eject their messes will now eject the unattached organs"
diff --git a/html/changelogs/AutoChangeLog-pr-11230.yml b/html/changelogs/AutoChangeLog-pr-11230.yml
new file mode 100644
index 00000000000..36c1f051aca
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11230.yml
@@ -0,0 +1,5 @@
+author: "Fox McCloud"
+delete-after: True
+changes:
+ - tweak: "the message for brain death will now properly and only occur when they have truly died from brain damage"
+ - bugfix: "Fixes being able to attain brain damage over 120"
diff --git a/html/changelogs/AutoChangeLog-pr-11253.yml b/html/changelogs/AutoChangeLog-pr-11253.yml
new file mode 100644
index 00000000000..0cfbb99257a
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11253.yml
@@ -0,0 +1,5 @@
+author: "Citinited"
+delete-after: True
+changes:
+ - bugfix: "You can no longer turn transit turfs into foamed metal flooring."
+ - bugfix: "Foamed metal floors have a sprite now."
diff --git a/html/changelogs/AutoChangeLog-pr-11257.yml b/html/changelogs/AutoChangeLog-pr-11257.yml
new file mode 100644
index 00000000000..a675de535f9
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11257.yml
@@ -0,0 +1,4 @@
+author: "Fox McCloud"
+delete-after: True
+changes:
+ - rscdel: "Updates nations. Updates nations so hard right into the void"
diff --git a/html/changelogs/AutoChangeLog-pr-11270.yml b/html/changelogs/AutoChangeLog-pr-11270.yml
new file mode 100644
index 00000000000..6ecdf8039c0
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11270.yml
@@ -0,0 +1,4 @@
+author: "TDSSS"
+delete-after: True
+changes:
+ - tweak: "nukies can buy plasma grenades again"
diff --git a/html/changelogs/AutoChangeLog-pr-11277.yml b/html/changelogs/AutoChangeLog-pr-11277.yml
new file mode 100644
index 00000000000..c966a9c74cb
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11277.yml
@@ -0,0 +1,4 @@
+author: "Arkatos"
+delete-after: True
+changes:
+ - tweak: "Shield Blobs automatically spawned around Blob Cores now give no refund upon removing. No freebies."
diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi
index 97256ff448a..9a8d69a66bd 100644
Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ
diff --git a/icons/mob/guardian.dmi b/icons/mob/guardian.dmi
index 2fa0a172bb9..a10e1e0b0ec 100644
Binary files a/icons/mob/guardian.dmi and b/icons/mob/guardian.dmi differ
diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi
index 68ebe9f6e91..b7f6b5c8f6a 100644
Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ
diff --git a/icons/mob/terrorspider64.dmi b/icons/mob/terrorspider64.dmi
new file mode 100644
index 00000000000..392ad43b3a7
Binary files /dev/null and b/icons/mob/terrorspider64.dmi differ
diff --git a/icons/turf/floors/plating.dmi b/icons/turf/floors/plating.dmi
index b7d8226024b..a1fe3dc4e6f 100644
Binary files a/icons/turf/floors/plating.dmi and b/icons/turf/floors/plating.dmi differ
diff --git a/interface/interface.dm b/interface/interface.dm
index 88bdb34e6b8..0bec55ef51c 100644
--- a/interface/interface.dm
+++ b/interface/interface.dm
@@ -52,7 +52,6 @@
src << link(config.forumurl)
else
to_chat(src, "The forum URL is not set in the server configuration.")
- return
/client/verb/rules()
set name = "Rules"
@@ -64,7 +63,6 @@
src << link(config.rulesurl)
else
to_chat(src, "The rules URL is not set in the server configuration.")
- return
/client/verb/github()
set name = "GitHub"
@@ -76,7 +74,6 @@
src << link(config.githuburl)
else
to_chat(src, "The GitHub URL is not set in the server configuration.")
- return
/client/verb/discord()
set name = "Discord"
@@ -88,7 +85,6 @@
src << link(config.discordurl)
else
to_chat(src, "The Discord URL is not set in the server configuration.")
- return
/client/verb/donate()
set name = "Donate"
@@ -100,8 +96,28 @@
src << link(config.donationsurl)
else
to_chat(src, "The rules URL is not set in the server configuration.")
- return
+/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"
set category = "OOC"
@@ -234,32 +250,3 @@ Any-Mode: (hotkey doesn't need to be on)
to_chat(src, hotkey_mode)
to_chat(src, other)
-
-//adv. hotkey mode verbs, vars located in /code/modules/client/client defines.dm
-/client/verb/hotkey_toggle()//toggles hotkey mode between on and off, respects selected type
- set name = ".Toggle Hotkey Mode"
-
- hotkeyon = !hotkeyon//toggle the var
- to_chat(usr, (hotkeyon ? "Hotkey mode enabled." : "Hotkey mode disabled."))//feedback to the user
-
- if(hotkeyon)//using an if statement because I don't want to clutter winset() with ? operators
- winset(usr, "mainwindow.hotkey_toggle", "is-checked=true")//checks the button
- else
- winset(usr, "mainwindow.hotkey_toggle", "is-checked=false")//unchecks the button
- if(mob)
- mob.update_interface()
-
-/client/verb/hotkey_mode()//asks user for the hotkey type and changes the macro accordingly
- set name = "Set Hotkey Mode"
- set category = "Preferences"
-
- var/hkt = input("Choose hotkey mode", "Hotkey mode") as null|anything in hotkeylist//ask the user for the hotkey type
- if(!hkt)
- return
- hotkeytype = hkt
-
- var/hotkeys = hotkeylist[hotkeytype]//get the list containing the hotkey names
- var/hotkeyname = hotkeys[hotkeyon ? "on" : "off"]//get the name of the hotkey, to not clutter winset() to much
-
- winset(usr, "mainwindow", "macro=[hotkeyname]")//change the hotkey
- to_chat(usr, "Hotkey mode changed to [hotkeytype].")
diff --git a/interface/skin.dmf b/interface/skin.dmf
index 996edf78905..19f5c219e3d 100644
--- a/interface/skin.dmf
+++ b/interface/skin.dmf
@@ -1,713 +1,7 @@
-macro "AZERTYoff"
- elem "AZRFF-TAB"
- name = "TAB"
- command = ".Toggle-hotkey-mode"
- 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 "AZERTYon"
- elem "AZRON-TAB"
- name = "TAB"
- command = ".Toggle-hotkey-mode"
- 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 "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 "macro"
elem "MACRO-TAB"
name = "TAB"
- command = ".Toggle-hotkey-mode"
+ 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"
@@ -893,7 +187,7 @@ macro "macro"
macro "hotkeymode"
elem "HKMODE-TAB"
name = "TAB"
- command = ".Toggle-hotkey-mode"
+ 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"
@@ -1346,6 +640,712 @@ macro "borgmacro"
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=borghotkeymode 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
+
menu "menu"
elem
name = "&File"
@@ -1537,11 +1537,11 @@ window "mainwindow"
size = 80x20
anchor1 = 100,100
anchor2 = none
+ background-color = none
+ saved-params = ""
is-flat = false
text = "Hotkey Toggle"
- command = ".Toggle-hotkey-mode"
- is-checked = false
- saved-params = "is-checked"
+ 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
diff --git a/paradise.dme b/paradise.dme
index 09323624471..de8e2934651 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -228,10 +228,11 @@
#include "code\controllers\subsystem\spacedrift.dm"
#include "code\controllers\subsystem\sun.dm"
#include "code\controllers\subsystem\throwing.dm"
-#include "code\controllers\subsystem\tickets.dm"
#include "code\controllers\subsystem\timer.dm"
#include "code\controllers\subsystem\weather.dm"
#include "code\controllers\subsystem\processing\processing.dm"
+#include "code\controllers\subsystem\tickets\mentor_tickets.dm"
+#include "code\controllers\subsystem\tickets\tickets.dm"
#include "code\datums\action.dm"
#include "code\datums\ai_law_sets.dm"
#include "code\datums\ai_laws.dm"
@@ -332,6 +333,7 @@
#include "code\datums\helper_datums\construction_datum.dm"
#include "code\datums\helper_datums\events.dm"
#include "code\datums\helper_datums\global_iterator.dm"
+#include "code\datums\helper_datums\hotkey_modes.dm"
#include "code\datums\helper_datums\icon_snapshot.dm"
#include "code\datums\helper_datums\map_template.dm"
#include "code\datums\helper_datums\teleport.dm"
@@ -548,9 +550,6 @@
#include "code\game\gamemodes\miniantags\sintouched\objectives.dm"
#include "code\game\gamemodes\miniantags\slaughter\bloodcrawl.dm"
#include "code\game\gamemodes\miniantags\slaughter\slaughter.dm"
-#include "code\game\gamemodes\nations\nations.dm"
-#include "code\game\gamemodes\nations\nationsdatums.dm"
-#include "code\game\gamemodes\nations\nationsprocs.dm"
#include "code\game\gamemodes\nuclear\nuclear.dm"
#include "code\game\gamemodes\nuclear\nuclear_challenge.dm"
#include "code\game\gamemodes\nuclear\nuclearbomb.dm"
@@ -1159,6 +1158,7 @@
#include "code\modules\admin\DB ban\functions.dm"
#include "code\modules\admin\permissionverbs\permissionedit.dm"
#include "code\modules\admin\tickets\adminticketsverbs.dm"
+#include "code\modules\admin\tickets\mentorticketsverbs.dm"
#include "code\modules\admin\verbs\adminhelp.dm"
#include "code\modules\admin\verbs\adminjump.dm"
#include "code\modules\admin\verbs\adminpm.dm"
@@ -2424,4 +2424,4 @@
#include "goon\code\datums\browserOutput.dm"
#include "interface\interface.dm"
#include "interface\skin.dmf"
-// END_INCLUDE
+// END_INCLUDE
\ No newline at end of file
diff --git a/sound/music/title2.ogg b/sound/music/title2.ogg
index af8cc5caae1..7b58ab60e4d 100644
Binary files a/sound/music/title2.ogg and b/sound/music/title2.ogg differ