Merge pull request #1045 from Citadel-Station-13/upstream-merge-27268
[MIRROR] World.dm Refactor
This commit is contained in:
@@ -41,6 +41,7 @@
|
||||
// Subsystem init_order, from highest priority to lowest priority
|
||||
// The numbers just define the ordering, they are meaningless otherwise.
|
||||
|
||||
#define INIT_ORDER_SERVER_MAINT 16
|
||||
#define INIT_ORDER_JOBS 15
|
||||
#define INIT_ORDER_EVENTS 14
|
||||
#define INIT_ORDER_TICKER 13
|
||||
|
||||
+14
-14
@@ -340,20 +340,20 @@ Proc for attack log creation, because really why not
|
||||
qdel(progbar)
|
||||
|
||||
|
||||
//some additional checks as a callback for for do_afters that want to break on losing health or on the mob taking action
|
||||
/mob/proc/break_do_after_checks(list/checked_health, check_clicks)
|
||||
if(check_clicks && next_move > world.time)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
//pass a list in the format list("health" = mob's health var) to check health during this
|
||||
/mob/living/break_do_after_checks(list/checked_health, check_clicks)
|
||||
if(islist(checked_health))
|
||||
if(health < checked_health["health"])
|
||||
return FALSE
|
||||
checked_health["health"] = health
|
||||
return ..()
|
||||
|
||||
//some additional checks as a callback for for do_afters that want to break on losing health or on the mob taking action
|
||||
/mob/proc/break_do_after_checks(list/checked_health, check_clicks)
|
||||
if(check_clicks && next_move > world.time)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
//pass a list in the format list("health" = mob's health var) to check health during this
|
||||
/mob/living/break_do_after_checks(list/checked_health, check_clicks)
|
||||
if(islist(checked_health))
|
||||
if(health < checked_health["health"])
|
||||
return FALSE
|
||||
checked_health["health"] = health
|
||||
return ..()
|
||||
|
||||
/proc/do_after(mob/user, delay, needhand = 1, atom/target = null, progress = 1, datum/callback/extra_checks = null)
|
||||
if(!user)
|
||||
return 0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
GLOBAL_VAR_INIT(master_mode, "traitor") //"extended"
|
||||
GLOBAL_VAR_INIT(master_mode, "traitor") //"extended"
|
||||
GLOBAL_VAR_INIT(secret_force_mode, "secret") // if this is anything but "secret", the secret rotation will forceably choose this mode
|
||||
|
||||
GLOBAL_VAR_INIT(wavesecret, 0) // meteor mode, delays wave progression, terrible name
|
||||
|
||||
@@ -8,7 +8,7 @@ GLOBAL_VAR_INIT(fileaccess_timer, 0)
|
||||
|
||||
GLOBAL_VAR_INIT(TAB, " ")
|
||||
|
||||
GLOBAL_DATUM(data_core, /datum/datacore)
|
||||
GLOBAL_DATUM_INIT(data_core, /datum/datacore, new)
|
||||
|
||||
GLOBAL_VAR_INIT(CELLRATE, 0.002) // multiplier for watts per tick <> cell storage (eg: .002 means if there is a load of 1000 watts, 20 units will be taken from a cell per second)
|
||||
GLOBAL_VAR_INIT(CHARGELEVEL, 0.001) // Cap for how fast cells charge, as a percentage-per-tick (.001 means cellcharge is capped to 1% per second)
|
||||
|
||||
+21
-21
@@ -92,9 +92,9 @@
|
||||
if(next_move > world.time) // in the year 2000...
|
||||
return
|
||||
|
||||
if(A.IsObscured())
|
||||
return
|
||||
|
||||
if(A.IsObscured())
|
||||
return
|
||||
|
||||
if(istype(loc,/obj/mecha))
|
||||
var/obj/mecha/M = loc
|
||||
return M.click_action(A,src,params)
|
||||
@@ -144,24 +144,24 @@
|
||||
else
|
||||
RangedAttack(A,params)
|
||||
|
||||
//Is the atom obscured by a PREVENT_CLICK_UNDER object above it
|
||||
/atom/proc/IsObscured()
|
||||
if(!isturf(loc)) //This only makes sense for things directly on turfs for now
|
||||
return FALSE
|
||||
var/turf/T = get_turf_pixel(src)
|
||||
if(!T)
|
||||
return FALSE
|
||||
for(var/atom/movable/AM in T)
|
||||
if(AM.flags & PREVENT_CLICK_UNDER && AM.density && AM.layer > layer)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/turf/IsObscured()
|
||||
for(var/atom/movable/AM in src)
|
||||
if(AM.flags & PREVENT_CLICK_UNDER && AM.density)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
//Is the atom obscured by a PREVENT_CLICK_UNDER object above it
|
||||
/atom/proc/IsObscured()
|
||||
if(!isturf(loc)) //This only makes sense for things directly on turfs for now
|
||||
return FALSE
|
||||
var/turf/T = get_turf_pixel(src)
|
||||
if(!T)
|
||||
return FALSE
|
||||
for(var/atom/movable/AM in T)
|
||||
if(AM.flags & PREVENT_CLICK_UNDER && AM.density && AM.layer > layer)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/turf/IsObscured()
|
||||
for(var/atom/movable/AM in src)
|
||||
if(AM.flags & PREVENT_CLICK_UNDER && AM.density)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/atom/movable/proc/CanReach(atom/target,obj/item/tool,view_only = FALSE)
|
||||
if(isturf(target) || isturf(target.loc) || DirectAccess(target)) //Directly accessible atoms
|
||||
if(Adjacent(target) || (tool && CheckToolReach(src, target, tool.reach))) //Adjacent or reaching attacks
|
||||
|
||||
@@ -83,6 +83,7 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
sortTim(subsystems, /proc/cmp_subsystem_init)
|
||||
reverseRange(subsystems)
|
||||
for(var/datum/controller/subsystem/ss in subsystems)
|
||||
testing("Shutdown [ss.name] subsystem")
|
||||
ss.Shutdown()
|
||||
|
||||
// Returns 1 if we created a new mc, 0 if we couldn't due to a recent restart,
|
||||
|
||||
@@ -2,7 +2,7 @@ SUBSYSTEM_DEF(blackbox)
|
||||
name = "Blackbox"
|
||||
wait = 6000
|
||||
flags = SS_NO_TICK_CHECK
|
||||
|
||||
|
||||
var/list/msg_common = list()
|
||||
var/list/msg_science = list()
|
||||
var/list/msg_command = list()
|
||||
@@ -42,7 +42,6 @@ SUBSYSTEM_DEF(blackbox)
|
||||
msg_cargo = SSblackbox.msg_cargo
|
||||
msg_other = SSblackbox.msg_other
|
||||
|
||||
|
||||
feedback = SSblackbox.feedback
|
||||
|
||||
//no touchie
|
||||
@@ -55,6 +54,8 @@ SUBSYSTEM_DEF(blackbox)
|
||||
return FALSE
|
||||
|
||||
/datum/controller/subsystem/blackbox/Shutdown()
|
||||
set_val("ahelp_unresolved", GLOB.ahelp_tickets.active_tickets.len)
|
||||
|
||||
var/pda_msg_amt = 0
|
||||
var/rc_msg_amt = 0
|
||||
|
||||
@@ -84,20 +85,16 @@ SUBSYSTEM_DEF(blackbox)
|
||||
|
||||
if (!SSdbcore.Connect())
|
||||
return
|
||||
|
||||
var/sqlrowlist = ""
|
||||
|
||||
var/list/sqlrowlist = list()
|
||||
|
||||
for (var/datum/feedback_variable/FV in feedback)
|
||||
if (sqlrowlist != "")
|
||||
sqlrowlist += ", " //a comma (,) at the start of the first row to insert will trigger a SQL error
|
||||
sqlrowlist += list("time" = "Now()", "round_id" = GLOB.round_id, "var_name" = "'[sanitizeSQL(FV.get_variable())]'", "var_value" = FV.get_value(), "details" = "'[sanitizeSQL(FV.get_details())]'")
|
||||
|
||||
sqlrowlist += list(list("time" = "Now()", "round_id" = GLOB.round_id, "var_name" = "'[sanitizeSQL(FV.get_variable())]'", "var_value" = FV.get_value(), "details" = "'[sanitizeSQL(FV.get_details())]'"))
|
||||
|
||||
if (sqlrowlist == "")
|
||||
if (!length(sqlrowlist))
|
||||
return
|
||||
|
||||
var/datum/DBQuery/query_feedback_save = SSdbcore.NewQuery("INSERT DELAYED IGNORE INTO [format_table_name("feedback")] VALUES " + sqlrowlist)
|
||||
query_feedback_save.Execute()
|
||||
SSdbcore.MassInsert(format_table_name("feedback"), sqlrowlist, ignore_errors = TRUE, delayed = TRUE)
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/LogBroadcast(blackbox_msg, freq)
|
||||
switch(freq)
|
||||
|
||||
@@ -5,6 +5,7 @@ SUBSYSTEM_DEF(server_maint)
|
||||
wait = 6
|
||||
flags = SS_POST_FIRE_TIMING
|
||||
priority = 10
|
||||
init_order = INIT_ORDER_SERVER_MAINT
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
|
||||
var/list/currentrun
|
||||
|
||||
@@ -16,7 +17,7 @@ SUBSYSTEM_DEF(server_maint)
|
||||
/datum/controller/subsystem/server_maint/fire(resumed = FALSE)
|
||||
if(!resumed)
|
||||
src.currentrun = GLOB.clients.Copy()
|
||||
|
||||
|
||||
var/list/currentrun = src.currentrun
|
||||
var/round_started = SSticker.HasRoundStarted()
|
||||
|
||||
@@ -37,4 +38,11 @@ SUBSYSTEM_DEF(server_maint)
|
||||
if (MC_TICK_CHECK) //one day, when ss13 has 1000 people per server, you guys are gonna be glad I added this tick check
|
||||
return
|
||||
|
||||
#undef PING_BUFFER_TIME
|
||||
/datum/controller/subsystem/server_maint/Shutdown()
|
||||
kick_clients_in_lobby("<span class='boldannounce'>The round came to an end with you in the lobby.</span>", TRUE) //second parameter ensures only afk clients are kicked
|
||||
for(var/thing in GLOB.clients)
|
||||
var/client/C = thing
|
||||
if(C && config.server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite
|
||||
C << link("byond://[config.server]")
|
||||
|
||||
#undef PING_BUFFER_TIME
|
||||
@@ -20,6 +20,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
|
||||
var/login_music //music played in pregame lobby
|
||||
var/round_end_sound //music/jingle played when the world reboots
|
||||
var/round_end_sound_sent = TRUE //If all clients have loaded it
|
||||
|
||||
var/list/datum/mind/minds = list() //The characters in the game. Used for objective tracking.
|
||||
|
||||
@@ -63,6 +64,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
var/modevoted = FALSE //Have we sent a vote for the gamemode?
|
||||
|
||||
/datum/controller/subsystem/ticker/Initialize(timeofday)
|
||||
load_mode()
|
||||
var/list/music = world.file2list(ROUND_START_MUSIC_LIST, "\n")
|
||||
login_music = pick(music)
|
||||
|
||||
@@ -637,9 +639,9 @@ SUBSYSTEM_DEF(ticker)
|
||||
|
||||
sleep(50)
|
||||
if(mode.station_was_nuked)
|
||||
world.Reboot("Station destroyed by Nuclear Device.", "end_proper", "nuke")
|
||||
Reboot("Station destroyed by Nuclear Device.", "end_proper", "nuke")
|
||||
else
|
||||
world.Reboot("Round ended.", "end_proper", "proper completion")
|
||||
Reboot("Round ended.", "end_proper", "proper completion")
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/send_tip_of_the_round()
|
||||
var/m
|
||||
@@ -806,3 +808,69 @@ SUBSYSTEM_DEF(ticker)
|
||||
start_at = world.time + newtime
|
||||
else
|
||||
timeLeft = newtime
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/load_mode()
|
||||
var/mode = trim(file2text("data/mode.txt"))
|
||||
if(mode)
|
||||
GLOB.master_mode = mode
|
||||
else
|
||||
GLOB.master_mode = "extended"
|
||||
log_game("Saved mode is '[GLOB.master_mode]'")
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/save_mode(the_mode)
|
||||
var/F = file("data/mode.txt")
|
||||
fdel(F)
|
||||
F << the_mode
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/SetRoundEndSound(the_sound)
|
||||
set waitfor = FALSE
|
||||
round_end_sound_sent = FALSE
|
||||
round_end_sound = fcopy_rsc(the_sound)
|
||||
for(var/thing in GLOB.clients)
|
||||
var/client/C = thing
|
||||
if (!C)
|
||||
continue
|
||||
C.Export("##action=load_rsc", round_end_sound)
|
||||
round_end_sound_sent = TRUE
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/Reboot(reason, feedback_c, feedback_r, delay)
|
||||
set waitfor = FALSE
|
||||
if(usr && !check_rights(R_SERVER, TRUE))
|
||||
return
|
||||
|
||||
if(!delay)
|
||||
delay = config.round_end_countdown * 10
|
||||
|
||||
if(delay_end)
|
||||
to_chat(world, "<span class='boldannounce'>An admin has delayed the round end.</span>")
|
||||
return
|
||||
|
||||
to_chat(world, "<span class='boldannounce'>Rebooting World in [delay/10] [(delay >= 10 && delay < 20) ? "second" : "seconds"]. [reason]</span>")
|
||||
|
||||
var/start_wait = world.time
|
||||
UNTIL(round_end_sound_sent && (world.time - start_wait) > (delay * 2)) //don't wait forever
|
||||
sleep(delay - (world.time - start_wait))
|
||||
|
||||
if(delay_end)
|
||||
to_chat(world, "<span class='boldannounce'>Reboot was cancelled by an admin.</span>")
|
||||
return
|
||||
|
||||
SSblackbox.set_details("[feedback_c]","[feedback_r]")
|
||||
|
||||
log_game("<span class='boldannounce'>Rebooting World. [reason]</span>")
|
||||
|
||||
world.Reboot()
|
||||
|
||||
/datum/controller/subsystem/ticker/Shutdown()
|
||||
if(!round_end_sound)
|
||||
round_end_sound = pick(\
|
||||
'sound/roundend/newroundsexy.ogg',
|
||||
'sound/roundend/apcdestroyed.ogg',
|
||||
'sound/roundend/bangindonk.ogg',
|
||||
'sound/roundend/leavingtg.ogg',
|
||||
'sound/roundend/its_only_game.ogg',
|
||||
'sound/roundend/yeehaw.ogg',
|
||||
'sound/roundend/disappointed.ogg'\
|
||||
)
|
||||
|
||||
world << sound(round_end_sound)
|
||||
@@ -55,6 +55,12 @@ SUBSYSTEM_DEF(title)
|
||||
var/F = file("data/previous_title.dat")
|
||||
F << file_path
|
||||
|
||||
for(var/thing in GLOB.clients)
|
||||
if(!thing)
|
||||
continue
|
||||
var/obj/screen/splash/S = new(thing, FALSE)
|
||||
S.Fade(FALSE,FALSE)
|
||||
|
||||
/datum/controller/subsystem/title/Recover()
|
||||
icon = SStitle.icon
|
||||
splash_turf = SStitle.splash_turf
|
||||
|
||||
@@ -2,9 +2,9 @@ SUBSYSTEM_DEF(vote)
|
||||
name = "Vote"
|
||||
wait = 10
|
||||
|
||||
flags = SS_KEEP_TIMING|SS_NO_INIT
|
||||
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
|
||||
flags = SS_KEEP_TIMING|SS_NO_INIT
|
||||
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
|
||||
|
||||
var/initiator = null
|
||||
var/started_time = null
|
||||
@@ -120,13 +120,13 @@ SUBSYSTEM_DEF(vote)
|
||||
if(SSticker && SSticker.mode)//Don't change the mode if the round already started.
|
||||
return message_admins("A vote has tried to change the gamemode, but the game has already started. Aborting.")
|
||||
GLOB.master_mode = .
|
||||
world.save_mode(.)
|
||||
SSticker.save_mode(.)
|
||||
to_chat(world, "<span class='adminnotice'><b>The mode is now: [GLOB.master_mode]</b></span>")
|
||||
log_admin("Gamemode has been voted for and switched to: [GLOB.master_mode].")
|
||||
if("gamemode")
|
||||
if(GLOB.master_mode != .)
|
||||
world.save_mode(.)
|
||||
if(SSticker.HasRoundStarted())
|
||||
SSticker.save_mode(.)
|
||||
if(SSticker.HasRoundStarted())
|
||||
restart = 1
|
||||
else
|
||||
GLOB.master_mode = .
|
||||
@@ -137,7 +137,7 @@ SUBSYSTEM_DEF(vote)
|
||||
active_admins = 1
|
||||
break
|
||||
if(!active_admins)
|
||||
world.Reboot("Restart vote successful.", "end_error", "restart vote")
|
||||
SSticker.Reboot("Restart vote successful.", "end_error", "restart vote")
|
||||
else
|
||||
to_chat(world, "<span style='boldannounce'>Notice:Restart vote will not restart the server automatically because there are active admins on.</span>")
|
||||
message_admins("A restart vote has passed, but there are active admins on with +server, so it has been canceled. If you wish, you may restart the server.")
|
||||
|
||||
@@ -459,8 +459,7 @@
|
||||
var/datum/game_mode/nuclear/NM = SSticker.mode
|
||||
NM.nukes_left --
|
||||
if(!SSticker.mode.check_finished())//If the mode does not deal with the nuke going off so just reboot because everyone is stuck as is
|
||||
spawn()
|
||||
world.Reboot("Station destroyed by Nuclear Device.", "end_error", "nuke - unhandled ending")
|
||||
SSticker.Reboot("Station destroyed by Nuclear Device.", "end_error", "nuke - unhandled ending")
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
M.dna.uni_identity = merge_text(M.dna.uni_identity, fields["UI"])
|
||||
M.updateappearance(mutations_overlay_update=1)
|
||||
log_attack(log_msg)
|
||||
return TRUE
|
||||
return TRUE
|
||||
|
||||
/obj/item/weapon/dnainjector/attack(mob/target, mob/user)
|
||||
if(!user.IsAdvancedToolUser())
|
||||
@@ -77,9 +77,9 @@
|
||||
|
||||
add_logs(user, target, "injected", src)
|
||||
|
||||
if(!inject(target, user)) //Now we actually do the heavy lifting.
|
||||
to_chat(user, "<span class='notice'>It appears that [target] does not have compatible DNA.</span>")
|
||||
|
||||
if(!inject(target, user)) //Now we actually do the heavy lifting.
|
||||
to_chat(user, "<span class='notice'>It appears that [target] does not have compatible DNA.</span>")
|
||||
|
||||
used = 1
|
||||
icon_state = "dnainjector0"
|
||||
desc += " This one is used up."
|
||||
|
||||
@@ -48,27 +48,27 @@
|
||||
/obj/item/weapon/grenade/attack_self(mob/user)
|
||||
if(!active)
|
||||
if(clown_check(user))
|
||||
preprime(user)
|
||||
preprime(user)
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
C.throw_mode_on()
|
||||
|
||||
/obj/item/weapon/grenade/proc/preprime(mob/user)
|
||||
if(user)
|
||||
to_chat(user, "<span class='warning'>You prime the [name]! [det_time/10] seconds!</span>")
|
||||
playsound(loc, 'sound/weapons/armbomb.ogg', 60, 1)
|
||||
active = TRUE
|
||||
icon_state = initial(icon_state) + "_active"
|
||||
add_fingerprint(user)
|
||||
var/turf/bombturf = get_turf(src)
|
||||
var/area/A = get_area(bombturf)
|
||||
if(user)
|
||||
var/message = "[ADMIN_LOOKUPFLW(user)]) has primed a [name] for detonation at [ADMIN_COORDJMP(bombturf)]"
|
||||
GLOB.bombers += message
|
||||
message_admins(message)
|
||||
log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] [COORD(bombturf)].")
|
||||
|
||||
addtimer(CALLBACK(src, .proc/prime), det_time)
|
||||
/obj/item/weapon/grenade/proc/preprime(mob/user)
|
||||
if(user)
|
||||
to_chat(user, "<span class='warning'>You prime the [name]! [det_time/10] seconds!</span>")
|
||||
playsound(loc, 'sound/weapons/armbomb.ogg', 60, 1)
|
||||
active = TRUE
|
||||
icon_state = initial(icon_state) + "_active"
|
||||
add_fingerprint(user)
|
||||
var/turf/bombturf = get_turf(src)
|
||||
var/area/A = get_area(bombturf)
|
||||
if(user)
|
||||
var/message = "[ADMIN_LOOKUPFLW(user)]) has primed a [name] for detonation at [ADMIN_COORDJMP(bombturf)]"
|
||||
GLOB.bombers += message
|
||||
message_admins(message)
|
||||
log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] [COORD(bombturf)].")
|
||||
|
||||
addtimer(CALLBACK(src, .proc/prime), det_time)
|
||||
|
||||
/obj/item/weapon/grenade/proc/prime()
|
||||
|
||||
@@ -108,4 +108,4 @@
|
||||
if(damage && attack_type == PROJECTILE_ATTACK && prob(15))
|
||||
owner.visible_message("<span class='danger'>[attack_text] hits [owner]'s [src], setting it off! What a shot!</span>")
|
||||
prime()
|
||||
return 1 //It hit the grenade, not them
|
||||
return 1 //It hit the grenade, not them
|
||||
|
||||
Executable → Regular
+2
-2
@@ -140,8 +140,8 @@
|
||||
item_state = "plasmaman_tank_belt"
|
||||
slot_flags = SLOT_BELT
|
||||
force = 5
|
||||
volume = 3
|
||||
w_class = WEIGHT_CLASS_SMALL //thanks i forgot this
|
||||
volume = 3
|
||||
w_class = WEIGHT_CLASS_SMALL //thanks i forgot this
|
||||
|
||||
/obj/item/weapon/tank/internals/plasmaman/belt/full/New()
|
||||
..()
|
||||
|
||||
@@ -419,13 +419,18 @@
|
||||
set desc="Restarts the world immediately"
|
||||
if (!usr.client.holder)
|
||||
return
|
||||
var/confirm = alert("Restart the game world?", "Restart", "Yes", "Cancel")
|
||||
if(confirm == "Cancel")
|
||||
return
|
||||
if(confirm == "Yes")
|
||||
SSticker.delay_end = 0
|
||||
|
||||
var/list/options = list("Regular Restart", "Hard Restart (No Delay/Feeback Reason)", "Hardest Restart (No actions, just reboot)")
|
||||
var result = input(usr, "Select reboot method", "World Reboot", options[1]) as null|anything in options
|
||||
if(result)
|
||||
SSblackbox.add_details("admin_verb","Reboot World") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
world.Reboot("Initiated by [usr.client.holder.fakekey ? "Admin" : usr.key].", "end_error", "admin reboot - by [usr.key] [usr.client.holder.fakekey ? "(stealth)" : ""]", 10)
|
||||
switch(result)
|
||||
if("Regular Restart")
|
||||
SSticker.Reboot("Initiated by [usr.client.holder.fakekey ? "Admin" : usr.key].", "end_error", "admin reboot - by [usr.key] [usr.client.holder.fakekey ? "(stealth)" : ""]", 10)
|
||||
if("Hard Restart (No Delay, No Feeback Reason)")
|
||||
world.Reboot()
|
||||
if("Hardest Restart (No actions, just reboot)")
|
||||
world.Reboot(fast_track = TRUE)
|
||||
|
||||
/datum/admins/proc/end_round()
|
||||
set category = "Server"
|
||||
|
||||
@@ -1206,7 +1206,7 @@
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] set the mode as [GLOB.master_mode].</span>")
|
||||
to_chat(world, "<span class='adminnotice'><b>The mode is now: [GLOB.master_mode]</b></span>")
|
||||
Game() // updates the main game menu
|
||||
world.save_mode(GLOB.master_mode)
|
||||
SSticker.save_mode(GLOB.master_mode)
|
||||
.(href, list("c_mode"=1))
|
||||
|
||||
else if(href_list["f_secret2"])
|
||||
|
||||
@@ -52,10 +52,7 @@
|
||||
if(!check_rights(R_SOUNDS))
|
||||
return
|
||||
|
||||
if(SSticker)
|
||||
SSticker.round_end_sound = fcopy_rsc(S)
|
||||
else
|
||||
return
|
||||
SSticker.SetRoundEndSound(S)
|
||||
|
||||
log_admin("[key_name(src)] set the round end sound to [S]")
|
||||
message_admins("[key_name_admin(src)] set the round end sound to [S]")
|
||||
|
||||
@@ -672,3 +672,7 @@ GLOBAL_LIST(external_rsc_urls)
|
||||
CRASH("change_view called without argument.")
|
||||
|
||||
view = new_size
|
||||
|
||||
/client/proc/AnnouncePR(announcement)
|
||||
if(prefs && prefs.chat_toggles & CHAT_PULLR)
|
||||
to_chat(src, announcement)
|
||||
@@ -5,7 +5,7 @@
|
||||
item_state = null
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
force = 10
|
||||
modifystate = TRUE
|
||||
modifystate = TRUE
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BACK
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/laser/pulse, /obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser)
|
||||
@@ -40,7 +40,7 @@
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
slot_flags = SLOT_BELT
|
||||
icon_state = "pulse_carbine"
|
||||
item_state = null
|
||||
item_state = null
|
||||
cell_type = "/obj/item/weapon/stock_parts/cell/pulse/carbine"
|
||||
can_flashlight = 1
|
||||
flight_x_offset = 18
|
||||
|
||||
@@ -190,7 +190,7 @@
|
||||
name = "dart"
|
||||
icon_state = "cbbolt"
|
||||
damage = 6
|
||||
var/piercing = FALSE
|
||||
var/piercing = FALSE
|
||||
|
||||
/obj/item/projectile/bullet/dart/New()
|
||||
..()
|
||||
@@ -201,15 +201,15 @@
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/M = target
|
||||
if(blocked != 100) // not completely blocked
|
||||
if(M.can_inject(null, FALSE, def_zone, piercing)) // Pass the hit zone to see if it can inject by whether it hit the head or the body.
|
||||
if(M.can_inject(null, FALSE, def_zone, piercing)) // Pass the hit zone to see if it can inject by whether it hit the head or the body.
|
||||
..()
|
||||
reagents.reaction(M, INJECT)
|
||||
reagents.trans_to(M, reagents.total_volume)
|
||||
return TRUE
|
||||
return TRUE
|
||||
else
|
||||
blocked = 100
|
||||
target.visible_message("<span class='danger'>\The [src] was deflected!</span>", \
|
||||
"<span class='userdanger'>You were protected against \the [src]!</span>")
|
||||
target.visible_message("<span class='danger'>\The [src] was deflected!</span>", \
|
||||
"<span class='userdanger'>You were protected against \the [src]!</span>")
|
||||
|
||||
..(target, blocked)
|
||||
reagents.set_reacting(TRUE)
|
||||
@@ -240,28 +240,28 @@
|
||||
nodamage = 1
|
||||
. = ..() // Execute the rest of the code.
|
||||
|
||||
/obj/item/projectile/bullet/dnainjector
|
||||
name = "\improper DNA injector"
|
||||
icon_state = "syringeproj"
|
||||
var/obj/item/weapon/dnainjector/injector
|
||||
|
||||
/obj/item/projectile/bullet/dnainjector/on_hit(atom/target, blocked = 0)
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/M = target
|
||||
if(blocked != 100)
|
||||
if(M.can_inject(null, FALSE, def_zone, FALSE))
|
||||
if(injector.inject(M, firer))
|
||||
QDEL_NULL(injector)
|
||||
return TRUE
|
||||
else
|
||||
blocked = 100
|
||||
target.visible_message("<span class='danger'>\The [src] was deflected!</span>", \
|
||||
"<span class='userdanger'>You were protected against \the [src]!</span>")
|
||||
return ..()
|
||||
|
||||
/obj/item/projectile/bullet/dnainjector/Destroy()
|
||||
QDEL_NULL(injector)
|
||||
return ..()
|
||||
/obj/item/projectile/bullet/dnainjector
|
||||
name = "\improper DNA injector"
|
||||
icon_state = "syringeproj"
|
||||
var/obj/item/weapon/dnainjector/injector
|
||||
|
||||
/obj/item/projectile/bullet/dnainjector/on_hit(atom/target, blocked = 0)
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/M = target
|
||||
if(blocked != 100)
|
||||
if(M.can_inject(null, FALSE, def_zone, FALSE))
|
||||
if(injector.inject(M, firer))
|
||||
QDEL_NULL(injector)
|
||||
return TRUE
|
||||
else
|
||||
blocked = 100
|
||||
target.visible_message("<span class='danger'>\The [src] was deflected!</span>", \
|
||||
"<span class='userdanger'>You were protected against \the [src]!</span>")
|
||||
return ..()
|
||||
|
||||
/obj/item/projectile/bullet/dnainjector/Destroy()
|
||||
QDEL_NULL(injector)
|
||||
return ..()
|
||||
|
||||
//// SNIPER BULLETS
|
||||
|
||||
|
||||
+45
-111
@@ -16,6 +16,33 @@
|
||||
/world/New()
|
||||
log_world("World loaded at [time_stamp()]")
|
||||
|
||||
SetupExternalRSC()
|
||||
|
||||
GLOB.config_error_log = file("data/logs/config_error.log") //temporary file used to record errors with loading config, moved to log directory once logging is set bl
|
||||
|
||||
make_datum_references_lists() //initialises global lists for referencing frequently used datums (so that we only ever do it once)
|
||||
|
||||
config = new
|
||||
|
||||
SetRoundID()
|
||||
|
||||
SetupLogs()
|
||||
|
||||
GLOB.revdata.DownloadPRDetails()
|
||||
|
||||
load_motd()
|
||||
load_admins()
|
||||
// load_mentors()
|
||||
load_menu()
|
||||
if(config.usewhitelist)
|
||||
load_whitelist()
|
||||
LoadBans()
|
||||
|
||||
GLOB.timezoneOffset = text2num(time2text(0,"hh")) * 36000
|
||||
|
||||
Master.Initialize(10, FALSE)
|
||||
|
||||
/world/proc/SetupExternalRSC()
|
||||
#if (PRELOAD_RSC == 0)
|
||||
external_rsc_urls = world.file2list("config/external_rsc_urls.txt","\n")
|
||||
var/i=1
|
||||
@@ -25,10 +52,8 @@
|
||||
else
|
||||
external_rsc_urls.Cut(i,i+1)
|
||||
#endif
|
||||
GLOB.config_error_log = file("data/logs/config_error.log") //temporary file used to record errors with loading config, moved to log directory once logging is set bl
|
||||
make_datum_references_lists() //initialises global lists for referencing frequently used datums (so that we only ever do it once)
|
||||
config = new
|
||||
GLOB.log_directory = "data/logs/[time2text(world.realtime, "YYYY/MM/DD")]/round-"
|
||||
|
||||
/world/proc/SetRoundID()
|
||||
if(config.sql_enabled)
|
||||
if(SSdbcore.Connect())
|
||||
log_world("Database connection established.")
|
||||
@@ -38,10 +63,14 @@
|
||||
query_feedback_max_id.Execute()
|
||||
if(query_feedback_max_id.NextRow())
|
||||
GLOB.round_id = query_feedback_max_id.item[1]
|
||||
GLOB.log_directory += "[GLOB.round_id]"
|
||||
else
|
||||
log_world("Your server failed to establish a connection with the database.")
|
||||
if(!GLOB.round_id)
|
||||
|
||||
/world/proc/SetupLogs()
|
||||
GLOB.log_directory = "data/logs/[time2text(world.realtime, "YYYY/MM/DD")]/round-"
|
||||
if(GLOB.round_id)
|
||||
GLOB.log_directory += "[GLOB.round_id]"
|
||||
else
|
||||
GLOB.log_directory += "[replacetext(time_stamp(), ":", ".")]"
|
||||
GLOB.world_game_log = file("[GLOB.log_directory]/game.log")
|
||||
GLOB.world_attack_log = file("[GLOB.log_directory]/attack.log")
|
||||
@@ -54,27 +83,10 @@
|
||||
if(fexists(GLOB.config_error_log))
|
||||
fcopy(GLOB.config_error_log, "[GLOB.log_directory]/config_error.log")
|
||||
fdel(GLOB.config_error_log)
|
||||
|
||||
|
||||
if(GLOB.round_id)
|
||||
log_game("Round ID: [GLOB.round_id]")
|
||||
|
||||
GLOB.revdata.DownloadPRDetails()
|
||||
load_mode()
|
||||
load_motd()
|
||||
load_admins()
|
||||
load_menu()
|
||||
if(config.usewhitelist)
|
||||
load_whitelist()
|
||||
//disabled to prevent runtimes until it's fixed
|
||||
// load_mentors()
|
||||
LoadBans()
|
||||
|
||||
GLOB.timezoneOffset = text2num(time2text(0,"hh")) * 36000
|
||||
|
||||
GLOB.data_core = new /datum/datacore()
|
||||
|
||||
Master.Initialize(10, FALSE)
|
||||
|
||||
#define IRC_STATUS_THROTTLE 50
|
||||
/world/Topic(T, addr, master, key)
|
||||
if(config && config.log_world_topic)
|
||||
@@ -200,99 +212,21 @@
|
||||
if(PRcounts[id] > PR_ANNOUNCEMENTS_PER_ROUND)
|
||||
return
|
||||
|
||||
#define CHAT_PULLR 64 //defined in preferences.dm, but not available here at compilation time
|
||||
var/final_composed = "<span class='announce'>PR: [announcement]</span>"
|
||||
for(var/client/C in GLOB.clients)
|
||||
if(C.prefs && (C.prefs.chat_toggles & CHAT_PULLR))
|
||||
C << "<span class='announce'>PR: [announcement]</span>"
|
||||
#undef CHAT_PULLR
|
||||
C.AnnouncePR(final_composed)
|
||||
|
||||
#define WORLD_REBOOT(X) log_world("World rebooted at [time_stamp()]"); ..(X); return;
|
||||
|
||||
/world/Reboot(var/reason, var/feedback_c, var/feedback_r, var/time)
|
||||
if (reason == 1) //special reboot, do none of the normal stuff
|
||||
/world/Reboot(reason = 0, fast_track = FALSE)
|
||||
if (reason || fast_track) //special reboot, do none of the normal stuff
|
||||
if (usr)
|
||||
log_admin("[key_name(usr)] Has requested an immediate world restart via client side debugging tools")
|
||||
message_admins("[key_name_admin(usr)] Has requested an immediate world restart via client side debugging tools")
|
||||
to_chat(world, "<span class='boldannounce'>Rebooting World immediately due to host request</span>")
|
||||
WORLD_REBOOT(1)
|
||||
var/delay
|
||||
if(time)
|
||||
delay = time
|
||||
else
|
||||
delay = config.round_end_countdown * 10
|
||||
if(SSticker.delay_end)
|
||||
to_chat(world, "<span class='boldannounce'>An admin has delayed the round end.</span>")
|
||||
return
|
||||
to_chat(world, "<span class='boldannounce'>Rebooting World in [delay/10] [(delay >= 10 && delay < 20) ? "second" : "seconds"]. [reason]</span>")
|
||||
var/round_end_sound_sent = FALSE
|
||||
if(SSticker.round_end_sound)
|
||||
round_end_sound_sent = TRUE
|
||||
for(var/thing in GLOB.clients)
|
||||
var/client/C = thing
|
||||
if (!C)
|
||||
continue
|
||||
C.Export("##action=load_rsc", SSticker.round_end_sound)
|
||||
sleep(delay)
|
||||
if(SSticker.delay_end)
|
||||
to_chat(world, "<span class='boldannounce'>Reboot was cancelled by an admin.</span>")
|
||||
return
|
||||
OnReboot(reason, feedback_c, feedback_r, round_end_sound_sent)
|
||||
WORLD_REBOOT(0)
|
||||
#undef WORLD_REBOOT
|
||||
|
||||
/world/proc/OnReboot(reason, feedback_c, feedback_r, round_end_sound_sent)
|
||||
SSblackbox.set_details("[feedback_c]","[feedback_r]")
|
||||
log_game("<span class='boldannounce'>Rebooting World. [reason]</span>")
|
||||
SSblackbox.set_val("ahelp_unresolved", GLOB.ahelp_tickets.active_tickets.len)
|
||||
Master.Shutdown() //run SS shutdowns
|
||||
RoundEndAnimation(round_end_sound_sent)
|
||||
kick_clients_in_lobby("<span class='boldannounce'>The round came to an end with you in the lobby.</span>", 1) //second parameter ensures only afk clients are kicked
|
||||
to_chat(world, "<span class='boldannounce'>Rebooting world...</span>")
|
||||
for(var/thing in GLOB.clients)
|
||||
var/client/C = thing
|
||||
if(C && config.server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite
|
||||
C << link("byond://[config.server]")
|
||||
|
||||
/world/proc/RoundEndAnimation(round_end_sound_sent)
|
||||
set waitfor = FALSE
|
||||
var/round_end_sound
|
||||
if(SSticker.round_end_sound)
|
||||
round_end_sound = SSticker.round_end_sound
|
||||
if (!round_end_sound_sent)
|
||||
for(var/thing in GLOB.clients)
|
||||
var/client/C = thing
|
||||
if (!C)
|
||||
continue
|
||||
C.Export("##action=load_rsc", round_end_sound)
|
||||
else
|
||||
round_end_sound = pick(\
|
||||
'sound/roundend/newroundsexy.ogg',
|
||||
'sound/roundend/apcdestroyed.ogg',
|
||||
'sound/roundend/bangindonk.ogg',
|
||||
'sound/roundend/leavingtg.ogg',
|
||||
'sound/roundend/its_only_game.ogg',
|
||||
'sound/roundend/yeehaw.ogg',
|
||||
'sound/roundend/disappointed.ogg'\
|
||||
)
|
||||
|
||||
for(var/thing in GLOB.clients)
|
||||
var/obj/screen/splash/S = new(thing, FALSE)
|
||||
S.Fade(FALSE,FALSE)
|
||||
|
||||
world << sound(round_end_sound)
|
||||
|
||||
/world/proc/load_mode()
|
||||
var/mode = trim(file2text("data/mode.txt"))
|
||||
if(mode)
|
||||
GLOB.master_mode = mode
|
||||
else
|
||||
GLOB.master_mode = "extended"
|
||||
log_game("Saved mode is '[GLOB.master_mode]'")
|
||||
|
||||
/world/proc/save_mode(the_mode)
|
||||
var/F = file("data/mode.txt")
|
||||
fdel(F)
|
||||
F << the_mode
|
||||
to_chat(world, "<span class='boldannounce'>Rebooting world...</span>")
|
||||
Master.Shutdown() //run SS shutdowns
|
||||
log_world("World rebooted at [time_stamp()]");
|
||||
..()
|
||||
|
||||
/world/proc/load_motd()
|
||||
GLOB.join_motd = file2text("config/motd.txt") + "<br>" + GLOB.revdata.GetTestMergeInfo()
|
||||
@@ -346,4 +280,4 @@
|
||||
if (features)
|
||||
s += ": [jointext(features, ", ")]"
|
||||
|
||||
status = s
|
||||
status = s
|
||||
@@ -3,37 +3,37 @@
|
||||
call config.bat
|
||||
call bin\findbyond.bat
|
||||
|
||||
echo Welcome to the start server watch dog script, This will start the server and make sure it stays running. To continue, press any key or wait 30 seconds.
|
||||
timeout 30
|
||||
echo Welcome to the start server watch dog script, This will start the server and make sure it stays running. To continue, press any key or wait 30 seconds.
|
||||
timeout 30
|
||||
|
||||
if not exist gamedata\data\logs\runtimes mkdir gamedata\data\logs\runtimes\
|
||||
|
||||
@call python bot\nudge.py "WATCHDOG" "Watch Dog online. Starting server" >nul 2>nul
|
||||
@call python bot\nudge.py "WATCHDOG" "Watch Dog online. Starting server" >nul 2>nul
|
||||
:START
|
||||
|
||||
|
||||
call bin\getcurdate.bat
|
||||
|
||||
call bin\getunixtime.bat UNIXTIME
|
||||
|
||||
echo %UNIXTIME%
|
||||
|
||||
set STARTTIME=%UNIXTIME%
|
||||
|
||||
|
||||
call bin\getunixtime.bat UNIXTIME
|
||||
|
||||
echo %UNIXTIME%
|
||||
|
||||
set STARTTIME=%UNIXTIME%
|
||||
|
||||
cls
|
||||
echo Watch Dog.
|
||||
echo Server Running. Watching for server exits.
|
||||
start /WAIT /ABOVENORMAL "" dreamdaemon.exe gamefolder\%PROJECTNAME%.dmb -port %PORT% -trusted -close -public -verbose
|
||||
start /WAIT /ABOVENORMAL "" dreamdaemon.exe gamefolder\%PROJECTNAME%.dmb -port %PORT% -trusted -close -public -verbose
|
||||
cls
|
||||
|
||||
call bin\getunixtime.bat UNIXTIME
|
||||
|
||||
SET /A Result=%UNIXTIME% - %STARTTIME%
|
||||
SET /A Result=180 - (%Result%/3)
|
||||
if %Result% LSS 0 set /A Result=0
|
||||
|
||||
|
||||
call bin\getunixtime.bat UNIXTIME
|
||||
|
||||
SET /A Result=%UNIXTIME% - %STARTTIME%
|
||||
SET /A Result=180 - (%Result%/3)
|
||||
if %Result% LSS 0 set /A Result=0
|
||||
|
||||
echo Watch Dog.
|
||||
echo Server exit detected. Restarting in %Result% seconds.
|
||||
@python bot\nudge.py "WATCHDOG" "Server exit detected. Restarting server in %Result% seconds." >nul 2>nul
|
||||
timeout %Result%
|
||||
echo Server exit detected. Restarting in %Result% seconds.
|
||||
@python bot\nudge.py "WATCHDOG" "Server exit detected. Restarting server in %Result% seconds." >nul 2>nul
|
||||
timeout %Result%
|
||||
|
||||
goto :START
|
||||
|
||||
Reference in New Issue
Block a user