Tg port 2 15 (#230)

* defines/helpers

* globalvars, onclick, controllers

* datums and game

* woooooooooorld. Uh. dm

* modules sans mobs client admin

* modules/admin

* pref shit

* modules/mob

* icon updates

* extra things

* Cherrypicked fixes from open PRs

* metastation.tgm fix

* a better meta fix

* reverts async breakings
This commit is contained in:
Poojawa
2017-02-15 03:35:32 -06:00
committed by GitHub
parent fd3923d684
commit fc2dbcd9fe
192 changed files with 10451 additions and 160669 deletions
+3
View File
@@ -64,3 +64,6 @@
#define TIMER_CLIENT_TIME 0x4
//Timer can be stopped using deltimer()
#define TIMER_STOPPABLE 0x8
//To be used with TIMER_UNIQUE
//prevents distinguishing identical timers with the wait variable
#define TIMER_NO_HASH_WAIT 0x10
+2
View File
@@ -93,3 +93,5 @@ var/global/list/all_scripture = list() //a list containing scripture instances;
#define SIGIL_ACCESS_RANGE 2 //range at which transmission sigils can access power
#define PROSELYTIZER_REPAIR_PER_TICK 4 //how much a proselytizer repairs each tick, and also how many deciseconds each tick is
#define OCULAR_WARDEN_EXCLUSION_RANGE 3 //the range at which ocular wardens cannot be placed near other ocular wardens
+3
View File
@@ -19,6 +19,9 @@
#define WIRE_LAYER 2.4
#define WIRE_TERMINAL_LAYER 2.45
#define LOW_OBJ_LAYER 2.5
#define LOW_SIGIL_LAYER 2.52
#define SIGIL_LAYER 2.54
#define HIGH_SIGIL_LAYER 2.56
#define BELOW_OPEN_DOOR_LAYER 2.6
#define OPEN_DOOR_LAYER 2.7
+4 -1
View File
@@ -346,7 +346,7 @@ var/global/list/ghost_others_options = list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
//debug printing macros
#define debug_world(msg) if (Debug2) world << "DEBUG: [msg]"
#define debug_admins(msg) if (Debug2) admins << "DEBUG: [msg]"
#define debug_world_log(msg) if (Debug2) world.log << "DEBUG: [msg]"
#define debug_world_log(msg) if (Debug2) log_world("DEBUG: [msg]")
#define COORD(A) "([A.x],[A.y],[A.z])"
#define INCREMENT_TALLY(L, stat) if(L[stat]){L[stat]++}else{L[stat] = 1}
@@ -409,3 +409,6 @@ var/global/list/ghost_others_options = list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
#define TURF_DECAL_PAINT "paint"
#define TURF_DECAL_DAMAGE "damage"
#define TURF_DECAL_DIRT "dirt"
//Error handler defines
#define ERROR_USEFUL_LEN 2
+33 -4
View File
@@ -1,16 +1,18 @@
//print a warning message to world.log
#define WARNING(MSG) warning("[MSG] in [__FILE__] at line [__LINE__] src: [src] usr: [usr].")
/proc/warning(msg)
world.log << "## WARNING: [msg]"
msg = "## WARNING: [msg]"
log_world(msg)
//not an error or a warning, but worth to mention on the world log, just in case.
#define NOTICE(MSG) notice(MSG)
/proc/notice(msg)
world.log << "## NOTICE: [msg]"
msg = "## NOTICE: [msg]"
log_world(msg)
//print a testing-mode debug message to world.log and world
#ifdef TESTING
#define testing(msg) world.log << "## TESTING: [msg]"; world << "## TESTING: [msg]"
#define testing(msg) log_world("## TESTING: [msg]"); world << "## TESTING: [msg]"
#else
#define testing(msg)
#endif
@@ -79,4 +81,31 @@
/proc/log_chat(text)
if (config.log_pda)
diary << "\[[time_stamp()]]CHAT: [text]"
diary << "\[[time_stamp()]]CHAT: [text]"
//This replaces world.log so it displays both in DD and the file
/proc/log_world(text)
if(config && config.log_runtimes)
world.log = runtime_diary
world.log << text
world.log = null
world.log << text
// Helper procs for building detailed log lines
/proc/datum_info_line(datum/D)
if(!istype(D))
return
if(!istype(D, /mob))
return "[D] ([D.type])"
var/mob/M = D
return "[M] ([M.ckey]) ([M.type])"
/proc/atom_loc_line(atom/A)
if(!istype(A))
return
var/turf/T = get_turf(A)
if(istype(T))
return "[A.loc] [COORD(T)] ([A.loc.type])"
else if(A.loc)
return "[A.loc] (0, 0, 0) ([A.loc.type])"
+2 -2
View File
@@ -5,7 +5,7 @@
var/DBQuery/query = dbcon.NewQuery("SELECT DATEDIFF(Now(),'[y]-[m]-[d]')")
if(!query.Execute())
world.log << "SQL ERROR doing datediff. Error : \[[query.ErrorMsg()]\]\n"
log_world("SQL ERROR doing datediff. Error : \[[query.ErrorMsg()]\]\n")
return FALSE
if(query.NextRow())
@@ -24,7 +24,7 @@
/client/proc/findJoinDate()
var/http[] = world.Export("http://byond.com/members/[src.ckey]?format=text")
if(!http)
world.log << "Failed to connect to byond age check for [src.ckey]"
log_world("Failed to connect to byond age check for [src.ckey]")
return FALSE
var/F = file2text(http["CONTENT"])
+12 -6
View File
@@ -420,10 +420,12 @@
return new /datum/projectile_data(src_x, src_y, time, distance, power_x, power_y, dest_x, dest_y)
/proc/showCandidatePollWindow(mob/dead/observer/G, poll_time, Question, list/candidates, ignore_category, time_passed)
/proc/showCandidatePollWindow(mob/dead/observer/G, poll_time, Question, list/candidates, ignore_category, time_passed, flashwindow = TRUE)
set waitfor = 0
G << 'sound/misc/notice2.ogg' //Alerting them to their consideration
if(flashwindow)
window_flash(G.client)
switch(ignore_category ? askuser(G,Question,"Please answer in [poll_time/10] seconds!","Yes","No","Never for this round", StealFocus=0, Timeout=poll_time) : askuser(G,Question,"Please answer in [poll_time/10] seconds!","Yes","No", StealFocus=0, Timeout=poll_time))
if(1)
G << "<span class='notice'>Choice registered: Yes.</span>"
@@ -441,7 +443,7 @@
poll_ignore[ignore_category] += G.ckey
G << "<span class='danger'>Choice registered: Never for this round.</span>"
/proc/pollCandidates(var/Question, var/jobbanType, var/datum/game_mode/gametypeCheck, var/be_special_flag = 0, var/poll_time = 300, var/ignore_category = null)
/proc/pollCandidates(var/Question, var/jobbanType, var/datum/game_mode/gametypeCheck, var/be_special_flag = 0, var/poll_time = 300, var/ignore_category = null, flashwindow = TRUE)
var/list/mob/dead/observer/candidates = list()
var/time_passed = world.time
if (!Question)
@@ -460,7 +462,7 @@
if(jobban_isbanned(G, jobbanType) || jobban_isbanned(G, "Syndicate"))
continue
showCandidatePollWindow(G, poll_time, Question, candidates, ignore_category, time_passed)
showCandidatePollWindow(G, poll_time, Question, candidates, ignore_category, time_passed, flashwindow)
sleep(poll_time)
//Check all our candidates, to make sure they didn't log off during the wait period.
@@ -507,7 +509,11 @@
if(M && !isnewplayer(M))
M << thing
/proc/window_flash(var/client_or_usr)
if (!client_or_usr)
/proc/window_flash(client/C, ignorepref = FALSE)
if(ismob(C))
var/mob/M = C
if(M.client)
C = M.client
if(!C || (!C.prefs.windowflashing && !ignorepref))
return
winset(client_or_usr, "mainwindow", "flash=5")
winset(C, "mainwindow", "flash=5")
+1 -1
View File
@@ -1,6 +1,6 @@
//Returns the world time in english
/proc/worldtime2text()
return gameTimestamp("hh:mm")
return gameTimestamp("hh:mm:ss")
/proc/time_stamp(format = "hh:mm:ss")
return time2text(world.timeofday, format)
+1
View File
@@ -2,5 +2,6 @@
#define POLL_IGNORE_PAI "pai"
#define POLL_IGNORE_SENTIENCE_POTION "sentience_potion"
#define POLL_IGNORE_POSSESSED_BLADE "possessed_blade"
var/list/poll_ignore = list()
+1
View File
@@ -1,4 +1,5 @@
var/diary = null
var/runtime_diary = null
var/diaryofmeanpeople = null
var/href_logfile = null
+1 -1
View File
@@ -187,4 +187,4 @@
//
/mob/living/silicon/ai/TurfAdjacent(var/turf/T)
return (cameranet && cameranet.checkTurfVis(T))
return (cameranet && cameranet.checkTurfVis(T))
+26 -10
View File
@@ -42,6 +42,7 @@
var/log_hrefs = 0 // log all links clicked in-game. Could be used for debugging and tracking down exploits
var/log_twitter = 0 // log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases.
var/log_world_topic = 0 // log all world.Topic() calls
var/log_runtimes = FALSE // log runtimes into a file
var/sql_enabled = 0 // for sql switching
var/allow_admin_ooccolor = 0 // Allows admins with relevant permissions to have their own ooc colour
var/allow_vote_restart = 0 // allow votes to restart
@@ -92,14 +93,6 @@
var/ipintel_save_bad = 1
var/ipintel_domain = "check.getipintel.net"
var/mentors_mobname_only = 0 // Only display mob name to mentors in mentorhelps
var/mentor_legacy_system = 0 // Whether to use the legacy mentor system (flat file) instead of SQL
// Discord crap.
var/discord_url = "hfdksjhfa.com"
var/discord_password
var/announce_watchlist = 0
var/announce_adminhelps = 0
var/admin_legacy_system = 0 //Defines whether the server uses the legacy admin system with admins.txt or the SQL system. Config option in config.txt
var/ban_legacy_system = 0 //Defines whether the server uses the legacy banning system with the files in /data or the SQL system. Config option in config.txt
var/use_age_restriction_for_jobs = 0 //Do jobs use account age restrictions? --requires database
@@ -249,6 +242,20 @@
var/minutetopiclimit
var/secondtopiclimit
var/error_cooldown = 600 // The "cooldown" time for each occurrence of a unique error
var/error_limit = 50 // How many occurrences before the next will silence them
var/error_silence_time = 6000 // How long a unique error will be silenced for
var/error_msg_delay = 50 // How long to wait between messaging admins about occurrences of a unique error
var/mentors_mobname_only = 0 // Only display mob name to mentors in mentorhelps
var/mentor_legacy_system = 0 // Whether to use the legacy mentor system (flat file) instead of SQL
// Discord crap.
var/discord_url = "hfdksjhfa.com"
var/discord_password
var/announce_watchlist = 0
var/announce_adminhelps = 0
/datum/configuration/New()
gamemode_cache = typecacheof(/datum/game_mode,TRUE)
for(var/T in gamemode_cache)
@@ -467,10 +474,11 @@
if("aggressive_changelog")
config.aggressive_changelog = 1
if("log_runtimes")
log_runtimes = TRUE
var/newlog = file("data/logs/runtimes/runtime-[time2text(world.realtime, "YYYY-MM-DD")].log")
if (world.log != newlog)
if(runtime_diary != newlog)
world.log << "Now logging runtimes to data/logs/runtimes/runtime-[time2text(world.realtime, "YYYY-MM-DD")].log"
world.log = newlog
runtime_diary = newlog
if("autoconvert_notes")
config.autoconvert_notes = 1
if("allow_webclient")
@@ -503,6 +511,14 @@
config.minutetopiclimit = text2num(value)
if("second_topic_limit")
config.secondtopiclimit = text2num(value)
if("error_cooldown")
error_cooldown = text2num(value)
if("error_limit")
error_limit = text2num(value)
if("error_silence_time")
error_silence_time = text2num(value)
if("error_msg_delay")
error_msg_delay = text2num(value)
if("announce_adminhelps")
config.announce_adminhelps = 1
if("discord_url")
+14 -14
View File
@@ -104,7 +104,7 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
msg += "\t [varname] = [D]([D.type])\n"
else
msg += "\t [varname] = [varval]\n"
world.log << msg
log_world(msg)
if (istype(Master.subsystems))
subsystems = Master.subsystems
StartProcessing(10)
@@ -139,7 +139,7 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
world << "<span class='boldannounce'>Initializations complete!</span>"
world.log << "Initializations complete."
log_world("Initializations complete.")
// Sort subsystems by display setting for easy access.
sortTim(subsystems, /proc/cmp_subsystem_display)
@@ -267,7 +267,7 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
subsystems_to_check = tickersubsystems
if (CheckQueue(subsystems_to_check) <= 0)
if (!SoftReset(tickersubsystems, normalsubsystems, lobbysubsystems))
world.log << "MC: SoftReset() failed, crashing"
log_world("MC: SoftReset() failed, crashing")
return
if (!error_level)
iteration++
@@ -279,7 +279,7 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
if (queue_head)
if (RunQueue() <= 0)
if (!SoftReset(tickersubsystems, normalsubsystems, lobbysubsystems))
world.log << "MC: SoftReset() failed, crashing"
log_world("MC: SoftReset() failed, crashing")
return
if (!error_level)
iteration++
@@ -451,9 +451,9 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
// called if any mc's queue procs runtime or exit improperly.
/datum/controller/master/proc/SoftReset(list/ticker_SS, list/normal_SS, list/lobby_SS)
. = 0
world.log << "MC: SoftReset called, resetting MC queue state."
log_world("MC: SoftReset called, resetting MC queue state.")
if (!istype(subsystems) || !istype(ticker_SS) || !istype(normal_SS) || !istype(lobby_SS))
world.log << "MC: SoftReset: Bad list contents: '[subsystems]' '[ticker_SS]' '[normal_SS]' '[lobby_SS]' Crashing!"
log_world("MC: SoftReset: Bad list contents: '[subsystems]' '[ticker_SS]' '[normal_SS]' '[lobby_SS]' Crashing!")
return
var/subsystemstocheck = subsystems + ticker_SS + normal_SS + lobby_SS
@@ -465,26 +465,26 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
ticker_SS -= list(SS)
normal_SS -= list(SS)
lobby_SS -= list(SS)
world.log << "MC: SoftReset: Found bad entry in subsystem list, '[SS]'"
log_world("MC: SoftReset: Found bad entry in subsystem list, '[SS]'")
continue
if (SS.queue_next && !istype(SS.queue_next))
world.log << "MC: SoftReset: Found bad data in subsystem queue, queue_next = '[SS.queue_next]'"
log_world("MC: SoftReset: Found bad data in subsystem queue, queue_next = '[SS.queue_next]'")
SS.queue_next = null
if (SS.queue_prev && !istype(SS.queue_prev))
world.log << "MC: SoftReset: Found bad data in subsystem queue, queue_prev = '[SS.queue_prev]'"
log_world("MC: SoftReset: Found bad data in subsystem queue, queue_prev = '[SS.queue_prev]'")
SS.queue_prev = null
SS.queued_priority = 0
SS.queued_time = 0
SS.state = SS_IDLE
if (queue_head && !istype(queue_head))
world.log << "MC: SoftReset: Found bad data in subsystem queue, queue_head = '[queue_head]'"
log_world("MC: SoftReset: Found bad data in subsystem queue, queue_head = '[queue_head]'")
queue_head = null
if (queue_tail && !istype(queue_tail))
world.log << "MC: SoftReset: Found bad data in subsystem queue, queue_tail = '[queue_tail]'"
log_world("MC: SoftReset: Found bad data in subsystem queue, queue_tail = '[queue_tail]'")
queue_tail = null
queue_priority_count = 0
queue_priority_count_bg = 0
world.log << "MC: SoftReset: Finished."
log_world("MC: SoftReset: Finished.")
. = 1
@@ -493,6 +493,6 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
if(!statclick)
statclick = new/obj/effect/statclick/debug("Initializing...", src)
stat("Master Controller:", statclick.update("(TickRate:[Master.processing]) (TickDrift:[round(Master.tickdrift)]) (Iteration:[Master.iteration])"))
stat("Byond:", "(FPS:[world.fps]) (TickCount:[world.time/world.tick_lag]) (TickDrift:[round(Master.tickdrift,1)]([round((Master.tickdrift/(world.time/world.tick_lag))*100,0.1)]%))")
stat("Master Controller:", statclick.update("(TickRate:[Master.processing]) (Iteration:[Master.iteration])"))
+1 -1
View File
@@ -157,7 +157,7 @@
var/time = (world.timeofday - start_timeofday) / 10
var/msg = "Initialized [name] subsystem within [time] seconds!"
world << "<span class='boldannounce'>[msg]</span>"
world.log << msg
log_world(msg)
return time
//hook for printing stats to the "MC" statuspanel for admins to see performance and related stats etc.
+2 -3
View File
@@ -224,7 +224,7 @@ var/datum/subsystem/garbage_collector/SSgarbage
/datum/var/gc_destroyed //Time when this object was destroyed.
#ifdef TESTING
/datum/var/running_find_references
/datum/var/running_find_references
/datum/var/last_find_references = 0
/datum/verb/find_refs()
@@ -333,7 +333,7 @@ var/datum/subsystem/garbage_collector/SSgarbage
else
DoSearchVar(variable, "[Xname]: [varname]")
#endif
else if(islist(X))
else if(islist(X))
if(src in X)
testing("Found [src.type] \ref[src] in list [Xname].")
#ifdef GC_FAILURE_HARD_LOOKUP
@@ -347,7 +347,6 @@ var/datum/subsystem/garbage_collector/SSgarbage
//update this list using tools/DMTreeToGlobalsList
/datum/proc/find_references_in_globals()
SearchVar(last_irc_status)
SearchVar(inerror)
SearchVar(failed_db_connections)
SearchVar(nextmap)
SearchVar(mapchanging)
+2 -2
View File
@@ -374,10 +374,10 @@ var/datum/subsystem/job/SSjob
S = sloc
break
if(!S) //if there isn't a spawnpoint send them to latejoin, if there's no latejoin go yell at your mapper
world.log << "Couldn't find a round start spawn point for [rank]"
log_world("Couldn't find a round start spawn point for [rank]")
S = pick(latejoin)
if(!S) //final attempt, lets find some area in the arrivals shuttle to spawn them in to.
world.log << "Couldn't find a round start latejoin spawn point."
log_world("Couldn't find a round start latejoin spawn point.")
for(var/turf/T in get_area_turfs(/area/shuttle/arrival))
if(!T.density)
var/clear = 1
+1 -1
View File
@@ -116,4 +116,4 @@ var/datum/subsystem/lighting/SSlighting
varval1 = "/list([length(varval1)])"
varval2 = "/list([length(varval2)])"
msg += "\t [varname] = [varval1] -> [varval2]\n"
world.log << msg
log_world(msg)
+1 -1
View File
@@ -45,7 +45,7 @@ var/datum/subsystem/minimap/SSminimap
for(var/z in z_levels)
if(!fexists(file(map_path(z,backup)))) //Let's make sure we have a file for this map
if(backup)
world.log << "Failed to find backup file for map [MAP_NAME] on zlevel [z]."
log_world("Failed to find backup file for map [MAP_NAME] on zlevel [z].")
return FALSE
return TRUE
+9 -8
View File
@@ -77,7 +77,7 @@ var/datum/subsystem/ticker/ticker
world << "Please set up your character and select \"Ready\". The game will start in [config.lobby_countdown] seconds."
current_state = GAME_STATE_PREGAME
for(var/client/C in clients)
window_flash(C) //let them know lobby has opened up.
window_flash(C, ignorepref = TRUE) //let them know lobby has opened up.
if(GAME_STATE_PREGAME)
//lobby stats for statpanels
@@ -106,6 +106,8 @@ var/datum/subsystem/ticker/ticker
if(timeLeft <= 0)
current_state = GAME_STATE_SETTING_UP
if(start_immediately)
fire()
if(GAME_STATE_SETTING_UP)
if(!setup())
@@ -212,11 +214,11 @@ var/datum/subsystem/ticker/ticker
//Deleting Startpoints but we need the ai point to AI-ize people later
if(S.name != "AI")
qdel(S)
/*
var/list/adm = get_admin_counts()
if(!adm["present"])
send2irc("Server", "Round just started with no active admins online!")
*/
var/list/allmins = adm["present"]
send2irc("Server", "Round of [hide_mode ? "secret":"[mode.name]"] has started[allmins.len ? ".":" with no active admins online!"]")
/datum/subsystem/ticker/proc/station_explosion_detonation(atom/bomb)
if(bomb) //BOOM
var/turf/epi = bomb.loc
@@ -554,7 +556,7 @@ var/datum/subsystem/ticker/ticker
for(var/path in SSgarbage.didntgc)
dellog += "Path : [path] \n"
dellog += "Failures : [SSgarbage.didntgc[path]] \n"
world.log << dellog
log_world(dellog)
CHECK_TICK
@@ -663,7 +665,6 @@ var/datum/subsystem/ticker/ticker
modevoted = ticker.modevoted
/datum/subsystem/ticker/proc/send_news_report()
var/news_message
var/news_source = "Nanotrasen News Network"
@@ -714,4 +715,4 @@ var/datum/subsystem/ticker/ticker
news_message = "During routine evacuation procedures, the emergency shuttle of [station_name()] had its navigation protocols corrupted and went off course, but was recovered shortly after."
if(news_message)
send2irc(news_source, news_message,"News_Report")
send2otherserver(news_source, news_message,"News_Report")
@@ -0,0 +1,43 @@
var/datum/subsystem/time_track/SStime_track
/datum/subsystem/time_track
name = "Time Tracking"
wait = 600
flags = SS_NO_INIT|SS_FIRE_IN_LOBBY
var/time_dilation_current = 0
var/time_dilation_avg_fast = 0
var/time_dilation_avg = 0
var/time_dilation_avg_slow = 0
var/first_run = TRUE
var/last_tick_realtime = 0
var/last_tick_byond_time = 0
var/last_tick_tickcount = 0
/datum/subsystem/time_track/New()
NEW_SS_GLOBAL(SStime_track)
/datum/subsystem/time_track/fire()
var/current_realtime = REALTIMEOFDAY
var/current_byondtime = world.time
var/current_tickcount = world.time/world.tick_lag
if (!first_run)
var/tick_drift = max(0, (((current_realtime - last_tick_realtime) - (current_byondtime - last_tick_byond_time)) / world.tick_lag))
time_dilation_current = tick_drift / (current_tickcount - last_tick_tickcount) * 100
time_dilation_avg_fast = MC_AVERAGE_FAST(time_dilation_avg_fast, time_dilation_current)
time_dilation_avg = MC_AVERAGE(time_dilation_avg, time_dilation_avg_fast)
time_dilation_avg_slow = MC_AVERAGE_SLOW(time_dilation_avg_slow, time_dilation_avg)
else
first_run = FALSE
last_tick_realtime = current_realtime
last_tick_byond_time = current_byondtime
last_tick_tickcount = current_tickcount
+6 -2
View File
@@ -299,7 +299,11 @@ proc/addtimer(datum/callback/callback, wait, flags)
var/hash
if (flags & TIMER_UNIQUE)
var/list/hashlist = list(callback.object, "(\ref[callback.object])", callback.delegate, wait, flags & TIMER_CLIENT_TIME)
var/list/hashlist
if(flags & TIMER_NO_HASH_WAIT)
hashlist = list(callback.object, "(\ref[callback.object])", callback.delegate, flags & TIMER_CLIENT_TIME)
else
hashlist = list(callback.object, "(\ref[callback.object])", callback.delegate, wait, flags & TIMER_CLIENT_TIME)
hashlist += callback.arguments
hash = hashlist.Join("|||||||")
@@ -341,4 +345,4 @@ proc/addtimer(datum/callback/callback, wait, flags)
#undef BUCKET_LEN
#undef BUCKET_POS
#undef BUCKET_POS
+5 -2
View File
@@ -76,7 +76,10 @@
A.can_be_carded = FALSE
A.requires_power = POWER_REQ_CLOCKCULT
A.languages_spoken &= ~HUMAN
A.add_atom_colour(list("#B18B25", "#92661A", "#6D370F", rgb(0,0,0)), ADMIN_COLOUR_PRIORITY)
var/list/AI_frame = list(image('icons/mob/clockwork_mobs.dmi', A, "aiframe")) //make the AI's cool frame
for(var/d in cardinal)
AI_frame += image('icons/mob/clockwork_mobs.dmi', A, "eye[rand(1, 10)]", dir = d) //the eyes are randomly fast or slow
A.add_overlay(AI_frame)
if(!A.lacks_power())
A.ai_restore_power()
if(A.eyeobj)
@@ -128,7 +131,7 @@
A.can_be_carded = initial(A.can_be_carded)
A.requires_power = initial(A.requires_power)
A.languages_spoken |= HUMAN
A.remove_atom_colour(ADMIN_COLOUR_PRIORITY, list("#B18B25", "#92661A", "#6D370F", rgb(0,0,0)))
A.cut_overlays()
S.make_laws()
S.update_icons()
S.show_laws()
+5 -5
View File
@@ -629,7 +629,7 @@
if (prompt != "Yes")
return
L.Cut(index, index+1)
world.log << "### ListVarEdit by [src]: /list's contents: REMOVED=[html_encode("[variable]")]"
log_world("### ListVarEdit by [src]: /list's contents: REMOVED=[html_encode("[variable]")]")
log_admin("[key_name(src)] modified list's contents: REMOVED=[variable]")
message_admins("[key_name_admin(src)] modified list's contents: REMOVED=[variable]")
@@ -648,7 +648,7 @@
return
uniqueList_inplace(L)
world.log << "### ListVarEdit by [src]: /list contents: CLEAR DUPES"
log_world("### ListVarEdit by [src]: /list contents: CLEAR DUPES")
log_admin("[key_name(src)] modified list's contents: CLEAR DUPES")
message_admins("[key_name_admin(src)] modified list's contents: CLEAR DUPES")
@@ -659,7 +659,7 @@
return
listclearnulls(L)
world.log << "### ListVarEdit by [src]: /list contents: CLEAR NULLS"
log_world("### ListVarEdit by [src]: /list contents: CLEAR NULLS")
log_admin("[key_name(src)] modified list's contents: CLEAR NULLS")
message_admins("[key_name_admin(src)] modified list's contents: CLEAR NULLS")
@@ -673,7 +673,7 @@
return
L.len = value["value"]
world.log << "### ListVarEdit by [src]: /list len: [L.len]"
log_world("### ListVarEdit by [src]: /list len: [L.len]")
log_admin("[key_name(src)] modified list's len: [L.len]")
message_admins("[key_name_admin(src)] modified list's len: [L.len]")
@@ -684,7 +684,7 @@
return
shuffle_inplace(L)
world.log << "### ListVarEdit by [src]: /list contents: SHUFFLE"
log_world("### ListVarEdit by [src]: /list contents: SHUFFLE")
log_admin("[key_name(src)] modified list's contents: SHUFFLE")
message_admins("[key_name_admin(src)] modified list's contents: SHUFFLE")
+8 -8
View File
@@ -19,17 +19,17 @@ var/global/datum/getrev/revdata = new()
parentcommit = head_log.group[1]
date = unix2date(text2num(head_log.group[2]))
commit = head_log.group[4]
world.log << "Running /tg/ revision:"
world.log << "[date]"
log_world("Running /tg/ revision:")
log_world("[date]")
if(testmerge.len)
world.log << commit
log_world(commit)
for(var/line in testmerge)
if(line)
world.log << "Test merge active of PR #[line]"
world.log << "Based off master commit [parentcommit]"
log_world("Test merge active of PR #[line]")
log_world("Based off master commit [parentcommit]")
else
world.log << parentcommit
world.log << "Current map - [MAP_NAME]" //can't think of anywhere better to put it
log_world(parentcommit)
log_world("Current map - [MAP_NAME]") //can't think of anywhere better to put it
/client/verb/showrevinfo()
set category = "OOC"
@@ -75,7 +75,7 @@ var/global/datum/getrev/revdata = new()
if(config.probabilities[ctag] > 0)
var/percentage = round(config.probabilities[ctag] / prob_sum * 100, 0.1)
src << "[ctag] [percentage]%"
src <<"<b>All Game Mode Odds:</b>"
var/sum = 0
for(var/ctag in config.probabilities)
+1 -1
View File
@@ -75,7 +75,7 @@
. = file(mappath)
if(!.)
world.log << "The file of [src] appears to be empty/non-existent."
log_world("The file of [src] appears to be empty/non-existent.")
/datum/map_template/proc/get_affected_turfs(turf/T, centered = FALSE)
var/turf/placement = T
+12 -1
View File
@@ -45,6 +45,10 @@
admin_notes = "No brig, no medical facilities, no air."
credit_cost = -7500
/datum/map_template/shuttle/emergency/airless/prerequisites_met()
// first 10 minutes only
return world.time - round_start_time < 6000
/datum/map_template/shuttle/emergency/asteroid
suffix = "asteroid"
name = "Asteroid Station Emergency Shuttle"
@@ -59,6 +63,13 @@
Has medical facilities."
credit_cost = 5000
/datum/map_template/shuttle/emergency/russiafightpit
suffix = "russiafightpit"
name = "Mother Russia Bleeds"
description = "Dis is a high-quality shuttle, da. Many seats, lots of space, all equipment! Even includes entertainment! Such as lots to drink, and a fighting arena for drunk crew to have fun! If arena not fun enough, simply press button of releasing bears. Do not worry, bears trained not to break out of fighting pit, so totally safe so long as nobody stupid or drunk enough to leave door open. Try not to let asimov babycons ruin fun!"
admin_notes = "Includes a small variety of weapons. And bears. Only captain-access can release the bears. Bears won't smash the windows themselves, but they can escape if someone lets them."
credit_cost = 5000 // While the shuttle is rusted and poorly maintained, trained bears are costly.
/datum/map_template/shuttle/emergency/meteor
suffix = "meteor"
name = "An Asteroid With Engines Strapped To It"
@@ -231,4 +242,4 @@
name = "Delta Station Emergency Shuttle"
description = "A large shuttle for a large station, this shuttle can comfortably fit all your overpopulation and crowding needs. Complete with all facilities plus additional equipment."
admin_notes = "Go big or go home."
credit_cost = 7500
credit_cost = 7500
+2 -2
View File
@@ -4,10 +4,10 @@
/area/CATEGORY/OR/DESCRIPTOR/NAME (you can make as many subdivisions as you want)
name = "NICE NAME" (not required but makes things really nice)
icon = "ICON FILENAME" (defaults to areas.dmi)
icon = 'ICON FILENAME' (defaults to 'icons/turf/areas.dmi')
icon_state = "NAME OF ICON" (defaults to "unknown" (blank))
requires_power = 0 (defaults to 1)
music = "music/music.ogg" (defaults to "music/music.ogg")
music = null (defaults to nothing, look in sound/ambience for music)
NOTE: there are two lists of areas in the end of this file: centcom and station itself. Please maintain these lists valid. --rastaf0
+6 -6
View File
@@ -126,32 +126,32 @@
/area/awaymission/centcomAway/general
name = "XCC-P5831"
music = "music/ambigen3.ogg"
music = 'sound/ambience/ambigen3.ogg'
/area/awaymission/centcomAway/maint
name = "XCC-P5831 Maintenance"
icon_state = "away1"
music = "music/ambisin1.ogg"
music = 'sound/ambience/ambisin1.ogg'
/area/awaymission/centcomAway/thunderdome
name = "XCC-P5831 Thunderdome"
icon_state = "away2"
music = "music/ambisin2.ogg"
music = 'sound/ambience/ambisin2.ogg'
/area/awaymission/centcomAway/cafe
name = "XCC-P5831 Kitchen Arena"
icon_state = "away3"
music = "music/ambisin3.ogg"
music = 'sound/ambience/ambisin3.ogg'
/area/awaymission/centcomAway/courtroom
name = "XCC-P5831 Courtroom"
icon_state = "away4"
music = "music/ambisin4.ogg"
music = 'sound/ambience/ambisin4.ogg'
/area/awaymission/centcomAway/hangar
name = "XCC-P5831 Hangars"
icon_state = "away4"
music = "music/ambigen5.ogg"
music = 'sound/ambience/ambigen5.ogg'
/*Cabin areas*/
-1
View File
@@ -5,7 +5,6 @@
//icon = "ICON FILENAME"
//icon_state = "NAME OF ICON"
requires_power = 0
music = "music/music.ogg"
/area/hell/trial1
name = "Hell Trial1"
+17 -5
View File
@@ -24,6 +24,7 @@
glide_size = 8
appearance_flags = TILE_BOUND
var/datum/forced_movement/force_moving = null //handled soley by forced_movement.dm
var/floating = FALSE
/atom/movable/SDQL_update(const/var_name, new_value)
if(var_name == "step_x" || var_name == "step_y" || var_name == "step_size" || var_name == "bound_x" || var_name == "bound_y" || var_name == "bound_width" || var_name == "bound_height")
@@ -140,7 +141,6 @@
if(destination)
if(pulledby)
pulledby.stop_pulling()
var/atom/oldloc = loc
var/same_loc = oldloc == destination
var/area/old_area = get_area(oldloc)
@@ -158,10 +158,10 @@
if(destarea && old_area != destarea)
destarea.Entered(src, oldloc)
for(var/atom/movable/AM in destination)
if(AM == src)
continue
AM.Crossed(src)
for(var/atom/movable/AM in destination)
if(AM == src)
continue
AM.Crossed(src)
Moved(oldloc, 0)
return 1
@@ -418,3 +418,15 @@
return FALSE
acted_explosions += ex_id
return TRUE
/atom/movable/proc/float(on)
if(throwing)
return
if(on && !floating)
animate(src, pixel_y = pixel_y + 2, time = 10, loop = -1)
sleep(10)
animate(src, pixel_y = pixel_y - 2, time = 10, loop = -1)
floating = TRUE
else if (!on && floating)
animate(src, pixel_y = initial(pixel_y), time = 10)
floating = FALSE
@@ -51,8 +51,10 @@
name = "dull sigil"
desc = "A dull, barely-visible golden sigil. It's as though light was carved into the ground."
icon = 'icons/effects/clockwork_effects.dmi'
clockwork_desc = "A sigil that will stun the first non-servant to cross it. Nar-Sie's dogs will be knocked down."
clockwork_desc = "A sigil that will stun the next non-Servant to cross it."
icon_state = "sigildull"
layer = HIGH_SIGIL_LAYER
alpha = 60
color = "#FAE48C"
sigil_name = "Sigil of Transgression"
@@ -78,8 +80,9 @@
desc = "A luminous golden sigil. Something about it really bothers you."
clockwork_desc = "A sigil that will enslave the first person to cross it, provided they remain on it for seven seconds."
icon_state = "sigilsubmission"
color = "#FAE48C"
layer = LOW_SIGIL_LAYER
alpha = 125
color = "#FAE48C"
stat_affected = UNCONSCIOUS
resist_string = "glows faintly yellow"
var/convert_time = 70
@@ -148,8 +151,8 @@
clockwork_desc = "A sigil that will enslave any person who crosses it, provided they remain on it for seven seconds. \n\
It can convert a mindshielded target once before disppearing, but can convert any number of non-implanted targets."
icon_state = "sigiltransgression"
color = "#A97F1B"
alpha = 200
color = "#A97F1B"
glow_light = 4 //bright light
glow_falloff = 3
delete_on_finish = FALSE
@@ -172,8 +175,8 @@
desc = "A glowing orange sigil. The air around it feels staticky."
clockwork_desc = "A sigil that will serve as a battery for clockwork structures."
icon_state = "sigiltransmission"
color = "#EC8A2D"
alpha = 50
color = "#EC8A2D"
resist_string = "glows faintly"
sigil_name = "Sigil of Transmission"
affects_servants = TRUE
@@ -189,7 +192,11 @@
/obj/effect/clockwork/sigil/transmission/examine(mob/user)
..()
if(is_servant_of_ratvar(user) || isobserver(user))
user << "<span class='[power_charge ? "brass":"alloy"]'>It is storing <b>[ratvar_awakens ? "INFINITY":"[power_charge]"]W</b> of power.</span>"
var/structure_number = 0
for(var/obj/structure/destructible/clockwork/powered/P in range(SIGIL_ACCESS_RANGE, src))
structure_number++
user << "<span class='[power_charge ? "brass":"alloy"]'>It is storing <b>[ratvar_awakens ? "INFINITY":"[power_charge]"]W</b> of power, \
and <b>[structure_number]</b> Clockwork Structure[structure_number == 1 ? "":"s"] [structure_number == 1 ? "is":"are"] in range.</span>"
if(iscyborg(user))
user << "<span class='brass'>You can recharge from the [sigil_name] by crossing it.</span>"
@@ -264,8 +271,9 @@
desc = "A faint blue sigil. Looking at it makes you feel protected."
clockwork_desc = "A sigil that will drain non-Servants that remain on it. Servants that remain on it will be healed if it has any vitality drained."
icon_state = "sigilvitality"
color = "#123456"
layer = SIGIL_LAYER
alpha = 75
color = "#123456"
affects_servants = TRUE
stat_affected = DEAD
resist_string = "glows shimmering yellow"
@@ -27,7 +27,7 @@
name = "Nezbere, the Brass Eidolon"
desc = "A towering colossus clad in nigh-impenetrable brass armor. Its gaze is stern yet benevolent, even upon you."
clockwork_desc = "One of Ratvar's four generals. Nezbere is responsible for the design, testing, and creation of everything in Ratvar's domain, and his loyalty to Ratvar knows no bounds. \
It is said that Ratvar once asked him to destroy the plans for a weapon Nezbere had made that could have harmed him and Nezbere responded by not only destroying the plans, \
It is said that Ratvar once asked him to destroy the plans for a weapon Nezbere had made that could have harmed him, and Nezbere responded by not only destroying the plans, \
but by taking his own life so that the device could never be replicated. Nezbere's zealotry is unmatched."
icon = 'icons/effects/340x428.dmi'
icon_state = "nezbere"
@@ -47,7 +47,7 @@
/obj/effect/clockwork/general_marker/nzcrentr
name = "Nzcrentr, the Eternal Thunderbolt"
desc = "A terrifying spiked construct crackling with limitless energy."
desc = "A terrifying spiked construct crackling with perpetual lightning."
clockwork_desc = "One of Ratvar's four generals. Before becoming one of Ratvar's generals, Nzcrentr sook out any and all sentient life to slaughter it for sport. \
Nzcrentr was coerced by Ratvar into entering a shell constructed by Nezbere, ostensibly made to grant Nzcrentr more power. In reality, the shell was made to trap and control it. \
Nzcrentr now serves loyally, though even one of Nezbere's finest creations was not enough to totally eliminate its will."
@@ -44,12 +44,14 @@
if((!clockcult_user || !is_servant_of_ratvar(src)) && cell && cell.charge)
. = min(cell.charge, 250)
cell.use(.)
src << "<span class='userdanger'>ERROR: Power loss detected!</span>"
if(prob(20))
src << "<span class='userdanger'>ERROR: Power loss detected!</span>"
spark_system.start()
/obj/mecha/power_drain(clockcult_user)
if((!clockcult_user || !occupant || occupant && !is_servant_of_ratvar(occupant)) && cell && cell.charge)
. = min(cell.charge, 250)
cell.use(.)
occupant_message("<span class='userdanger'>Power loss detected!</span>")
if(prob(20))
occupant_message("<span class='userdanger'>Power loss detected!</span>")
spark_system.start()
@@ -45,6 +45,15 @@
servant_of_ratvar_messages = list("The eye flickers before falling dark." = FALSE, "You feel watched." = FALSE, "\"...\"" = FALSE)
w_class = WEIGHT_CLASS_NORMAL
/obj/item/clockwork/component/belligerent_eye/lens_gem
name = "lens gem"
desc = "A tiny pinkish gem. It catches the light oddly, almost glowing."
clockwork_desc = "The gem from an interdiction lens. <b>Serviceable as a substitute for a belligerent eye.</b>"
icon_state = "lens_gem"
cultist_message = "The gem turns black and cold for a moment before its normal glow returns."
servant_of_ratvar_messages = list("\"Disgusting failure.\"" = TRUE, "You feel scrutinized." = FALSE, "\"Weaklings.\"" = TRUE, "\"Pathetic defenses.\"" = TRUE)
w_class = WEIGHT_CLASS_TINY
/obj/item/clockwork/component/vanguard_cogwheel
name = "vanguard cogwheel"
desc = "A sturdy brass cog with a faintly glowing blue gem in its center."
@@ -54,14 +63,14 @@
servant_of_ratvar_messages = list("\"Be safe, child.\"" = FALSE, "You feel unexplainably comforted." = FALSE, "\"Never forget: Pain is temporary. What you do for the Justiciar is eternal.\"" = FALSE)
message_span = "inathneq"
/obj/item/clockwork/component/vanguard_cogwheel/pinion_lock
name = "pinion lock"
desc = "A dented and scratched gear. It's very heavy."
clockwork_desc = "A broken gear lock for pinion airlocks. <b>Serviceable as a substitute for a vanguard cogwheel.</b>"
icon_state = "pinion_lock"
cultist_message = "The gear grows warm in your hands."
servant_of_ratvar_messages = list("The lock isn't getting any lighter." = FALSE, "\"Damaged gears are better than broken bodies.\"" = TRUE, \
"\"It's a shame it can't be reused.\"" = TRUE)
/obj/item/clockwork/component/vanguard_cogwheel/onyx_prism
name = "onyx prism"
desc = "An onyx prism with a small aperture. It's very heavy."
clockwork_desc = "A broken prism from a mending motor. <b>Serviceable as a substitute for a vanguard cogwheel.</b>"
icon_state = "onyx_prism"
cultist_message = "The prism grows painfully hot in your hands."
servant_of_ratvar_messages = list("The prism isn't getting any lighter." = FALSE, "\"So... you haven't failed yet. Have hope, child.\"" = TRUE, \
"\"Better these machines break than you do.\"" = TRUE)
w_class = WEIGHT_CLASS_NORMAL
/obj/item/clockwork/component/geis_capacitor
@@ -74,6 +83,15 @@
"\"The fact that Ratvar has to depend on simpletons like you is appalling.\"" = FALSE)
message_span = "sevtug"
/obj/item/clockwork/component/geis_capacitor/fallen_armor
name = "fallen armor"
desc = "Lifeless chunks of armor. They're designed in a strange way and won't fit on you."
clockwork_desc = "The armor from a former clockwork marauder. <b>Serviceable as a substitute for a geis capacitor.</b>"
icon_state = "fallen_armor"
cultist_message = "Red flame sputters from the mask's eye before winking out."
servant_of_ratvar_messages = list("A piece of armor hovers away from the others for a moment." = FALSE, "Red flame appears in the cuirass before sputtering out." = FALSE)
w_class = WEIGHT_CLASS_NORMAL
/obj/item/clockwork/component/geis_capacitor/antennae
name = "mania motor antennae"
desc = "A pair of dented and bent antennae. They constantly emit a static hiss."
@@ -100,17 +118,16 @@
icon_state = "smashed_anime_fragment"
cultist_message = "The shards vibrate in your hands for a moment."
servant_of_ratvar_messages = list("\"...still fight...\"" = FALSE, "\"...where am I...?\"" = FALSE, "\"...put me... slab...\"" = FALSE)
message_span = "heavy_brass"
w_class = WEIGHT_CLASS_NORMAL
/obj/item/clockwork/component/replicant_alloy/fallen_armor
name = "fallen armor"
desc = "Lifeless chunks of armor. They're designed in a strange way and won't fit on you."
clockwork_desc = "The armor from a former clockwork marauder. <b>Serviceable as a substitute for replicant alloy.</b>"
icon_state = "fallen_armor"
cultist_message = "Red flame sputters from the mask's eye before winking out."
servant_of_ratvar_messages = list("A piece of armor hovers away from the others for a moment." = FALSE, "Red flame appears in the cuirass before sputtering out." = FALSE)
message_span = "heavy_brass"
/obj/item/clockwork/component/replicant_alloy/replication_plate
name = "replication plate"
desc = "A flat, heavy disc of metal with a triangular formation on its surface."
clockwork_desc = "The replication plate from a tinkerer's daemon. <b>Serviceable as a substitute for replicant alloy.</b>"
icon_state = "replication_plate"
cultist_message = "The plate shudders in your hands, as though trying to get away."
servant_of_ratvar_messages = list("\"Put this in a slab and get back to work.\"" = FALSE, "\"Worse servants than you have held these.\"" = TRUE, \
"\"It would be wise to protect these better, friend.\"" = TRUE)
w_class = WEIGHT_CLASS_NORMAL
/obj/item/clockwork/component/hierophant_ansible
@@ -183,3 +200,9 @@
randomsinglesprite = TRUE
randomspritemax = 3
icon_state = "shard_small"
/obj/item/clockwork/alloy_shards/pinion_lock
name = "pinion lock"
desc = "A dented and scratched gear. It's very heavy."
clockwork_desc = "A broken gear lock for pinion airlocks. Can be proselytized for additional power."
icon_state = "pinion_lock"
@@ -304,8 +304,8 @@
for(var/mob/living/M in living_mob_list)
if(is_servant_of_ratvar(M) && (ishuman(M) || issilicon(M)))
servants++
if(servants > 5)
servants -= 5
if(servants > SCRIPT_SERVANT_REQ)
servants -= SCRIPT_SERVANT_REQ
production_time += min(SLAB_SERVANT_SLOWDOWN * servants, SLAB_SLOWDOWN_MAXIMUM)
var/production_text_addon = ""
if(production_time != SLAB_PRODUCTION_TIME+SLAB_SLOWDOWN_MAXIMUM)
@@ -54,6 +54,7 @@
/obj/item/device/mmi/posibrain/soul_vessel/attack(mob/living/target, mob/living/carbon/human/user)
if(!is_servant_of_ratvar(user) || !ishuman(target) || used || (brainmob && brainmob.key))
..()
return
if(is_servant_of_ratvar(target))
user << "<span class='nezbere'>\"It would be more wise to revive your allies, friend.\"</span>"
return
@@ -13,7 +13,7 @@
attack_sound = 'sound/weapons/bladeslice.ogg'
weather_immunities = list("lava")
movement_type = FLYING
loot = list(/obj/item/clockwork/component/replicant_alloy/fallen_armor)
loot = list(/obj/item/clockwork/component/geis_capacitor/fallen_armor)
var/true_name = "Meme Master 69" //Required to call forth the marauder
var/global/list/possible_true_names = list("Servant", "Warden", "Serf", "Page", "Usher", "Knave", "Vassal", "Escort")
var/mob/living/host //The mob that the marauder is living inside of
@@ -176,13 +176,13 @@
/datum/clockwork_scripture/create_object/sigil_of_transmission
descname = "Structure Battery"
name = "Sigil of Transmission"
desc = "Scribes a sigil beneath the invoker which stores power to power clockwork structures."
desc = "Places a sigil that stores energy to power clockwork structures."
invocations = list("Divinity...", "...power our creations!")
channel_time = 70
consumed_components = list(VANGUARD_COGWHEEL = 1, GEIS_CAPACITOR = 1, HIEROPHANT_ANSIBLE = 2)
whispered = TRUE
object_path = /obj/effect/clockwork/sigil/transmission
creator_message = "<span class='brass'>A sigil silently appears below you. It will automatically power clockwork structures adjecent to it.</span>"
creator_message = "<span class='brass'>A sigil silently appears below you. It will automatically power clockwork structures near it.</span>"
usage_tip = "Cyborgs can charge from this sigil by remaining over it for 5 seconds."
tier = SCRIPTURE_APPLICATION
one_per_tile = TRUE
@@ -194,7 +194,7 @@
//Interdiction Lens: Creates a powerful totem that disables radios and cameras and drains power into nearby sigils of transmission.
/datum/clockwork_scripture/create_object/interdiction_lens
descname = "Structure, Disables Machinery"
descname = "Structure, Area Sabotage, Power Generator"
name = "Interdiction Lens"
desc = "Creates a clockwork totem that sabotages nearby machinery and funnels drained power into nearby Sigils of Transmission or the area's APC."
invocations = list("May this totem...", "...shroud the false suns!")
@@ -216,14 +216,14 @@
//Mending Motor: Creates a prism that will quickly heal mechanical servants/clockwork structures and consume power or replicant alloy.
/datum/clockwork_scripture/create_object/mending_motor
descname = "Structure, Repairs Other Structures"
descname = "Powered Structure, Repairs Other Structures"
name = "Mending Motor"
desc = "Creates a mechanized prism that will rapidly repair damage to clockwork creatures, converted cyborgs, and clockwork structures. Requires power to function."
desc = "Creates a mechanized prism that will rapidly repair damaged clockwork constructs, converted cyborgs, and clockwork structures."
invocations = list("May this prism...", "...mend our dents and scratches!")
channel_time = 80
consumed_components = list(VANGUARD_COGWHEEL = 3, GEIS_CAPACITOR = 1, REPLICANT_ALLOY = 1)
object_path = /obj/structure/destructible/clockwork/powered/mending_motor
creator_message = "<span class='brass'>You form a mending motor, which will consume power to mend constructs and structures.</span>"
creator_message = "<span class='brass'>You form a mending motor, which will rapidly repair damaged clockwork constructs, converted cyborgs, and clockwork structures.</span>"
observer_message = "<span class='warning'>An onyx prism forms in midair and sprouts tendrils to support itself!</span>"
invokers_required = 2
multiple_invokers_used = TRUE
@@ -238,9 +238,9 @@
//Mania Motor: Creates a malevolent transmitter that will broadcast the whispers of Sevtug into the minds of nearby nonservants, causing a variety of mental effects at a power cost.
/datum/clockwork_scripture/create_object/mania_motor
descname = "Structure, Area Denial"
descname = "Powered Structure, Area Denial"
name = "Mania Motor"
desc = "Creates a mania motor which will cause brain damage and hallucinations in nearby non-servant humans. It will also try to convert humans directly adjecent to the motor."
desc = "Creates a mania motor which will cause brain damage and hallucinations in nearby non-Servant humans. It will also try to convert humans directly adjecent to the motor."
invocations = list("May this transmitter...", "...break the will of all who oppose us!")
channel_time = 80
consumed_components = list(GEIS_CAPACITOR = 3, REPLICANT_ALLOY = 1, HIEROPHANT_ANSIBLE = 1)
@@ -249,7 +249,7 @@
observer_message = "<span class='warning'>A two-pronged machine rises from the ground!</span>"
invokers_required = 2
multiple_invokers_used = TRUE
usage_tip = "Eligible human servants next to the motor will be converted at an additional power cost. It will also cure hallucinations and brain damage in nearby servants."
usage_tip = "Eligible non-Servant humans next to the motor will be converted at an additional power cost. It will also cure hallucinations and brain damage in nearby Servants."
tier = SCRIPTURE_APPLICATION
one_per_tile = TRUE
primary_component = GEIS_CAPACITOR
@@ -260,9 +260,10 @@
//Tinkerer's Daemon: Creates an efficient machine that rapidly produces components at a power cost.
/datum/clockwork_scripture/create_object/tinkerers_daemon
descname = "Structure, Component Generator"
descname = "Powered Structure, Component Generator"
name = "Tinkerer's Daemon"
desc = "Creates a tinkerer's daemon which can rapidly collect components. It will only function if it has sufficient power, is outnumbered by servants by a ratio of 5:1, and there is at least one existing cache."
desc = "Creates a tinkerer's daemon which can rapidly collect components. It will only function if it has sufficient power, is outnumbered by Servants by a ratio of 5:1, \
and there is at least one existing cache."
invocations = list("May this generator...", "...collect Engine parts that yet hold greatness!")
channel_time = 80
consumed_components = list(BELLIGERENT_EYE = 1, GEIS_CAPACITOR = 1, REPLICANT_ALLOY = 3)
@@ -294,9 +295,9 @@
//Clockwork Obelisk: Creates a powerful obelisk that can be used to broadcast messages or open a gateway to any servant or clockwork obelisk at a power cost.
/datum/clockwork_scripture/create_object/clockwork_obelisk
descname = "Structure, Teleportation Hub"
descname = "Powered Structure, Teleportation Hub"
name = "Clockwork Obelisk"
desc = "Creates a clockwork obelisk that can broadcast messages over the Hierophant Network or open a Spatial Gateway to any living servant or clockwork obelisk."
desc = "Creates a clockwork obelisk that can broadcast messages over the Hierophant Network or open a Spatial Gateway to any living Servant or clockwork obelisk."
invocations = list("May this obelisk...", "...take us to all places!")
channel_time = 80
consumed_components = list(BELLIGERENT_EYE = 1, VANGUARD_COGWHEEL = 1, HIEROPHANT_ANSIBLE = 3)
@@ -253,14 +253,15 @@
/datum/clockwork_scripture/create_object/tinkerers_cache
descname = "Necessary Structure, Shares Components"
name = "Tinkerer's Cache"
desc = "Forms a cache that can store an infinite amount of components. All caches are linked and will provide components to slabs."
desc = "Forms a cache that can store an infinite amount of components. All caches are linked and will provide components to slabs. \
Striking a cache with a slab will transfer that slab's components to the global cache."
invocations = list("Constructing...", "...a cache!")
channel_time = 50
consumed_components = list(BELLIGERENT_EYE = 0, VANGUARD_COGWHEEL = 0, GEIS_CAPACITOR = 0, REPLICANT_ALLOY = 1, HIEROPHANT_ANSIBLE = 0)
object_path = /obj/structure/destructible/clockwork/cache
creator_message = "<span class='brass'>You form a tinkerer's cache, which is capable of storing components, which will automatically be used by slabs.</span>"
observer_message = "<span class='warning'>A hollow brass spire rises and begins to blaze!</span>"
usage_tip = "Slabs will draw components from the global cache after the slab's own repositories, making caches very efficient."
usage_tip = "Slabs will draw components from the global cache after the slab's own repositories, making caches extremely useful."
tier = SCRIPTURE_DRIVER
one_per_tile = TRUE
primary_component = REPLICANT_ALLOY
@@ -299,17 +300,17 @@
/datum/clockwork_scripture/create_object/sigil_of_transgression
descname = "Trap, Stunning"
name = "Sigil of Transgression"
desc = "Wards a tile with a sigil. The next person to cross the sigil will be smitten and unable to move. Nar-Sian cultists are stunned altogether."
invocations = list("Divinity, dazzle...", "...those who tresspass here!")
desc = "Wards a tile with a sigil, which will stun the next non-Servant to cross it."
invocations = list("Divinity, smite...", "...those who tresspass here!")
channel_time = 50
consumed_components = list(HIEROPHANT_ANSIBLE = 1)
whispered = TRUE
object_path = /obj/effect/clockwork/sigil/transgression
creator_message = "<span class='brass'>A sigil silently appears below you. The next non-servant to cross it will be immobilized.</span>"
creator_message = "<span class='brass'>A sigil silently appears below you. The next non-Servant to cross it will be stunned.</span>"
usage_tip = "The sigil, while fairly powerful in its stun, does not induce muteness in its victim."
tier = SCRIPTURE_DRIVER
one_per_tile = TRUE
primary_component = HIEROPHANT_ANSIBLE
sort_priority = 10
quickbind = TRUE
quickbind_desc = "Creates a Sigil of Transgression, which will stun the first non-Servant to cross it."
quickbind_desc = "Creates a Sigil of Transgression, which will stun the next non-Servant to cross it."
@@ -6,11 +6,11 @@
/datum/clockwork_scripture/invoke_inathneq
descname = "Area Invulnerability"
name = "Invoke Inath-neq, the Resonant Cogwheel"
desc = "Taps the limitless power of Inath-neq, one of Ratvar's four generals. The benevolence of Inath-Neq will grant complete invulnerability to all servants in range for fifteen seconds."
desc = "Taps the limitless power of Inath-neq, one of Ratvar's four generals. The benevolence of Inath-Neq will grant complete invulnerability to all Servants in range for fifteen seconds."
invocations = list("I call upon you, Vanguard!!", "Let the Resonant Cogs turn once more!!", "Grant me and my allies the strength to vanquish our foes!!")
channel_time = 100
consumed_components = list(VANGUARD_COGWHEEL = 6, GEIS_CAPACITOR = 3, REPLICANT_ALLOY = 3, HIEROPHANT_ANSIBLE = 3)
usage_tip = "Those affected by this scripture are only weak to things that outright destroy bodies, such as bombs or the singularity."
usage_tip = "Servants affected by this scripture are only weak to things that outright destroy bodies, such as bombs or the singularity."
tier = SCRIPTURE_REVENANT
primary_component = VANGUARD_COGWHEEL
sort_priority = 2
@@ -124,7 +124,7 @@
return FALSE
if(!slab.no_cost && ratvar_awakens)
invoker << "<span class='nezbere'>\"[text2ratvar("Our master is here already. You do not require my help, friend.")]\"</span>\n\
<span class='warning'>Nezbere will not grant his power while Ratvar's dwarfs his own!</span>"
<span class='warning'>There is no need for Nezbere's assistance while Ratvar is risen!</span>"
return FALSE
return TRUE
@@ -165,8 +165,8 @@
/datum/clockwork_scripture/invoke_nzcrentr
descname = "Area Lightning Blast"
name = "Invoke Nzcrentr, the Eternal Thunderbolt"
desc = "Taps the limitless power of Nzcrentr, one of Ratvar's four generals. The immense energy Nzcrentr wields will allow you to imbue a tiny fraction of it into your body. After several \
seconds, anyone near you will be struck by a devastating lightning bolt."
desc = "Taps the limitless power of Nzcrentr, one of Ratvar's four generals. Nzcrentr will grant you a tiny fraction of its boundless power. After several seconds, all non-Servants near you \
will be struck by devastating lightning bolts."
invocations = list("I call upon you, Amperage!!", "Let your energy flow through me!!", "Let your boundless power shatter stars!!")
channel_time = 100
consumed_components = list(BELLIGERENT_EYE = 3, GEIS_CAPACITOR = 3, REPLICANT_ALLOY = 3, HIEROPHANT_ANSIBLE = 6)
@@ -187,7 +187,7 @@
clockwork_generals_invoked["nzcrentr"] = world.time + CLOCKWORK_GENERAL_COOLDOWN
hierophant_message("<span class='nzcrentr_large'>[text2ratvar("Amperage: \"[invoker.real_name] has called forth my power. Hope [invoker.p_they()] [invoker.p_do()] not shatter under it!")]\"</span>", FALSE, invoker)
invoker.visible_message("<span class='warning'>[invoker] begins to radiate a blinding light!</span>", \
"<span class='nzcrentr'>\"[text2ratvar("The boss says it's okay to do this. Don't blame me if you die from it.")]\"</span>\n \
"<span class='nzcrentr'>\"[text2ratvar("The boss says it's okay to do this. Don't blame me if you die from it.")]\"</span>\n\
<span class='userdanger'>You feel limitless power surging through you!</span>")
playsound(invoker, 'sound/magic/clockwork/invoke_general.ogg', 50, 0)
sleep(2)
@@ -197,7 +197,7 @@
sleep(88)
if(invoker)
invoker.visible_message("<span class='warning'>Massive bolts of energy emerge from across [invoker]'s body!</span>", \
"<span class='nzcrentr'>\"[text2ratvar("I told you you wouldn't be able to handle it.")]\"</span>\n \
"<span class='nzcrentr'>\"[text2ratvar("I told you you wouldn't be able to handle it.")]\"</span>\n\
<span class='userdanger'>TOO... MUCH! CAN'T... TAKE IT!</span>")
playsound(invoker, 'sound/magic/lightningbolt.ogg', 100, 0)
if(invoker.stat == CONSCIOUS)
@@ -6,12 +6,12 @@
/datum/clockwork_scripture/create_object/ocular_warden
descname = "Structure, Turret"
name = "Ocular Warden"
desc = "Forms an automatic short-range turret that deals low sustained damage to the unenlightened in its range."
desc = "Forms an automatic short-range turret which will automatically attack nearby unrestrained non-Servants that can see it."
invocations = list("Guardians...", "...of the Engine...", "...defend us!")
channel_time = 120
consumed_components = list(BELLIGERENT_EYE = 1, REPLICANT_ALLOY = 1)
object_path = /obj/structure/destructible/clockwork/ocular_warden
creator_message = "<span class='brass'>You form an ocular warden, which will focus its searing gaze upon nearby unenlightened.</span>"
creator_message = "<span class='brass'>You form an ocular warden, which will automatically attack nearby unrestrained non-Servants that can see it.</span>"
observer_message = "<span class='warning'>A brass eye takes shape and slowly rises into the air, its red iris glaring!</span>"
usage_tip = "Although powerful, the warden is very fragile and should optimally be placed behind barricades."
tier = SCRIPTURE_SCRIPT
@@ -23,7 +23,7 @@
quickbind_desc = "Creates an Ocular Warden, which will automatically attack nearby unrestrained non-Servants that can see it."
/datum/clockwork_scripture/create_object/ocular_warden/check_special_requirements()
for(var/obj/structure/destructible/clockwork/ocular_warden/W in range(3, invoker))
for(var/obj/structure/destructible/clockwork/ocular_warden/W in range(OCULAR_WARDEN_EXCLUSION_RANGE, invoker))
invoker << "<span class='neovgre'>You sense another ocular warden too near this location. Placing another this close would cause them to fight.</span>" //fluff message
return FALSE
return ..()
@@ -52,7 +52,7 @@
/datum/clockwork_scripture/create_object/vitality_matrix
descname = "Trap, Damage to Healing"
name = "Vitality Matrix"
desc = "Scribes a sigil beneath the invoker which drains life from any living non-Servants that cross it. Servants that cross it, however, will be healed based on how much Vitality all \
desc = "Places a sigil that drains life from any living non-Servants that cross it. Servants that cross it, however, will be healed based on how much Vitality all \
Matrices have drained from non-Servants. Dead Servants can be revived by this sigil if there is vitality equal to the target Servant's non-oxygen damage."
invocations = list("Divinity...", "...steal their life...", "...for these shells!")
channel_time = 60
@@ -11,7 +11,8 @@
max_integrity = 150
obj_integrity = 150
break_message = "<span class='warning'>The obelisk falls to the ground, undamaged!</span>"
debris = list(/obj/item/clockwork/alloy_shards/small = 3, \
debris = list(/obj/item/clockwork/alloy_shards/small = 4, \
/obj/item/clockwork/alloy_shards/medium = 2, \
/obj/item/clockwork/component/hierophant_ansible/obelisk = 1)
var/hierophant_cost = MIN_CLOCKCULT_POWER //how much it costs to broadcast with large text
var/gateway_cost = 2000 //how much it costs to open a gateway
@@ -8,8 +8,11 @@
active_icon = "interdiction_lens_active"
inactive_icon = "interdiction_lens"
unanchored_icon = "interdiction_lens_unwrenched"
break_message = "<span class='warning'>The lens flares a blinding violet before shattering!</span>"
break_message = "<span class='warning'>The lens flares a blinding violet before the totem beneath it shatters!</span>"
break_sound = 'sound/effects/Glassbr3.ogg'
debris = list(/obj/item/clockwork/alloy_shards/small = 2, \
/obj/item/clockwork/alloy_shards/large = 2, \
/obj/item/clockwork/component/belligerent_eye/lens_gem = 1)
var/recharging = 0 //world.time when the lens was last used
var/recharge_time = 1200 //if it drains no power and affects no objects, it turns off for two minutes
var/disabled = FALSE //if it's actually usable
@@ -8,11 +8,11 @@
inactive_icon = "mania_motor_inactive"
unanchored_icon = "mania_motor_unwrenched"
construction_value = 20
max_integrity = 80
obj_integrity = 80
max_integrity = 100
obj_integrity = 100
break_message = "<span class='warning'>The antenna break off, leaving a pile of shards!</span>"
debris = list(/obj/item/clockwork/alloy_shards/large = 1, \
/obj/item/clockwork/alloy_shards/small = 3, \
debris = list(/obj/item/clockwork/alloy_shards/large = 2, \
/obj/item/clockwork/alloy_shards/small = 2, \
/obj/item/clockwork/component/geis_capacitor/antennae = 1)
var/mania_cost = 150
var/convert_cost = 150
@@ -62,30 +62,7 @@
var/turf/T = get_turf(src)
var/hum = get_sfx('sound/effects/screech.ogg') //like playsound, same sound for everyone affected
var/efficiency = get_efficiency_mod()
for(var/mob/living/carbon/human/H in view(1, src))
if(is_servant_of_ratvar(H) || H.null_rod_check() || H.stat == DEAD)
continue
if(!H.Adjacent(src))
H << "<span class='sevtug'>\"[text2ratvar(pick(close_messages))]\"</span>"
continue
if(try_use_power(convert_cost))
H.playsound_local(T, hum, 80, 1)
if(!H.stat)
if(H.getBrainLoss() < 100)
H.adjustBrainLoss(30 * efficiency)
H.visible_message("<span class='warning'>[H] reaches out and touches [src].</span>", "<span class='sevtug'>You touch [src] involuntarily.</span>")
else
H.Paralyse(3)
else if(is_eligible_servant(H))
H << "<span class='sevtug'>\"[text2ratvar("You are mine and his, now.")]\"</span>"
add_servant_of_ratvar(H)
H.Paralyse(5)
else
H << "<span class='sevtug'>\"[text2ratvar(pick(convert_messages))]\"</span>"
else
visible_message("<span class='warning'>[src]'s antennae fizzle quietly.</span>")
playsound(src, 'sound/effects/light_flicker.ogg', 50, 1)
for(var/mob/living/carbon/human/H in range(10, src))
for(var/mob/living/carbon/human/H in viewers(7, src))
if(is_servant_of_ratvar(H)) //heals servants of braindamage, hallucination, druggy, dizziness, and confusion
var/brainloss = H.getBrainLoss()
if(brainloss)
@@ -98,14 +75,34 @@
H.dizziness = 0
if(H.confused)
H.confused = 0
else if(!H.null_rod_check() && H.stat == CONSCIOUS)
else if(!H.null_rod_check() && H.stat != DEAD)
var/distance = 0 + get_dist(T, get_turf(H))
var/falloff_distance = min((110) - distance * 10, 80)
var/sound_distance = falloff_distance * 0.5
var/targetbrainloss = H.getBrainLoss()
if(distance >= 4 && prob(falloff_distance * 0.5))
if(distance > 3 && prob(falloff_distance * 0.5))
H << "<span class='sevtug_small'>\"[text2ratvar(pick(mania_messages))]\"</span>"
H.playsound_local(T, hum, sound_distance, 1)
if(distance <= 1)
if(!H.Adjacent(src))
H << "<span class='sevtug'>\"[text2ratvar(pick(close_messages))]\"</span>"
H.playsound_local(T, hum, sound_distance, 1)
else if(!try_use_power(convert_cost))
visible_message("<span class='warning'>[src]'s antennae fizzle quietly.</span>")
playsound(src, 'sound/effects/light_flicker.ogg', 50, 1)
else
H.playsound_local(T, hum, 80, 1)
if(!H.stat)
if(H.getBrainLoss() < 100)
H.adjustBrainLoss(20 * efficiency)
H.visible_message("<span class='warning'>[H] reaches out and touches [src].</span>", "<span class='sevtug'>You touch [src] involuntarily.</span>")
else
H.Paralyse(3)
else if(is_eligible_servant(H))
H << "<span class='sevtug'>\"[text2ratvar("You are mine and his, now.")]\"</span>"
add_servant_of_ratvar(H)
H.Paralyse(5)
else
H.playsound_local(T, hum, sound_distance, 1)
switch(distance)
if(0 to 3)
if(prob(falloff_distance * 0.5))
@@ -113,31 +110,31 @@
H << "<span class='sevtug_small'>\"[text2ratvar(pick(mania_messages))]\"</span>"
else
H << "<span class='sevtug'>\"[text2ratvar(pick(compel_messages))]\"</span>"
if(targetbrainloss <= 50)
H.adjustBrainLoss((50 * efficiency) - targetbrainloss) //got too close had brain eaten
H.adjust_drugginess(Clamp(7 * efficiency, 0, 100 - H.druggy))
H.hallucination = min(H.hallucination + (7 * efficiency), 100)
H.dizziness = min(H.dizziness + (3 * efficiency), 45)
H.confused = min(H.confused + (3 * efficiency), 45)
if(4 to 5)
if(targetbrainloss <= 50)
H.adjustBrainLoss(1 * efficiency)
H.adjust_drugginess(Clamp(5 * efficiency, 0, 80 - H.druggy))
H.hallucination = min(H.hallucination + (5 * efficiency), 80)
H.dizziness = min(H.dizziness + (2 * efficiency), 30)
H.confused = min(H.confused + (2 * efficiency), 30)
if(6 to 7)
if(targetbrainloss <= 30)
H.adjustBrainLoss(1 * efficiency)
H.adjust_drugginess(Clamp(2 * efficiency, 0, 60 - H.druggy))
H.hallucination = min(H.hallucination + (2 * efficiency), 60)
H.dizziness = min(H.dizziness + (2 * efficiency), 15)
H.confused = min(H.confused + (2 * efficiency), 15)
if(8 to 9)
if(targetbrainloss <= 40)
H.adjustBrainLoss(3 * efficiency)
H.adjust_drugginess(Clamp(7 * efficiency, 0, 50 - H.druggy))
H.hallucination = min(H.hallucination + (7 * efficiency), 50)
H.dizziness = min(H.dizziness + (3 * efficiency), 20)
H.confused = min(H.confused + (3 * efficiency), 20)
if(3 to 5)
if(targetbrainloss <= 20)
H.adjustBrainLoss(2 * efficiency)
H.adjust_drugginess(Clamp(5 * efficiency, 0, 25 - H.druggy))
H.hallucination = min(H.hallucination + (5 * efficiency), 25)
H.dizziness = min(H.dizziness + (2 * efficiency), 10)
H.confused = min(H.confused + (2 * efficiency), 10)
if(5 to 6)
if(targetbrainloss <= 10)
H.adjustBrainLoss(1 * efficiency)
H.adjust_drugginess(Clamp(2 * efficiency, 0, 40 - H.druggy))
H.hallucination = min(H.hallucination + (2 * efficiency), 40)
if(10 to INFINITY)
H.adjust_drugginess(Clamp(2 * efficiency, 0, 20 - H.druggy))
H.hallucination = min(H.hallucination + (2 * efficiency), 20)
H.dizziness = min(H.dizziness + (2 * efficiency), 5)
H.confused = min(H.confused + (2 * efficiency), 5)
if(6 to 7)
if(targetbrainloss <= 5)
H.adjustBrainLoss(1 * efficiency)
H.adjust_drugginess(Clamp(2 * efficiency, 0, 10 - H.druggy))
H.hallucination = min(H.hallucination + (2 * efficiency), 10)
if(7 to INFINITY)
H.adjust_drugginess(Clamp(2 * efficiency, 0, 5 - H.druggy))
H.hallucination = min(H.hallucination + (2 * efficiency), 5)
@@ -10,11 +10,11 @@
construction_value = 20
max_integrity = 125
obj_integrity = 125
break_message = "<span class='warning'>The prism collapses with a heavy thud!</span>"
debris = list(/obj/item/clockwork/alloy_shards/small = 5, \
break_message = "<span class='warning'>The prism falls to the ground with a heavy thud!</span>"
debris = list(/obj/item/clockwork/alloy_shards/small = 3, \
/obj/item/clockwork/alloy_shards/medium = 1, \
/obj/item/clockwork/alloy_shards/large = 1, \
/obj/item/clockwork/component/vanguard_cogwheel = 1)
/obj/item/clockwork/component/vanguard_cogwheel/onyx_prism = 1)
var/heal_attempts = 4
var/heal_cost = MIN_CLOCKCULT_POWER*2
var/static/list/damage_heal_order = list(BRUTE, BURN, OXY)
@@ -2,7 +2,7 @@
/obj/structure/destructible/clockwork/ocular_warden
name = "ocular warden"
desc = "A large brass eye with tendrils trailing below it and a wide red iris."
clockwork_desc = "A fragile turret that will deal sustained damage to any non-faithful it sees."
clockwork_desc = "A fragile turret which will automatically attack nearby unrestrained non-Servants that can see it."
icon_state = "ocular_warden"
unanchored_icon = "ocular_warden_unwrenched"
obj_integrity = 25
@@ -39,7 +39,7 @@
user << "<span class='warning'>[src] is too damaged to unsecure!</span>"
return FAILED_UNFASTEN
else
for(var/obj/structure/destructible/clockwork/ocular_warden/W in orange(3, src))
for(var/obj/structure/destructible/clockwork/ocular_warden/W in orange(OCULAR_WARDEN_EXCLUSION_RANGE, src))
if(!silent)
user << "<span class='neovgre'>You sense another ocular warden too near this location. Activating this one this close would cause them to fight.</span>"
return FAILED_UNFASTEN
@@ -10,10 +10,10 @@
max_integrity = 100
obj_integrity = 100
construction_value = 20
break_message = "<span class='warning'>The daemon shatters into millions of pieces!</span>"
debris = list(/obj/item/clockwork/alloy_shards/large = 2, \
/obj/item/clockwork/alloy_shards/medium = 4, \
/obj/item/clockwork/alloy_shards/small = 6)
break_message = "<span class='warning'>The daemon shatters into millions of pieces, leaving only a disc of metal!</span>"
debris = list(/obj/item/clockwork/alloy_shards/medium = 1, \
/obj/item/clockwork/alloy_shards/small = 6, \
/obj/item/clockwork/component/replicant_alloy/replication_plate = 1)
var/image/daemon_glow
var/image/component_glow
var/component_id_to_produce
+1 -1
View File
@@ -286,7 +286,7 @@
var/timer = SSshuttle.emergency.timeLeft(1) + cursetime
SSshuttle.emergency.setTimer(timer)
user << "<span class='danger'>You shatter the orb! A dark essence spirals into the air, then disappears.</span>"
playsound(user.loc, "sound/effects/Glassbr1.ogg", 50, 1)
playsound(user.loc, 'sound/effects/Glassbr1.ogg', 50, 1)
qdel(src)
sleep(20)
var/global/list/curses
+3 -3
View File
@@ -507,7 +507,7 @@
feedback_add_details("wizard_spell_learned",log_name)
rightandwrong(0, user, 25)
active = 1
playsound(get_turf(user),"sound/magic/CastSummon.ogg",50,1)
playsound(get_turf(user), 'sound/magic/CastSummon.ogg', 50, 1)
user << "<span class='notice'>You have cast summon guns!</span>"
return 1
@@ -525,7 +525,7 @@
feedback_add_details("wizard_spell_learned",log_name)
rightandwrong(1, user, 25)
active = 1
playsound(get_turf(user),"sound/magic/CastSummon.ogg",50,1)
playsound(get_turf(user), 'sound/magic/CastSummon.ogg', 50, 1)
user << "<span class='notice'>You have cast summon magic!</span>"
return 1
@@ -545,7 +545,7 @@
feedback_add_details("wizard_spell_learned",log_name)
summonevents()
times++
playsound(get_turf(user),"sound/magic/CastSummon.ogg",50,1)
playsound(get_turf(user), 'sound/magic/CastSummon.ogg', 50, 1)
user << "<span class='notice'>You have cast summon events.</span>"
return 1
@@ -175,7 +175,10 @@
name = "circuit board (Xenobiology Console)"
build_path = /obj/machinery/computer/camera_advanced/xenobio
origin_tech = "programming=3;bio=3"
/obj/item/weapon/circuitboard/computer/base_construction
name = "circuit board (Aux Mining Base Construction Console)"
build_path = /obj/machinery/computer/camera_advanced/base_construction
origin_tech = "programming=3;engineering=3"
/obj/item/weapon/circuitboard/computer/aiupload
name = "AI Upload (Computer Board)"
build_path = /obj/machinery/computer/upload/ai
@@ -127,7 +127,7 @@ var/const/CALL_SHUTTLE_REASON_LENGTH = 12
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
make_announcement(usr)
/* if("crossserver")
if("crossserver")
if(authenticated==2)
if(CM.lastTimeUsed + 600 > world.time)
usr << "<span class='warning'>Arrays recycling. Please stand by.</span>"
@@ -142,7 +142,7 @@ var/const/CALL_SHUTTLE_REASON_LENGTH = 12
log_say("[key_name(usr)] has sent a message to the other server: [input]")
message_admins("[key_name_admin(usr)] has sent a message to the other server.")
CM.lastTimeUsed = world.time
*/
if("purchase_menu")
state = STATE_PURCHASE
@@ -144,7 +144,7 @@
/obj/machinery/computer/gulag_teleporter_computer/proc/teleport(mob/user)
log_game("[user]([user.ckey] teleported [prisoner]([prisoner.ckey]) to the Labor Camp ([beacon.x], [beacon.y], [beacon.z]) for [id.goal] points.")
teleporter.handle_prisoner(id, temporary_record)
playsound(loc, "sound/weapons/emitter.ogg", 50, 1)
playsound(loc, 'sound/weapons/emitter.ogg', 50, 1)
prisoner.forceMove(get_turf(beacon))
prisoner.Weaken(2) // small travel dizziness
prisoner << "<span class='warning'>The teleportation makes you a little dizzy.</span>"
+1 -1
View File
@@ -489,7 +489,7 @@
new/obj/item/stack/tile/brass(T, 4)
else
new/obj/item/clockwork/alloy_shards(T)
new/obj/item/clockwork/component/vanguard_cogwheel/pinion_lock(T)
new/obj/item/clockwork/alloy_shards/pinion_lock(T)
qdel(src)
/obj/machinery/door/airlock/clockwork/proc/attempt_construction(obj/item/I, mob/living/user)
+1 -1
View File
@@ -96,7 +96,7 @@
return
var/area/A = get_area(src)
A.firealert(src)
playsound(src.loc, 'goon/sound/machinery/FireAlarm.ogg', 75, 0)
playsound(src.loc, 'goon/sound/machinery/FireAlarm.ogg', 75, 1)
/obj/machinery/firealarm/proc/alarm_in(time)
addtimer(CALLBACK(src, .proc/alarm), time)
@@ -569,6 +569,28 @@
/obj/machinery/porta_turret/ai/assess_perp(mob/living/carbon/human/perp)
return 10 //AI turrets shoot at everything not in their faction
/obj/machinery/porta_turret/aux_base
name = "perimeter defense turret"
desc = "A plasma cutter turret calibrated to defend outposts against non-humanoid fauna."
req_access = list() //Can be disabled/enabled by any humanoid!
installation = null
lethal_projectile = /obj/item/projectile/plasma
lethal_projectile_sound = 'sound/weapons/plasma_cutter.ogg'
mode = TURRET_LETHAL //It would be useless in stun mode anyway
faction = "neutral" //Minebots, medibots, etc that should not be shot.
/obj/machinery/porta_turret/aux_base/assess_perp(mob/living/carbon/human/perp)
return 0 //Never shoot humanoids. You are on your own if Ashwalkers or the like attack!
/obj/machinery/porta_turret/aux_base/setup()
return
/obj/machinery/porta_turret/aux_base/New()
..()
cover.name = name
cover.desc = desc
////////////////////////
//Turret Control Panel//
////////////////////////
+58 -34
View File
@@ -728,6 +728,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
/obj/item/weapon/reagent_containers/food/drinks/soda_cans/space_up = 10,
/obj/item/weapon/reagent_containers/food/drinks/soda_cans/lemon_lime = 10)
contraband = list(/obj/item/weapon/reagent_containers/food/drinks/soda_cans/thirteenloko = 6)
premium = list(/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/filled/nuka_cola = 1)
refill_canister = /obj/item/weapon/vending_refill/cola
//This one's from bay12
@@ -917,40 +918,63 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
/obj/item/clothing/head/cueball = 1,
/obj/item/clothing/under/scratch = 1,
/obj/item/clothing/under/sailor=1,
/obj/item/clothing/shoes/megaboots=1,
/obj/item/clothing/gloves/megagloves=1,
/obj/item/clothing/head/helmet/megahelmet=1,
/obj/item/clothing/shoes/megaboots=1,
/obj/item/clothing/gloves/megagloves=1,
/obj/item/clothing/head/helmet/megahelmet=1,
/obj/item/clothing/under/mega=1,
/obj/item/clothing/shoes/protoboots=1,
/obj/item/clothing/gloves/protogloves=1,
/obj/item/clothing/head/helmet/protohelmet = 1,
/obj/item/clothing/shoes/protoboots=1,
/obj/item/clothing/gloves/protogloves=1,
/obj/item/clothing/head/helmet/protohelmet = 1,
/obj/item/clothing/under/proto = 1,
/obj/item/clothing/shoes/megaxboots = 1,
/obj/item/clothing/gloves/megaxgloves = 1,
/obj/item/clothing/head/helmet/megaxhelmet = 1,
/obj/item/clothing/shoes/megaxboots = 1,
/obj/item/clothing/gloves/megaxgloves = 1,
/obj/item/clothing/head/helmet/megaxhelmet = 1,
/obj/item/clothing/under/megax = 1,
/obj/item/clothing/shoes/joeboots = 1,
/obj/item/clothing/gloves/joegloves = 1,
/obj/item/clothing/shoes/joeboots = 1,
/obj/item/clothing/gloves/joegloves = 1,
/obj/item/clothing/head/helmet/joehelmet = 1,
/obj/item/clothing/under/joe = 1,
/obj/item/clothing/under/vault = 1,
/obj/item/clothing/under/roll = 1,
/obj/item/clothing/head/clownpiece = 1,
/obj/item/clothing/under/clownpiece = 1,
/obj/item/clothing/suit/clownpiece = 1)
contraband = list(/obj/item/clothing/suit/judgerobe = 1,/obj/item/clothing/head/powdered_wig = 1,/obj/item/weapon/gun/magic/wand = 2,/obj/item/clothing/glasses/sunglasses/garb = 2,
/obj/item/clothing/gloves/anchor_arms = 1,
/obj/item/clothing/suit/kaminacape = 1,
/obj/item/clothing/under/soldieruniform = 1, /obj/item/clothing/head/stalhelm = 1, /obj/item/clothing/suit/soldiercoat = 1,
/obj/item/clothing/under/officeruniform = 1, /obj/item/clothing/head/naziofficer = 1, /obj/item/clothing/suit/officercoat = 1,
/obj/item/clothing/head/panzer = 1,
/obj/item/clothing/under/russobluecamooutfit = 1, /obj/item/clothing/head/russobluecamohat = 1,
/obj/item/clothing/suit/russofurcoat = 1, /obj/item/clothing/head/russofurhat = 1,
/obj/item/clothing/under/rottensuit = 1, /obj/item/clothing/shoes/rottenshoes = 1,
/obj/item/clothing/head/helmet/biker = 1, /obj/item/clothing/under/bikersuit = 1, /obj/item/clothing/gloves/bikergloves = 1,
/obj/item/clothing/under/jacketsuit = 1, /obj/item/clothing/head/helmet/richard = 1,
/obj/item/clothing/under/vault13 = 1)
premium = list(/obj/item/clothing/suit/pirate/captain = 2, /obj/item/clothing/head/pirate/captain = 2, /obj/item/clothing/head/helmet/roman = 1, /obj/item/clothing/head/helmet/roman/legionaire = 1, /obj/item/clothing/under/roman = 1, /obj/item/clothing/shoes/roman = 1, /obj/item/weapon/shield/riot/roman = 1, /obj/item/weapon/skub = 1)
/obj/item/clothing/head/clownpiece = 1,
/obj/item/clothing/under/clownpiece = 1,
/obj/item/clothing/suit/clownpiece = 1
)
contraband = list(/obj/item/clothing/suit/judgerobe = 1,
/obj/item/clothing/head/powdered_wig = 1,
/obj/item/weapon/gun/magic/wand = 2,
/obj/item/clothing/glasses/sunglasses/garb = 2,
/obj/item/clothing/gloves/anchor_arms = 1,
/obj/item/clothing/suit/kaminacape = 1,
/obj/item/clothing/under/soldieruniform = 1,
/obj/item/clothing/head/stalhelm = 1,
/obj/item/clothing/suit/soldiercoat = 1,
/obj/item/clothing/under/officeruniform = 1,
/obj/item/clothing/head/naziofficer = 1,
/obj/item/clothing/suit/officercoat = 1,
/obj/item/clothing/head/panzer = 1,
/obj/item/clothing/under/russobluecamooutfit = 1,
/obj/item/clothing/head/russobluecamohat = 1,
/obj/item/clothing/suit/russofurcoat = 1,
/obj/item/clothing/head/russofurhat = 1,
/obj/item/clothing/under/rottensuit = 1,
/obj/item/clothing/shoes/rottenshoes = 1,
/obj/item/clothing/head/helmet/biker = 1,
/obj/item/clothing/under/bikersuit = 1,
/obj/item/clothing/gloves/bikergloves = 1,
/obj/item/clothing/under/jacketsuit = 1,
/obj/item/clothing/head/helmet/richard = 1,
/obj/item/clothing/under/vault13 = 1
)
premium = list(/obj/item/clothing/suit/pirate/captain = 2,
/obj/item/clothing/head/pirate/captain = 2,
/obj/item/clothing/head/helmet/roman = 1,
/obj/item/clothing/head/helmet/roman/legionaire = 1,
/obj/item/clothing/under/roman = 1,
/obj/item/clothing/shoes/roman = 1,
/obj/item/weapon/shield/riot/roman = 1,
/obj/item/weapon/skub = 1
)
refill_canister = /obj/item/weapon/vending_refill/autodrobe
/obj/machinery/vending/dinnerware
@@ -1062,14 +1086,14 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
/obj/item/clothing/suit/jacket/letterman_red=1, /obj/item/clothing/under/wintercasualwear=1, /obj/item/clothing/under/casualwear=1, /obj/item/clothing/under/casualhoodie=1,
/obj/item/clothing/under/casualhoodie/skirt=1)
contraband = list(/obj/item/clothing/under/syndicate/tacticool=1,/obj/item/clothing/mask/balaclava=1,/obj/item/clothing/head/ushanka=1,/obj/item/clothing/under/soviet=1,/obj/item/weapon/storage/belt/fannypack/black=2,/obj/item/clothing/suit/jacket/letterman_syndie=1,/obj/item/clothing/under/jabroni=1, /obj/item/clothing/suit/vapeshirt=1, /obj/item/clothing/under/geisha=1,
/obj/item/clothing/under/wedding/bride_orange=1,
/obj/item/clothing/under/wedding/bride_purple=1,
/obj/item/clothing/under/wedding/bride_blue=1,
/obj/item/clothing/under/wedding/bride_red=1,
/obj/item/clothing/under/wedding/bride_white=1,
/obj/item/clothing/under/wedding/bride_orange=1,
/obj/item/clothing/under/wedding/bride_purple=1,
/obj/item/clothing/under/wedding/bride_blue=1,
/obj/item/clothing/under/wedding/bride_red=1,
/obj/item/clothing/under/wedding/bride_white=1,
/obj/item/clothing/under/keyholesweater=1,
/obj/item/clothing/suit/doshjacket=1,
/obj/item/clothing/under/squatter_outfit = 1,
/obj/item/clothing/suit/doshjacket=1,
/obj/item/clothing/under/squatter_outfit = 1,
/obj/item/clothing/head/squatter_hat = 1)
premium = list(/obj/item/clothing/under/suit_jacket/checkered=1,/obj/item/clothing/head/mailman=1,/obj/item/clothing/under/rank/mailman=1,/obj/item/clothing/suit/jacket/leather=1,/obj/item/clothing/suit/jacket/leather/overcoat=1,/obj/item/clothing/under/pants/mustangjeans=1,/obj/item/clothing/neck/necklace/dope=3,/obj/item/clothing/suit/jacket/letterman_nanotrasen=1)
refill_canister = /obj/item/weapon/vending_refill/clothing
+1 -1
View File
@@ -245,7 +245,7 @@
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/silenced
name = "\improper S.H.H. \"Quietus\" Carbine"
desc = "A weapon for combat exosuits. A mime invention, field tests have shown that targets cannot even scream before going down."
fire_sound = "sound/weapons/Gunshot_silenced.ogg"
fire_sound = 'sound/weapons/Gunshot_silenced.ogg'
icon_state = "mecha_mime"
equip_cooldown = 30
projectile = /obj/item/projectile/bullet/mime
+1 -1
View File
@@ -1050,4 +1050,4 @@ var/year_integer = text2num(year) // = 2013???
/obj/mecha/update_remote_sight(mob/living/user)
if(occupant_sight_flags)
if(user == occupant)
user.sight |= occupant_sight_flags
user.sight |= occupant_sight_flags
+1 -1
View File
@@ -174,4 +174,4 @@
cargo -= O
else
if(user.loc == src) //so we don't get the message if we resisted multiple times and succeeded.
user << "<span class='warning'>You fail to push [O] out of [src]!</span>"
user << "<span class='warning'>You fail to push [O] out of [src]!</span>"
@@ -87,7 +87,7 @@
/obj/item/clothing/gloves/color/fyellow = 1,
/obj/item/clothing/head/hardhat = 1,
/obj/item/clothing/head/hardhat/red = 1,
/obj/item/clothing/head/that{throwforce = 1; throwing = 1} = 1,
/obj/item/clothing/head/that{throwforce = 1;} = 1,
/obj/item/clothing/head/ushanka = 1,
/obj/item/clothing/head/welding = 1,
/obj/item/clothing/mask/gas = 15,
+2 -2
View File
@@ -104,7 +104,7 @@ var/explosionid = 1
for(var/obj/structure/blob/B in T)
cached_exp_block[T] += B.explosion_block
CHECK_TICK
//flash mobs
if(flash_range)
for(var/mob/living/L in viewers(flash_range, epicenter))
@@ -179,7 +179,7 @@ var/explosionid = 1
var/took = (world.timeofday-start)/10
//You need to press the DebugGame verb to see these now....they were getting annoying and we've collected a fair bit of data. Just -test- changes to explosion code using this please so we can compare
if(Debug2)
world.log << "## DEBUG: Explosion([x0],[y0],[z0])(d[devastation_range],h[heavy_impact_range],l[light_impact_range]): Took [took] seconds."
log_world("## DEBUG: Explosion([x0],[y0],[z0])(d[devastation_range],h[heavy_impact_range],l[light_impact_range]): Took [took] seconds.")
//Machines which report explosions.
for(var/array in doppler_arrays)
+13 -14
View File
@@ -192,24 +192,23 @@ var/global/list/datum/stack_recipe/reinforced_glass_recipes = list ( \
var/mob/living/carbon/human/H = AM
if(PIERCEIMMUNE in H.dna.species.species_traits)
return
if(H.dna.species.id == "slime")
return
if(H.dna.species.id == "jelly")
if(H.dna.species.id == "slime" || "jelly")
return
var/picked_def_zone = pick("l_leg", "r_leg")
var/obj/item/bodypart/O = H.get_bodypart(picked_def_zone)
if(!istype(O))
return
var/feetCover = (H.wear_suit && H.wear_suit.body_parts_covered & FEET) || (H.w_uniform && H.w_uniform.body_parts_covered & FEET)
if(!H.shoes && !feetCover)
H.apply_damage(5, BRUTE, picked_def_zone)
if(cooldown < world.time - 10) //cooldown to avoid message spam.
if(!H.incapacitated())
H.visible_message("<span class='danger'>[H] steps in the broken glass!</span>", \
"<span class='userdanger'>You step in the broken glass!</span>")
else
H.visible_message("<span class='danger'>[H] slides on the broken glass!</span>", \
"<span class='userdanger'>You slide on the broken glass!</span>")
if(H.shoes || feetCover || H.movement_type & FLYING || H.buckled)
return
H.apply_damage(5, BRUTE, picked_def_zone)
if(cooldown < world.time - 10) //cooldown to avoid message spam.
if(!H.incapacitated())
H.visible_message("<span class='danger'>[H] steps in the broken glass!</span>", \
"<span class='userdanger'>You step in the broken glass!</span>")
else
H.visible_message("<span class='danger'>[H] slides on the broken glass!</span>", \
"<span class='userdanger'>You slide on the broken glass!</span>")
cooldown = world.time
H.Weaken(3)
cooldown = world.time
H.Weaken(3)
@@ -189,6 +189,8 @@ var/global/list/datum/stack_recipe/cloth_recipes = list ( \
null, \
new/datum/stack_recipe("fingerless gloves", /obj/item/clothing/gloves/fingerless, 1), \
new/datum/stack_recipe("black gloves", /obj/item/clothing/gloves/color/black, 3), \
null, \
new/datum/stack_recipe("blindfold", /obj/item/clothing/glasses/sunglasses/blindfold, 2), \
)
/obj/item/stack/sheet/cloth
+2 -6
View File
@@ -766,12 +766,8 @@
else if(istype(over_object, /obj/screen/inventory/hand))
var/obj/screen/inventory/hand/H = over_object
if(!remove_item_from_storage(M))
M.temporarilyRemoveItemFromInventory(src, TRUE)
if(!M.put_in_hand(src, H.held_index))
qdel(src)
return
usr << "<span class='notice'>You pick up the deck.</span>"
if(M.putItemFromInventoryInHandIfPossible(src, H.held_index))
usr << "<span class='notice'>You pick up the deck.</span>"
else
usr << "<span class='warning'>You can't reach it from here!</span>"
+1 -1
View File
@@ -609,4 +609,4 @@ var/global/list/RPD_recipes=list(
#undef METER_MODE
#undef DISPOSALS_MODE
#undef CATEGORY_ATMOS
#undef CATEGORY_DISPOSALS
#undef CATEGORY_DISPOSALS
+2 -6
View File
@@ -93,13 +93,9 @@
/obj/item/weapon/defibrillator/MouseDrop(obj/over_object)
if(ismob(src.loc))
var/mob/M = src.loc
if(istype(over_object, /obj/screen/inventory/hand))
if(!M.incapacitated() && istype(over_object, /obj/screen/inventory/hand))
var/obj/screen/inventory/hand/H = over_object
if(!M.temporarilyRemoveItemFromInventory(src))
return
if(!M.put_in_hand(src, H.held_index))
qdel(src) //wewie
M.putItemFromInventoryInHandIfPossible(src, H.held_index)
/obj/item/weapon/defibrillator/attackby(obj/item/weapon/W, mob/user, params)
if(W == paddles)
@@ -220,10 +220,10 @@
possessed = TRUE
var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as the spirit of [user.real_name]'s blade?", ROLE_PAI, null, FALSE, 100)
var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as the spirit of [user.real_name]'s blade?", ROLE_PAI, null, FALSE, 100, POLL_IGNORE_POSSESSED_BLADE)
var/mob/dead/observer/theghost = null
if(candidates.len)
if(LAZYLEN(candidates))
theghost = pick(candidates)
var/mob/living/simple_animal/shade/S = new(src)
S.real_name = name
@@ -20,6 +20,9 @@
if(requires_sharpness && !I.sharpness)
user << "<span class='notice'>You can only sharpen items that are already sharp, such as knives.</span>"
return
if(istype(I, /obj/item/weapon/melee/energy))
user << "<span class='notice'>You don't think \the [I] will be the thing getting modified if you use it on \the [src].</span>"
return
if(istype(I, /obj/item/weapon/twohanded))//some twohanded items should still be sharpenable, but handle force differently. therefore i need this stuff
var/obj/item/weapon/twohanded/TH = I
if(TH.force_wielded >= max)
@@ -581,6 +581,12 @@
new /obj/item/stack/medical/ointment(src)
new /obj/item/weapon/reagent_containers/hypospray/medipen(src)
/obj/item/weapon/storage/box/hug/survival/New()
..()
new /obj/item/clothing/mask/breath(src)
new /obj/item/weapon/tank/internals/emergency_oxygen(src)
new /obj/item/weapon/reagent_containers/hypospray/medipen(src)
/obj/item/ammo_casing/shotgun/rubbershot
/obj/item/weapon/storage/box/rubbershot
@@ -60,10 +60,10 @@
..()
if(empty) return
icon_state = pick("antitoxin","antitoxfirstaid","antitoxfirstaid2","antitoxfirstaid3")
for(var/i in 1 to 3)
for(var/i in 1 to 4)
new /obj/item/weapon/reagent_containers/syringe/charcoal(src)
for(var/i in 1 to 3)
new /obj/item/weapon/reagent_containers/pill/charcoal(src)
for(var/i in 1 to 2)
new /obj/item/weapon/storage/pill_bottle/charcoal(src)
new /obj/item/device/healthanalyzer(src)
return
@@ -138,21 +138,14 @@
var/mob/M = usr
if(!istype(over_object, /obj/screen) || !Adjacent(M))
return ..()
if(!M.restrained() && !M.stat && istype(over_object, /obj/screen/inventory/hand))
if(!M.incapacitated() && istype(over_object, /obj/screen/inventory/hand))
var/obj/screen/inventory/hand/H = over_object
if(!M.temporarilyRemoveItemFromInventory(src))
return
if(!M.put_in_hand(src,H.held_index))
qdel(src)
return
src.add_fingerprint(usr)
return
if(M.putItemFromInventoryInHandIfPossible(src, H.held_index))
add_fingerprint(usr)
if(over_object == usr && in_range(src, usr) || usr.contents.Find(src))
if(usr.s_active)
usr.s_active.close(usr)
src.show_to(usr)
return
return
/obj/item/weapon/storage/box/silver_sulf
name = "box of silver sulfadiazine patches"
@@ -45,7 +45,7 @@
show_to(M)
return
if(!M.restrained() && !M.stat)
if(!M.incapacitated())
if(!istype(over_object, /obj/screen))
return content_can_dump(over_object, M)
@@ -54,14 +54,9 @@
playsound(loc, "rustle", 50, 1, -5)
if(istype(over_object, /obj/screen/inventory/hand))
var/obj/screen/inventory/hand/H = over_object
if(!M.temporarilyRemoveItemFromInventory(src))
return
if(!M.put_in_hand(src,H.held_index))
qdel(src)
return
M.putItemFromInventoryInHandIfPossible(src, H.held_index)
add_fingerprint(usr)
@@ -85,10 +85,7 @@
var/mob/M = src.loc
if(istype(M) && istype(over_object, /obj/screen/inventory/hand))
var/obj/screen/inventory/hand/H = over_object
if(!M.temporarilyRemoveItemFromInventory(src))
return
M.put_in_hand(src, H.held_index)
M.putItemFromInventoryInHandIfPossible(src, H.held_index)
/obj/item/weapon/watertank/attackby(obj/item/W, mob/user, params)
if(W == noz)
+2 -2
View File
@@ -297,7 +297,7 @@
return (BRUTELOSS)
/obj/item/weapon/wirecutters/power/attack_self(mob/user)
playsound(get_turf(user),"sound/items/change_jaws.ogg",50,1)
playsound(get_turf(user), 'sound/items/change_jaws.ogg', 50, 1)
var/obj/item/weapon/crowbar/power/pryjaws = new /obj/item/weapon/crowbar/power
user << "<span class='notice'>You attach the pry jaws to [src].</span>"
qdel(src)
@@ -735,7 +735,7 @@
return (BRUTELOSS)
/obj/item/weapon/crowbar/power/attack_self(mob/user)
playsound(get_turf(user),"sound/items/change_jaws.ogg",50,1)
playsound(get_turf(user), 'sound/items/change_jaws.ogg', 50, 1)
var/obj/item/weapon/wirecutters/power/cutjaws = new /obj/item/weapon/wirecutters/power
user << "<span class='notice'>You attach the cutting jaws to [src].</span>"
qdel(src)
+2 -2
View File
@@ -496,7 +496,7 @@
/obj/item/weapon/twohanded/required/chainsaw/doomslayer/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type)
if(attack_type == PROJECTILE_ATTACK)
owner.visible_message("<span class='danger'>Ranged attacks just make [owner] angrier!</span>")
playsound(src, pick("sound/weapons/bulletflyby.ogg","sound/weapons/bulletflyby2.ogg","sound/weapons/bulletflyby3.ogg"), 75, 1)
playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, 1)
return 1
return 0
@@ -613,7 +613,7 @@
if(prob(final_block_chance))
if(attack_type == PROJECTILE_ATTACK)
owner.visible_message("<span class='danger'>[owner] deflects [attack_text] with [src]!</span>")
playsound(src, pick("sound/weapons/bulletflyby.ogg","sound/weapons/bulletflyby2.ogg","sound/weapons/bulletflyby3.ogg"), 75, 1)
playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, 1)
return 1
else
owner.visible_message("<span class='danger'>[owner] parries [attack_text] with [src]!</span>")
@@ -51,8 +51,8 @@
/obj/item/weapon/vending_refill/cola
machine_name = "Robust Softdrinks"
icon_state = "refill_cola"
charges = list(20, 2, 0)//of 60 standard, 6 contraband
init_charges = list(20, 2, 0)
charges = list(20, 2, 1)//of 60 standard, 6 contraband, 1 premium
init_charges = list(20, 2, 1)
/obj/item/weapon/vending_refill/cigarette
machine_name = "ShadyCigs Deluxe"
+1 -1
View File
@@ -388,7 +388,7 @@ var/highlander_claymores = 0
throw_speed = 0
sharpness = IS_SHARP
attack_verb = list("sawed", "torn", "cut", "chopped", "diced")
hitsound = "sound/weapons/chainsawhit.ogg"
hitsound = 'sound/weapons/chainsawhit.ogg'
/obj/item/weapon/mounted_chainsaw/dropped()
..()
+1 -1
View File
@@ -73,7 +73,7 @@
if(alert)
var/area/alarmed = get_area(src)
alarmed.burglaralert(src)
playsound(src, "sound/effects/alert.ogg", 50, 1)
playsound(src, 'sound/effects/alert.ogg', 50, 1)
/*
@@ -57,7 +57,7 @@
..()
var/area/A = get_area(src)
if(A)
notify_ghosts("An ash walker egg is ready to hatch in \the [A.name].", source = src, action=NOTIFY_ATTACK)
notify_ghosts("An ash walker egg is ready to hatch in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE)
//Timeless prisons: Spawns in Wish Granter prisons in lavaland. Ghosts become age-old users of the Wish Granter and are advised to seek repentance for their past.
/obj/effect/mob_spawn/human/exile
@@ -113,7 +113,7 @@
mob_species = species
var/area/A = get_area(src)
if(A)
notify_ghosts("\A [initial(species.id)] golem shell has been completed in \the [A.name].", source = src, action=NOTIFY_ATTACK)
notify_ghosts("\A [initial(species.id)] golem shell has been completed in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE)
if(has_owner && creator)
flavour_text = "You are a golem. You move slowly, but are highly resistant to heat and cold as well as blunt trauma. You are unable to wear clothes, but can still use most tools. \
Serve [creator], and assist [creator.p_them()] in completing [creator.p_their()] goals at any cost."
@@ -81,7 +81,7 @@
return
if(user.pulling != L)
return
playsound(src.loc, "sound/effects/splat.ogg", 25, 1)
playsound(src.loc, 'sound/effects/splat.ogg', 25, 1)
L.visible_message("<span class='danger'>[user] slams [L] onto the meat spike!</span>", "<span class='userdanger'>[user] slams you onto the meat spike!</span>", "<span class='italics'>You hear a squishy wet noise.</span>")
L.loc = src.loc
L.emote("scream")
@@ -0,0 +1,90 @@
/obj/structure/life_candle
name = "life candle"
desc = "You are dead. Insert quarter to continue."
icon = 'icons/obj/candle.dmi'
icon_state = "candle1"
var/icon_state_active = "candle1_lit"
var/icon_state_inactive = "candle1"
anchored = TRUE
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
var/lit_luminosity = 2
var/list/datum/mind/linked_minds = list()
// If the body is destroyed, what do we spawn for them
var/mob_type = /mob/living/carbon/human
// If the respawned person is given a specific outfit
var/datum/outfit/outfit
// How long until we respawn them after their death.
var/respawn_time = 50
var/respawn_sound = 'sound/magic/Staff_animation.ogg'
/obj/structure/life_candle/attack_hand(mob/user)
if(!user.mind)
return
if(user.mind in linked_minds)
user.visible_message("<span class='notice'>[user] reaches out and pinches the flame of [src].</span>", "<span class='warning'>You sever the connection between yourself and [src].</span>")
linked_minds -= user.mind
else
user.visible_message("<span class='notice'>[user] touches [src]. It seems to respond to their presence!</span>", "<span class='warning'>You create a connection between you and [src].</span>")
linked_minds |= user.mind
update_icon()
float(linked_minds.len)
if(linked_minds.len)
START_PROCESSING(SSobj, src)
SetLuminosity(lit_luminosity)
else
STOP_PROCESSING(SSobj, src)
SetLuminosity(0)
/obj/structure/life_candle/update_icon()
if(linked_minds.len)
icon_state = icon_state_active
else
icon_state = icon_state_inactive
/obj/structure/life_candle/examine(mob/user)
. = ..()
if(linked_minds.len)
user << "[src] is active, and linked to [linked_minds.len] souls."
else
user << "It is static, still, unmoving."
/obj/structure/life_candle/process()
if(!linked_minds.len)
STOP_PROCESSING(SSobj, src)
return
for(var/m in linked_minds)
var/datum/mind/mind = m
if(!mind.current || (mind.current && mind.current.stat == DEAD))
addtimer(CALLBACK(src, .proc/respawn, mind), respawn_time, TIMER_UNIQUE)
/obj/structure/life_candle/proc/respawn(datum/mind/mind)
var/turf/T = get_turf(src)
var/mob/living/body
if(mind.current)
if(mind.current.stat != DEAD)
return
else
body = mind.current
if(!body)
body = new mob_type(T)
var/mob/ghostie = mind.get_ghost(TRUE)
if(ghostie.client && ghostie.client.prefs)
ghostie.client.prefs.copy_to(body)
mind.transfer_to(body)
else
body.forceMove(T)
body.revive(1,1)
mind.grab_ghost(TRUE)
body.flash_act()
if(ishuman(body) && istype(outfit))
outfit.equip(body)
playsound(T, respawn_sound, 50, 1)
+10 -15
View File
@@ -24,6 +24,7 @@
var/list/decals
var/requires_activation //add to air processing after initialize?
var/changing_turf = FALSE
/turf/SDQL_update(const/var_name, new_value)
if(var_name == "x" || var_name == "y" || var_name == "z")
@@ -50,12 +51,16 @@
/turf/proc/Initalize_Atmos(times_fired)
CalculateAdjacentTurfs()
/turf/Destroy()
/turf/Destroy(force)
if(!changing_turf)
stack_trace("Incorrect turf deletion")
changing_turf = FALSE
SSair.remove_from_active(src)
visibilityChanged()
initialized = FALSE
requires_activation = FALSE
..()
return QDEL_HINT_HARDDEL_NOW
return QDEL_HINT_IWILLGC
/turf/attack_hand(mob/user)
user.Move_Pulled(src)
@@ -188,24 +193,14 @@
return
if(!use_preloader && path == type) // Don't no-op if the map loader requires it to be reconstructed
return src
var/old_blueprint_data = blueprint_data
SSair.remove_from_active(src)
var/list/old_checkers = proximity_checkers
var/old_ex_level = explosion_level
var/old_ex_id = explosion_id
Destroy() //❄
changing_turf = TRUE
qdel(src) //Just get the side effects and call Destroy
var/turf/W = new path(src)
W.proximity_checkers = old_checkers
W.explosion_level = old_ex_level
W.explosion_id = old_ex_id
if(!defer_change)
W.AfterChange(ignore_air)
W.blueprint_data = old_blueprint_data
return W
/turf/proc/AfterChange(ignore_air = FALSE) //called after a turf has been replaced in ChangeTurf()
+1 -1
View File
@@ -62,7 +62,7 @@
var/ckeytext = ckey(key)
if(!establish_db_connection())
world.log << "Ban database connection failure. Key [ckeytext] not checked"
log_world("Ban database connection failure. Key [ckeytext] not checked")
diary << "Ban database connection failure. Key [ckeytext] not checked"
return
+2 -2
View File
@@ -129,7 +129,7 @@ var/list/admin_ranks = list() //list of all admin_rank datums
else
establish_db_connection()
if(!dbcon.IsConnected())
world.log << "Failed to connect to database in load_admin_ranks(). Reverting to legacy system."
log_world("Failed to connect to database in load_admin_ranks(). Reverting to legacy system.")
diary << "Failed to connect to database in load_admin_ranks(). Reverting to legacy system."
config.admin_legacy_system = 1
load_admin_ranks()
@@ -204,7 +204,7 @@ var/list/admin_ranks = list() //list of all admin_rank datums
else
establish_db_connection()
if(!dbcon.IsConnected())
world.log << "Failed to connect to database in load_admins(). Reverting to legacy system."
log_world("Failed to connect to database in load_admins(). Reverting to legacy system.")
diary << "Failed to connect to database in load_admins(). Reverting to legacy system."
config.admin_legacy_system = 1
load_admins()
+2 -1
View File
@@ -163,7 +163,8 @@ var/list/admin_verbs_debug = list(
/client/proc/map_template_upload,
/client/proc/jump_to_ruin,
/client/proc/clear_dynamic_transit,
/client/proc/toggle_medal_disable
/client/proc/toggle_medal_disable,
/client/proc/view_runtimes
)
var/list/admin_verbs_possess = list(
/proc/possess,
+4 -1
View File
@@ -346,6 +346,7 @@
var/living_players = 0
var/living_players_connected = 0
var/living_players_antagonist = 0
var/brains = 0
var/other_players = 0
for(var/mob/M in mob_list)
if(M.ckey)
@@ -362,11 +363,13 @@
observers++
if(M.client)
observers_connected++
else if(isbrain(M))
brains++
else
other_players++
dat += "<BR><b><font color='blue' size='3'>Players:|[connected_players - lobby_players] ingame|[connected_players] connected|[lobby_players] lobby|</font></b>"
dat += "<BR><b><font color='green'>Living Players:|[living_players_connected] active|[living_players - living_players_connected] disconnected|[living_players_antagonist] antagonists|</font></b>"
dat += "<BR><b><font color='red'>Dead/Observing players:|[observers_connected] active|[observers - observers_connected] disconnected|</font></b>"
dat += "<BR><b><font color='red'>Dead/Observing players:|[observers_connected] active|[observers - observers_connected] disconnected|[brains] brains|</font></b>"
if(other_players)
dat += "<BR><span class='userdanger'>[other_players] players in invalid state or the statistics code is bugged!</span>"
dat += "<BR>"
+11
View File
@@ -2291,6 +2291,17 @@
ticker.mode.station_goals += G
modify_goals()
else if(href_list["viewruntime"])
var/datum/error_viewer/error_viewer = locate(href_list["viewruntime"])
if(!istype(error_viewer))
usr << "<span class='warning'>That runtime viewer no longer exists.</span>"
return
if(href_list["viewruntime_backto"])
error_viewer.show_to(owner, locate(href_list["viewruntime_backto"]), href_list["viewruntime_linear"])
else
error_viewer.show_to(owner, null, href_list["viewruntime_linear"])
else if(href_list["mentormemoeditlist"])
var/sql_key = sanitizeSQL("[href_list["memoeditlist"]]")
var/DBQuery/query_memoedits = dbcon.NewQuery("SELECT edits FROM [format_table_name("mentor_memo")] WHERE (ckey = '[sql_key]')")
+11 -1
View File
@@ -758,4 +758,14 @@ var/list/TYPES_SHORTCUTS = list(
message_admins("<span class='adminnotice'>[key_name_admin(src)] [global.medals_enabled ? "disabled" : "enabled"] the medal hub lockout.</span>")
feedback_add_details("admin_verb","TMH") // If...
log_admin("[key_name(src)] [global.medals_enabled ? "disabled" : "enabled"] the medal hub lockout.")
log_admin("[key_name(src)] [global.medals_enabled ? "disabled" : "enabled"] the medal hub lockout.")
/client/proc/view_runtimes()
set category = "Debug"
set name = "View Runtimes"
set desc = "Open the runtime Viewer"
if(!holder)
return
error_cache.show_to(src)
+1 -1
View File
@@ -193,7 +193,7 @@
if (rejected)
src << "[rejected] out of [count] objects rejected your edit"
world.log << "### MassVarEdit by [src]: [O.type] (A/R [accepted]/[rejected]) [variable]=[html_encode("[O.vars[variable]]")]([list2params(value)])"
log_world("### MassVarEdit by [src]: [O.type] (A/R [accepted]/[rejected]) [variable]=[html_encode("[O.vars[variable]]")]([list2params(value)])")
log_admin("[key_name(src)] mass modified [original_name]'s [variable] to [O.vars[variable]] ([accepted] objects modified)")
message_admins("[key_name_admin(src)] mass modified [original_name]'s [variable] to [O.vars[variable]] ([accepted] objects modified)")
+7 -7
View File
@@ -337,7 +337,7 @@ var/list/VVpixelmovement = list("step_x", "step_y", "bound_height", "bound_width
if (O.vv_edit_var(objectvar, L) == FALSE)
src << "Your edit was rejected by the object."
return
world.log << "### ListVarEdit by [src]: [(O ? O.type : "/list")] [objectvar]: ADDED=[var_value]"
log_world("### ListVarEdit by [src]: [(O ? O.type : "/list")] [objectvar]: ADDED=[var_value]")
log_admin("[key_name(src)] modified [original_name]'s [objectvar]: ADDED=[var_value]")
message_admins("[key_name_admin(src)] modified [original_name]'s [objectvar]: ADDED=[var_value]")
@@ -380,7 +380,7 @@ var/list/VVpixelmovement = list("step_x", "step_y", "bound_height", "bound_width
if (!O.vv_edit_var(objectvar, L))
src << "Your edit was rejected by the object."
return
world.log << "### ListVarEdit by [src]: [O.type] [objectvar]: CLEAR NULLS"
log_world("### ListVarEdit by [src]: [O.type] [objectvar]: CLEAR NULLS")
log_admin("[key_name(src)] modified [original_name]'s [objectvar]: CLEAR NULLS")
message_admins("[key_name_admin(src)] modified [original_name]'s list [objectvar]: CLEAR NULLS")
return
@@ -390,7 +390,7 @@ var/list/VVpixelmovement = list("step_x", "step_y", "bound_height", "bound_width
if (!O.vv_edit_var(objectvar, L))
src << "Your edit was rejected by the object."
return
world.log << "### ListVarEdit by [src]: [O.type] [objectvar]: CLEAR DUPES"
log_world("### ListVarEdit by [src]: [O.type] [objectvar]: CLEAR DUPES")
log_admin("[key_name(src)] modified [original_name]'s [objectvar]: CLEAR DUPES")
message_admins("[key_name_admin(src)] modified [original_name]'s list [objectvar]: CLEAR DUPES")
return
@@ -400,7 +400,7 @@ var/list/VVpixelmovement = list("step_x", "step_y", "bound_height", "bound_width
if (!O.vv_edit_var(objectvar, L))
src << "Your edit was rejected by the object."
return
world.log << "### ListVarEdit by [src]: [O.type] [objectvar]: SHUFFLE"
log_world("### ListVarEdit by [src]: [O.type] [objectvar]: SHUFFLE")
log_admin("[key_name(src)] modified [original_name]'s [objectvar]: SHUFFLE")
message_admins("[key_name_admin(src)] modified [original_name]'s list [objectvar]: SHUFFLE")
return
@@ -477,7 +477,7 @@ var/list/VVpixelmovement = list("step_x", "step_y", "bound_height", "bound_width
if (O.vv_edit_var(objectvar, L))
src << "Your edit was rejected by the object."
return
world.log << "### ListVarEdit by [src]: [O.type] [objectvar]: REMOVED=[html_encode("[original_var]")]"
log_world("### ListVarEdit by [src]: [O.type] [objectvar]: REMOVED=[html_encode("[original_var]")]")
log_admin("[key_name(src)] modified [original_name]'s [objectvar]: REMOVED=[original_var]")
message_admins("[key_name_admin(src)] modified [original_name]'s [objectvar]: REMOVED=[original_var]")
return
@@ -496,7 +496,7 @@ var/list/VVpixelmovement = list("step_x", "step_y", "bound_height", "bound_width
if (O.vv_edit_var(objectvar, L) == FALSE)
src << "Your edit was rejected by the object."
return
world.log << "### ListVarEdit by [src]: [(O ? O.type : "/list")] [objectvar]: [original_var]=[new_var]"
log_world("### ListVarEdit by [src]: [(O ? O.type : "/list")] [objectvar]: [original_var]=[new_var]")
log_admin("[key_name(src)] modified [original_name]'s [objectvar]: [original_var]=[new_var]")
message_admins("[key_name_admin(src)] modified [original_name]'s varlist [objectvar]: [original_var]=[new_var]")
@@ -605,6 +605,6 @@ var/list/VVpixelmovement = list("step_x", "step_y", "bound_height", "bound_width
if (O.vv_edit_var(variable, var_new) == FALSE)
src << "Your edit was rejected by the object."
return
world.log << "### VarEdit by [src]: [O.type] [variable]=[html_encode("[O.vars[variable]]")]"
log_world("### VarEdit by [src]: [O.type] [variable]=[html_encode("[O.vars[variable]]")]")
log_admin("[key_name(src)] modified [original_name]'s [variable] to [O.vars[variable]]")
message_admins("[key_name_admin(src)] modified [original_name]'s [variable] to [O.vars[variable]]")
+5 -1
View File
@@ -508,7 +508,11 @@ Traitors and the like can also be revived with the previous role mostly intact.
log_admin("[key_name(usr)] deleted [O] at ([O.x],[O.y],[O.z])")
message_admins("[key_name_admin(usr)] deleted [O] at ([O.x],[O.y],[O.z])")
feedback_add_details("admin_verb","DEL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
qdel(O)
if(isturf(O))
var/turf/T = O
T.ChangeTurf(T.baseturf)
else
qdel(O)
/client/proc/cmd_admin_list_open_jobs()
set category = "Admin"
+1 -1
View File
@@ -93,7 +93,7 @@
M.temporarilyRemoveItemFromInventory(src, TRUE) //Remove the tank from your character,in case you were holding it
if(!M.put_in_hands(R)) //Equips the bomb if possible, or puts it on the floor.
forceMove(M.loc)
forceMove(get_turf(M))
R.bombassembly = S //Tell the bomb about its assembly part
S.master = R //Tell the assembly about its new owner
+2 -8
View File
@@ -37,17 +37,11 @@
create(ckey = user.ckey)
/obj/effect/mob_spawn/Initialize(mapload)
if(roundstart && (mapload || (ticker && ticker.current_state > GAME_STATE_SETTING_UP)))
if(instant || (roundstart && (mapload || (ticker && ticker.current_state > GAME_STATE_SETTING_UP))))
create()
else
poi_list |= src
/obj/effect/mob_spawn/New()
..()
if(instant)
create()
/obj/effect/mob_spawn/Destroy()
poi_list.Remove(src)
. = ..()
@@ -483,4 +477,4 @@
if(despawn == "No" || !loc || !Adjacent(user))
return
user.visible_message("<span class='notice'>[user.name] climbs back into cryosleep...</span>")
qdel(user)
qdel(user)
@@ -586,7 +586,7 @@ var/swapmaps_byname
else if(swapmaps_mode!=SWAPMAPS_TEXT && fexists("map_[template_id].txt"))
text=1
else
world.log << "SwapMaps error in SwapMaps_CreateFromTemplate(): map_[template_id] file not found."
log_world("SwapMaps error in SwapMaps_CreateFromTemplate(): map_[template_id] file not found.")
return
if(text)
S=new
@@ -613,7 +613,7 @@ var/swapmaps_byname
else if(swapmaps_mode!=SWAPMAPS_TEXT && fexists("map_[chunk_id].txt"))
text=1
else
world.log << "SwapMaps error in SwapMaps_LoadChunk(): map_[chunk_id] file not found."
log_world("SwapMaps error in SwapMaps_LoadChunk(): map_[chunk_id] file not found.")
return
if(text)
S=new
@@ -631,9 +631,11 @@ var/swapmaps_byname
/proc/SwapMaps_SaveChunk(chunk_id,turf/corner1,turf/corner2)
if(!corner1 || !corner2)
world.log << "SwapMaps error in SwapMaps_SaveChunk():"
if(!corner1) world.log << " corner1 turf is null"
if(!corner2) world.log << " corner2 turf is null"
log_world("SwapMaps error in SwapMaps_SaveChunk():")
if(!corner1)
log_world(" corner1 turf is null")
if(!corner2)
log_world(" corner2 turf is null")
return
var/swapmap/M=new
M.id=chunk_id
@@ -660,7 +662,7 @@ var/swapmaps_byname
else if(swapmaps_mode!=SWAPMAPS_TEXT && fexists("map_[id].txt"))
text=1
else
world.log << "SwapMaps error in SwapMaps_GetSize(): map_[id] file not found."
log_world("SwapMaps error in SwapMaps_GetSize(): map_[id] file not found.")
return
if(text)
S=new
+4 -4
View File
@@ -18,7 +18,7 @@ var/global/list/potentialRandomZlevels = generateMapList(filename = "config/away
maploader.load_map(file)
smooth_zlevel(world.maxz)
SortAreas()
world.log << "loaded [file] as z-level [world.maxz]"
log_world("loaded [file] as z-level [world.maxz]")
/proc/reset_gateway_spawns(reset = FALSE)
for(var/obj/machinery/gateway/G in world)
@@ -92,7 +92,7 @@ var/global/list/potentialRandomZlevels = generateMapList(filename = "config/away
if(ruins && ruins.len)
ruin = ruins[pick(ruins)]
else
world.log << "Ruin loader had no ruins to pick from with [budget] left to spend."
log_world("Ruin loader had no ruins to pick from with [budget] left to spend.")
break
// Can we afford it
if(ruin.cost > budget)
@@ -119,7 +119,7 @@ var/global/list/potentialRandomZlevels = generateMapList(filename = "config/away
if(!valid)
continue
world.log << "Ruin \"[ruin.name]\" placed at ([T.x], [T.y], [T.z])"
log_world("Ruin \"[ruin.name]\" placed at ([T.x], [T.y], [T.z])")
var/obj/effect/ruin_loader/R = new /obj/effect/ruin_loader(T)
R.Load(ruins,ruin)
@@ -129,7 +129,7 @@ var/global/list/potentialRandomZlevels = generateMapList(filename = "config/away
break
if(!overall_sanity)
world.log << "Ruin loader gave up with [budget] left to spend."
log_world("Ruin loader gave up with [budget] left to spend.")
/obj/effect/ruin_loader
+6 -2
View File
@@ -31,6 +31,7 @@ var/list/preferences_datums = list()
var/hotkeys = FALSE
var/tgui_fancy = TRUE
var/tgui_lock = TRUE
var/windowflashing = TRUE
var/toggles = TOGGLES_DEFAULT
var/chat_toggles = TOGGLES_DEFAULT_CHAT
var/ghost_form = "ghost"
@@ -66,7 +67,6 @@ var/list/preferences_datums = list()
var/list/custom_names = list("clown", "mime", "ai", "cyborg", "religion", "deity")
var/prefered_security_department = SEC_DEPT_RANDOM
var/uplink_spawn_loc = UPLINK_PDA
//Mob preview
var/icon/preview_icon = null
@@ -106,6 +106,8 @@ var/list/preferences_datums = list()
var/parallax = PARALLAX_DISABLE //Starting disabled by default so people stop freaking about about certain issues.
var/uplink_spawn_loc = UPLINK_PDA
/datum/preferences/New(client/C)
parent = C
custom_names["ai"] = pick(ai_names)
@@ -465,6 +467,7 @@ var/list/preferences_datums = list()
dat += "<b>Keybindings:</b> <a href='?_src_=prefs;preference=hotkeys'>[(hotkeys) ? "Hotkeys" : "Default"]</a><br>"
dat += "<b>tgui Style:</b> <a href='?_src_=prefs;preference=tgui_fancy'>[(tgui_fancy) ? "Fancy" : "No Frills"]</a><br>"
dat += "<b>tgui Monitors:</b> <a href='?_src_=prefs;preference=tgui_lock'>[(tgui_lock) ? "Primary" : "All"]</a><br>"
dat += "<b>Window Flashing:</b> <a href='?_src_=prefs;preference=winflash'>[(windowflashing) ? "Yes" : "No"]</a><br>"
dat += "<b>Play admin midis:</b> <a href='?_src_=prefs;preference=hear_midis'>[(toggles & SOUND_MIDI) ? "Yes" : "No"]</a><br>"
dat += "<b>Play lobby music:</b> <a href='?_src_=prefs;preference=lobby_music'>[(toggles & SOUND_LOBBY) ? "Yes" : "No"]</a><br>"
dat += "<b>Ghost ears:</b> <a href='?_src_=prefs;preference=ghost_ears'>[(chat_toggles & CHAT_GHOSTEARS) ? "All Speech" : "Nearest Creatures"]</a><br>"
@@ -1358,7 +1361,8 @@ var/list/preferences_datums = list()
tgui_fancy = !tgui_fancy
if("tgui_lock")
tgui_lock = !tgui_lock
if("winflash")
windowflashing = !windowflashing
if("hear_adminhelps")
toggles ^= SOUND_ADMINHELP
if("announce_login")
+6 -5
View File
@@ -153,6 +153,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["hotkeys"] >> hotkeys
S["tgui_fancy"] >> tgui_fancy
S["tgui_lock"] >> tgui_lock
S["windowflash"] >> windowflashing
if(islist(S["be_special"]))
S["be_special"] >> be_special
@@ -174,7 +175,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["uses_glasses_colour"]>> uses_glasses_colour
S["clientfps"] >> clientfps
S["parallax"] >> parallax
S["uplink_loc"] >> uplink_spawn_loc
//citadel code
S["arousable"] >> arousable
@@ -190,6 +190,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
hotkeys = sanitize_integer(hotkeys, 0, 1, initial(hotkeys))
tgui_fancy = sanitize_integer(tgui_fancy, 0, 1, initial(tgui_fancy))
tgui_lock = sanitize_integer(tgui_lock, 0, 1, initial(tgui_lock))
windowflashing = sanitize_integer(windowflashing, 0, 1, initial(windowflashing))
default_slot = sanitize_integer(default_slot, 1, max_save_slots, initial(default_slot))
toggles = sanitize_integer(toggles, 0, 65535, initial(toggles))
clientfps = sanitize_integer(clientfps, 0, 1000, 0)
@@ -218,6 +219,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["hotkeys"] << hotkeys
S["tgui_fancy"] << tgui_fancy
S["tgui_lock"] << tgui_lock
S["windowflash"] << windowflashing
S["be_special"] << be_special
S["default_slot"] << default_slot
S["toggles"] << toggles
@@ -290,6 +292,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["undershirt"] >> undershirt
S["socks"] >> socks
S["backbag"] >> backbag
S["uplink_loc"] >> uplink_spawn_loc
S["feature_mcolor"] >> features["mcolor"]
S["feature_mcolor2"] >> features["mcolor2"]
S["feature_mcolor3"] >> features["mcolor3"]
@@ -372,6 +375,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
eye_color = sanitize_hexcolor(eye_color, 3, 0)
skin_tone = sanitize_inlist(skin_tone, skin_tones)
backbag = sanitize_inlist(backbag, backbaglist, initial(backbag))
uplink_spawn_loc = sanitize_inlist(uplink_spawn_loc, uplink_spawn_loc_list, initial(uplink_spawn_loc))
features["mcolor"] = sanitize_hexcolor(features["mcolor"], 3, 0)
features["mcolor2"] = sanitize_hexcolor(features["mcolor2"], 3, 0)
features["mcolor3"] = sanitize_hexcolor(features["mcolor3"], 3, 0)
@@ -393,8 +397,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
features["xenodorsal"] = sanitize_inlist(features["xenodorsal"], xeno_dorsal_list)
features["feature_lizard_legs"] = sanitize_inlist(features["legs"], legs_list, "Normal Legs")
uplink_spawn_loc = sanitize_inlist(uplink_spawn_loc, uplink_spawn_loc_list, initial(uplink_spawn_loc))
joblessrole = sanitize_integer(joblessrole, 1, 3, initial(joblessrole))
job_civilian_high = sanitize_integer(job_civilian_high, 0, 65535, initial(job_civilian_high))
job_civilian_med = sanitize_integer(job_civilian_med, 0, 65535, initial(job_civilian_med))
@@ -435,6 +437,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["undershirt"] << undershirt
S["socks"] << socks
S["backbag"] << backbag
S["uplink_loc"] << uplink_spawn_loc
S["flavor_text"] << flavor_text
S["species"] << pref_species.id
S["feature_mcolor"] << features["mcolor"]
@@ -465,8 +468,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["religion_name"] << custom_names["religion"]
S["deity_name"] << custom_names["deity"]
S["prefered_security_department"] << prefered_security_department
S["uplink_loc"] << uplink_spawn_loc
//Jobs
S["joblessrole"] << joblessrole
+3 -7
View File
@@ -46,14 +46,10 @@
if(istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech
return
if(!M.restrained() && !M.stat && loc == M && istype(over_object, /obj/screen/inventory/hand))
if(!M.incapacitated() && loc == M && istype(over_object, /obj/screen/inventory/hand))
var/obj/screen/inventory/hand/H = over_object
if(!M.temporarilyRemoveItemFromInventory(src))
return
if(!M.put_in_hand(src, H.held_index))
qdel(src)
return
add_fingerprint(usr)
if(M.putItemFromInventoryInHandIfPossible(src, H.held_index))
add_fingerprint(usr)
/obj/item/clothing/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback)
if(pockets)
+1 -1
View File
@@ -15,7 +15,7 @@
/obj/item/clothing/shoes/clown_shoes/banana_shoes/step_action()
if(on)
if(footstep > 1)//honks when its on
playsound(src, "sound/items/bikehorn.ogg", 75, 1)
playsound(src, 'sound/items/bikehorn.ogg', 75, 1)
footstep = 0
else
footstep++
+2 -2
View File
@@ -63,12 +63,12 @@
var/current_time = time_stamp()
if(!fingerprintshidden[M.key])
fingerprintshidden[M.key] = "First: [M.real_name]\[[current_time]\][hasgloves]."
fingerprintshidden[M.key] = "First: [M.real_name]\[[current_time]\][hasgloves]. Ckey: [M.ckey]"
else
var/laststamppos = findtext(fingerprintshidden[M.key], " Last: ")
if(laststamppos)
fingerprintshidden[M.key] = copytext(fingerprintshidden[M.key], 1, laststamppos)
fingerprintshidden[M.key] += " Last: [M.real_name]\[[current_time]\][hasgloves]."
fingerprintshidden[M.key] += " Last: [M.real_name]\[[current_time]\][hasgloves]. Ckey: [M.ckey]"
fingerprintslast = M.ckey
+114
View File
@@ -0,0 +1,114 @@
var/global/list/error_last_seen = list()
var/global/list/error_cooldown = list() /* Error_cooldown items will either be positive(cooldown time) or negative(silenced error)
If negative, starts at -1, and goes down by 1 each time that error gets skipped*/
var/global/total_runtimes = 0
var/global/total_runtimes_skipped = 0
#ifdef DEBUG
/world/Error(exception/E, datum/e_src)
if(!istype(E)) //Something threw an unusual exception
log_world("\[[time_stamp()]] Uncaught exception: [E]")
return ..()
if(!error_last_seen) // A runtime is occurring too early in start-up initialization
return ..()
total_runtimes++
var/erroruid = "[E.file][E.line]"
var/last_seen = error_last_seen[erroruid]
var/cooldown = error_cooldown[erroruid] || 0
if(last_seen == null)
error_last_seen[erroruid] = world.time
last_seen = world.time
if(cooldown < 0)
error_cooldown[erroruid]-- //Used to keep track of skip count for this error
total_runtimes_skipped++
return //Error is currently silenced, skip handling it
//Handle cooldowns and silencing spammy errors
var/silencing = FALSE
// We can runtime before config is initialized because BYOND initialize objs/map before a bunch of other stuff happens.
// This is a bunch of workaround code for that. Hooray!
var/configured_error_cooldown = initial(config.error_cooldown)
var/configured_error_limit = initial(config.error_limit)
var/configured_error_silence_time = initial(config.error_silence_time)
if(config)
configured_error_cooldown = config.error_cooldown
configured_error_limit = config.error_limit
configured_error_silence_time = config.error_silence_time
//Each occurence of an unique error adds to its cooldown time...
cooldown = max(0, cooldown - (world.time - last_seen)) + configured_error_cooldown
// ... which is used to silence an error if it occurs too often, too fast
if(cooldown > configured_error_cooldown * configured_error_limit)
cooldown = -1
silencing = TRUE
spawn(0)
usr = null
sleep(configured_error_silence_time)
var/skipcount = abs(error_cooldown[erroruid]) - 1
error_cooldown[erroruid] = 0
if(skipcount > 0)
world.log << "\[[time_stamp()]] Skipped [skipcount] runtimes in [E.file],[E.line]."
error_cache.log_error(E, skip_count = skipcount)
error_last_seen[erroruid] = world.time
error_cooldown[erroruid] = cooldown
var/list/usrinfo = null
var/locinfo
if(istype(usr))
usrinfo = list(" usr: [datum_info_line(usr)]")
locinfo = atom_loc_line(usr)
if(locinfo)
usrinfo += " usr.loc: [locinfo]"
// The proceeding mess will almost definitely break if error messages are ever changed
var/list/splitlines = splittext(E.desc, "\n")
var/list/desclines = list()
if(LAZYLEN(splitlines) > ERROR_USEFUL_LEN) // If there aren't at least three lines, there's no info
for(var/line in splitlines)
if(LAZYLEN(line) < 3 || findtext(line, "source file:") || findtext(line, "usr.loc:"))
continue
if(findtext(line, "usr:"))
if(usrinfo)
desclines.Add(usrinfo)
usrinfo = null
continue // Our usr info is better, replace it
if(copytext(line, 1, 3) != " ")
desclines += (" " + line) // Pad any unpadded lines, so they look pretty
else
desclines += line
if(usrinfo) //If this info isn't null, it hasn't been added yet
desclines.Add(usrinfo)
if(silencing)
desclines += " (This error will now be silenced for [configured_error_silence_time / 600] minutes)"
if(error_cache)
error_cache.log_error(E, desclines)
world.log << "\[[time_stamp()]] Runtime in [E.file],[E.line]: [E]"
for(var/line in desclines)
world.log << line
/* This logs the runtime in the old format */
E.name = "\n\[[time2text(world.timeofday,"hh:mm:ss")]\][E.name]"
//Original
//
var/list/split = splittext(E.desc, "\n")
for (var/i in 1 to split.len)
if (split[i] != "")
split[i] = "\[[time2text(world.timeofday,"hh:mm:ss")]\][split[i]]"
E.desc = jointext(split, "\n")
if(config && config.log_runtimes)
world.log = runtime_diary
..(E)
world.log = null
#endif

Some files were not shown because too many files have changed in this diff Show More