diff --git a/SQL/database_changelog.txt b/SQL/database_changelog.txt
index d0546da131..d28b33a8eb 100644
--- a/SQL/database_changelog.txt
+++ b/SQL/database_changelog.txt
@@ -1,3 +1,23 @@
+20 May 2017, by Jordie0608
+
+Created table `round` to replace tracking of the datapoints 'round_start', 'round_end', 'server_ip', 'game_mode', 'round_end_results', 'end_error', 'end_proper', 'emergency_shuttle', 'map_name' and 'station_renames' in the `feedback` table.
+Once created this table is populated with rows from the `feedback` table.
+
+START TRANSACTION;
+CREATE TABLE `feedback`.`round` (`id` INT(11) NOT NULL AUTO_INCREMENT, `start_datetime` DATETIME NOT NULL, `end_datetime` DATETIME NULL, `server_ip` INT(10) UNSIGNED NOT NULL, `server_port` SMALLINT(5) UNSIGNED NOT NULL, `commit_hash` CHAR(40) NULL, `game_mode` VARCHAR(32) NULL, `game_mode_result` VARCHAR(64) NULL, `end_state` VARCHAR(64) NULL, `shuttle_name` VARCHAR(64) NULL, `map_name` VARCHAR(32) NULL, `station_name` VARCHAR(80) NULL, PRIMARY KEY (`id`));
+INSERT INTO `feedback`.`round`
+(`id`, `start_datetime`, `end_datetime`, `server_ip`, `server_port`, `commit_hash`, `game_mode`, `game_mode_result`, `end_state`, `shuttle_name`, `map_name`, `station_name`)
+SELECT DISTINCT ri.round_id, IFNULL(STR_TO_DATE(st.details,'%a %b %e %H:%i:%s %Y'), TIMESTAMP(0)), STR_TO_DATE(et.details,'%a %b %e %H:%i:%s %Y'), IFNULL(INET_ATON(SUBSTRING_INDEX(IF(si.details = '', '0', IF(SUBSTRING_INDEX(si.details, ':', 1) LIKE '%_._%', si.details, '0')), ':', 1)), INET_ATON(0)), IFNULL(IF(si.details LIKE '%:_%', CAST(SUBSTRING_INDEX(si.details, ':', -1) AS UNSIGNED), '0'), '0'), ch.details, gm.details, mr.details, IFNULL(es.details, ep.details), ss.details, mn.details, sn.details
+FROM `feedback`.`feedback`AS ri
+LEFT JOIN `feedback`.`feedback` AS st ON ri.round_id = st.round_id AND st.var_name = "round_start" LEFT JOIN `feedback`.`feedback` AS et ON ri.round_id = et.round_id AND et.var_name = "round_end" LEFT JOIN `feedback`.`feedback` AS si ON ri.round_id = si.round_id AND si.var_name = "server_ip" LEFT JOIN `feedback`.`feedback` AS ch ON ri.round_id = ch.round_id AND ch.var_name = "revision" LEFT JOIN `feedback`.`feedback` AS gm ON ri.round_id = gm.round_id AND gm.var_name = "game_mode" LEFT JOIN `feedback`.`feedback` AS mr ON ri.round_id = mr.round_id AND mr.var_name = "round_end_result" LEFT JOIN `feedback`.`feedback` AS es ON ri.round_id = es.round_id AND es.var_name = "end_state" LEFT JOIN `feedback`.`feedback` AS ep ON ri.round_id = ep.round_id AND ep.var_name = "end_proper" LEFT JOIN `feedback`.`feedback` AS ss ON ri.round_id = ss.round_id AND ss.var_name = "emergency_shuttle" LEFT JOIN `feedback`.`feedback` AS mn ON ri.round_id = mn.round_id AND mn.var_name = "map_name" LEFT JOIN `feedback`.`feedback` AS sn ON ri.round_id = sn.round_id AND sn.var_name = "station_renames";
+COMMIT;
+
+It's not necessary to delete the rows from the `feedback` table but henceforth these datapoints will be in the `round` table.
+
+Remember to add a prefix to the table names if you use them
+
+----------------------------------------------------
+
21 April 2017, by Jordie0608
Modified table 'player', adding the column 'accountjoindate', removing the column 'id' and making the column 'ckey' the primary key.
diff --git a/SQL/tgstation_schema.sql b/SQL/tgstation_schema.sql
index 73e2d465f3..46729fc9bb 100644
--- a/SQL/tgstation_schema.sql
+++ b/SQL/tgstation_schema.sql
@@ -362,6 +362,29 @@ CREATE TABLE `poll_vote` (
KEY `idx_pvote_optionid_ckey` (`optionid`,`ckey`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `round`
+--
+DROP TABLE IF EXISTS `round`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `round` (
+ `id` INT(11) NOT NULL AUTO_INCREMENT,
+ `start_datetime` DATETIME NOT NULL,
+ `end_datetime` DATETIME NULL,
+ `server_ip` INT(10) UNSIGNED NOT NULL,
+ `server_port` SMALLINT(5) UNSIGNED NOT NULL,
+ `commit_hash` CHAR(40) NULL,
+ `game_mode` VARCHAR(32) NULL,
+ `game_mode_result` VARCHAR(64) NULL,
+ `end_state` VARCHAR(64) NULL,
+ `shuttle_name` VARCHAR(64) NULL,
+ `map_name` VARCHAR(32) NULL,
+ `station_name` VARCHAR(80) NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
diff --git a/SQL/tgstation_schema_prefixed.sql b/SQL/tgstation_schema_prefixed.sql
index 4d74b9deaa..f717bf96ad 100644
--- a/SQL/tgstation_schema_prefixed.sql
+++ b/SQL/tgstation_schema_prefixed.sql
@@ -362,6 +362,29 @@ CREATE TABLE `SS13_poll_vote` (
KEY `idx_pvote_optionid_ckey` (`optionid`,`ckey`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `SS13_round`
+--
+DROP TABLE IF EXISTS `SS13_round`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `SS13_round` (
+ `id` INT(11) NOT NULL AUTO_INCREMENT,
+ `start_datetime` DATETIME NOT NULL,
+ `end_datetime` DATETIME NULL,
+ `server_ip` INT(10) UNSIGNED NOT NULL,
+ `server_port` SMALLINT(5) UNSIGNED NOT NULL,
+ `commit_hash` CHAR(40) NULL,
+ `game_mode` VARCHAR(32) NULL,
+ `game_mode_result` VARCHAR(64) NULL,
+ `end_state` VARCHAR(64) NULL,
+ `shuttle_name` VARCHAR(64) NULL,
+ `map_name` VARCHAR(32) NULL,
+ `station_name` VARCHAR(80) NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm
index 7303f0f33a..0858d6acdb 100644
--- a/code/__DEFINES/subsystems.dm
+++ b/code/__DEFINES/subsystems.dm
@@ -42,6 +42,7 @@
// Subsystems shutdown in the reverse of the order they initialize in
// The numbers just define the ordering, they are meaningless otherwise.
+#define INIT_ORDER_DBCORE 17
#define INIT_ORDER_SERVER_MAINT 16
#define INIT_ORDER_JOBS 15
#define INIT_ORDER_EVENTS 14
diff --git a/code/controllers/subsystem/blackbox.dm b/code/controllers/subsystem/blackbox.dm
index f606a0d61a..46a963ee53 100644
--- a/code/controllers/subsystem/blackbox.dm
+++ b/code/controllers/subsystem/blackbox.dm
@@ -82,8 +82,6 @@ SUBSYSTEM_DEF(blackbox)
add_details("radio_usage","PDA-[pda_msg_amt]")
add_details("radio_usage","RC-[rc_msg_amt]")
- set_details("round_end","[time2text(world.realtime)]") //This one MUST be the last one that gets set.
-
if (!SSdbcore.Connect())
return
diff --git a/code/controllers/subsystem/dbcore.dm b/code/controllers/subsystem/dbcore.dm
index cf3efc3bc3..b052b20f5d 100644
--- a/code/controllers/subsystem/dbcore.dm
+++ b/code/controllers/subsystem/dbcore.dm
@@ -1,7 +1,7 @@
SUBSYSTEM_DEF(dbcore)
name = "Database"
flags = SS_NO_INIT|SS_NO_FIRE
-
+ init_order = INIT_ORDER_DBCORE
var/const/FAILED_DB_CONNECTION_CUTOFF = 5
var/const/Default_Cursor = 0
@@ -30,6 +30,11 @@ SUBSYSTEM_DEF(dbcore)
_db_con = SSdbcore._db_con
/datum/controller/subsystem/dbcore/Shutdown()
+ //This is as close as we can get to the true round end before Disconnect() without changing where it's called, defeating the reason this is a subsystem
+ if(SSdbcore.Connect())
+ var/sql_station_name = sanitizeSQL(station_name())
+ var/datum/DBQuery/query_round_end = SSdbcore.NewQuery("INSERT INTO [format_table_name("round")] (end_datetime, game_mode_result, end_state, station_name) VALUES (Now(), '[SSticker.mode_result]', '[SSticker.end_state]', '[sql_station_name]') WHERE id = [GLOB.round_id]")
+ query_round_end.Execute()
if(IsConnected())
Disconnect()
@@ -48,7 +53,7 @@ SUBSYSTEM_DEF(dbcore)
if(failed_connections > FAILED_DB_CONNECTION_CUTOFF) //If it failed to establish a connection more than 5 times in a row, don't bother attempting to connect anymore.
return FALSE
-
+
if(!config.sql_enabled)
return FALSE
@@ -171,16 +176,16 @@ Delayed insert mode was removed in mysql 7 and only works with MyISAM type table
var/_db_query
/datum/DBQuery/New(sql_query, datum/controller/subsystem/dbcore/connection_handler, cursor_handler)
- if(sql_query)
+ if(sql_query)
sql = sql_query
- if(connection_handler)
+ if(connection_handler)
db_connection = connection_handler
- if(cursor_handler)
+ if(cursor_handler)
default_cursor = cursor_handler
item = list()
_db_query = _dm_db_new_query()
-/datum/DBQuery/proc/Connect(datum/controller/subsystem/dbcore/connection_handler)
+/datum/DBQuery/proc/Connect(datum/controller/subsystem/dbcore/connection_handler)
db_connection = connection_handler
/datum/DBQuery/proc/warn_execute()
@@ -194,16 +199,16 @@ Delayed insert mode was removed in mysql 7 and only works with MyISAM type table
if(!. && log_error)
log_sql("[ErrorMsg()] | Query used: [sql]")
-/datum/DBQuery/proc/NextRow()
+/datum/DBQuery/proc/NextRow()
return _dm_db_next_row(_db_query,item,conversions)
/datum/DBQuery/proc/RowsAffected()
return _dm_db_rows_affected(_db_query)
-/datum/DBQuery/proc/RowCount()
+/datum/DBQuery/proc/RowCount()
return _dm_db_row_count(_db_query)
-/datum/DBQuery/proc/ErrorMsg()
+/datum/DBQuery/proc/ErrorMsg()
return _dm_db_error_msg(_db_query)
/datum/DBQuery/proc/Columns()
@@ -232,11 +237,11 @@ Delayed insert mode was removed in mysql 7 and only works with MyISAM type table
return db_connection.Quote(str)
/datum/DBQuery/proc/SetConversion(column,conversion)
- if(istext(column))
+ if(istext(column))
column = columns.Find(column)
- if(!conversions)
+ if(!conversions)
conversions = list(column)
- else if(conversions.len < column)
+ else if(conversions.len < column)
conversions.len = column
conversions[column] = conversion
diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm
index 0d1eaadc08..a26c0bd2cd 100644
--- a/code/controllers/subsystem/ticker.dm
+++ b/code/controllers/subsystem/ticker.dm
@@ -60,6 +60,8 @@ SUBSYSTEM_DEF(ticker)
var/round_start_time = 0
var/list/round_start_events
+ var/mode_result = "undefined"
+ var/end_state = "undefined"
var/modevoted = FALSE //Have we sent a vote for the gamemode?
@@ -639,9 +641,9 @@ SUBSYSTEM_DEF(ticker)
sleep(50)
if(mode.station_was_nuked)
- Reboot("Station destroyed by Nuclear Device.", "end_proper", "nuke")
+ Reboot("Station destroyed by Nuclear Device.", "nuke")
else
- Reboot("Round ended.", "end_proper", "proper completion")
+ Reboot("Round ended.", "proper completion")
/datum/controller/subsystem/ticker/proc/send_tip_of_the_round()
var/m
@@ -842,7 +844,7 @@ SUBSYSTEM_DEF(ticker)
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)
+/datum/controller/subsystem/ticker/proc/Reboot(reason, end_string, delay)
set waitfor = FALSE
if(usr && !check_rights(R_SERVER, TRUE))
return
@@ -864,7 +866,9 @@ SUBSYSTEM_DEF(ticker)
to_chat(world, "Reboot was cancelled by an admin.")
return
- SSblackbox.set_details("[feedback_c]","[feedback_r]")
+ if(end_string)
+ end_state = end_string
+
log_game("Rebooting World. [reason]")
diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm
index deea959c00..bdb129c867 100644
--- a/code/controllers/subsystem/vote.dm
+++ b/code/controllers/subsystem/vote.dm
@@ -137,7 +137,7 @@ SUBSYSTEM_DEF(vote)
active_admins = 1
break
if(!active_admins)
- SSticker.Reboot("Restart vote successful.", "end_error", "restart vote")
+ SSticker.Reboot("Restart vote successful.", "restart vote")
else
to_chat(world, "Notice:Restart vote will not restart the server automatically because there are active admins on.")
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.")
diff --git a/code/game/gamemodes/blob/blob_finish.dm b/code/game/gamemodes/blob/blob_finish.dm
index 47e2ce6a14..8ba6a2f125 100644
--- a/code/game/gamemodes/blob/blob_finish.dm
+++ b/code/game/gamemodes/blob/blob_finish.dm
@@ -20,7 +20,7 @@
if(round_converted) //So badmin blobs later don't step on the dead natural blobs metaphorical toes
..()
if(blobwincount <= GLOB.blobs_legit.len)
- SSblackbox.set_details("round_end_result","win - blob took over")
+ SSticker.mode_result = "win - blob took over"
to_chat(world, "The blob has taken over the station!")
to_chat(world, "The entire station was eaten by the Blob!")
log_game("Blob mode completed with a blob victory.")
@@ -28,7 +28,7 @@
SSticker.news_report = BLOB_WIN
else if(station_was_nuked)
- SSblackbox.set_details("round_end_result","halfwin - nuke")
+ SSticker.mode_result = "halfwin - nuke"
to_chat(world, "Partial Win: The station has been destroyed!")
to_chat(world, "Directive 7-12 has been successfully carried out, preventing the Blob from spreading.")
log_game("Blob mode completed with a tie (station destroyed).")
@@ -36,7 +36,7 @@
SSticker.news_report = BLOB_NUKE
else if(!GLOB.blob_cores.len)
- SSblackbox.set_details("round_end_result","loss - blob eliminated")
+ SSticker.mode_result = "loss - blob eliminated"
to_chat(world, "The staff has won!")
to_chat(world, "The alien organism has been eradicated from the station!")
log_game("Blob mode completed with a crew victory.")
diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm
index 132c834f10..48e1ff1957 100644
--- a/code/game/gamemodes/clock_cult/clock_cult.dm
+++ b/code/game/gamemodes/clock_cult/clock_cult.dm
@@ -191,7 +191,7 @@ Credit where due:
var/datum/game_mode/clockwork_cult/C = SSticker.mode
if(C.check_clockwork_victory())
text += "Ratvar's servants have succeeded in fulfilling His goals!"
- SSblackbox.set_details("round_end_result", "win - servants completed their objective (summon ratvar)")
+ SSticker.mode_result = "win - servants completed their objective (summon ratvar)"
else
var/half_victory = FALSE
var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = locate() in GLOB.all_clockwork_objects
@@ -200,10 +200,10 @@ Credit where due:
if(half_victory)
text += "The crew escaped before Ratvar could rise, but the gateway \
was successfully constructed!"
- SSblackbox.set_details("round_end_result", "halfwin - servants constructed the gateway but their objective was not completed (summon ratvar)")
+ SSticker.mode_result = "halfwin - servants constructed the gateway but their objective was not completed (summon ratvar)"
else
text += "Ratvar's servants have failed!"
- SSblackbox.set_details("round_end_result", "loss - servants failed their objective (summon ratvar)")
+ SSticker.mode_result = "loss - servants failed their objective (summon ratvar)"
text += "
The servants' objective was:
[CLOCKCULT_OBJECTIVE]"
text += "
Ratvar's servants had [GLOB.clockwork_caches] Tinkerer's Caches."
text += "
Construction Value(CV) was: [GLOB.clockwork_construction_value]"
diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm
index 5de8a39216..a58c4874dc 100644
--- a/code/game/gamemodes/cult/cult.dm
+++ b/code/game/gamemodes/cult/cult.dm
@@ -208,12 +208,10 @@
/datum/game_mode/cult/declare_completion()
if(!check_cult_victory())
- SSblackbox.set_details("round_end_result","win - cult win")
- SSblackbox.set_val("round_end_result",acolytes_survived)
+ SSticker.mode_result = "win - cult win"
to_chat(world, "The cult has succeeded! Nar-sie has snuffed out another torch in the void!")
else
- SSblackbox.set_details("round_end_result","loss - staff stopped the cult")
- SSblackbox.set_val("round_end_result",acolytes_survived)
+ SSticker.mode_result = "loss - staff stopped the cult"
to_chat(world, "The staff managed to stop the cult! Dark words and heresy are no match for Nanotrasen's finest!")
var/text = ""
@@ -257,22 +255,15 @@
/datum/game_mode/proc/datum_cult_completion()
var/text = ""
- var/acolytes_survived = 0
- for(var/datum/mind/cult_mind in cult)
- if (cult_mind.current && cult_mind.current.stat != DEAD)
- if(cult_mind.current.onCentcom() || cult_mind.current.onSyndieBase())
- acolytes_survived++
var/cult_fail = 0
cult_fail += eldergod
if(!GLOB.sac_complete)
cult_fail++
if(!cult_fail)
- SSblackbox.set_details("round_end_result","win - cult win")
- SSblackbox.set_val("round_end_result",acolytes_survived)
+ SSticker.mode_result = "win - cult win"
to_chat(world, "The cult has succeeded! Nar-sie has snuffed out another torch in the void!")
else
- SSblackbox.set_details("round_end_result","loss - staff stopped the cult")
- SSblackbox.set_val("round_end_result",acolytes_survived)
+ SSticker.mode_result = "loss - staff stopped the cult"
to_chat(world, "The staff managed to stop the cult! Dark words and heresy are no match for Nanotrasen's finest!")
if(cult_objectives.len)
text += "
The cultists' objectives were:"
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 0129197273..c57e9180f5 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -80,11 +80,17 @@
report = config.intercept
addtimer(CALLBACK(GLOBAL_PROC, .proc/display_roundstart_logout_report), ROUNDSTART_LOGOUT_REPORT_TIME)
- SSblackbox.set_details("round_start","[time2text(world.realtime)]")
- if(SSticker && SSticker.mode)
- SSblackbox.set_details("game_mode","[SSticker.mode]")
- if(GLOB.revdata.commit)
- SSblackbox.set_details("revision","[GLOB.revdata.commit]")
+ if(SSdbcore.Connect())
+ var/sql
+ if(SSticker && SSticker.mode)
+ sql += "game_mode = '[SSticker.mode]'"
+ if(sql)
+ sql += ", "
+ if(GLOB.revdata.commit)
+ sql += "commit_hash = '[GLOB.revdata.commit]'"
+ if(sql)
+ var/datum/DBQuery/query_round_game_mode = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET [sql] WHERE id = [GLOB.round_id]")
+ query_round_game_mode.Execute()
if(report)
addtimer(CALLBACK(src, .proc/send_intercept, 0), rand(waittime_l, waittime_h))
generate_station_goals()
diff --git a/code/game/gamemodes/gang/gang.dm b/code/game/gamemodes/gang/gang.dm
index f32fc80d61..6606a0d871 100644
--- a/code/game/gamemodes/gang/gang.dm
+++ b/code/game/gamemodes/gang/gang.dm
@@ -288,12 +288,12 @@ GLOBAL_LIST_INIT(gang_outfit_pool, list(/obj/item/clothing/suit/jacket/leather,/
return
if(!winner)
to_chat(world, "The station was [station_was_nuked ? "destroyed!" : "evacuated before a gang could claim it! The station wins!"]
")
- SSblackbox.set_details("round_end_result","loss - gangs failed takeover")
+ SSticker.mode_result = "loss - gangs failed takeover"
SSticker.news_report = GANG_LOSS
else
to_chat(world, "The [winner.name] Gang successfully performed a hostile takeover of the station!
")
- SSblackbox.set_details("round_end_result","win - gang domination complete")
+ SSticker.mode_result = "win - gang domination complete"
SSticker.news_report = GANG_TAKEOVER
diff --git a/code/game/gamemodes/meteor/meteor.dm b/code/game/gamemodes/meteor/meteor.dm
index 400b38309b..6d4a678913 100644
--- a/code/game/gamemodes/meteor/meteor.dm
+++ b/code/game/gamemodes/meteor/meteor.dm
@@ -50,8 +50,6 @@
else
to_chat(world, "Nobody survived the meteor storm!")
- SSblackbox.set_details("round_end_result","end - evacuation")
- SSblackbox.set_val("round_end_result",survivors)
-
+ SSticker.mode_result = "end - evacuation"
..()
return 1
diff --git a/code/game/gamemodes/miniantags/monkey/monkey.dm b/code/game/gamemodes/miniantags/monkey/monkey.dm
index f9ea8dcc2c..20ba54afc4 100644
--- a/code/game/gamemodes/miniantags/monkey/monkey.dm
+++ b/code/game/gamemodes/miniantags/monkey/monkey.dm
@@ -107,10 +107,8 @@
/datum/game_mode/monkey/declare_completion()
if(check_monkey_victory())
- SSblackbox.set_details("round_end_result","win - monkey win")
- SSblackbox.set_val("round_end_result",escaped_monkeys)
+ SSticker.mode_result = "win - monkey win"
to_chat(world, "The monkeys have overthrown their captors! Eeek eeeek!!")
else
- SSblackbox.set_details("round_end_result","loss - staff stopped the monkeys")
- SSblackbox.set_val("round_end_result",escaped_monkeys)
+ SSticker.mode_result = "loss - staff stopped the monkeys"
to_chat(world, "The staff managed to contain the monkey infestation!")
diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm
index 6af3e86b7e..14a5ffcd5e 100644
--- a/code/game/gamemodes/nuclear/nuclear.dm
+++ b/code/game/gamemodes/nuclear/nuclear.dm
@@ -201,70 +201,70 @@
if(nuke_off_station == NUKE_SYNDICATE_BASE)
- SSblackbox.set_details("round_end_result","loss - syndicate nuked - disk secured")
+ SSticker.mode_result = "loss - syndicate nuked - disk secured"
to_chat(world, "Humiliating Syndicate Defeat")
to_chat(world, "The crew of [station_name()] gave [syndicate_name()] operatives back their bomb! The syndicate base was destroyed! Next time, don't lose the nuke!")
SSticker.news_report = NUKE_SYNDICATE_BASE
else if(!disk_rescued && station_was_nuked && !syndies_didnt_escape)
- SSblackbox.set_details("round_end_result","win - syndicate nuke")
+ SSticker.mode_result = "win - syndicate nuke"
to_chat(world, "Syndicate Major Victory!")
to_chat(world, "[syndicate_name()] operatives have destroyed [station_name()]!")
SSticker.news_report = STATION_NUKED
else if (!disk_rescued && station_was_nuked && syndies_didnt_escape)
- SSblackbox.set_details("round_end_result","halfwin - syndicate nuke - did not evacuate in time")
+ SSticker.mode_result = "halfwin - syndicate nuke - did not evacuate in time"
to_chat(world, "Total Annihilation")
to_chat(world, "[syndicate_name()] operatives destroyed [station_name()] but did not leave the area in time and got caught in the explosion. Next time, don't lose the disk!")
SSticker.news_report = STATION_NUKED
else if (!disk_rescued && !station_was_nuked && nuke_off_station && !syndies_didnt_escape)
- SSblackbox.set_details("round_end_result","halfwin - blew wrong station")
+ SSticker.mode_result = "halfwin - blew wrong station"
to_chat(world, "Crew Minor Victory")
to_chat(world, "[syndicate_name()] operatives secured the authentication disk but blew up something that wasn't [station_name()]. Next time, don't do that!")
SSticker.news_report = NUKE_MISS
else if (!disk_rescued && !station_was_nuked && nuke_off_station && syndies_didnt_escape)
- SSblackbox.set_details("round_end_result","halfwin - blew wrong station - did not evacuate in time")
+ SSticker.mode_result = "halfwin - blew wrong station - did not evacuate in time"
to_chat(world, "[syndicate_name()] operatives have earned Darwin Award!")
to_chat(world, "[syndicate_name()] operatives blew up something that wasn't [station_name()] and got caught in the explosion. Next time, don't do that!")
SSticker.news_report = NUKE_MISS
else if ((disk_rescued || SSshuttle.emergency.mode != SHUTTLE_ENDGAME) && are_operatives_dead())
- SSblackbox.set_details("round_end_result","loss - evacuation - disk secured - syndi team dead")
+ SSticker.mode_result = "loss - evacuation - disk secured - syndi team dead"
to_chat(world, "Crew Major Victory!")
to_chat(world, "The Research Staff has saved the disk and killed the [syndicate_name()] Operatives")
SSticker.news_report = OPERATIVES_KILLED
else if (disk_rescued)
- SSblackbox.set_details("round_end_result","loss - evacuation - disk secured")
+ SSticker.mode_result = "loss - evacuation - disk secured"
to_chat(world, "Crew Major Victory")
to_chat(world, "The Research Staff has saved the disk and stopped the [syndicate_name()] Operatives!")
SSticker.news_report = OPERATIVES_KILLED
else if (!disk_rescued && are_operatives_dead())
- SSblackbox.set_details("round_end_result","halfwin - evacuation - disk not secured")
+ SSticker.mode_result = "halfwin - evacuation - disk not secured"
to_chat(world, "Neutral Victory!")
to_chat(world, "The Research Staff failed to secure the authentication disk but did manage to kill most of the [syndicate_name()] Operatives!")
SSticker.news_report = OPERATIVE_SKIRMISH
else if (!disk_rescued && crew_evacuated)
- SSblackbox.set_details("round_end_result","halfwin - detonation averted")
+ SSticker.mode_result = "halfwin - detonation averted"
to_chat(world, "Syndicate Minor Victory!")
to_chat(world, "[syndicate_name()] operatives survived the assault but did not achieve the destruction of [station_name()]. Next time, don't lose the disk!")
SSticker.news_report = OPERATIVE_SKIRMISH
else if (!disk_rescued && !crew_evacuated)
- SSblackbox.set_details("round_end_result","halfwin - interrupted")
+ SSticker.mode_result = "halfwin - interrupted"
to_chat(world, "Neutral Victory")
to_chat(world, "Round was mysteriously interrupted!")
diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm
index 5964983b09..0cad439948 100644
--- a/code/game/gamemodes/nuclear/nuclearbomb.dm
+++ b/code/game/gamemodes/nuclear/nuclearbomb.dm
@@ -459,7 +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
- SSticker.Reboot("Station destroyed by Nuclear Device.", "end_error", "nuke - unhandled ending")
+ SSticker.Reboot("Station destroyed by Nuclear Device.", "nuke - unhandled ending")
/*
diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm
index 7a31d1f3cd..5cfdb11087 100644
--- a/code/game/gamemodes/revolution/revolution.dm
+++ b/code/game/gamemodes/revolution/revolution.dm
@@ -345,13 +345,13 @@
//////////////////////////////////////////////////////////////////////
/datum/game_mode/revolution/declare_completion()
if(finished == 1)
- SSblackbox.set_details("round_end_result","win - heads killed")
+ SSticker.mode_result = "win - heads killed"
to_chat(world, "The heads of staff were killed or exiled! The revolutionaries win!")
SSticker.news_report = REVS_WIN
else if(finished == 2)
- SSblackbox.set_details("round_end_result","loss - rev heads killed")
+ SSticker.mode_result = "loss - rev heads killed"
to_chat(world, "The heads of staff managed to stop the revolution!")
SSticker.news_report = REVS_LOSE
diff --git a/code/game/gamemodes/wizard/raginmages.dm b/code/game/gamemodes/wizard/raginmages.dm
index dd69d77b14..d8bf34c99e 100644
--- a/code/game/gamemodes/wizard/raginmages.dm
+++ b/code/game/gamemodes/wizard/raginmages.dm
@@ -133,7 +133,7 @@
/datum/game_mode/wizard/raginmages/declare_completion()
if(finished)
- SSblackbox.set_details("round_end_result","loss - wizard killed")
+ SSticker.mode_result = "loss - wizard killed"
to_chat(world, "The crew has managed to hold off the wizard attack! The Space Wizards Federation has been taught a lesson they will not soon forget!")
..(1)
diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm
index 0d169e9024..ef8db43171 100644
--- a/code/game/gamemodes/wizard/wizard.dm
+++ b/code/game/gamemodes/wizard/wizard.dm
@@ -180,7 +180,7 @@
/datum/game_mode/wizard/declare_completion()
if(finished)
- SSblackbox.set_details("round_end_result","loss - wizard killed")
+ SSticker.mode_result = "loss - wizard killed"
to_chat(world, "The wizard[(wizards.len>1)?"s":""] has been killed by the crew! The Space Wizards Federation has been taught a lesson they will not soon forget!")
SSticker.news_report = WIZARD_KILLED
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index c426cf2b41..b89d219245 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -1,826 +1,828 @@
-////////////////////////////////
-/proc/message_admins(msg)
- msg = "ADMIN LOG: [msg]"
- to_chat(GLOB.admins, msg)
-
-/proc/relay_msg_admins(msg)
- msg = "RELAY: [msg]"
- to_chat(GLOB.admins, msg)
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////Panels
-
-/datum/admins/proc/show_player_panel(mob/M in GLOB.mob_list)
- set category = "Admin"
- set name = "Show Player Panel"
- set desc="Edit player (respawn, ban, heal, etc)"
-
- if(!check_rights())
- return
-
- if(!isobserver(usr))
- log_game("[key_name_admin(usr)] checked the player panel while in game.")
-
- if(!M)
- to_chat(usr, "You seem to be selecting a mob that doesn't exist anymore.")
- return
-
- var/body = "
Options for [M.key]"
- body += "Options panel for [M]"
- if(M.client)
- body += " played by [M.client] "
- body += "\[[M.client.holder ? M.client.holder.rank : "Player"]\]"
-
- if(isnewplayer(M))
- body += " Hasn't Entered Game "
- else
- body += " \[Heal\] "
-
- if(M.client)
- body += "
\[First Seen: [M.client.player_join_date]\]\[Byond account registered on: [M.client.account_join_date]\]"
- body += "
Show related accounts by: "
- body += "\[ CID | "
- body += "IP \]"
-
- body += "
\[ "
- body += "VV - "
- body += "TP - "
- body += "PM - "
- body += "SM - "
- body += "FLW - "
- body += "LOGS\]
"
-
- body += "Mob type = [M.type]
"
-
- body += "Kick | "
- body += "Ban | "
- body += "Jobban | "
- body += "Identity Ban | "
- if(jobban_isbanned(M, "OOC"))
- body+= "OOCBan | "
- else
- body+= "OOCBan | "
- if(jobban_isbanned(M, "emote"))
- body+= "EmoteBan | "
- else
- body+= "Emoteban | "
-
- body += "Notes | Messages | Watchlist | "
- if(M.client)
- body += "| Prison | "
- body += "\ Send back to Lobby | "
- var/muted = M.client.prefs.muted
- body += "
Mute: "
- body += "\[IC | "
- body += "OOC | "
- body += "PRAY | "
- body += "ADMINHELP | "
- body += "DEADCHAT\]"
- body += "(toggle all)"
-
- body += "
"
- body += "Jump to | "
- body += "Get | "
- body += "Send To"
-
- body += "
"
- body += "Traitor panel | "
- body += "Narrate to | "
- body += "Subtle message | "
- body += "Language Menu"
-
- if (M.client)
- if(!isnewplayer(M))
- body += "
"
- body += "Transformation:"
- body += "
"
-
- //Human
- if(ishuman(M))
- body += "Human | "
- else
- body += "Humanize | "
-
- //Monkey
- if(ismonkey(M))
- body += "Monkeyized | "
- else
- body += "Monkeyize | "
-
- //Corgi
- if(iscorgi(M))
- body += "Corgized | "
- else
- body += "Corgize | "
-
- //AI / Cyborg
- if(isAI(M))
- body += "Is an AI "
- else if(ishuman(M))
- body += "Make AI | "
- body += "Make Robot | "
- body += "Make Alien | "
- body += "Make Slime | "
- body += "Make Blob | "
-
- //Simple Animals
- if(isanimal(M))
- body += "Re-Animalize | "
- else
- body += "Animalize | "
-
- body += "
"
- body += "Rudimentary transformation:
These transformations only create a new mob type and copy stuff over. They do not take into account MMIs and similar mob-specific things. The buttons in 'Transformations' are preferred, when possible.
"
- body += "Observer | "
- body += "\[ Alien: Drone, "
- body += "Hunter, "
- body += "Sentinel, "
- body += "Praetorian, "
- body += "Queen, "
- body += "Larva \] "
- body += "Human "
- body += "\[ slime: Baby, "
- body += "Adult \] "
- body += "Monkey | "
- body += "Cyborg | "
- body += "Cat | "
- body += "Runtime | "
- body += "Corgi | "
- body += "Ian | "
- body += "Crab | "
- body += "Coffee | "
- //body += "Parrot | "
- //body += "Poly | "
- body += "\[ Construct: Juggernaut , "
- body += "Artificer , "
- body += "Wraith \] "
- body += "Shade"
- body += "
"
-
- if (M.client)
- body += "
"
- body += "Other actions:"
- body += "
"
- body += "Forcesay | "
- body += "Thunderdome 1 | "
- body += "Thunderdome 2 | "
- body += "Thunderdome Admin | "
- body += "Thunderdome Observer | "
-
- body += "
"
- body += ""
-
- usr << browse(body, "window=adminplayeropts-\ref[M];size=550x515")
- SSblackbox.add_details("admin_verb","Player Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-
-/datum/admins/proc/access_news_network() //MARKER
- set category = "Fun"
- set name = "Access Newscaster Network"
- set desc = "Allows you to view, add and edit news feeds."
-
- if (!istype(src,/datum/admins))
- src = usr.client.holder
- if (!istype(src,/datum/admins))
- to_chat(usr, "Error: you are not an admin!")
- return
- var/dat
- dat = text("Admin NewscasterAdmin Newscaster Unit
")
-
- switch(admincaster_screen)
- if(0)
- dat += "Welcome to the admin newscaster.
Here you can add, edit and censor every newspiece on the network."
- dat += "
Feed channels and stories entered through here will be uneditable and handled as official news by the rest of the units."
- dat += "
Note that this panel allows full freedom over the news network, there are no constrictions except the few basic ones. Don't break things!"
- if(GLOB.news_network.wanted_issue.active)
- dat+= "
Read Wanted Issue"
- dat+= "
Create Feed Channel"
- dat+= "
View Feed Channels"
- dat+= "
Submit new Feed story"
- dat+= "
Exit"
- var/wanted_already = 0
- if(GLOB.news_network.wanted_issue.active)
- wanted_already = 1
- dat+="
Feed Security functions:
"
- dat+="
[(wanted_already) ? ("Manage") : ("Publish")] \"Wanted\" Issue"
- dat+="
Censor Feed Stories"
- dat+="
Mark Feed Channel with Nanotrasen D-Notice (disables and locks the channel)."
- dat+="
The newscaster recognises you as:
[src.admin_signature]"
- if(1)
- dat+= "Station Feed Channels
"
- if( isemptylist(GLOB.news_network.network_channels) )
- dat+="No active channels found..."
- else
- for(var/datum/newscaster/feed_channel/CHANNEL in GLOB.news_network.network_channels)
- if(CHANNEL.is_admin_channel)
- dat+="[CHANNEL.channel_name]
"
- else
- dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ()]
"
- dat+="
Refresh"
- dat+="
Back"
- if(2)
- dat+="Creating new Feed Channel..."
- dat+="
Channel Name: [src.admincaster_feed_channel.channel_name]
"
- dat+="Channel Author: [src.admin_signature]
"
- dat+="Will Accept Public Feeds: [(src.admincaster_feed_channel.locked) ? ("NO") : ("YES")]
"
- dat+="
Submit
Cancel
"
- if(3)
- dat+="Creating new Feed Message..."
- dat+="
Receiving Channel: [src.admincaster_feed_channel.channel_name]
" //MARK
- dat+="Message Author: [src.admin_signature]
"
- dat+="Message Body: [src.admincaster_feed_message.returnBody(-1)]
"
- dat+="
Submit
Cancel
"
- if(4)
- dat+="Feed story successfully submitted to [src.admincaster_feed_channel.channel_name].
"
- dat+="
Return
"
- if(5)
- dat+="Feed Channel [src.admincaster_feed_channel.channel_name] created successfully.
"
- dat+="
Return
"
- if(6)
- dat+="ERROR: Could not submit Feed story to Network.
"
- if(src.admincaster_feed_channel.channel_name=="")
- dat+="Invalid receiving channel name.
"
- if(src.admincaster_feed_message.returnBody(-1) == "" || src.admincaster_feed_message.returnBody(-1) == "\[REDACTED\]")
- dat+="Invalid message body.
"
- dat+="
Return
"
- if(7)
- dat+="ERROR: Could not submit Feed Channel to Network.
"
- if(src.admincaster_feed_channel.channel_name =="" || src.admincaster_feed_channel.channel_name == "\[REDACTED\]")
- dat+="Invalid channel name.
"
- var/check = 0
- for(var/datum/newscaster/feed_channel/FC in GLOB.news_network.network_channels)
- if(FC.channel_name == src.admincaster_feed_channel.channel_name)
- check = 1
- break
- if(check)
- dat+="Channel name already in use.
"
- dat+="
Return
"
- if(9)
- dat+="[admincaster_feed_channel.channel_name]: \[created by: [admincaster_feed_channel.returnAuthor(-1)]\]
"
- if(src.admincaster_feed_channel.censored)
- dat+="ATTENTION: This channel has been deemed as threatening to the welfare of the station, and marked with a Nanotrasen D-Notice.
"
- dat+="No further feed story additions are allowed while the D-Notice is in effect.
"
- else
- if( isemptylist(src.admincaster_feed_channel.messages) )
- dat+="No feed messages found in channel...
"
- else
- var/i = 0
- for(var/datum/newscaster/feed_message/MESSAGE in src.admincaster_feed_channel.messages)
- i++
- dat+="-[MESSAGE.returnBody(-1)]
"
- if(MESSAGE.img)
- usr << browse_rsc(MESSAGE.img, "tmp_photo[i].png")
- dat+="
"
- dat+="\[Story by [MESSAGE.returnAuthor(-1)]\]
"
- dat+="[MESSAGE.comments.len] comment[MESSAGE.comments.len > 1 ? "s" : ""]:
"
- for(var/datum/newscaster/feed_comment/comment in MESSAGE.comments)
- dat+="[comment.body]
[comment.author] [comment.time_stamp]
"
- dat+="
"
- dat+="
Refresh"
- dat+="
Back"
- if(10)
- dat+="Nanotrasen Feed Censorship Tool
"
- dat+="NOTE: Due to the nature of news Feeds, total deletion of a Feed Story is not possible.
"
- dat+="Keep in mind that users attempting to view a censored feed will instead see the \[REDACTED\] tag above it."
- dat+="
Select Feed channel to get Stories from:
"
- if(isemptylist(GLOB.news_network.network_channels))
- dat+="No feed channels found active...
"
- else
- for(var/datum/newscaster/feed_channel/CHANNEL in GLOB.news_network.network_channels)
- dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ()]
"
- dat+="
Cancel"
- if(11)
- dat+="Nanotrasen D-Notice Handler
"
- dat+="A D-Notice is to be bestowed upon the channel if the handling Authority deems it as harmful for the station's"
- dat+="morale, integrity or disciplinary behaviour. A D-Notice will render a channel unable to be updated by anyone, without deleting any feed"
- dat+="stories it might contain at the time. You can lift a D-Notice if you have the required access at any time.
"
- if(isemptylist(GLOB.news_network.network_channels))
- dat+="No feed channels found active...
"
- else
- for(var/datum/newscaster/feed_channel/CHANNEL in GLOB.news_network.network_channels)
- dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ()]
"
-
- dat+="
Back"
- if(12)
- dat+="[src.admincaster_feed_channel.channel_name]: \[ created by: [src.admincaster_feed_channel.returnAuthor(-1)] \]
"
- dat+="[(src.admincaster_feed_channel.authorCensor) ? ("Undo Author censorship") : ("Censor channel Author")]
"
-
- if( isemptylist(src.admincaster_feed_channel.messages) )
- dat+="No feed messages found in channel...
"
- else
- for(var/datum/newscaster/feed_message/MESSAGE in src.admincaster_feed_channel.messages)
- dat+="-[MESSAGE.returnBody(-1)]
\[Story by [MESSAGE.returnAuthor(-1)]\]
"
- dat+="[(MESSAGE.bodyCensor) ? ("Undo story censorship") : ("Censor story")] - [(MESSAGE.authorCensor) ? ("Undo Author Censorship") : ("Censor message Author")]
"
- dat+="[MESSAGE.comments.len] comment[MESSAGE.comments.len > 1 ? "s" : ""]: [MESSAGE.locked ? "Unlock" : "Lock"]
"
- for(var/datum/newscaster/feed_comment/comment in MESSAGE.comments)
- dat+="[comment.body] X
[comment.author] [comment.time_stamp]
"
- dat+="
Back"
- if(13)
- dat+="[src.admincaster_feed_channel.channel_name]: \[ created by: [src.admincaster_feed_channel.returnAuthor(-1)] \]
"
- dat+="Channel messages listed below. If you deem them dangerous to the station, you can Bestow a D-Notice upon the channel.
"
- if(src.admincaster_feed_channel.censored)
- dat+="ATTENTION: This channel has been deemed as threatening to the welfare of the station, and marked with a Nanotrasen D-Notice.
"
- dat+="No further feed story additions are allowed while the D-Notice is in effect.
"
- else
- if( isemptylist(src.admincaster_feed_channel.messages) )
- dat+="No feed messages found in channel...
"
- else
- for(var/datum/newscaster/feed_message/MESSAGE in src.admincaster_feed_channel.messages)
- dat+="-[MESSAGE.returnBody(-1)]
\[Story by [MESSAGE.returnAuthor(-1)]\]
"
- dat+="
Back"
- if(14)
- dat+="Wanted Issue Handler:"
- var/wanted_already = 0
- var/end_param = 1
- if(GLOB.news_network.wanted_issue.active)
- wanted_already = 1
- end_param = 2
- if(wanted_already)
- dat+="
A wanted issue is already in Feed Circulation. You can edit or cancel it below."
- dat+="
"
- dat+="Criminal Name: [src.admincaster_wanted_message.criminal]
"
- dat+="Description: [src.admincaster_wanted_message.body]
"
- if(wanted_already)
- dat+="Wanted Issue created by:[GLOB.news_network.wanted_issue.scannedUser]
"
- else
- dat+="Wanted Issue will be created under prosecutor:[src.admin_signature]
"
- dat+="
[(wanted_already) ? ("Edit Issue") : ("Submit")]"
- if(wanted_already)
- dat+="
Take down Issue"
- dat+="
Cancel"
- if(15)
- dat+="Wanted issue for [src.admincaster_wanted_message.criminal] is now in Network Circulation.
"
- dat+="
Return
"
- if(16)
- dat+="ERROR: Wanted Issue rejected by Network.
"
- if(src.admincaster_wanted_message.criminal =="" || src.admincaster_wanted_message.criminal == "\[REDACTED\]")
- dat+="Invalid name for person wanted.
"
- if(src.admincaster_wanted_message.body == "" || src.admincaster_wanted_message.body == "\[REDACTED\]")
- dat+="Invalid description.
"
- dat+="
Return
"
- if(17)
- dat+="Wanted Issue successfully deleted from Circulation
"
- dat+="
Return
"
- if(18)
- dat+="-- STATIONWIDE WANTED ISSUE --
\[Submitted by: [GLOB.news_network.wanted_issue.scannedUser]\]
"
- dat+="Criminal: [GLOB.news_network.wanted_issue.criminal]
"
- dat+="Description: [GLOB.news_network.wanted_issue.body]
"
- dat+="Photo:: "
- if(GLOB.news_network.wanted_issue.img)
- usr << browse_rsc(GLOB.news_network.wanted_issue.img, "tmp_photow.png")
- dat+="
"
- else
- dat+="None"
- dat+="
Back
"
- if(19)
- dat+="Wanted issue for [src.admincaster_wanted_message.criminal] successfully edited.
"
- dat+="
Return
"
- else
- dat+="I'm sorry to break your immersion. This shit's bugged. Report this bug to Agouri, polyxenitopalidou@gmail.com"
-
- //to_chat(world, "Channelname: [src.admincaster_feed_channel.channel_name] [src.admincaster_feed_channel.author]")
- //to_chat(world, "Msg: [src.admincaster_feed_message.author] [src.admincaster_feed_message.body]")
- usr << browse(dat, "window=admincaster_main;size=400x600")
- onclose(usr, "admincaster_main")
-
-
-/datum/admins/proc/Game()
- if(!check_rights(0))
- return
-
- var/dat = {"
- Game Panel
\n
- Change Game Mode
- "}
- if(GLOB.master_mode == "secret")
- dat += "(Force Secret Mode)
"
-
- dat += {"
-
- Create Object
- Quick Create Object
- Create Turf
- Create Mob
- "}
-
- if(marked_datum && istype(marked_datum, /atom))
- dat += "Duplicate Marked Datum
"
-
- usr << browse(dat, "window=admin2;size=210x200")
- return
-
-/////////////////////////////////////////////////////////////////////////////////////////////////admins2.dm merge
-//i.e. buttons/verbs
-
-
-/datum/admins/proc/restart()
- set category = "Server"
- set name = "Reboot World"
- set desc="Restarts the world immediately"
- if (!usr.client.holder)
- return
-
- 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!
- switch(result)
- if("Regular Restart")
- SSticker.Reboot("Initiated by [usr.client.holder.fakekey ? "Admin" : usr.key].", "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)")
+////////////////////////////////
+/proc/message_admins(msg)
+ msg = "ADMIN LOG: [msg]"
+ to_chat(GLOB.admins, msg)
+
+/proc/relay_msg_admins(msg)
+ msg = "RELAY: [msg]"
+ to_chat(GLOB.admins, msg)
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////Panels
+
+/datum/admins/proc/show_player_panel(mob/M in GLOB.mob_list)
+ set category = "Admin"
+ set name = "Show Player Panel"
+ set desc="Edit player (respawn, ban, heal, etc)"
+
+ if(!check_rights())
+ return
+
+ if(!isobserver(usr))
+ log_game("[key_name_admin(usr)] checked the player panel while in game.")
+
+ if(!M)
+ to_chat(usr, "You seem to be selecting a mob that doesn't exist anymore.")
+ return
+
+ var/body = "Options for [M.key]"
+ body += "Options panel for [M]"
+ if(M.client)
+ body += " played by [M.client] "
+ body += "\[[M.client.holder ? M.client.holder.rank : "Player"]\]"
+
+ if(isnewplayer(M))
+ body += " Hasn't Entered Game "
+ else
+ body += " \[Heal\] "
+
+ if(M.client)
+ body += "
\[First Seen: [M.client.player_join_date]\]\[Byond account registered on: [M.client.account_join_date]\]"
+ body += "
Show related accounts by: "
+ body += "\[ CID | "
+ body += "IP \]"
+
+ body += "
\[ "
+ body += "VV - "
+ body += "TP - "
+ body += "PM - "
+ body += "SM - "
+ body += "FLW - "
+ body += "LOGS\]
"
+
+ body += "Mob type = [M.type]
"
+
+ body += "Kick | "
+ body += "Ban | "
+ body += "Jobban | "
+ body += "Identity Ban | "
+ if(jobban_isbanned(M, "OOC"))
+ body+= "OOCBan | "
+ else
+ body+= "OOCBan | "
+ if(jobban_isbanned(M, "emote"))
+ body+= "EmoteBan | "
+ else
+ body+= "Emoteban | "
+
+ body += "Notes | Messages | Watchlist | "
+ if(M.client)
+ body += "| Prison | "
+ body += "\ Send back to Lobby | "
+ var/muted = M.client.prefs.muted
+ body += "
Mute: "
+ body += "\[IC | "
+ body += "OOC | "
+ body += "PRAY | "
+ body += "ADMINHELP | "
+ body += "DEADCHAT\]"
+ body += "(toggle all)"
+
+ body += "
"
+ body += "Jump to | "
+ body += "Get | "
+ body += "Send To"
+
+ body += "
"
+ body += "Traitor panel | "
+ body += "Narrate to | "
+ body += "Subtle message | "
+ body += "Language Menu"
+
+ if (M.client)
+ if(!isnewplayer(M))
+ body += "
"
+ body += "Transformation:"
+ body += "
"
+
+ //Human
+ if(ishuman(M))
+ body += "Human | "
+ else
+ body += "Humanize | "
+
+ //Monkey
+ if(ismonkey(M))
+ body += "Monkeyized | "
+ else
+ body += "Monkeyize | "
+
+ //Corgi
+ if(iscorgi(M))
+ body += "Corgized | "
+ else
+ body += "Corgize | "
+
+ //AI / Cyborg
+ if(isAI(M))
+ body += "Is an AI "
+ else if(ishuman(M))
+ body += "Make AI | "
+ body += "Make Robot | "
+ body += "Make Alien | "
+ body += "Make Slime | "
+ body += "Make Blob | "
+
+ //Simple Animals
+ if(isanimal(M))
+ body += "Re-Animalize | "
+ else
+ body += "Animalize | "
+
+ body += "
"
+ body += "Rudimentary transformation:
These transformations only create a new mob type and copy stuff over. They do not take into account MMIs and similar mob-specific things. The buttons in 'Transformations' are preferred, when possible.
"
+ body += "Observer | "
+ body += "\[ Alien: Drone, "
+ body += "Hunter, "
+ body += "Sentinel, "
+ body += "Praetorian, "
+ body += "Queen, "
+ body += "Larva \] "
+ body += "Human "
+ body += "\[ slime: Baby, "
+ body += "Adult \] "
+ body += "Monkey | "
+ body += "Cyborg | "
+ body += "Cat | "
+ body += "Runtime | "
+ body += "Corgi | "
+ body += "Ian | "
+ body += "Crab | "
+ body += "Coffee | "
+ //body += "Parrot | "
+ //body += "Poly | "
+ body += "\[ Construct: Juggernaut , "
+ body += "Artificer , "
+ body += "Wraith \] "
+ body += "Shade"
+ body += "
"
+
+ if (M.client)
+ body += "
"
+ body += "Other actions:"
+ body += "
"
+ body += "Forcesay | "
+ body += "Thunderdome 1 | "
+ body += "Thunderdome 2 | "
+ body += "Thunderdome Admin | "
+ body += "Thunderdome Observer | "
+
+ body += "
"
+ body += ""
+
+ usr << browse(body, "window=adminplayeropts-\ref[M];size=550x515")
+ SSblackbox.add_details("admin_verb","Player Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+
+/datum/admins/proc/access_news_network() //MARKER
+ set category = "Fun"
+ set name = "Access Newscaster Network"
+ set desc = "Allows you to view, add and edit news feeds."
+
+ if (!istype(src,/datum/admins))
+ src = usr.client.holder
+ if (!istype(src,/datum/admins))
+ to_chat(usr, "Error: you are not an admin!")
+ return
+ var/dat
+ dat = text("Admin NewscasterAdmin Newscaster Unit
")
+
+ switch(admincaster_screen)
+ if(0)
+ dat += "Welcome to the admin newscaster.
Here you can add, edit and censor every newspiece on the network."
+ dat += "
Feed channels and stories entered through here will be uneditable and handled as official news by the rest of the units."
+ dat += "
Note that this panel allows full freedom over the news network, there are no constrictions except the few basic ones. Don't break things!"
+ if(GLOB.news_network.wanted_issue.active)
+ dat+= "
Read Wanted Issue"
+ dat+= "
Create Feed Channel"
+ dat+= "
View Feed Channels"
+ dat+= "
Submit new Feed story"
+ dat+= "
Exit"
+ var/wanted_already = 0
+ if(GLOB.news_network.wanted_issue.active)
+ wanted_already = 1
+ dat+="
Feed Security functions:
"
+ dat+="
[(wanted_already) ? ("Manage") : ("Publish")] \"Wanted\" Issue"
+ dat+="
Censor Feed Stories"
+ dat+="
Mark Feed Channel with Nanotrasen D-Notice (disables and locks the channel)."
+ dat+="
The newscaster recognises you as:
[src.admin_signature]"
+ if(1)
+ dat+= "Station Feed Channels
"
+ if( isemptylist(GLOB.news_network.network_channels) )
+ dat+="No active channels found..."
+ else
+ for(var/datum/newscaster/feed_channel/CHANNEL in GLOB.news_network.network_channels)
+ if(CHANNEL.is_admin_channel)
+ dat+="[CHANNEL.channel_name]
"
+ else
+ dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ()]
"
+ dat+="
Refresh"
+ dat+="
Back"
+ if(2)
+ dat+="Creating new Feed Channel..."
+ dat+="
Channel Name: [src.admincaster_feed_channel.channel_name]
"
+ dat+="Channel Author: [src.admin_signature]
"
+ dat+="Will Accept Public Feeds: [(src.admincaster_feed_channel.locked) ? ("NO") : ("YES")]
"
+ dat+="
Submit
Cancel
"
+ if(3)
+ dat+="Creating new Feed Message..."
+ dat+="
Receiving Channel: [src.admincaster_feed_channel.channel_name]
" //MARK
+ dat+="Message Author: [src.admin_signature]
"
+ dat+="Message Body: [src.admincaster_feed_message.returnBody(-1)]
"
+ dat+="
Submit
Cancel
"
+ if(4)
+ dat+="Feed story successfully submitted to [src.admincaster_feed_channel.channel_name].
"
+ dat+="
Return
"
+ if(5)
+ dat+="Feed Channel [src.admincaster_feed_channel.channel_name] created successfully.
"
+ dat+="
Return
"
+ if(6)
+ dat+="ERROR: Could not submit Feed story to Network.
"
+ if(src.admincaster_feed_channel.channel_name=="")
+ dat+="Invalid receiving channel name.
"
+ if(src.admincaster_feed_message.returnBody(-1) == "" || src.admincaster_feed_message.returnBody(-1) == "\[REDACTED\]")
+ dat+="Invalid message body.
"
+ dat+="
Return
"
+ if(7)
+ dat+="ERROR: Could not submit Feed Channel to Network.
"
+ if(src.admincaster_feed_channel.channel_name =="" || src.admincaster_feed_channel.channel_name == "\[REDACTED\]")
+ dat+="Invalid channel name.
"
+ var/check = 0
+ for(var/datum/newscaster/feed_channel/FC in GLOB.news_network.network_channels)
+ if(FC.channel_name == src.admincaster_feed_channel.channel_name)
+ check = 1
+ break
+ if(check)
+ dat+="Channel name already in use.
"
+ dat+="
Return
"
+ if(9)
+ dat+="[admincaster_feed_channel.channel_name]: \[created by: [admincaster_feed_channel.returnAuthor(-1)]\]
"
+ if(src.admincaster_feed_channel.censored)
+ dat+="ATTENTION: This channel has been deemed as threatening to the welfare of the station, and marked with a Nanotrasen D-Notice.
"
+ dat+="No further feed story additions are allowed while the D-Notice is in effect.
"
+ else
+ if( isemptylist(src.admincaster_feed_channel.messages) )
+ dat+="No feed messages found in channel...
"
+ else
+ var/i = 0
+ for(var/datum/newscaster/feed_message/MESSAGE in src.admincaster_feed_channel.messages)
+ i++
+ dat+="-[MESSAGE.returnBody(-1)]
"
+ if(MESSAGE.img)
+ usr << browse_rsc(MESSAGE.img, "tmp_photo[i].png")
+ dat+="
"
+ dat+="\[Story by [MESSAGE.returnAuthor(-1)]\]
"
+ dat+="[MESSAGE.comments.len] comment[MESSAGE.comments.len > 1 ? "s" : ""]:
"
+ for(var/datum/newscaster/feed_comment/comment in MESSAGE.comments)
+ dat+="[comment.body]
[comment.author] [comment.time_stamp]
"
+ dat+="
"
+ dat+="
Refresh"
+ dat+="
Back"
+ if(10)
+ dat+="Nanotrasen Feed Censorship Tool
"
+ dat+="NOTE: Due to the nature of news Feeds, total deletion of a Feed Story is not possible.
"
+ dat+="Keep in mind that users attempting to view a censored feed will instead see the \[REDACTED\] tag above it."
+ dat+="
Select Feed channel to get Stories from:
"
+ if(isemptylist(GLOB.news_network.network_channels))
+ dat+="No feed channels found active...
"
+ else
+ for(var/datum/newscaster/feed_channel/CHANNEL in GLOB.news_network.network_channels)
+ dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ()]
"
+ dat+="
Cancel"
+ if(11)
+ dat+="Nanotrasen D-Notice Handler
"
+ dat+="A D-Notice is to be bestowed upon the channel if the handling Authority deems it as harmful for the station's"
+ dat+="morale, integrity or disciplinary behaviour. A D-Notice will render a channel unable to be updated by anyone, without deleting any feed"
+ dat+="stories it might contain at the time. You can lift a D-Notice if you have the required access at any time.
"
+ if(isemptylist(GLOB.news_network.network_channels))
+ dat+="No feed channels found active...
"
+ else
+ for(var/datum/newscaster/feed_channel/CHANNEL in GLOB.news_network.network_channels)
+ dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ()]
"
+
+ dat+="
Back"
+ if(12)
+ dat+="[src.admincaster_feed_channel.channel_name]: \[ created by: [src.admincaster_feed_channel.returnAuthor(-1)] \]
"
+ dat+="[(src.admincaster_feed_channel.authorCensor) ? ("Undo Author censorship") : ("Censor channel Author")]
"
+
+ if( isemptylist(src.admincaster_feed_channel.messages) )
+ dat+="No feed messages found in channel...
"
+ else
+ for(var/datum/newscaster/feed_message/MESSAGE in src.admincaster_feed_channel.messages)
+ dat+="-[MESSAGE.returnBody(-1)]
\[Story by [MESSAGE.returnAuthor(-1)]\]
"
+ dat+="[(MESSAGE.bodyCensor) ? ("Undo story censorship") : ("Censor story")] - [(MESSAGE.authorCensor) ? ("Undo Author Censorship") : ("Censor message Author")]
"
+ dat+="[MESSAGE.comments.len] comment[MESSAGE.comments.len > 1 ? "s" : ""]: [MESSAGE.locked ? "Unlock" : "Lock"]
"
+ for(var/datum/newscaster/feed_comment/comment in MESSAGE.comments)
+ dat+="[comment.body] X
[comment.author] [comment.time_stamp]
"
+ dat+="
Back"
+ if(13)
+ dat+="[src.admincaster_feed_channel.channel_name]: \[ created by: [src.admincaster_feed_channel.returnAuthor(-1)] \]
"
+ dat+="Channel messages listed below. If you deem them dangerous to the station, you can Bestow a D-Notice upon the channel.
"
+ if(src.admincaster_feed_channel.censored)
+ dat+="ATTENTION: This channel has been deemed as threatening to the welfare of the station, and marked with a Nanotrasen D-Notice.
"
+ dat+="No further feed story additions are allowed while the D-Notice is in effect.
"
+ else
+ if( isemptylist(src.admincaster_feed_channel.messages) )
+ dat+="No feed messages found in channel...
"
+ else
+ for(var/datum/newscaster/feed_message/MESSAGE in src.admincaster_feed_channel.messages)
+ dat+="-[MESSAGE.returnBody(-1)]
\[Story by [MESSAGE.returnAuthor(-1)]\]
"
+ dat+="
Back"
+ if(14)
+ dat+="Wanted Issue Handler:"
+ var/wanted_already = 0
+ var/end_param = 1
+ if(GLOB.news_network.wanted_issue.active)
+ wanted_already = 1
+ end_param = 2
+ if(wanted_already)
+ dat+="
A wanted issue is already in Feed Circulation. You can edit or cancel it below."
+ dat+="
"
+ dat+="Criminal Name: [src.admincaster_wanted_message.criminal]
"
+ dat+="Description: [src.admincaster_wanted_message.body]
"
+ if(wanted_already)
+ dat+="Wanted Issue created by:[GLOB.news_network.wanted_issue.scannedUser]
"
+ else
+ dat+="Wanted Issue will be created under prosecutor:[src.admin_signature]
"
+ dat+="
[(wanted_already) ? ("Edit Issue") : ("Submit")]"
+ if(wanted_already)
+ dat+="
Take down Issue"
+ dat+="
Cancel"
+ if(15)
+ dat+="Wanted issue for [src.admincaster_wanted_message.criminal] is now in Network Circulation.
"
+ dat+="
Return
"
+ if(16)
+ dat+="ERROR: Wanted Issue rejected by Network.
"
+ if(src.admincaster_wanted_message.criminal =="" || src.admincaster_wanted_message.criminal == "\[REDACTED\]")
+ dat+="Invalid name for person wanted.
"
+ if(src.admincaster_wanted_message.body == "" || src.admincaster_wanted_message.body == "\[REDACTED\]")
+ dat+="Invalid description.
"
+ dat+="
Return
"
+ if(17)
+ dat+="Wanted Issue successfully deleted from Circulation
"
+ dat+="
Return
"
+ if(18)
+ dat+="-- STATIONWIDE WANTED ISSUE --
\[Submitted by: [GLOB.news_network.wanted_issue.scannedUser]\]
"
+ dat+="Criminal: [GLOB.news_network.wanted_issue.criminal]
"
+ dat+="Description: [GLOB.news_network.wanted_issue.body]
"
+ dat+="Photo:: "
+ if(GLOB.news_network.wanted_issue.img)
+ usr << browse_rsc(GLOB.news_network.wanted_issue.img, "tmp_photow.png")
+ dat+="
"
+ else
+ dat+="None"
+ dat+="
Back
"
+ if(19)
+ dat+="Wanted issue for [src.admincaster_wanted_message.criminal] successfully edited.
"
+ dat+="
Return
"
+ else
+ dat+="I'm sorry to break your immersion. This shit's bugged. Report this bug to Agouri, polyxenitopalidou@gmail.com"
+
+ //to_chat(world, "Channelname: [src.admincaster_feed_channel.channel_name] [src.admincaster_feed_channel.author]")
+ //to_chat(world, "Msg: [src.admincaster_feed_message.author] [src.admincaster_feed_message.body]")
+ usr << browse(dat, "window=admincaster_main;size=400x600")
+ onclose(usr, "admincaster_main")
+
+
+/datum/admins/proc/Game()
+ if(!check_rights(0))
+ return
+
+ var/dat = {"
+ Game Panel
\n
+ Change Game Mode
+ "}
+ if(GLOB.master_mode == "secret")
+ dat += "(Force Secret Mode)
"
+
+ dat += {"
+
+ Create Object
+ Quick Create Object
+ Create Turf
+ Create Mob
+ "}
+
+ if(marked_datum && istype(marked_datum, /atom))
+ dat += "Duplicate Marked Datum
"
+
+ usr << browse(dat, "window=admin2;size=210x200")
+ return
+
+/////////////////////////////////////////////////////////////////////////////////////////////////admins2.dm merge
+//i.e. buttons/verbs
+
+
+/datum/admins/proc/restart()
+ set category = "Server"
+ set name = "Reboot World"
+ set desc="Restarts the world immediately"
+ if (!usr.client.holder)
+ return
+
+ 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!
+
+ switch(result)
+ if("Regular Restart")
+ SSticker.Reboot("Initiated by [usr.client.holder.fakekey ? "Admin" : usr.key].", "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"
- set name = "End Round"
- set desc = "Attempts to produce a round end report and then restart the server organically."
-
- if (!usr.client.holder)
- return
- var/confirm = alert("End the round and restart the game world?", "End Round", "Yes", "Cancel")
- if(confirm == "Cancel")
- return
- if(confirm == "Yes")
- SSticker.force_ending = 1
- SSblackbox.add_details("admin_verb","End Round") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-
-/datum/admins/proc/announce()
- set category = "Special Verbs"
- set name = "Announce"
- set desc="Announce your desires to the world"
- if(!check_rights(0))
- return
-
- var/message = input("Global message to send:", "Admin Announce", null, null) as message
- if(message)
- if(!check_rights(R_SERVER,0))
- message = adminscrub(message,500)
- to_chat(world, "[usr.client.holder.fakekey ? "Administrator" : usr.key] Announces:\n \t [message]")
- log_admin("Announce: [key_name(usr)] : [message]")
- SSblackbox.add_details("admin_verb","Announce") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/datum/admins/proc/set_admin_notice()
- set category = "Special Verbs"
- set name = "Set Admin Notice"
- set desc ="Set an announcement that appears to everyone who joins the server. Only lasts this round"
- if(!check_rights(0))
- return
-
- var/new_admin_notice = input(src,"Set a public notice for this round. Everyone who joins the server will see it.\n(Leaving it blank will delete the current notice):","Set Notice",GLOB.admin_notice) as message|null
- if(new_admin_notice == null)
- return
- if(new_admin_notice == GLOB.admin_notice)
- return
- if(new_admin_notice == "")
- message_admins("[key_name(usr)] removed the admin notice.")
- log_admin("[key_name(usr)] removed the admin notice:\n[GLOB.admin_notice]")
- else
- message_admins("[key_name(usr)] set the admin notice.")
- log_admin("[key_name(usr)] set the admin notice:\n[new_admin_notice]")
- to_chat(world, "Admin Notice:\n \t [new_admin_notice]")
- SSblackbox.add_details("admin_verb","Set Admin Notice") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
- GLOB.admin_notice = new_admin_notice
- return
-
-/datum/admins/proc/toggleooc()
- set category = "Server"
- set desc="Toggle dis bitch"
- set name="Toggle OOC"
- toggle_ooc()
- log_admin("[key_name(usr)] toggled OOC.")
- message_admins("[key_name_admin(usr)] toggled OOC.")
- SSblackbox.add_details("admin_toggle","Toggle OOC|[GLOB.ooc_allowed]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/datum/admins/proc/toggleoocdead()
- set category = "Server"
- set desc="Toggle dis bitch"
- set name="Toggle Dead OOC"
- GLOB.dooc_allowed = !( GLOB.dooc_allowed )
-
- log_admin("[key_name(usr)] toggled OOC.")
- message_admins("[key_name_admin(usr)] toggled Dead OOC.")
- SSblackbox.add_details("admin_toggle","Toggle Dead OOC|[GLOB.dooc_allowed]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/datum/admins/proc/startnow()
- set category = "Server"
- set desc="Start the round RIGHT NOW"
- set name="Start Now"
- if(SSticker.current_state == GAME_STATE_PREGAME || SSticker.current_state == GAME_STATE_STARTUP)
- SSticker.start_immediately = TRUE
- log_admin("[usr.key] has started the game.")
- var/msg = ""
- if(SSticker.current_state == GAME_STATE_STARTUP)
- msg = " (The server is still setting up, but the round will be \
- started as soon as possible.)"
- message_admins("\
- [usr.key] has started the game.[msg]")
- SSblackbox.add_details("admin_verb","Start Now") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
- return 1
- else
- to_chat(usr, "Error: Start Now: Game has already started.")
-
- return 0
-
-/datum/admins/proc/toggleenter()
- set category = "Server"
- set desc="People can't enter"
- set name="Toggle Entering"
- GLOB.enter_allowed = !( GLOB.enter_allowed )
- if (!( GLOB.enter_allowed ))
- to_chat(world, "New players may no longer enter the game.")
- else
- to_chat(world, "New players may now enter the game.")
- log_admin("[key_name(usr)] toggled new player game entering.")
- message_admins("[key_name_admin(usr)] toggled new player game entering.")
- world.update_status()
- SSblackbox.add_details("admin_toggle","Toggle Entering|[GLOB.enter_allowed]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/datum/admins/proc/toggleAI()
- set category = "Server"
- set desc="People can't be AI"
- set name="Toggle AI"
- config.allow_ai = !( config.allow_ai )
- if (!( config.allow_ai ))
- to_chat(world, "The AI job is no longer chooseable.")
- else
- to_chat(world, "The AI job is chooseable now.")
- log_admin("[key_name(usr)] toggled AI allowed.")
- world.update_status()
- SSblackbox.add_details("admin_toggle","Toggle AI|[config.allow_ai]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/datum/admins/proc/toggleaban()
- set category = "Server"
- set desc="Respawn basically"
- set name="Toggle Respawn"
- GLOB.abandon_allowed = !( GLOB.abandon_allowed )
- if (GLOB.abandon_allowed)
- to_chat(world, "You may now respawn.")
- else
- to_chat(world, "You may no longer respawn :(")
- message_admins("[key_name_admin(usr)] toggled respawn to [GLOB.abandon_allowed ? "On" : "Off"].")
- log_admin("[key_name(usr)] toggled respawn to [GLOB.abandon_allowed ? "On" : "Off"].")
- world.update_status()
- SSblackbox.add_details("admin_toggle","Toggle Respawn|[GLOB.abandon_allowed]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/datum/admins/proc/delay()
- set category = "Server"
- set desc="Delay the game start"
- set name="Delay pre-game"
-
- var/newtime = input("Set a new time in seconds. Set -1 for indefinite delay.","Set Delay",round(SSticker.GetTimeLeft()/10)) as num|null
- if(SSticker.current_state > GAME_STATE_PREGAME)
- return alert("Too late... The game has already started!")
- if(newtime)
- SSticker.SetTimeLeft(newtime * 10)
- if(newtime < 0)
- to_chat(world, "The game start has been delayed.")
- log_admin("[key_name(usr)] delayed the round start.")
- else
- to_chat(world, "The game will start in [newtime] seconds.")
- world << 'sound/ai/attention.ogg'
- log_admin("[key_name(usr)] set the pre-game delay to [newtime] seconds.")
- SSblackbox.add_details("admin_verb","Delay Game Start") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/datum/admins/proc/unprison(mob/M in GLOB.mob_list)
- set category = "Admin"
- set name = "Unprison"
- if (M.z == ZLEVEL_CENTCOM)
- M.loc = pick(GLOB.latejoin)
- message_admins("[key_name_admin(usr)] has unprisoned [key_name_admin(M)]")
- log_admin("[key_name(usr)] has unprisoned [key_name(M)]")
- else
- alert("[M.name] is not prisoned.")
- SSblackbox.add_details("admin_verb","Unprison") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-////////////////////////////////////////////////////////////////////////////////////////////////ADMIN HELPER PROCS
-
-/*
-/datum/admins/proc/get_sab_desc(var/target)
- switch(target)
- if(1)
- return "Destroy at least 70% of the plasma canisters on the station"
- if(2)
- return "Destroy the AI"
- if(3)
- var/count = 0
- for(var/mob/living/carbon/monkey/Monkey in world)
+
+/datum/admins/proc/end_round()
+ set category = "Server"
+ set name = "End Round"
+ set desc = "Attempts to produce a round end report and then restart the server organically."
+
+ if (!usr.client.holder)
+ return
+ var/confirm = alert("End the round and restart the game world?", "End Round", "Yes", "Cancel")
+ if(confirm == "Cancel")
+ return
+ if(confirm == "Yes")
+ SSticker.force_ending = 1
+ SSblackbox.add_details("admin_verb","End Round") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+
+/datum/admins/proc/announce()
+ set category = "Special Verbs"
+ set name = "Announce"
+ set desc="Announce your desires to the world"
+ if(!check_rights(0))
+ return
+
+ var/message = input("Global message to send:", "Admin Announce", null, null) as message
+ if(message)
+ if(!check_rights(R_SERVER,0))
+ message = adminscrub(message,500)
+ to_chat(world, "[usr.client.holder.fakekey ? "Administrator" : usr.key] Announces:\n \t [message]")
+ log_admin("Announce: [key_name(usr)] : [message]")
+ SSblackbox.add_details("admin_verb","Announce") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/datum/admins/proc/set_admin_notice()
+ set category = "Special Verbs"
+ set name = "Set Admin Notice"
+ set desc ="Set an announcement that appears to everyone who joins the server. Only lasts this round"
+ if(!check_rights(0))
+ return
+
+ var/new_admin_notice = input(src,"Set a public notice for this round. Everyone who joins the server will see it.\n(Leaving it blank will delete the current notice):","Set Notice",GLOB.admin_notice) as message|null
+ if(new_admin_notice == null)
+ return
+ if(new_admin_notice == GLOB.admin_notice)
+ return
+ if(new_admin_notice == "")
+ message_admins("[key_name(usr)] removed the admin notice.")
+ log_admin("[key_name(usr)] removed the admin notice:\n[GLOB.admin_notice]")
+ else
+ message_admins("[key_name(usr)] set the admin notice.")
+ log_admin("[key_name(usr)] set the admin notice:\n[new_admin_notice]")
+ to_chat(world, "Admin Notice:\n \t [new_admin_notice]")
+ SSblackbox.add_details("admin_verb","Set Admin Notice") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ GLOB.admin_notice = new_admin_notice
+ return
+
+/datum/admins/proc/toggleooc()
+ set category = "Server"
+ set desc="Toggle dis bitch"
+ set name="Toggle OOC"
+ toggle_ooc()
+ log_admin("[key_name(usr)] toggled OOC.")
+ message_admins("[key_name_admin(usr)] toggled OOC.")
+ SSblackbox.add_details("admin_toggle","Toggle OOC|[GLOB.ooc_allowed]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/datum/admins/proc/toggleoocdead()
+ set category = "Server"
+ set desc="Toggle dis bitch"
+ set name="Toggle Dead OOC"
+ GLOB.dooc_allowed = !( GLOB.dooc_allowed )
+
+ log_admin("[key_name(usr)] toggled OOC.")
+ message_admins("[key_name_admin(usr)] toggled Dead OOC.")
+ SSblackbox.add_details("admin_toggle","Toggle Dead OOC|[GLOB.dooc_allowed]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/datum/admins/proc/startnow()
+ set category = "Server"
+ set desc="Start the round RIGHT NOW"
+ set name="Start Now"
+ if(SSticker.current_state == GAME_STATE_PREGAME || SSticker.current_state == GAME_STATE_STARTUP)
+ SSticker.start_immediately = TRUE
+ log_admin("[usr.key] has started the game.")
+ var/msg = ""
+ if(SSticker.current_state == GAME_STATE_STARTUP)
+ msg = " (The server is still setting up, but the round will be \
+ started as soon as possible.)"
+ message_admins("\
+ [usr.key] has started the game.[msg]")
+ SSblackbox.add_details("admin_verb","Start Now") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ return 1
+ else
+ to_chat(usr, "Error: Start Now: Game has already started.")
+
+ return 0
+
+/datum/admins/proc/toggleenter()
+ set category = "Server"
+ set desc="People can't enter"
+ set name="Toggle Entering"
+ GLOB.enter_allowed = !( GLOB.enter_allowed )
+ if (!( GLOB.enter_allowed ))
+ to_chat(world, "New players may no longer enter the game.")
+ else
+ to_chat(world, "New players may now enter the game.")
+ log_admin("[key_name(usr)] toggled new player game entering.")
+ message_admins("[key_name_admin(usr)] toggled new player game entering.")
+ world.update_status()
+ SSblackbox.add_details("admin_toggle","Toggle Entering|[GLOB.enter_allowed]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/datum/admins/proc/toggleAI()
+ set category = "Server"
+ set desc="People can't be AI"
+ set name="Toggle AI"
+ config.allow_ai = !( config.allow_ai )
+ if (!( config.allow_ai ))
+ to_chat(world, "The AI job is no longer chooseable.")
+ else
+ to_chat(world, "The AI job is chooseable now.")
+ log_admin("[key_name(usr)] toggled AI allowed.")
+ world.update_status()
+ SSblackbox.add_details("admin_toggle","Toggle AI|[config.allow_ai]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/datum/admins/proc/toggleaban()
+ set category = "Server"
+ set desc="Respawn basically"
+ set name="Toggle Respawn"
+ GLOB.abandon_allowed = !( GLOB.abandon_allowed )
+ if (GLOB.abandon_allowed)
+ to_chat(world, "You may now respawn.")
+ else
+ to_chat(world, "You may no longer respawn :(")
+ message_admins("[key_name_admin(usr)] toggled respawn to [GLOB.abandon_allowed ? "On" : "Off"].")
+ log_admin("[key_name(usr)] toggled respawn to [GLOB.abandon_allowed ? "On" : "Off"].")
+ world.update_status()
+ SSblackbox.add_details("admin_toggle","Toggle Respawn|[GLOB.abandon_allowed]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/datum/admins/proc/delay()
+ set category = "Server"
+ set desc="Delay the game start"
+ set name="Delay pre-game"
+
+ var/newtime = input("Set a new time in seconds. Set -1 for indefinite delay.","Set Delay",round(SSticker.GetTimeLeft()/10)) as num|null
+ if(SSticker.current_state > GAME_STATE_PREGAME)
+ return alert("Too late... The game has already started!")
+ if(newtime)
+ SSticker.SetTimeLeft(newtime * 10)
+ if(newtime < 0)
+ to_chat(world, "The game start has been delayed.")
+ log_admin("[key_name(usr)] delayed the round start.")
+ else
+ to_chat(world, "The game will start in [newtime] seconds.")
+ world << 'sound/ai/attention.ogg'
+ log_admin("[key_name(usr)] set the pre-game delay to [newtime] seconds.")
+ SSblackbox.add_details("admin_verb","Delay Game Start") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/datum/admins/proc/unprison(mob/M in GLOB.mob_list)
+ set category = "Admin"
+ set name = "Unprison"
+ if (M.z == ZLEVEL_CENTCOM)
+ M.loc = pick(GLOB.latejoin)
+ message_admins("[key_name_admin(usr)] has unprisoned [key_name_admin(M)]")
+ log_admin("[key_name(usr)] has unprisoned [key_name(M)]")
+ else
+ alert("[M.name] is not prisoned.")
+ SSblackbox.add_details("admin_verb","Unprison") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+////////////////////////////////////////////////////////////////////////////////////////////////ADMIN HELPER PROCS
+
+/*
+/datum/admins/proc/get_sab_desc(var/target)
+ switch(target)
+ if(1)
+ return "Destroy at least 70% of the plasma canisters on the station"
+ if(2)
+ return "Destroy the AI"
+ if(3)
+ var/count = 0
+ for(var/mob/living/carbon/monkey/Monkey in world)
if(Monkey.z == ZLEVEL_STATION)
- count++
- return "Kill all [count] of the monkeys on the station"
- if(4)
- return "Cut power to at least 80% of the station"
- else
- return "Error: Invalid sabotage target: [target]"
-*/
-/datum/admins/proc/spawn_atom(object as text)
- set category = "Debug"
- set desc = "(atom path) Spawn an atom"
- set name = "Spawn"
-
- if(!check_rights(R_SPAWN))
- return
-
- var/chosen = pick_closest_path(object)
- if(!chosen)
- return
- if(ispath(chosen,/turf))
- var/turf/T = get_turf(usr.loc)
- T.ChangeTurf(chosen)
- else
- var/atom/A = new chosen(usr.loc)
- A.admin_spawned = TRUE
-
- log_admin("[key_name(usr)] spawned [chosen] at ([usr.x],[usr.y],[usr.z])")
- SSblackbox.add_details("admin_verb","Spawn Atom") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-
-/datum/admins/proc/show_traitor_panel(mob/M in GLOB.mob_list)
- set category = "Admin"
- set desc = "Edit mobs's memory and role"
- set name = "Show Traitor Panel"
-
- if(!istype(M))
- to_chat(usr, "This can only be used on instances of type /mob")
- return
- if(!M.mind)
- to_chat(usr, "This mob has no mind!")
- return
-
- M.mind.edit_memory()
- SSblackbox.add_details("admin_verb","Traitor Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-
-/datum/admins/proc/toggletintedweldhelmets()
- set category = "Debug"
- set desc="Reduces view range when wearing welding helmets"
- set name="Toggle tinted welding helmes"
- GLOB.tinted_weldhelh = !( GLOB.tinted_weldhelh )
- if (GLOB.tinted_weldhelh)
- to_chat(world, "The tinted_weldhelh has been enabled!")
- else
- to_chat(world, "The tinted_weldhelh has been disabled!")
- log_admin("[key_name(usr)] toggled tinted_weldhelh.")
- message_admins("[key_name_admin(usr)] toggled tinted_weldhelh.")
- SSblackbox.add_details("admin_toggle","Toggle Tinted Welding Helmets|[GLOB.tinted_weldhelh]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/datum/admins/proc/toggleguests()
- set category = "Server"
- set desc="Guests can't enter"
- set name="Toggle guests"
- GLOB.guests_allowed = !( GLOB.guests_allowed )
- if (!( GLOB.guests_allowed ))
- to_chat(world, "Guests may no longer enter the game.")
- else
- to_chat(world, "Guests may now enter the game.")
- log_admin("[key_name(usr)] toggled guests game entering [GLOB.guests_allowed?"":"dis"]allowed.")
- message_admins("[key_name_admin(usr)] toggled guests game entering [GLOB.guests_allowed?"":"dis"]allowed.")
- SSblackbox.add_details("admin_toggle","Toggle Guests|[GLOB.guests_allowed]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/datum/admins/proc/output_ai_laws()
- var/ai_number = 0
- for(var/mob/living/silicon/S in GLOB.mob_list)
- ai_number++
- if(isAI(S))
- to_chat(usr, "AI [key_name(S, usr)]'s laws:")
- else if(iscyborg(S))
- var/mob/living/silicon/robot/R = S
- to_chat(usr, "CYBORG [key_name(S, usr)] [R.connected_ai?"(Slaved to: [R.connected_ai])":"(Independant)"]: laws:")
- else if (ispAI(S))
- to_chat(usr, "pAI [key_name(S, usr)]'s laws:")
- else
- to_chat(usr, "SOMETHING SILICON [key_name(S, usr)]'s laws:")
-
- if (S.laws == null)
- to_chat(usr, "[key_name(S, usr)]'s laws are null?? Contact a coder.")
- else
- S.laws.show_laws(usr)
- if(!ai_number)
- to_chat(usr, "No AIs located" )
-
-/datum/admins/proc/output_all_devil_info()
- var/devil_number = 0
- for(var/D in SSticker.mode.devils)
- devil_number++
- to_chat(usr, "Devil #[devil_number]:
" + SSticker.mode.printdevilinfo(D))
- if(!devil_number)
- to_chat(usr, "No Devils located" )
-
-/datum/admins/proc/output_devil_info(mob/living/M)
- if(is_devil(M))
- to_chat(usr, SSticker.mode.printdevilinfo(M.mind))
- else
- to_chat(usr, "[M] is not a devil.")
-
-/datum/admins/proc/manage_free_slots()
- if(!check_rights())
- return
- var/dat = "Manage Free Slots"
- var/count = 0
-
- if(SSticker && !SSticker.mode)
- alert(usr, "You cannot manage jobs before the round starts!")
- return
-
- if(SSjob)
- for(var/datum/job/job in SSjob.occupations)
- count++
- var/J_title = html_encode(job.title)
- var/J_opPos = html_encode(job.total_positions - (job.total_positions - job.current_positions))
- var/J_totPos = html_encode(job.total_positions)
- if(job.total_positions < 0)
- dat += "[J_title]: [J_opPos] (unlimited)"
- else
- dat += "[J_title]: [J_opPos]/[J_totPos]"
-
- if(job.title == "AI" || job.title == "Cyborg")
- dat += " (Cannot Late Join)
"
- continue
- if(job.total_positions >= 0)
- dat += " Add | "
- if(job.total_positions > job.current_positions)
- dat += "Remove | "
- else
- dat += "Remove | "
- dat += "Unlimit"
- else
- dat += " Limit"
- dat += "
"
-
- dat += ""
- var/winheight = 100 + (count * 20)
- winheight = min(winheight, 690)
- usr << browse(dat, "window=players;size=375x[winheight]")
-
-//
-//
-//ALL DONE
-//*********************************************************************************************************
-//TO-DO:
-//
-//
-
-//RIP ferry snowflakes
-
-//Kicks all the clients currently in the lobby. The second parameter (kick_only_afk) determins if an is_afk() check is ran, or if all clients are kicked
-//defaults to kicking everyone (afk + non afk clients in the lobby)
-//returns a list of ckeys of the kicked clients
-/proc/kick_clients_in_lobby(message, kick_only_afk = 0)
- var/list/kicked_client_names = list()
- for(var/client/C in GLOB.clients)
- if(isnewplayer(C.mob))
- if(kick_only_afk && !C.is_afk()) //Ignore clients who are not afk
- continue
- if(message)
- to_chat(C, message)
- kicked_client_names.Add("[C.ckey]")
- qdel(C)
- return kicked_client_names
-
-//returns 1 to let the dragdrop code know we are trapping this event
-//returns 0 if we don't plan to trap the event
-/datum/admins/proc/cmd_ghost_drag(mob/dead/observer/frommob, mob/living/tomob)
-
- //this is the exact two check rights checks required to edit a ckey with vv.
- if (!check_rights(R_VAREDIT,0) || !check_rights(R_SPAWN|R_DEBUG,0))
- return 0
-
- if (!frommob.ckey)
- return 0
-
- var/question = ""
- if (tomob.ckey)
- question = "This mob already has a user ([tomob.key]) in control of it! "
- question += "Are you sure you want to place [frommob.name]([frommob.key]) in control of [tomob.name]?"
-
- var/ask = alert(question, "Place ghost in control of mob?", "Yes", "No")
- if (ask != "Yes")
- return 1
-
- if (!frommob || !tomob) //make sure the mobs don't go away while we waited for a response
- return 1
-
- tomob.ghostize(0)
-
- message_admins("[key_name_admin(usr)] has put [frommob.ckey] in control of [tomob.name].")
- log_admin("[key_name(usr)] stuffed [frommob.ckey] into [tomob.name].")
- SSblackbox.add_details("admin_verb","Ghost Drag Control")
-
- tomob.ckey = frommob.ckey
- qdel(frommob)
-
- return 1
-
-/client/proc/adminGreet(logout)
- if(SSticker.HasRoundStarted())
- var/string
- if(logout && config && config.announce_admin_logout)
- string = pick(
- "Admin logout: [key_name(src)]")
- else if(!logout && config && config.announce_admin_login && (prefs.toggles & ANNOUNCE_LOGIN))
- string = pick(
- "Admin login: [key_name(src)]")
- if(string)
+ count++
+ return "Kill all [count] of the monkeys on the station"
+ if(4)
+ return "Cut power to at least 80% of the station"
+ else
+ return "Error: Invalid sabotage target: [target]"
+*/
+/datum/admins/proc/spawn_atom(object as text)
+ set category = "Debug"
+ set desc = "(atom path) Spawn an atom"
+ set name = "Spawn"
+
+ if(!check_rights(R_SPAWN))
+ return
+
+ var/chosen = pick_closest_path(object)
+ if(!chosen)
+ return
+ if(ispath(chosen,/turf))
+ var/turf/T = get_turf(usr.loc)
+ T.ChangeTurf(chosen)
+ else
+ var/atom/A = new chosen(usr.loc)
+ A.admin_spawned = TRUE
+
+ log_admin("[key_name(usr)] spawned [chosen] at ([usr.x],[usr.y],[usr.z])")
+ SSblackbox.add_details("admin_verb","Spawn Atom") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+
+/datum/admins/proc/show_traitor_panel(mob/M in GLOB.mob_list)
+ set category = "Admin"
+ set desc = "Edit mobs's memory and role"
+ set name = "Show Traitor Panel"
+
+ if(!istype(M))
+ to_chat(usr, "This can only be used on instances of type /mob")
+ return
+ if(!M.mind)
+ to_chat(usr, "This mob has no mind!")
+ return
+
+ M.mind.edit_memory()
+ SSblackbox.add_details("admin_verb","Traitor Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+
+/datum/admins/proc/toggletintedweldhelmets()
+ set category = "Debug"
+ set desc="Reduces view range when wearing welding helmets"
+ set name="Toggle tinted welding helmes"
+ GLOB.tinted_weldhelh = !( GLOB.tinted_weldhelh )
+ if (GLOB.tinted_weldhelh)
+ to_chat(world, "The tinted_weldhelh has been enabled!")
+ else
+ to_chat(world, "The tinted_weldhelh has been disabled!")
+ log_admin("[key_name(usr)] toggled tinted_weldhelh.")
+ message_admins("[key_name_admin(usr)] toggled tinted_weldhelh.")
+ SSblackbox.add_details("admin_toggle","Toggle Tinted Welding Helmets|[GLOB.tinted_weldhelh]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/datum/admins/proc/toggleguests()
+ set category = "Server"
+ set desc="Guests can't enter"
+ set name="Toggle guests"
+ GLOB.guests_allowed = !( GLOB.guests_allowed )
+ if (!( GLOB.guests_allowed ))
+ to_chat(world, "Guests may no longer enter the game.")
+ else
+ to_chat(world, "Guests may now enter the game.")
+ log_admin("[key_name(usr)] toggled guests game entering [GLOB.guests_allowed?"":"dis"]allowed.")
+ message_admins("[key_name_admin(usr)] toggled guests game entering [GLOB.guests_allowed?"":"dis"]allowed.")
+ SSblackbox.add_details("admin_toggle","Toggle Guests|[GLOB.guests_allowed]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/datum/admins/proc/output_ai_laws()
+ var/ai_number = 0
+ for(var/mob/living/silicon/S in GLOB.mob_list)
+ ai_number++
+ if(isAI(S))
+ to_chat(usr, "AI [key_name(S, usr)]'s laws:")
+ else if(iscyborg(S))
+ var/mob/living/silicon/robot/R = S
+ to_chat(usr, "CYBORG [key_name(S, usr)] [R.connected_ai?"(Slaved to: [R.connected_ai])":"(Independant)"]: laws:")
+ else if (ispAI(S))
+ to_chat(usr, "pAI [key_name(S, usr)]'s laws:")
+ else
+ to_chat(usr, "SOMETHING SILICON [key_name(S, usr)]'s laws:")
+
+ if (S.laws == null)
+ to_chat(usr, "[key_name(S, usr)]'s laws are null?? Contact a coder.")
+ else
+ S.laws.show_laws(usr)
+ if(!ai_number)
+ to_chat(usr, "No AIs located" )
+
+/datum/admins/proc/output_all_devil_info()
+ var/devil_number = 0
+ for(var/D in SSticker.mode.devils)
+ devil_number++
+ to_chat(usr, "Devil #[devil_number]:
" + SSticker.mode.printdevilinfo(D))
+ if(!devil_number)
+ to_chat(usr, "No Devils located" )
+
+/datum/admins/proc/output_devil_info(mob/living/M)
+ if(is_devil(M))
+ to_chat(usr, SSticker.mode.printdevilinfo(M.mind))
+ else
+ to_chat(usr, "[M] is not a devil.")
+
+/datum/admins/proc/manage_free_slots()
+ if(!check_rights())
+ return
+ var/dat = "Manage Free Slots"
+ var/count = 0
+
+ if(SSticker && !SSticker.mode)
+ alert(usr, "You cannot manage jobs before the round starts!")
+ return
+
+ if(SSjob)
+ for(var/datum/job/job in SSjob.occupations)
+ count++
+ var/J_title = html_encode(job.title)
+ var/J_opPos = html_encode(job.total_positions - (job.total_positions - job.current_positions))
+ var/J_totPos = html_encode(job.total_positions)
+ if(job.total_positions < 0)
+ dat += "[J_title]: [J_opPos] (unlimited)"
+ else
+ dat += "[J_title]: [J_opPos]/[J_totPos]"
+
+ if(job.title == "AI" || job.title == "Cyborg")
+ dat += " (Cannot Late Join)
"
+ continue
+ if(job.total_positions >= 0)
+ dat += " Add | "
+ if(job.total_positions > job.current_positions)
+ dat += "Remove | "
+ else
+ dat += "Remove | "
+ dat += "Unlimit"
+ else
+ dat += " Limit"
+ dat += "
"
+
+ dat += ""
+ var/winheight = 100 + (count * 20)
+ winheight = min(winheight, 690)
+ usr << browse(dat, "window=players;size=375x[winheight]")
+
+//
+//
+//ALL DONE
+//*********************************************************************************************************
+//TO-DO:
+//
+//
+
+//RIP ferry snowflakes
+
+//Kicks all the clients currently in the lobby. The second parameter (kick_only_afk) determins if an is_afk() check is ran, or if all clients are kicked
+//defaults to kicking everyone (afk + non afk clients in the lobby)
+//returns a list of ckeys of the kicked clients
+/proc/kick_clients_in_lobby(message, kick_only_afk = 0)
+ var/list/kicked_client_names = list()
+ for(var/client/C in GLOB.clients)
+ if(isnewplayer(C.mob))
+ if(kick_only_afk && !C.is_afk()) //Ignore clients who are not afk
+ continue
+ if(message)
+ to_chat(C, message)
+ kicked_client_names.Add("[C.ckey]")
+ qdel(C)
+ return kicked_client_names
+
+//returns 1 to let the dragdrop code know we are trapping this event
+//returns 0 if we don't plan to trap the event
+/datum/admins/proc/cmd_ghost_drag(mob/dead/observer/frommob, mob/living/tomob)
+
+ //this is the exact two check rights checks required to edit a ckey with vv.
+ if (!check_rights(R_VAREDIT,0) || !check_rights(R_SPAWN|R_DEBUG,0))
+ return 0
+
+ if (!frommob.ckey)
+ return 0
+
+ var/question = ""
+ if (tomob.ckey)
+ question = "This mob already has a user ([tomob.key]) in control of it! "
+ question += "Are you sure you want to place [frommob.name]([frommob.key]) in control of [tomob.name]?"
+
+ var/ask = alert(question, "Place ghost in control of mob?", "Yes", "No")
+ if (ask != "Yes")
+ return 1
+
+ if (!frommob || !tomob) //make sure the mobs don't go away while we waited for a response
+ return 1
+
+ tomob.ghostize(0)
+
+ message_admins("[key_name_admin(usr)] has put [frommob.ckey] in control of [tomob.name].")
+ log_admin("[key_name(usr)] stuffed [frommob.ckey] into [tomob.name].")
+ SSblackbox.add_details("admin_verb","Ghost Drag Control")
+
+ tomob.ckey = frommob.ckey
+ qdel(frommob)
+
+ return 1
+
+/client/proc/adminGreet(logout)
+ if(SSticker.HasRoundStarted())
+ var/string
+ if(logout && config && config.announce_admin_logout)
+ string = pick(
+ "Admin logout: [key_name(src)]")
+ else if(!logout && config && config.announce_admin_login && (prefs.toggles & ANNOUNCE_LOGIN))
+ string = pick(
+ "Admin login: [key_name(src)]")
+ if(string)
message_admins("[string]")
\ No newline at end of file
diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm
index d479ddf1bc..e1ed63793d 100644
--- a/code/modules/shuttle/emergency.dm
+++ b/code/modules/shuttle/emergency.dm
@@ -297,7 +297,9 @@
setTimer(SSshuttle.emergencyDockTime)
send2irc("Server", "The Emergency Shuttle has docked with the station.")
priority_announce("The Emergency Shuttle has docked with the station. You have [timeLeft(600)] minutes to board the Emergency Shuttle.", null, 'sound/AI/shuttledock.ogg', "Priority")
- SSblackbox.add_details("emergency_shuttle", src.name)
+ if(SSdbcore.Connect())
+ var/datum/DBQuery/query_round_shuttle_name = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET shuttle_name = '[name]' WHERE id = [GLOB.round_id]")
+ query_round_shuttle_name.Execute()
// Gangs only have one attempt left if the shuttle has
// docked with the station to prevent suffering from
diff --git a/code/world.dm b/code/world.dm
index df083571c4..dc71eed15f 100644
--- a/code/world.dm
+++ b/code/world.dm
@@ -56,13 +56,12 @@
/world/proc/SetRoundID()
if(config.sql_enabled)
if(SSdbcore.Connect())
- log_world("Database connection established.")
- var/datum/DBQuery/query_feedback_create_round = SSdbcore.NewQuery("INSERT INTO [format_table_name("feedback")] SELECT null, Now(), IFNULL(MAX(round_id),0)+1, \"server_ip\", 0, \"[world.internet_address]:[world.port]\" FROM [format_table_name("feedback")]")
- query_feedback_create_round.Execute()
- var/datum/DBQuery/query_feedback_max_id = SSdbcore.NewQuery("SELECT MAX(round_id) FROM [format_table_name("feedback")]")
- query_feedback_max_id.Execute()
- if(query_feedback_max_id.NextRow())
- GLOB.round_id = query_feedback_max_id.item[1]
+ var/datum/DBQuery/query_round_start = SSdbcore.NewQuery("INSERT INTO [format_table_name("round")] (start_datetime, server_ip, server_port) VALUES (Now(), INET_ATON('[world.internet_address]'), '[world.port]')")
+ query_round_start.Execute()
+ var/datum/DBQuery/query_round_last_id = SSdbcore.NewQuery("SELECT LAST_INSERT_ID()")
+ query_round_last_id.Execute()
+ if(query_round_last_id.NextRow())
+ GLOB.round_id = query_round_last_id.item[1]
else
log_world("Your server failed to establish a connection with the database.")
@@ -225,7 +224,7 @@
else
to_chat(world, "Rebooting world...")
Master.Shutdown() //run SS shutdowns
- log_world("World rebooted at [time_stamp()]");
+ log_world("World rebooted at [time_stamp()]")
..()
/world/proc/load_motd()