diff --git a/code/__DEFINES/process_scheduler.dm b/code/__DEFINES/process_scheduler.dm
index f1e30c23ed3..5cdb99fc4bd 100644
--- a/code/__DEFINES/process_scheduler.dm
+++ b/code/__DEFINES/process_scheduler.dm
@@ -16,3 +16,6 @@
// Sleep check macro
#define SCHECK if(world.tick_usage >= next_sleep_usage) defer()
+
+//Timing Controller
+#define GLOBAL_PROC "some_magic_bullshit"
\ No newline at end of file
diff --git a/code/controllers/Processes/timer.dm b/code/controllers/Processes/timer.dm
index 2e60f8752b8..4add16aae31 100644
--- a/code/controllers/Processes/timer.dm
+++ b/code/controllers/Processes/timer.dm
@@ -6,7 +6,7 @@ var/global/datum/controller/process/timer/timer_master
/datum/controller/process/timer/setup()
name = "timer"
- schedule_interval = 5 //every 0.5 seconds
+ schedule_interval = 1 //every 0.1 seconds--2 server ticks
timer_master = src
log_startup_progress("Timer process starting up.")
@@ -30,7 +30,10 @@ var/global/datum/controller/process/timer/timer_master
/datum/controller/process/timer/proc/runevent(datum/timedevent/event)
set waitfor = 0
if(event.thingToCall)
- call(event.thingToCall, event.procToCall)(arglist(event.argList))
+ if(event.thingToCall == GLOBAL_PROC && istext(event.procToCall))
+ call("/proc/[event.procToCall]")(arglist(event.argList))
+ else
+ call(event.thingToCall, event.procToCall)(arglist(event.argList))
/datum/timedevent
var/thingToCall
@@ -42,8 +45,7 @@ var/global/datum/controller/process/timer/timer_master
var/static/nextid = 1
/datum/timedevent/New()
- id = nextid
- nextid++
+ id = nextid++
/datum/timedevent/Destroy()
timer_master.processing_timers -= src
@@ -53,7 +55,7 @@ var/global/datum/controller/process/timer/timer_master
/proc/addtimer(thingToCall, procToCall, wait, unique = FALSE, ...)
if(!timer_master) //can't run timers before the mc has been created
return
- if(!thingToCall || !procToCall || wait <= 0)
+ if(!thingToCall || !procToCall)
return
if(timer_master.disabled)
timer_master.disabled = 0
@@ -71,11 +73,17 @@ var/global/datum/controller/process/timer/timer_master
// Check for dupes if unique = 1.
if(unique)
- if(event.hash in timer_master.hashes)
- return
+ var/datum/timedevent/hash_event = timer_master.hashes[event.hash]
+ if(hash_event)
+ return hash_event.id
+ timer_master.hashes[event.hash] = event
+ if(wait <= 0)
+ timer_master.runevent(event)
+ timer_master.hashes -= event.hash
+ return
// If we are unique (or we're not checking that), add the timer and return the id.
timer_master.processing_timers += event
- timer_master.hashes += event.hash
+
return event.id
/proc/deltimer(id)
diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm
index 88b631f5c18..9ac4a0eb4d6 100644
--- a/code/controllers/configuration.dm
+++ b/code/controllers/configuration.dm
@@ -139,6 +139,7 @@
var/list/irc_bot_host = list()
var/main_irc = ""
var/admin_irc = ""
+ var/admin_notify_irc = ""
var/python_path = "" //Path to the python executable. Defaults to "python" on windows and "/usr/bin/env python2" on unix
var/default_laws = 0 //Controls what laws the AI spawns with.
@@ -468,6 +469,9 @@
if("admin_irc")
config.admin_irc = value
+ if("admin_notify_irc")
+ config.admin_notify_irc = value
+
if("python_path")
if(value)
config.python_path = value
diff --git a/code/game/gamemodes/changeling/powers/revive.dm b/code/game/gamemodes/changeling/powers/revive.dm
index 2585287528c..8cb58d8dbe0 100644
--- a/code/game/gamemodes/changeling/powers/revive.dm
+++ b/code/game/gamemodes/changeling/powers/revive.dm
@@ -5,10 +5,6 @@
//Revive from regenerative stasis
/obj/effect/proc_holder/changeling/revive/sting_action(var/mob/living/carbon/user)
- if(user.stat == DEAD)
- dead_mob_list -= user
- living_mob_list |= user
- user.stat = CONSCIOUS
user.setToxLoss(0)
user.setOxyLoss(0)
user.setCloneLoss(0)
@@ -63,12 +59,13 @@
IO.damage = 0
IO.trace_chemicals = list()
H.updatehealth()
+
to_chat(user, "We have regenerated.")
user.regenerate_icons()
user.status_flags &= ~(FAKEDEATH)
- user.update_canmove()
+ user.update_revive() //Handle waking up the changeling after the regenerative stasis has completed.
user.mind.changeling.purchasedpowers -= src
user.med_hud_set_status()
user.med_hud_set_health()
diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm
index 5deb2bafa0f..1b31f2d554a 100644
--- a/code/game/gamemodes/gameticker.dm
+++ b/code/game/gamemodes/gameticker.dm
@@ -209,12 +209,9 @@ var/round_start_time = 0
//start_events() //handles random events and space dust.
//new random event system is handled from the MC.
- var/admins_number = 0
- for(var/client/C)
- if(C.holder)
- admins_number++
- if(admins_number == 0)
- send2adminirc("Round has started with no admins online.")
+ var/list/admins_number = staff_countup(R_BAN)
+ if(admins_number[1] == 0 && admins_number[3] == 0)
+ send2irc(config.admin_notify_irc, "Round has started with no admins online.")
auto_toggle_ooc(0) // Turn it off
round_start_time = world.time
diff --git a/code/game/gamemodes/nuclear/pinpointer.dm b/code/game/gamemodes/nuclear/pinpointer.dm
index ee36a71a9cd..f118bf548f0 100644
--- a/code/game/gamemodes/nuclear/pinpointer.dm
+++ b/code/game/gamemodes/nuclear/pinpointer.dm
@@ -179,7 +179,7 @@
/obj/item/weapon/pinpointer/nukeop
var/mode = 0 //Mode 0 locates disk, mode 1 locates the shuttle
var/obj/docking_port/mobile/home = null
- slot_flags = SLOT_BELT
+ slot_flags = SLOT_BELT | SLOT_PDA
/obj/item/weapon/pinpointer/nukeop/attack_self(mob/user as mob)
if(!active)
diff --git a/code/game/gamemodes/vampire/vampire.dm b/code/game/gamemodes/vampire/vampire.dm
index dd40a6817b6..39c9c24ec50 100644
--- a/code/game/gamemodes/vampire/vampire.dm
+++ b/code/game/gamemodes/vampire/vampire.dm
@@ -242,6 +242,10 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha
owner.mind.spell_list.Remove(ability)
qdel(ability)
+/datum/vampire/proc/update_owner(var/mob/living/carbon/human/current) //Called when a vampire gets cloned. This updates vampire.owner to the new body.
+ if(current.mind && current.mind.vampire && current.mind.vampire.owner && (current.mind.vampire.owner != current))
+ current.mind.vampire.owner = current
+
/mob/proc/make_vampire()
if(!mind)
return
@@ -325,8 +329,7 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha
else if(istype(p, /datum/vampire_passive))
var/datum/vampire_passive/power = p
to_chat(owner, "[power.gain_desc]")
-
-
+
/datum/game_mode/proc/remove_vampire(datum/mind/vampire_mind)
if(vampire_mind in vampires)
ticker.mode.vampires -= vampire_mind
@@ -335,12 +338,12 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha
if(vampire_mind.vampire)
vampire_mind.vampire.remove_vampire_powers()
qdel(vampire_mind.vampire)
- vampire_mind.vampire = null
+ vampire_mind.vampire = null
if(issilicon(vampire_mind.current))
to_chat(vampire_mind.current, "You have been turned into a robot! You can feel your powers fading away...")
else
to_chat(vampire_mind.current, "You have been brainwashed! You are no longer a vampire.")
- ticker.mode.update_vampire_icons_removed(vampire_mind)
+ ticker.mode.update_vampire_icons_removed(vampire_mind)
//prepare for copypaste
/datum/game_mode/proc/update_vampire_icons_added(datum/mind/vampire_mind)
diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm
index a3bd840750e..b8b2629b22b 100644
--- a/code/game/machinery/computer/message.dm
+++ b/code/game/machinery/computer/message.dm
@@ -145,7 +145,7 @@
if(!auth)
dat += "
Please authenticate with the server in order to show additional options."
else
- dat += "
Reg, #514 forbids sending messages to a Head of Staff containing Erotic Rendering Properties."
+ dat += "
Reg, #514 forbids sending messages containing Erotic Rendering Properties."
//Message Logs
if(1)
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 3e62232fda5..d13273eaae1 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -533,7 +533,8 @@ About the new airlock wires panel:
shockedby += text("\[[time_stamp()]\] - EMP)")
message = "The door is now electrified [duration == -1 ? "permanently" : "for [duration] second\s"]."
electrified_until = duration == -1 ? -1 : world.time + SecondsToTicks(duration)
- electrified_timer = addtimer(src, "electrify", SecondsToTicks(duration), 1, 0)
+ if(duration != -1)
+ electrified_timer = addtimer(src, "electrify", SecondsToTicks(duration), 1, 0)
if(feedback && message)
to_chat(usr, message)
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 687fc00797d..eb32af7802d 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -1001,3 +1001,22 @@ var/gamma_ship_location = 1 // 0 = station , 1 = space
qdel(frommob)
return 1
+
+// Returns a list of the number of admins in various categories
+// result[1] is the number of staff that match the rank mask and are active
+// result[2] is the number of staff that do not match the rank mask
+// result[3] is the number of staff that match the rank mask and are inactive
+/proc/staff_countup(rank_mask = R_BAN)
+ var/list/result = list(0, 0, 0)
+ for(var/client/X in admins)
+ if(rank_mask && !check_rights_for(X, rank_mask))
+ result[2]++
+ continue
+ if(X.holder.fakekey)
+ result[2]++
+ continue
+ if(X.is_afk())
+ result[3]++
+ continue
+ result[1]++
+ return result
diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm
index 0cf9b0a0915..0209b16c40e 100644
--- a/code/modules/client/client procs.dm
+++ b/code/modules/client/client procs.dm
@@ -238,7 +238,7 @@
if((last_message_time + throttle > world.time) && !check_rights(R_ADMIN, 0))
var/wait_time = round(((last_message_time + throttle) - world.time) / 10, 1)
to_chat(src, "You are sending messages to quickly. Please wait [wait_time] [wait_time == 1 ? "second" : "seconds"] before sending another message.")
- return 1
+ return 1
last_message_time = world.time
if(config.automute_on && !check_rights(R_ADMIN, 0) && last_message == message)
last_message_count++
@@ -437,7 +437,7 @@
var/watchreason = check_watchlist(ckey)
if(watchreason)
message_admins("Notice: [key_name_admin(src)] is on the watchlist and has just connected - Reason: [watchreason]")
- send2adminirc("Watchlist - [key_name(src)] is on the watchlist and has just connected - Reason: [watchreason]")
+ send2irc(config.admin_notify_irc, "Watchlist - [key_name(src)] is on the watchlist and has just connected - Reason: [watchreason]")
//Just the standard check to see if it's actually a number
if(sql_id)
diff --git a/code/modules/computer3/computers/message.dm b/code/modules/computer3/computers/message.dm
index 3864082a8cb..35e981a4a7a 100644
--- a/code/modules/computer3/computers/message.dm
+++ b/code/modules/computer3/computers/message.dm
@@ -104,7 +104,7 @@
if(!auth)
dat += "
Please authenticate with the server in order to show additional options."
else
- dat += "
Reg, #514 forbids sending messages to a Head of Staff containing Erotic Rendering Properties."
+ dat += "
Reg, #514 forbids sending messages containing Erotic Rendering Properties."
//Message Logs
if(1)
diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm
index 3ced404f91b..63875ee04ee 100644
--- a/code/modules/customitems/item_defines.dm
+++ b/code/modules/customitems/item_defines.dm
@@ -655,3 +655,8 @@
suit_adjusted = 1
species_fit = null
sprite_sheets = null
+
+/obj/item/weapon/storage/backpack/fluff/krich_back //lizardzsi: Krichahka
+ name = "Voxcaster"
+ desc = "Battered, Sol-made military radio backpack that had its speakers fried from playing Vox opera. The words 'Swift-Talon' are crudely scratched onto its side."
+ icon_state = "voxcaster_fluff"
diff --git a/code/modules/mob/living/silicon/ai/freelook/chunk.dm b/code/modules/mob/living/silicon/ai/freelook/chunk.dm
index 71d80df9e02..eeeeed8e8bb 100644
--- a/code/modules/mob/living/silicon/ai/freelook/chunk.dm
+++ b/code/modules/mob/living/silicon/ai/freelook/chunk.dm
@@ -114,7 +114,7 @@
var/turf/t = turf
if(obscuredTurfs[t])
if(!t.obscured)
- t.obscured = image('icons/effects/cameravis.dmi', t, "black", 15)
+ t.obscured = image('icons/effects/cameravis.dmi', t, null, 15)
obscured += t.obscured
for(var/eye in seenby)
diff --git a/code/modules/mob/logout.dm b/code/modules/mob/logout.dm
index d83a5efe339..b9fed474cdf 100644
--- a/code/modules/mob/logout.dm
+++ b/code/modules/mob/logout.dm
@@ -3,15 +3,19 @@
unset_machine()
player_list -= src
log_access("Logout: [key_name(src)]")
- if(admin_datums[src.ckey])
- if(ticker && ticker.current_state == GAME_STATE_PLAYING) //Only report this stuff if we are currently playing.
- var/admins_number = admins.len
-
+ // `holder` is nil'd out by now, so we check the `admin_datums` array directly
+ //Only report this stuff if we are currently playing.
+ if(admin_datums[ckey] && ticker && ticker.current_state == GAME_STATE_PLAYING)
+ var/datum/admins/temp_admin = admin_datums[ckey]
+ // Triggers on people with banhammer power only - no mentors tripping the alarm
+ if(temp_admin.rights & R_BAN)
message_admins("Admin logout: [key_name_admin(src)]")
- if(admins_number == 0) //Apparently the admin logging out is no longer an admin at this point, so we have to check this towards 0 and not towards 1. Awell.
- send2adminirc("[key_name(src)] logged out - no more admins online.")
+ var/list/admincounter = staff_countup(R_BAN)
+ if(admincounter[1] == 0) // No active admins
+ send2irc(config.admin_notify_irc, "[key_name(src)] logged out - No active admins, [admincounter[2]] non-admin staff, [admincounter[3]] inactive staff.")
+
..()
-
- callHook("mob_logout", list("client" = client, "mob" = src))
-
- return 1
\ No newline at end of file
+
+ callHook("mob_logout", list("client" = client, "mob" = src))
+
+ return 1
diff --git a/config/example/config.txt b/config/example/config.txt
index f2087eebaa2..31bde9c5e4f 100644
--- a/config/example/config.txt
+++ b/config/example/config.txt
@@ -248,6 +248,9 @@ GHOST_INTERACTION
## IRC channel to send adminhelps to. Leave blank to disable adminhelps-to-irc.
#ADMIN_IRC #admin
+## IRC channel to send direct messages to admins to. Leave blank to disable.
+#ADMIN_NOTIFY_IRC #paradiseStaff
+
## Path to the python2 executable on the system. Leave blank for default.
## Default is "python" on Windows, "/usr/bin/env python2" on UNIX.
#PYTHON_PATH pythonw
diff --git a/html/changelog.html b/html/changelog.html
index 46d21c4293a..aaecde3bc11 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -55,6 +55,31 @@
-->
+
06 December 2016
+
Markolie updated:
+
+ - The track button on the AI crew monitor now works.
+ - Permanent door electrification by alt-clicking a door as an AI or setting it manually now works again.
+
+
+
05 December 2016
+
KasparoVy updated:
+
+ - Resolves an issue where cloned vampires could no longer drain blood, burn in the chapel or use their powers properly.
+
+
+
04 December 2016
+
KasparoVy updated:
+
+ - Resolves an issue with changeling regenerative stasis where changelings who initiated it while alive and died during the waiting period did not come back to life. Now they will, as intended.
+
+
+
03 December 2016
+
Kyep updated:
+
+ - the anti-ERP warning message on PDA message consoles is now accurate.
+
+
01 December 2016
Crazylemon64 updated:
diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml
index da0a01e1120..781a18d0ea8 100644
--- a/html/changelogs/.all_changelog.yml
+++ b/html/changelogs/.all_changelog.yml
@@ -3127,3 +3127,20 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
pod is destroyed in any method.
- bugfix: Pilots of spacepods will now get the same warnings for damage/core destruction
that passengers get.
+2016-12-03:
+ Kyep:
+ - tweak: the anti-ERP warning message on PDA message consoles is now accurate.
+2016-12-04:
+ KasparoVy:
+ - bugfix: Resolves an issue with changeling regenerative stasis where changelings
+ who initiated it while alive and died during the waiting period did not come
+ back to life. Now they will, as intended.
+2016-12-05:
+ KasparoVy:
+ - bugfix: Resolves an issue where cloned vampires could no longer drain blood, burn
+ in the chapel or use their powers properly.
+2016-12-06:
+ Markolie:
+ - bugfix: The track button on the AI crew monitor now works.
+ - bugfix: Permanent door electrification by alt-clicking a door as an AI or setting
+ it manually now works again.
diff --git a/icons/effects/cameravis.dmi b/icons/effects/cameravis.dmi
index 25dbc6c8e0e..378c19bad45 100644
Binary files a/icons/effects/cameravis.dmi and b/icons/effects/cameravis.dmi differ
diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi
index 4c7a3707efd..9cf930476d5 100644
Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ
diff --git a/icons/mob/species/vox/back.dmi b/icons/mob/species/vox/back.dmi
index 6ab32288475..0a88536cc83 100644
Binary files a/icons/mob/species/vox/back.dmi and b/icons/mob/species/vox/back.dmi differ
diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi
index d21263adf0f..bd09b38dcd4 100644
Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ
diff --git a/nano/templates/crew_monitor.tmpl b/nano/templates/crew_monitor.tmpl
index f41b341e5c6..15ad2168808 100644
--- a/nano/templates/crew_monitor.tmpl
+++ b/nano/templates/crew_monitor.tmpl
@@ -10,7 +10,7 @@ Used In File(s): \code\game\machinery\computer\crew.dm
{{else value.sensor_type == 2}}
| {{:value.name}} ({{:value.assignment}}) | {{:value.dead ? "Deceased" : "Living"}} ({{:value.oxy}}/{{:value.tox}}/{{:value.fire}}/{{:value.brute}}) | Not Available | {{if data.isAI}}{{:helper.link('Track', null, {}, 'disabled')}} | {{/if}}
{{else value.sensor_type == 3}}
- | {{:value.name}} ({{:value.assignment}}) | {{:value.dead ? "Deceased" : "Living"}} ({{:value.oxy}}/{{:value.tox}}/{{:value.fire}}/{{:value.brute}}) | {{:value.area}}({{:value.x}}, {{:value.y}}) | {{if data.isAI}}{{:helper.link('Track', null, {'track' : value.reference})}} | {{/if}}
+ | {{:value.name}} ({{:value.assignment}}) | {{:value.dead ? "Deceased" : "Living"}} ({{:value.oxy}}/{{:value.tox}}/{{:value.fire}}/{{:value.brute}}) | {{:value.area}}({{:value.x}}, {{:value.y}}) | {{if data.isAI}}{{:helper.link('Track', null, {'track' : value.ref})}} | {{/if}}
{{/if}}
{{/for}}
\ No newline at end of file