Merge branch 'master' into upstream-merge-26425
This commit is contained in:
@@ -79,8 +79,8 @@
|
||||
validckey = 1
|
||||
if(!validckey)
|
||||
if(!banned_mob || (banned_mob && !IsGuestKey(banned_mob.key)))
|
||||
message_admins("<font color='red'>[key_name_admin(usr)] attempted to ban [ckey], but [ckey] has not been seen yet. Please only ban actual players.</font>",1)
|
||||
return
|
||||
if(alert(usr, "[ckey] has not been seen before, are you sure you want to create a ban for them?", "Unknown ckey", "Yes", "No", "Cancel") != "Yes")
|
||||
return
|
||||
|
||||
var/a_ckey
|
||||
var/a_computerid
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
|
||||
if(!SSdbcore.Connect())
|
||||
log_world("Ban database connection failure. Key [ckeytext] not checked")
|
||||
GLOB.diary << "Ban database connection failure. Key [ckeytext] not checked"
|
||||
GLOB.world_game_log << "Ban database connection failure. Key [ckeytext] not checked"
|
||||
return
|
||||
|
||||
var/ipquery = ""
|
||||
|
||||
@@ -1,50 +1,21 @@
|
||||
//By Carnwennan
|
||||
|
||||
//This system was made as an alternative to all the in-game lists and variables used to log stuff in-game.
|
||||
//lists and variables are great. However, they have several major flaws:
|
||||
//Firstly, they use memory. TGstation has one of the highest memory usage of all the ss13 branches.
|
||||
//Secondly, they are usually stored in an object. This means that they aren't centralised. It also means that
|
||||
//the data is lost when the object is deleted! This is especially annoying for things like the singulo engine!
|
||||
#define INVESTIGATE_DIR "data/investigate/"
|
||||
|
||||
//SYSTEM
|
||||
/proc/investigate_subject2file(subject)
|
||||
return file("[INVESTIGATE_DIR][subject].html")
|
||||
|
||||
/proc/investigate_reset()
|
||||
if(fdel(INVESTIGATE_DIR))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/atom/proc/investigate_log(message, subject)
|
||||
if(!message)
|
||||
return
|
||||
var/F = investigate_subject2file(subject)
|
||||
if(!F)
|
||||
atom/proc/investigate_log(message, subject)
|
||||
if(!message || !subject)
|
||||
return
|
||||
var/F = file("[GLOB.log_directory]/[subject].html")
|
||||
F << "<small>[time_stamp()] \ref[src] ([x],[y],[z])</small> || [src] [message]<br>"
|
||||
|
||||
//ADMINVERBS
|
||||
/client/proc/investigate_show( subject in list("hrefs","notes, memos, watchlist","singulo","wires","telesci", "gravity", "records", "cargo", "supermatter", "atmos", "experimentor", "botany") )
|
||||
|
||||
/client/proc/investigate_show( subject in list("hrefs","notes, memos, watchlist","singulo","wires","telesci", "gravity", "records", "cargo", "supermatter", "atmos", "experimentor", "botany") )
|
||||
set name = "Investigate"
|
||||
set category = "Admin"
|
||||
if(!holder)
|
||||
return
|
||||
switch(subject)
|
||||
if("singulo", "wires", "telesci", "gravity", "records", "cargo", "supermatter", "atmos", "botany") //general one-round-only stuff
|
||||
var/F = investigate_subject2file(subject)
|
||||
if(!F)
|
||||
to_chat(src, "<font color='red'>Error: admin_investigate: [INVESTIGATE_DIR][subject] is an invalid path or cannot be accessed.</font>")
|
||||
return
|
||||
src << browse(F,"window=investigate[subject];size=800x300")
|
||||
if("hrefs") //persistent logs and stuff
|
||||
if(GLOB.href_logfile)
|
||||
src << browse(GLOB.href_logfile,"window=investigate[subject];size=800x300")
|
||||
else if(!config.log_hrefs)
|
||||
to_chat(src, "<span class='danger'>Href logging is off and no logfile was found.</span>")
|
||||
return
|
||||
else
|
||||
to_chat(src, "<span class='danger'>No href logfile was found.</span>")
|
||||
return
|
||||
if("notes, memos, watchlist")
|
||||
browse_messages()
|
||||
else
|
||||
var/F = file("[GLOB.log_directory]/[subject].html")
|
||||
if(!fexists(F))
|
||||
to_chat(src, "<span class='danger'>No [subject] logfile was found.</span>")
|
||||
return
|
||||
src << browse(F,"window=investigate[subject];size=800x300")
|
||||
@@ -127,7 +127,7 @@ GLOBAL_PROTECT(admin_ranks)
|
||||
else
|
||||
if(!SSdbcore.Connect())
|
||||
log_world("Failed to connect to database in load_admin_ranks(). Reverting to legacy system.")
|
||||
GLOB.diary << "Failed to connect to database in load_admin_ranks(). Reverting to legacy system."
|
||||
GLOB.world_game_log << "Failed to connect to database in load_admin_ranks(). Reverting to legacy system."
|
||||
config.admin_legacy_system = 1
|
||||
load_admin_ranks()
|
||||
return
|
||||
@@ -202,7 +202,7 @@ GLOBAL_PROTECT(admin_ranks)
|
||||
else
|
||||
if(!SSdbcore.Connect())
|
||||
log_world("Failed to connect to database in load_admins(). Reverting to legacy system.")
|
||||
GLOB.diary << "Failed to connect to database in load_admins(). Reverting to legacy system."
|
||||
GLOB.world_game_log << "Failed to connect to database in load_admins(). Reverting to legacy system."
|
||||
config.admin_legacy_system = 1
|
||||
load_admins()
|
||||
return
|
||||
|
||||
@@ -4,18 +4,12 @@ GLOBAL_PROTECT(admin_verbs_default)
|
||||
GLOBAL_LIST_INIT(admin_verbs_default, world.AVerbsDefault())
|
||||
/world/proc/AVerbsDefault()
|
||||
return list(
|
||||
/client/proc/toggleadminhelpsound, /*toggles whether we hear a sound when adminhelps/PMs are used*/
|
||||
/client/proc/toggleannouncelogin, /*toggles if an admin's login is announced during a round*/
|
||||
/client/proc/deadmin, /*destroys our own admin datum so we can play as a regular player*/
|
||||
/client/proc/cmd_admin_say, /*admin-only ooc chat*/
|
||||
/client/proc/hide_verbs, /*hides all our adminverbs*/
|
||||
/client/proc/hide_most_verbs, /*hides all our hideable adminverbs*/
|
||||
/client/proc/debug_variables, /*allows us to -see- the variables of any instance in the game. +VAREDIT needed to modify*/
|
||||
/client/proc/deadchat, /*toggles deadchat on/off*/
|
||||
/client/proc/dsay, /*talk in deadchat using our ckey/fakekey*/
|
||||
/client/proc/toggleprayers, /*toggles prayers on/off*/
|
||||
/client/verb/toggleprayersounds, /*Toggles prayer sounds (HALLELUJAH!)*/
|
||||
/client/proc/toggle_hear_radio, /*toggles whether we hear the radio*/
|
||||
/client/proc/investigate_show, /*various admintools for investigation. Such as a singulo grief-log*/
|
||||
/client/proc/secrets,
|
||||
/client/proc/restart_controller,
|
||||
@@ -32,7 +26,6 @@ GLOBAL_PROTECT(admin_verbs_admin)
|
||||
GLOBAL_LIST_INIT(admin_verbs_admin, world.AVerbsAdmin())
|
||||
/world/proc/AVerbsAdmin()
|
||||
return list(
|
||||
/client/proc/player_panel_new, /*shows an interface for all players, with links to various panels*/
|
||||
/client/proc/invisimin, /*allows our mob to go invisible/visible*/
|
||||
// /datum/admins/proc/show_traitor_panel, /*interface which shows a mob's mind*/ -Removed due to rare practical use. Moved to debug verbs ~Errorage
|
||||
/datum/admins/proc/show_player_panel, /*shows an interface for individual players, with various links (links require additional flags*/
|
||||
@@ -46,16 +39,14 @@ GLOBAL_LIST_INIT(admin_verbs_admin, world.AVerbsAdmin())
|
||||
/datum/admins/proc/set_admin_notice,/*announcement all clients see when joining the server.*/
|
||||
/client/proc/admin_ghost, /*allows us to ghost/reenter body at will*/
|
||||
/client/proc/toggle_view_range, /*changes how far we can see*/
|
||||
/datum/admins/proc/view_txt_log, /*shows the server log (diary) for today*/
|
||||
/datum/admins/proc/view_txt_log, /*shows the server log (world_game_log) for today*/
|
||||
/datum/admins/proc/view_atk_log, /*shows the server combat-log, doesn't do anything presently*/
|
||||
/client/proc/cmd_admin_subtle_message, /*send an message to somebody as a 'voice in their head'*/
|
||||
/client/proc/cmd_admin_delete, /*delete an instance/object/mob/etc*/
|
||||
/client/proc/cmd_admin_check_contents, /*displays the contents of an instance*/
|
||||
/client/proc/check_antagonists, /*shows all antags*/
|
||||
/datum/admins/proc/access_news_network, /*allows access of newscasters*/
|
||||
/client/proc/giveruntimelog, /*allows us to give access to runtime logs to somebody*/
|
||||
/client/proc/getruntimelog, /*allows us to access runtime logs to somebody*/
|
||||
/client/proc/getserverlog, /*allows us to fetch server logs (diary) for other days*/
|
||||
/client/proc/getserverlog, /*allows us to fetch server logs (world_game_log) for other days*/
|
||||
/client/proc/jumptocoord, /*we ghost and jump to a coordinate*/
|
||||
/client/proc/Getmob, /*teleports a mob to our location*/
|
||||
/client/proc/Getkey, /*teleports a mob with a certain ckey to our location*/
|
||||
@@ -116,7 +107,6 @@ GLOBAL_LIST_INIT(admin_verbs_server, world.AVerbsServer())
|
||||
/datum/admins/proc/end_round,
|
||||
/datum/admins/proc/delay,
|
||||
/datum/admins/proc/toggleaban,
|
||||
/client/proc/toggle_log_hrefs,
|
||||
/client/proc/everyone_random,
|
||||
/datum/admins/proc/toggleAI,
|
||||
/client/proc/cmd_admin_delete, /*delete an instance/object/mob/etc*/
|
||||
@@ -182,9 +172,6 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list(
|
||||
/client/proc/set_ooc,
|
||||
/client/proc/reset_ooc,
|
||||
/client/proc/deadmin,
|
||||
/client/proc/deadchat,
|
||||
/client/proc/toggleprayers,
|
||||
/client/proc/toggle_hear_radio,
|
||||
/datum/admins/proc/show_traitor_panel,
|
||||
/datum/admins/proc/toggleenter,
|
||||
/datum/admins/proc/toggleguests,
|
||||
@@ -223,7 +210,6 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list(
|
||||
/datum/admins/proc/restart,
|
||||
/datum/admins/proc/delay,
|
||||
/datum/admins/proc/toggleaban,
|
||||
/client/proc/toggle_log_hrefs,
|
||||
/client/proc/everyone_random,
|
||||
/datum/admins/proc/toggleAI,
|
||||
/client/proc/restart_controller,
|
||||
@@ -398,13 +384,6 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list(
|
||||
mob.invisibility = INVISIBILITY_OBSERVER
|
||||
to_chat(mob, "<span class='adminnotice'><b>Invisimin on. You are now as invisible as a ghost.</b></span>")
|
||||
|
||||
/client/proc/player_panel_new()
|
||||
set name = "Player Panel"
|
||||
set category = "Admin"
|
||||
if(holder)
|
||||
holder.player_panel_new()
|
||||
SSblackbox.add_details("admin_verb","Player Panel New") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/check_antagonists()
|
||||
set name = "Check Antagonists"
|
||||
set category = "Admin"
|
||||
@@ -638,19 +617,6 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list(
|
||||
togglebuildmode(src.mob)
|
||||
SSblackbox.add_details("admin_verb","Toggle Build Mode") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/toggle_log_hrefs()
|
||||
set name = "Toggle href logging"
|
||||
set category = "Server"
|
||||
if(!holder)
|
||||
return
|
||||
if(config)
|
||||
if(config.log_hrefs)
|
||||
config.log_hrefs = 0
|
||||
to_chat(src, "<b>Stopped logging hrefs</b>")
|
||||
else
|
||||
config.log_hrefs = 1
|
||||
to_chat(src, "<b>Started logging hrefs</b>")
|
||||
|
||||
/client/proc/check_ai_laws()
|
||||
set name = "Check AI Laws"
|
||||
set category = "Admin"
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
/datum/menu/Admin/Generate_list(client/C)
|
||||
if (C.holder)
|
||||
. = ..()
|
||||
|
||||
/datum/menu/Admin/verb/playerpanel()
|
||||
set name = "Player Panel"
|
||||
set desc = "Player Panel"
|
||||
set category = "Admin"
|
||||
usr.client.holder.player_panel_new()
|
||||
SSblackbox.add_details("admin_verb","Player Panel New") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
return
|
||||
@@ -1,10 +0,0 @@
|
||||
diff a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm (rejected hunks)
|
||||
@@ -8,7 +8,7 @@
|
||||
if(href_list["ahelp"])
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
-
|
||||
+
|
||||
var/ahelp_ref = href_list["ahelp"]
|
||||
var/datum/admin_help/AH = locate(ahelp_ref)
|
||||
if(AH)
|
||||
@@ -71,7 +71,7 @@
|
||||
if("select", "delete", "update")
|
||||
select_types = query_tree[query_tree[1]]
|
||||
|
||||
from_objs = SDQL_from_objs(query_tree["from"])
|
||||
from_objs = world.SDQL_from_objs(query_tree["from"])
|
||||
|
||||
var/list/objs = list()
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
if("call")
|
||||
for(var/datum/d in objs)
|
||||
try
|
||||
SDQL_var(d, query_tree["call"][1], source = d)
|
||||
world.SDQL_var(d, query_tree["call"][1], source = d)
|
||||
catch(var/exception/e)
|
||||
runtime_tracker += SDQL_parse_exception(e)
|
||||
runtimes++
|
||||
@@ -177,15 +177,6 @@
|
||||
returning += "Description: [E.desc]<BR>"
|
||||
return returning
|
||||
|
||||
/proc/SDQL_callproc_global(procname,args_list)
|
||||
set waitfor = FALSE
|
||||
WrapAdminProcCall(GLOBAL_PROC, procname, args_list)
|
||||
|
||||
/proc/SDQL_callproc(thing, procname, args_list)
|
||||
set waitfor = FALSE
|
||||
if(hascall(thing, procname))
|
||||
WrapAdminProcCall(thing, procname, args_list)
|
||||
|
||||
/proc/SDQL_parse(list/query_list)
|
||||
var/datum/SDQL_parser/parser = new()
|
||||
var/list/querys = list()
|
||||
@@ -249,15 +240,10 @@
|
||||
|
||||
|
||||
|
||||
/proc/SDQL_from_objs(list/tree)
|
||||
/world/proc/SDQL_from_objs(list/tree)
|
||||
if("world" in tree)
|
||||
if(IsAdminAdvancedProcCall())
|
||||
var/msg = "WARNING: Attempt to retrieve world reference made by [usr]!"
|
||||
log_admin(msg)
|
||||
message_admins(msg)
|
||||
return
|
||||
return world
|
||||
return SDQL_expression(world, tree)
|
||||
return src
|
||||
return SDQL_expression(src, tree)
|
||||
|
||||
/proc/SDQL_get_all(type, location)
|
||||
var/list/out = list()
|
||||
@@ -417,12 +403,12 @@
|
||||
result = dummy
|
||||
val += result
|
||||
else
|
||||
val = SDQL_var(object, expression, i, object)
|
||||
val = world.SDQL_var(object, expression, i, object)
|
||||
i = expression.len
|
||||
|
||||
return list("val" = val, "i" = i)
|
||||
|
||||
/proc/SDQL_var(datum/object, list/expression, start = 1, source)
|
||||
/world/proc/SDQL_var(datum/object, list/expression, start = 1, source)
|
||||
var/v
|
||||
var/long = start < expression.len
|
||||
if(object == world && long && expression[start + 1] == ".")
|
||||
@@ -456,11 +442,6 @@
|
||||
else
|
||||
return null
|
||||
if("world")
|
||||
if(IsAdminAdvancedProcCall())
|
||||
var/msg = "WARNING: Attempt to retrieve world reference made by [usr]!"
|
||||
log_admin(msg)
|
||||
message_admins(msg)
|
||||
return
|
||||
v = world
|
||||
if("global")
|
||||
v = GLOB
|
||||
|
||||
@@ -103,6 +103,7 @@
|
||||
if(!recipient)
|
||||
if(holder)
|
||||
to_chat(src, "<font color='red'>Error: Admin-PM: Client not found.</font>")
|
||||
to_chat(src, msg)
|
||||
else
|
||||
current_ticket.MessageNoRecipient(msg)
|
||||
return
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
if (!msg)
|
||||
return
|
||||
var/nicknames = world.file2list("config/admin_nicknames.txt")
|
||||
var/static/nicknames = world.file2list("config/admin_nicknames.txt")
|
||||
|
||||
var/rendered = "<span class='game deadsay'><span class='prefix'>DEAD:</span> <span class='name'>ADMIN([src.holder.fakekey ? pick(nicknames) : src.key])</span> says, <span class='message'>\"[msg]\"</span></span>"
|
||||
|
||||
|
||||
@@ -1,62 +1,3 @@
|
||||
/*
|
||||
HOW DO I LOG RUNTIMES?
|
||||
Firstly, start dreamdeamon if it isn't already running. Then select "world>Log Session" (or press the F3 key)
|
||||
navigate the popup window to the data/logs/runtimes/ folder from where your tgstation .dmb is located.
|
||||
(you may have to make this folder yourself)
|
||||
|
||||
OPTIONAL: you can select the little checkbox down the bottom to make dreamdeamon save the log everytime you
|
||||
start a world. Just remember to repeat these steps with a new name when you update to a new revision!
|
||||
|
||||
Save it with the name of the revision your server uses (e.g. r3459.txt).
|
||||
Game Masters will now be able to grant access any runtime logs you have archived this way!
|
||||
This will allow us to gather information on bugs across multiple servers and make maintaining the TG
|
||||
codebase for the entire /TG/station commuity a TONNE easier :3 Thanks for your help!
|
||||
*/
|
||||
|
||||
|
||||
//This proc allows Game Masters to grant a client access to the .getruntimelog verb
|
||||
//Permissions expire at the end of each round.
|
||||
//Runtimes can be used to meta or spot game-crashing exploits so it's advised to only grant coders that
|
||||
//you trust access. Also, it may be wise to ensure that they are not going to play in the current round.
|
||||
/client/proc/giveruntimelog()
|
||||
set name = ".giveruntimelog"
|
||||
set desc = "Give somebody access to any session logfiles saved to the /log/runtime/ folder."
|
||||
set category = null
|
||||
|
||||
if(!src.holder)
|
||||
to_chat(src, "<font color='red'>Only Admins may use this command.</font>")
|
||||
return
|
||||
|
||||
var/client/target = input(src,"Choose somebody to grant access to the server's runtime logs (permissions expire at the end of each round):","Grant Permissions",null) as null|anything in GLOB.clients
|
||||
if(!istype(target,/client))
|
||||
to_chat(src, "<font color='red'>Error: giveruntimelog(): Client not found.</font>")
|
||||
return
|
||||
|
||||
target.verbs |= /client/proc/getruntimelog
|
||||
to_chat(target, "<font color='red'>You have been granted access to runtime logs. Please use them responsibly or risk being banned.</font>")
|
||||
return
|
||||
|
||||
|
||||
//This proc allows download of runtime logs saved within the data/logs/ folder by dreamdeamon.
|
||||
//It works similarly to show-server-log.
|
||||
/client/proc/getruntimelog()
|
||||
set name = ".getruntimelog"
|
||||
set desc = "Retrieve any session logfiles saved by dreamdeamon."
|
||||
set category = null
|
||||
|
||||
var/path = browse_files("data/logs/runtimes/")
|
||||
if(!path)
|
||||
return
|
||||
|
||||
if(file_spam_check())
|
||||
return
|
||||
|
||||
message_admins("[key_name_admin(src)] accessed file: [path]")
|
||||
src << ftp(file(path))
|
||||
to_chat(src, "Attempting to send file, this may take a fair few minutes if the file is very large.")
|
||||
return
|
||||
|
||||
|
||||
//This proc allows download of past server logs saved within the data/logs/ folder.
|
||||
//It works similarly to show-server-log.
|
||||
/client/proc/getserverlog()
|
||||
@@ -83,10 +24,10 @@
|
||||
/datum/admins/proc/view_txt_log()
|
||||
set category = "Admin"
|
||||
set name = "Show Server Log"
|
||||
set desc = "Shows today's server log."
|
||||
set desc = "Shows server log for this round."
|
||||
|
||||
if(fexists("[GLOB.diary]"))
|
||||
src << ftp(GLOB.diary)
|
||||
if(fexists("[GLOB.world_game_log]"))
|
||||
src << ftp(GLOB.world_game_log)
|
||||
else
|
||||
to_chat(src, "<font color='red'>Server log not found, try using .getserverlog.</font>")
|
||||
return
|
||||
@@ -97,10 +38,10 @@
|
||||
/datum/admins/proc/view_atk_log()
|
||||
set category = "Admin"
|
||||
set name = "Show Server Attack Log"
|
||||
set desc = "Shows today's server attack log."
|
||||
set desc = "Shows server attack log for this round."
|
||||
|
||||
if(fexists("[GLOB.diaryofmeanpeople]"))
|
||||
src << ftp(GLOB.diaryofmeanpeople)
|
||||
if(fexists("[GLOB.world_attack_log]"))
|
||||
src << ftp(GLOB.world_attack_log)
|
||||
else
|
||||
to_chat(src, "<font color='red'>Server attack log not found, try using .getserverlog.</font>")
|
||||
return
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
var/res = alert(usr, "Show the title of this song to the players?",, "No", "Yes", "Cancel")
|
||||
switch(res)
|
||||
if("Yes")
|
||||
to_chat(world, "An admin played: [S]")
|
||||
to_chat(world, "<span class='boldannounce'>An admin played: [S]</span>")
|
||||
if("Cancel")
|
||||
return
|
||||
|
||||
|
||||
@@ -350,7 +350,6 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
|
||||
if(G_found.mind && !G_found.mind.active)
|
||||
G_found.mind.transfer_to(new_character) //be careful when doing stuff like this! I've already checked the mind isn't in use
|
||||
new_character.mind.special_verbs = list()
|
||||
else
|
||||
new_character.mind_initialize()
|
||||
if(!new_character.mind.assigned_role)
|
||||
|
||||
@@ -16,22 +16,17 @@
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 100, bomb = 0, bio = 100, rad = 100, fire = 40, acid = 0)
|
||||
|
||||
|
||||
/obj/machinery/meter/New()
|
||||
..()
|
||||
/obj/machinery/meter/Initialize(mapload)
|
||||
. = ..()
|
||||
SSair.atmos_machinery += src
|
||||
src.target = locate(/obj/machinery/atmospherics/pipe) in loc
|
||||
return 1
|
||||
if (mapload && !target)
|
||||
target = locate(/obj/machinery/atmospherics/pipe) in loc
|
||||
|
||||
/obj/machinery/meter/Destroy()
|
||||
SSair.atmos_machinery -= src
|
||||
src.target = null
|
||||
return ..()
|
||||
|
||||
/obj/machinery/meter/Initialize(mapload)
|
||||
..()
|
||||
if (mapload && !target)
|
||||
src.target = locate(/obj/machinery/atmospherics/pipe) in loc
|
||||
|
||||
/obj/machinery/meter/process_atmos()
|
||||
if(!target)
|
||||
icon_state = "meterX"
|
||||
|
||||
@@ -227,7 +227,7 @@ GLOBAL_DATUM(the_gateway, /obj/machinery/gateway/centerstation)
|
||||
if(check_exile_implant(C))
|
||||
say("Rejecting [AM]: Exile implant detected in contained lifeform.")
|
||||
return
|
||||
if(AM.buckled_mobs.len)
|
||||
if(AM.has_buckled_mobs())
|
||||
for(var/mob/living/carbon/C in AM.buckled_mobs)
|
||||
if(check_exile_implant(C))
|
||||
say("Rejecting [AM]: Exile implant detected in close proximity lifeform.")
|
||||
|
||||
@@ -64,17 +64,18 @@
|
||||
next_check = world.time + cooldown
|
||||
|
||||
/obj/structure/academy_wizard_spawner/proc/give_control()
|
||||
set waitfor = FALSE
|
||||
|
||||
if(!current_wizard)
|
||||
return
|
||||
spawn(0)
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as Wizard Academy Defender?", "wizard", null, ROLE_WIZARD, current_wizard)
|
||||
var/mob/dead/observer/chosen = null
|
||||
|
||||
if(candidates.len)
|
||||
chosen = pick(candidates)
|
||||
message_admins("[key_name_admin(chosen)] was spawned as Wizard Academy Defender")
|
||||
current_wizard.ghostize() // on the off chance braindead defender gets back in
|
||||
current_wizard.key = chosen.key
|
||||
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as Wizard Academy Defender?", "wizard", null, be_special_flag = ROLE_WIZARD, M = current_wizard)
|
||||
var/mob/dead/observer/chosen = null
|
||||
|
||||
if(candidates.len)
|
||||
chosen = pick(candidates)
|
||||
message_admins("[key_name_admin(chosen)] was spawned as Wizard Academy Defender")
|
||||
current_wizard.ghostize() // on the off chance braindead defender gets back in
|
||||
current_wizard.key = chosen.key
|
||||
|
||||
/obj/structure/academy_wizard_spawner/proc/summon_wizard()
|
||||
var/turf/T = src.loc
|
||||
|
||||
@@ -50,11 +50,6 @@
|
||||
material_id = MAT_PLASMA
|
||||
message = "cm3 of plasma"
|
||||
|
||||
/datum/export/material/plasma/get_cost(obj/O, contr = 0, emag = 0)
|
||||
. = ..()
|
||||
if(emag) // Syndicate pays you more for the plasma.
|
||||
. = round(. * 1.5)
|
||||
|
||||
// Uranium. Still useful for both power generation and nuclear annihilation.
|
||||
/datum/export/material/uranium
|
||||
cost = 400
|
||||
@@ -98,4 +93,4 @@
|
||||
message = "cm3 of glass"
|
||||
material_id = MAT_GLASS
|
||||
export_types = list(/obj/item/stack/sheet/glass, /obj/item/weapon/ore,
|
||||
/obj/item/weapon/shard)
|
||||
/obj/item/weapon/shard)
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
|
||||
// Wood. Quite expensive in the grim and dark 26 century.
|
||||
/datum/export/stack/wood
|
||||
cost = 25
|
||||
cost = 50
|
||||
unit_name = "wood plank"
|
||||
export_types = list(/obj/item/stack/sheet/mineral/wood)
|
||||
|
||||
|
||||
@@ -182,14 +182,14 @@
|
||||
/datum/supply_pack/emergency/syndicate
|
||||
name = "NULL_ENTRY"
|
||||
hidden = TRUE
|
||||
cost = 14000
|
||||
cost = 20000
|
||||
contains = list()
|
||||
crate_name = "emergency crate"
|
||||
crate_type = /obj/structure/closet/crate/internals
|
||||
dangerous = TRUE
|
||||
|
||||
/datum/supply_pack/emergency/syndicate/fill(obj/structure/closet/crate/C)
|
||||
var/crate_value = 50
|
||||
var/crate_value = 30
|
||||
var/list/uplink_items = get_uplink_items(SSticker.mode)
|
||||
while(crate_value)
|
||||
var/category = pick(uplink_items)
|
||||
@@ -828,6 +828,14 @@
|
||||
/obj/item/weapon/defibrillator/loaded)
|
||||
crate_name = "defibrillator crate"
|
||||
|
||||
/datum/supply_pack/medical/vending
|
||||
name = "Medical Vending Crate"
|
||||
cost = 2000
|
||||
contains = list(/obj/item/weapon/vending_refill/medical,
|
||||
/obj/item/weapon/vending_refill/medical,
|
||||
/obj/item/weapon/vending_refill/medical)
|
||||
crate_name = "medical vending crate"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////// Science /////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1681,8 +1689,8 @@
|
||||
crate_name = "art supply crate"
|
||||
|
||||
/datum/supply_pack/misc/soapstone
|
||||
name = "Librarian Engraving/Scribbling Crate"
|
||||
crate_name = "librarian engraving/scribbling crate"
|
||||
name = "Curator Engraving/Scribbling Crate"
|
||||
crate_name = "curator engraving/scribbling crate"
|
||||
cost = 3000
|
||||
contains = list(/obj/item/soapstone)
|
||||
access = GLOB.access_library
|
||||
|
||||
@@ -80,8 +80,7 @@
|
||||
*/
|
||||
|
||||
//Logs all hrefs
|
||||
if(config && config.log_hrefs && GLOB.href_logfile)
|
||||
GLOB.href_logfile << "<small>[time_stamp(show_ds = TRUE)] [src] (usr:[usr])</small> || [hsrc ? "[hsrc] " : ""][href]<br>"
|
||||
GLOB.world_href_log << "<small>[time_stamp(show_ds = TRUE)] [src] (usr:[usr])</small> || [hsrc ? "[hsrc] " : ""][href]<br>"
|
||||
|
||||
// Admin PM
|
||||
if(href_list["priv_msg"])
|
||||
@@ -361,6 +360,27 @@ GLOBAL_LIST(external_rsc_urls)
|
||||
|
||||
hook_vr("client_new",list(src))
|
||||
|
||||
var/list/topmenus = GLOB.menulist[/datum/menu]
|
||||
for (var/thing in topmenus)
|
||||
var/datum/menu/topmenu = thing
|
||||
var/topmenuname = "[topmenu]"
|
||||
if (topmenuname == "[topmenu.type]")
|
||||
var/list/tree = splittext(topmenuname, "/")
|
||||
topmenuname = tree[tree.len]
|
||||
winset(src, "[topmenu.type]", "parent=menu;name=[url_encode(topmenuname)]")
|
||||
var/list/entries = topmenu.Generate_list(src)
|
||||
for (var/child in entries)
|
||||
winset(src, "[url_encode(child)]", "[entries[child]]")
|
||||
if (!ispath(child, /datum/menu))
|
||||
var/atom/verb/verbpath = child
|
||||
if (copytext(verbpath.name,1,2) != "@")
|
||||
new child(src)
|
||||
|
||||
for (var/thing in prefs.menuoptions)
|
||||
var/datum/menu/menuitem = GLOB.menulist[thing]
|
||||
if (menuitem)
|
||||
menuitem.Load_checked(src)
|
||||
|
||||
//////////////
|
||||
//DISCONNECT//
|
||||
//////////////
|
||||
|
||||
@@ -168,6 +168,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
|
||||
var/uplink_spawn_loc = UPLINK_PDA
|
||||
|
||||
var/list/menuoptions
|
||||
|
||||
//citadel code
|
||||
var/arousable = TRUE //Allows players to disable arousal from the character creation menu
|
||||
var/flavor_text = ""
|
||||
@@ -194,6 +196,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if(!loaded_preferences_successfully)
|
||||
save_preferences()
|
||||
save_character() //let's save this new random character so it doesn't keep generating new ones.
|
||||
menuoptions = list()
|
||||
return
|
||||
|
||||
/datum/preferences/proc/ShowChoices(mob/user)
|
||||
@@ -790,7 +793,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if(href_list["jobbancheck"])
|
||||
var/job = sanitizeSQL(href_list["jobbancheck"])
|
||||
var/sql_ckey = sanitizeSQL(user.ckey)
|
||||
var/datum/DBQuery/query_get_jobban = SSdbcore.NewQuery("SELECT reason, bantime, duration, expiration_time, a_ckey FROM [format_table_name("ban")] WHERE ckey = '[sql_ckey]' AND (bantype = 'JOB_PERMABAN' OR (bantype = 'JOB_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned) AND job = '[job]'")
|
||||
var/datum/DBQuery/query_get_jobban = SSdbcore.NewQuery("SELECT reason, bantime, duration, expiration_time, a_ckey FROM [format_table_name("ban")] WHERE ckey = '[sql_ckey]' AND (bantype = 'JOB_PERMABAN' OR (bantype = 'JOB_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned) AND job = '[job]'")
|
||||
if(!query_get_jobban.warn_execute())
|
||||
return
|
||||
if(query_get_jobban.NextRow())
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//This is the lowest supported version, anything below this is completely obsolete and the entire savefile will be wiped.
|
||||
#define SAVEFILE_VERSION_MIN 10
|
||||
#define SAVEFILE_VERSION_MIN 15
|
||||
|
||||
//This is the current version, anything below this will attempt to update (if it's not obsolete)
|
||||
#define SAVEFILE_VERSION_MAX 20
|
||||
@@ -88,15 +88,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
|
||||
|
||||
/datum/preferences/proc/update_preferences(current_version, savefile/S)
|
||||
if(current_version < 10)
|
||||
toggles |= MEMBER_PUBLIC
|
||||
if(current_version < 11)
|
||||
chat_toggles = TOGGLES_DEFAULT_CHAT
|
||||
toggles = TOGGLES_DEFAULT
|
||||
if(current_version < 12)
|
||||
ignoring = list()
|
||||
if(current_version < 15)
|
||||
toggles |= SOUND_ANNOUNCEMENTS
|
||||
|
||||
|
||||
//should this proc get fairly long (say 3 versions long),
|
||||
@@ -106,16 +97,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
//It's only really meant to avoid annoying frequent players
|
||||
//if your savefile is 3 months out of date, then 'tough shit'.
|
||||
/datum/preferences/proc/update_character(current_version, savefile/S)
|
||||
if(pref_species && !(pref_species.id in GLOB.roundstart_species))
|
||||
var/rando_race = pick(config.roundstart_races)
|
||||
pref_species = new rando_race()
|
||||
|
||||
if(current_version < 13 || !istext(backbag))
|
||||
switch(backbag)
|
||||
if(2)
|
||||
backbag = DSATCHEL
|
||||
else
|
||||
backbag = DBACKPACK
|
||||
if(current_version < 16)
|
||||
var/berandom
|
||||
S["userandomjob"] >> berandom
|
||||
@@ -186,12 +167,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["tgui_fancy"] >> tgui_fancy
|
||||
S["tgui_lock"] >> tgui_lock
|
||||
S["windowflash"] >> windowflashing
|
||||
S["be_special"] >> be_special
|
||||
|
||||
if(islist(S["be_special"]))
|
||||
S["be_special"] >> be_special
|
||||
else //force update and store the old bitflag version of be_special
|
||||
needs_update = 12
|
||||
S["be_special"] >> old_be_special
|
||||
|
||||
S["default_slot"] >> default_slot
|
||||
S["chat_toggles"] >> chat_toggles
|
||||
@@ -207,6 +184,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["uses_glasses_colour"]>> uses_glasses_colour
|
||||
S["clientfps"] >> clientfps
|
||||
S["parallax"] >> parallax
|
||||
S["menuoptions"] >> menuoptions
|
||||
//citadel code
|
||||
S["arousable"] >> arousable
|
||||
|
||||
@@ -231,6 +209,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
ghost_orbit = sanitize_inlist(ghost_orbit, GLOB.ghost_orbits, initial(ghost_orbit))
|
||||
ghost_accs = sanitize_inlist(ghost_accs, GLOB.ghost_accs_options, GHOST_ACCS_DEFAULT_OPTION)
|
||||
ghost_others = sanitize_inlist(ghost_others, GLOB.ghost_others_options, GHOST_OTHERS_DEFAULT_OPTION)
|
||||
menuoptions = SANITIZE_LIST(menuoptions)
|
||||
be_special = SANITIZE_LIST(be_special)
|
||||
|
||||
|
||||
return 1
|
||||
|
||||
@@ -267,6 +248,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["uses_glasses_colour"]<< uses_glasses_colour
|
||||
S["clientfps"] << clientfps
|
||||
S["parallax"] << parallax
|
||||
S["menuoptions"] << menuoptions
|
||||
//citadel code
|
||||
S["arousable"] << arousable
|
||||
|
||||
@@ -299,9 +281,10 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
if(config.mutant_races && species_id && (species_id in GLOB.roundstart_species))
|
||||
var/newtype = GLOB.roundstart_species[species_id]
|
||||
pref_species = new newtype()
|
||||
else
|
||||
else if (config.roundstart_races.len)
|
||||
var/rando_race = pick(config.roundstart_races)
|
||||
pref_species = new rando_race()
|
||||
if (rando_race)
|
||||
pref_species = new rando_race()
|
||||
|
||||
if(!S["features["mcolor"]"] || S["features["mcolor"]"] == "#000")
|
||||
S["features["mcolor"]"] << "#FFF"
|
||||
@@ -565,7 +548,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
|
||||
#undef SAVEFILE_VERSION_MAX
|
||||
#undef SAVEFILE_VERSION_MIN
|
||||
/*
|
||||
|
||||
#ifdef TESTING
|
||||
//DEBUG
|
||||
//Some crude tools for testing savefiles
|
||||
//path is the savefile path
|
||||
@@ -576,4 +560,5 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
/client/verb/savefile_import(path as text)
|
||||
var/savefile/S = new /savefile(path)
|
||||
S.ImportText("/",file("[path].txt"))
|
||||
*/
|
||||
|
||||
#endif
|
||||
@@ -1,162 +1,249 @@
|
||||
//toggles
|
||||
/client/verb/toggle_ghost_ears()
|
||||
set name = "Show/Hide GhostEars"
|
||||
set category = "Preferences"
|
||||
set desc = ".Toggle Between seeing all mob speech, and only speech of nearby mobs"
|
||||
prefs.chat_toggles ^= CHAT_GHOSTEARS
|
||||
to_chat(src, "As a ghost, you will now [(prefs.chat_toggles & CHAT_GHOSTEARS) ? "see all speech in the world" : "only see speech from nearby mobs"].")
|
||||
prefs.save_preferences()
|
||||
SSblackbox.add_details("preferences_verb","Toggle Ghost Ears|[prefs.chat_toggles & CHAT_GHOSTEARS]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
//this works as is to create a single checked item, but has no back end code for toggleing the check yet
|
||||
#define TOGGLE_CHECKBOX(PARENT, CHILD) PARENT/CHILD/abstract = TRUE;PARENT/CHILD/checkbox = CHECKBOX_TOGGLE;PARENT/CHILD/verb/CHILD
|
||||
|
||||
/client/verb/toggle_ghost_sight()
|
||||
set name = "Show/Hide GhostSight"
|
||||
set category = "Preferences"
|
||||
set desc = ".Toggle Between seeing all mob emotes, and only emotes of nearby mobs"
|
||||
prefs.chat_toggles ^= CHAT_GHOSTSIGHT
|
||||
to_chat(src, "As a ghost, you will now [(prefs.chat_toggles & CHAT_GHOSTSIGHT) ? "see all emotes in the world" : "only see emotes from nearby mobs"].")
|
||||
prefs.save_preferences()
|
||||
SSblackbox.add_details("preferences_verb","Toggle Ghost Sight|[prefs.chat_toggles & CHAT_GHOSTSIGHT]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
//Example usage TOGGLE_CHECKBOX(datum/menu/Settings/Ghost/chatterbox, toggle_ghost_ears)()
|
||||
|
||||
/client/verb/toggle_ghost_whispers()
|
||||
set name = "Show/Hide GhostWhispers"
|
||||
set category = "Preferences"
|
||||
set desc = ".Toggle between hearing all whispers, and only whispers of nearby mobs"
|
||||
prefs.chat_toggles ^= CHAT_GHOSTWHISPER
|
||||
to_chat(src, "As a ghost, you will now [(prefs.chat_toggles & CHAT_GHOSTWHISPER) ? "see all whispers in the world" : "only see whispers from nearby mobs"].")
|
||||
prefs.save_preferences()
|
||||
SSblackbox.add_details("preferences_verb","Toggle Ghost Whispers|[prefs.chat_toggles & CHAT_GHOSTWHISPER]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
//override because we don't want to save preferences twice.
|
||||
/datum/menu/Settings/Set_checked(client/C, verbpath)
|
||||
if (checkbox == CHECKBOX_GROUP)
|
||||
C.prefs.menuoptions[type] = verbpath
|
||||
else if (checkbox == CHECKBOX_TOGGLE)
|
||||
var/checked = Get_checked(C)
|
||||
C.prefs.menuoptions[type] = !checked
|
||||
winset(C, "[verbpath]", "is-checked = [!checked]")
|
||||
|
||||
/client/verb/toggle_ghost_radio()
|
||||
set name = "Show/Hide GhostRadio"
|
||||
/datum/menu/Settings/verb/setup_character()
|
||||
set name = "Game Preferences"
|
||||
set category = "Preferences"
|
||||
set desc = ".Enable or disable hearing radio chatter as a ghost"
|
||||
prefs.chat_toggles ^= CHAT_GHOSTRADIO
|
||||
to_chat(src, "As a ghost, you will now [(prefs.chat_toggles & CHAT_GHOSTRADIO) ? "see radio chatter" : "not see radio chatter"].")
|
||||
prefs.save_preferences()
|
||||
SSblackbox.add_details("preferences_verb","Toggle Ghost Radio|[prefs.chat_toggles & CHAT_GHOSTRADIO]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! //social experiment, increase the generation whenever you copypaste this shamelessly GENERATION 1
|
||||
set desc = "Open Game Preferences Window"
|
||||
usr.client.prefs.current_tab = 1
|
||||
usr.client.prefs.ShowChoices(usr)
|
||||
|
||||
//toggles
|
||||
/datum/menu/Settings/Ghost/chatterbox
|
||||
name = "Chat Box Spam"
|
||||
|
||||
/client/verb/toggle_ghost_pda()
|
||||
TOGGLE_CHECKBOX(/datum/menu/Settings/Ghost/chatterbox, toggle_ghost_ears)()
|
||||
set name = "Show/Hide GhostEars"
|
||||
set category = "Preferences"
|
||||
set desc = "See All Speech"
|
||||
usr.client.prefs.chat_toggles ^= CHAT_GHOSTEARS
|
||||
to_chat(usr, "As a ghost, you will now [(usr.client.prefs.chat_toggles & CHAT_GHOSTEARS) ? "see all speech in the world" : "only see speech from nearby mobs"].")
|
||||
usr.client.prefs.save_preferences()
|
||||
SSblackbox.add_details("preferences_verb","Toggle Ghost Ears|[usr.client.prefs.chat_toggles & CHAT_GHOSTEARS]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
/datum/menu/Settings/Ghost/chatterbox/toggle_ghost_ears/Get_checked(client/C)
|
||||
return C.prefs.chat_toggles & CHAT_GHOSTEARS
|
||||
|
||||
TOGGLE_CHECKBOX(/datum/menu/Settings/Ghost/chatterbox, toggle_ghost_sight)()
|
||||
set name = "Show/Hide GhostSight"
|
||||
set category = "Preferences"
|
||||
set desc = "See All Emotes"
|
||||
usr.client.prefs.chat_toggles ^= CHAT_GHOSTSIGHT
|
||||
to_chat(usr, "As a ghost, you will now [(usr.client.prefs.chat_toggles & CHAT_GHOSTSIGHT) ? "see all emotes in the world" : "only see emotes from nearby mobs"].")
|
||||
usr.client.prefs.save_preferences()
|
||||
SSblackbox.add_details("preferences_verb","Toggle Ghost Sight|[usr.client.prefs.chat_toggles & CHAT_GHOSTSIGHT]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
/datum/menu/Settings/Ghost/chatterbox/toggle_ghost_sight/Get_checked(client/C)
|
||||
return C.prefs.chat_toggles & CHAT_GHOSTSIGHT
|
||||
|
||||
TOGGLE_CHECKBOX(/datum/menu/Settings/Ghost/chatterbox, toggle_ghost_whispers)()
|
||||
set name = "Show/Hide GhostWhispers"
|
||||
set category = "Preferences"
|
||||
set desc = "See All Whispers"
|
||||
usr.client.prefs.chat_toggles ^= CHAT_GHOSTWHISPER
|
||||
to_chat(usr, "As a ghost, you will now [(usr.client.prefs.chat_toggles & CHAT_GHOSTWHISPER) ? "see all whispers in the world" : "only see whispers from nearby mobs"].")
|
||||
usr.client.prefs.save_preferences()
|
||||
SSblackbox.add_details("preferences_verb","Toggle Ghost Whispers|[usr.client.prefs.chat_toggles & CHAT_GHOSTWHISPER]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
/datum/menu/Settings/Ghost/chatterbox/toggle_ghost_whispers/Get_checked(client/C)
|
||||
return C.prefs.chat_toggles & CHAT_GHOSTWHISPER
|
||||
|
||||
TOGGLE_CHECKBOX(/datum/menu/Settings/Ghost/chatterbox, toggle_ghost_radio)()
|
||||
set name = "Show/Hide GhostRadio"
|
||||
set category = "Preferences"
|
||||
set desc = "See All Radio Chatter"
|
||||
usr.client.prefs.chat_toggles ^= CHAT_GHOSTRADIO
|
||||
to_chat(usr, "As a ghost, you will now [(usr.client.prefs.chat_toggles & CHAT_GHOSTRADIO) ? "see radio chatter" : "not see radio chatter"].")
|
||||
usr.client.prefs.save_preferences()
|
||||
SSblackbox.add_details("preferences_verb","Toggle Ghost Radio|[usr.client.prefs.chat_toggles & CHAT_GHOSTRADIO]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! //social experiment, increase the generation whenever you copypaste this shamelessly GENERATION 1
|
||||
/datum/menu/Settings/Ghost/chatterbox/toggle_ghost_radio/Get_checked(client/C)
|
||||
return C.prefs.chat_toggles & CHAT_GHOSTRADIO
|
||||
|
||||
TOGGLE_CHECKBOX(/datum/menu/Settings/Ghost/chatterbox, toggle_ghost_pda)()
|
||||
set name = "Show/Hide GhostPDA"
|
||||
set category = "Preferences"
|
||||
set desc = ".Toggle Between seeing all mob pda messages, and only pda messages of nearby mobs"
|
||||
prefs.chat_toggles ^= CHAT_GHOSTPDA
|
||||
to_chat(src, "As a ghost, you will now [(prefs.chat_toggles & CHAT_GHOSTPDA) ? "see all pda messages in the world" : "only see pda messages from nearby mobs"].")
|
||||
prefs.save_preferences()
|
||||
SSblackbox.add_details("preferences_verb","Toggle Ghost PDA|[prefs.chat_toggles & CHAT_GHOSTPDA]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
set category = "Preferences"
|
||||
set desc = "See All PDA Messages"
|
||||
usr.client.prefs.chat_toggles ^= CHAT_GHOSTPDA
|
||||
to_chat(usr, "As a ghost, you will now [(usr.client.prefs.chat_toggles & CHAT_GHOSTPDA) ? "see all pda messages in the world" : "only see pda messages from nearby mobs"].")
|
||||
usr.client.prefs.save_preferences()
|
||||
SSblackbox.add_details("preferences_verb","Toggle Ghost PDA|[usr.client.prefs.chat_toggles & CHAT_GHOSTPDA]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
/datum/menu/Settings/Ghost/chatterbox/toggle_ghost_pda/Get_checked(client/C)
|
||||
return C.prefs.chat_toggles & CHAT_GHOSTPDA
|
||||
|
||||
/datum/menu/Settings/Ghost/chatterbox/Events
|
||||
name = "Events"
|
||||
|
||||
//please be aware that the following two verbs have inverted stat output, so that "Toggle Deathrattle|1" still means you activated it
|
||||
/client/verb/toggle_deathrattle()
|
||||
TOGGLE_CHECKBOX(/datum/menu/Settings/Ghost/chatterbox/Events, toggle_deathrattle)()
|
||||
set name = "Toggle Deathrattle"
|
||||
set category = "Preferences"
|
||||
set desc = "Toggle recieving a message in deadchat when sentient mobs die."
|
||||
prefs.toggles ^= DISABLE_DEATHRATTLE
|
||||
prefs.save_preferences()
|
||||
to_chat(usr, "You will [(prefs.toggles & DISABLE_DEATHRATTLE) ? "no longer" : "now"] get messages when a sentient mob dies.")
|
||||
SSblackbox.add_details("preferences_verb", "Toggle Deathrattle|[!(prefs.toggles & DISABLE_DEATHRATTLE)]") //If you are copy-pasting this, maybe you should spend some time reading the comments.
|
||||
|
||||
/client/verb/toggle_arrivalrattle()
|
||||
set category = "Preferences"
|
||||
set desc = "Death"
|
||||
usr.client.prefs.toggles ^= DISABLE_DEATHRATTLE
|
||||
usr.client.prefs.save_preferences()
|
||||
to_chat(usr, "You will [(usr.client.prefs.toggles & DISABLE_DEATHRATTLE) ? "no longer" : "now"] get messages when a sentient mob dies.")
|
||||
SSblackbox.add_details("preferences_verb", "Toggle Deathrattle|[!(usr.client.prefs.toggles & DISABLE_DEATHRATTLE)]") //If you are copy-pasting this, maybe you should spend some time reading the comments.
|
||||
/datum/menu/Settings/Ghost/chatterbox/Events/toggle_deathrattle/Get_checked(client/C)
|
||||
return !(C.prefs.toggles & DISABLE_DEATHRATTLE)
|
||||
|
||||
TOGGLE_CHECKBOX(/datum/menu/Settings/Ghost/chatterbox/Events, toggle_arrivalrattle)()
|
||||
set name = "Toggle Arrivalrattle"
|
||||
set category = "Preferences"
|
||||
set desc = "Toggle recieving a message in deadchat when someone joins the station."
|
||||
prefs.toggles ^= DISABLE_ARRIVALRATTLE
|
||||
to_chat(usr, "You will [(prefs.toggles & DISABLE_ARRIVALRATTLE) ? "no longer" : "now"] get messages when someone joins the station.")
|
||||
prefs.save_preferences()
|
||||
SSblackbox.add_details("preferences_verb", "Toggle Arrivalrattle|[!(prefs.toggles & DISABLE_ARRIVALRATTLE)]") //If you are copy-pasting this, maybe you should rethink where your life went so wrong.
|
||||
|
||||
/client/verb/togglemidroundantag()
|
||||
set category = "Preferences"
|
||||
set desc = "New Player Arrival"
|
||||
usr.client.prefs.toggles ^= DISABLE_ARRIVALRATTLE
|
||||
to_chat(usr, "You will [(usr.client.prefs.toggles & DISABLE_ARRIVALRATTLE) ? "no longer" : "now"] get messages when someone joins the station.")
|
||||
usr.client.prefs.save_preferences()
|
||||
SSblackbox.add_details("preferences_verb", "Toggle Arrivalrattle|[!(usr.client.prefs.toggles & DISABLE_ARRIVALRATTLE)]") //If you are copy-pasting this, maybe you should rethink where your life went so wrong.
|
||||
/datum/menu/Settings/Ghost/chatterbox/Events/toggle_arrivalrattle/Get_checked(client/C)
|
||||
return !(C.prefs.toggles & DISABLE_ARRIVALRATTLE)
|
||||
|
||||
TOGGLE_CHECKBOX(/datum/menu/Settings/Ghost, togglemidroundantag)()
|
||||
set name = "Toggle Midround Antagonist"
|
||||
set category = "Preferences"
|
||||
set desc = "Toggles whether or not you will be considered for antagonist status given during a round."
|
||||
prefs.toggles ^= MIDROUND_ANTAG
|
||||
prefs.save_preferences()
|
||||
to_chat(src, "You will [(prefs.toggles & MIDROUND_ANTAG) ? "now" : "no longer"] be considered for midround antagonist positions.")
|
||||
SSblackbox.add_details("preferences_verb","Toggle Midround Antag|[prefs.toggles & MIDROUND_ANTAG]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggletitlemusic()
|
||||
set category = "Preferences"
|
||||
set desc = "Midround Antagonist"
|
||||
usr.client.prefs.toggles ^= MIDROUND_ANTAG
|
||||
usr.client.prefs.save_preferences()
|
||||
to_chat(usr, "You will [(usr.client.prefs.toggles & MIDROUND_ANTAG) ? "now" : "no longer"] be considered for midround antagonist positions.")
|
||||
SSblackbox.add_details("preferences_verb","Toggle Midround Antag|[usr.client.prefs.toggles & MIDROUND_ANTAG]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
/datum/menu/Settings/Ghost/togglemidroundantag/Get_checked(client/C)
|
||||
return C.prefs.toggles & MIDROUND_ANTAG
|
||||
|
||||
TOGGLE_CHECKBOX(/datum/menu/Settings/Sound, toggletitlemusic)()
|
||||
set name = "Hear/Silence LobbyMusic"
|
||||
set category = "Preferences"
|
||||
set desc = "Toggles hearing the GameLobby music"
|
||||
prefs.toggles ^= SOUND_LOBBY
|
||||
prefs.save_preferences()
|
||||
if(prefs.toggles & SOUND_LOBBY)
|
||||
to_chat(src, "You will now hear music in the game lobby.")
|
||||
if(isnewplayer(mob))
|
||||
playtitlemusic()
|
||||
set desc = "Hear Music In Lobby"
|
||||
usr.client.prefs.toggles ^= SOUND_LOBBY
|
||||
usr.client.prefs.save_preferences()
|
||||
if(usr.client.prefs.toggles & SOUND_LOBBY)
|
||||
to_chat(usr, "You will now hear music in the game lobby.")
|
||||
if(isnewplayer(usr))
|
||||
usr.client.playtitlemusic()
|
||||
else
|
||||
to_chat(src, "You will no longer hear music in the game lobby.")
|
||||
mob.stop_sound_channel(CHANNEL_LOBBYMUSIC)
|
||||
SSblackbox.add_details("preferences_verb","Toggle Lobby Music|[prefs.toggles & SOUND_LOBBY]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
to_chat(usr, "You will no longer hear music in the game lobby.")
|
||||
usr.stop_sound_channel(CHANNEL_LOBBYMUSIC)
|
||||
SSblackbox.add_details("preferences_verb","Toggle Lobby Music|[usr.client.prefs.toggles & SOUND_LOBBY]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
/datum/menu/Settings/Sound/toggletitlemusic/Get_checked(client/C)
|
||||
return C.prefs.toggles & SOUND_LOBBY
|
||||
|
||||
|
||||
/client/verb/togglemidis()
|
||||
TOGGLE_CHECKBOX(/datum/menu/Settings/Sound, togglemidis)()
|
||||
set name = "Hear/Silence Midis"
|
||||
set category = "Preferences"
|
||||
set desc = "Toggles hearing sounds uploaded by admins"
|
||||
prefs.toggles ^= SOUND_MIDI
|
||||
prefs.save_preferences()
|
||||
if(prefs.toggles & SOUND_MIDI)
|
||||
to_chat(src, "You will now hear any sounds uploaded by admins.")
|
||||
set desc = "Hear Admin Triggered Sounds (Midis)"
|
||||
usr.client.prefs.toggles ^= SOUND_MIDI
|
||||
usr.client.prefs.save_preferences()
|
||||
if(usr.client.prefs.toggles & SOUND_MIDI)
|
||||
to_chat(usr, "You will now hear any sounds uploaded by admins.")
|
||||
else
|
||||
to_chat(src, "You will no longer hear sounds uploaded by admins")
|
||||
mob.stop_sound_channel(CHANNEL_ADMIN)
|
||||
SSblackbox.add_details("preferences_verb","Toggle Hearing Midis|[prefs.toggles & SOUND_MIDI]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
to_chat(usr, "You will no longer hear sounds uploaded by admins")
|
||||
usr.stop_sound_channel(CHANNEL_ADMIN)
|
||||
SSblackbox.add_details("preferences_verb","Toggle Hearing Midis|[usr.client.prefs.toggles & SOUND_MIDI]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
/datum/menu/Settings/Sound/togglemidis/Get_checked(client/C)
|
||||
return C.prefs.toggles & SOUND_MIDI
|
||||
|
||||
/client/verb/stop_client_sounds()
|
||||
set name = "Stop Sounds"
|
||||
|
||||
TOGGLE_CHECKBOX(/datum/menu/Settings/Sound, toggle_instruments)()
|
||||
set name = "Hear/Silence Instruments"
|
||||
set category = "Preferences"
|
||||
set desc = "Kills all currently playing sounds, use if admin taste in midis a shite"
|
||||
src << sound(null)
|
||||
SSblackbox.add_details("preferences_verb","Stop Self Sounds") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
set desc = "Hear In-game Instruments"
|
||||
usr.client.prefs.toggles ^= SOUND_INSTRUMENTS
|
||||
usr.client.prefs.save_preferences()
|
||||
if(usr.client.prefs.toggles & SOUND_INSTRUMENTS)
|
||||
to_chat(usr, "You will now hear people playing musical instruments.")
|
||||
else
|
||||
to_chat(usr, "You will no longer hear musical instruments.")
|
||||
SSblackbox.add_details("preferences_verb","Toggle Instruments|[usr.client.prefs.toggles & SOUND_INSTRUMENTS]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
/datum/menu/Settings/Sound/toggle_instruments/Get_checked(client/C)
|
||||
return C.prefs.toggles & SOUND_INSTRUMENTS
|
||||
|
||||
|
||||
/client/verb/listen_ooc()
|
||||
set name = "Show/Hide OOC"
|
||||
set category = "Preferences"
|
||||
set desc = "Toggles seeing OutOfCharacter chat"
|
||||
prefs.chat_toggles ^= CHAT_OOC
|
||||
prefs.save_preferences()
|
||||
to_chat(src, "You will [(prefs.chat_toggles & CHAT_OOC) ? "now" : "no longer"] see messages on the OOC channel.")
|
||||
SSblackbox.add_details("preferences_verb","Toggle Seeing OOC|[prefs.chat_toggles & CHAT_OOC]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/Toggle_Soundscape() //All new ambience should be added here so it works with this verb until someone better at things comes up with a fix that isn't awful
|
||||
TOGGLE_CHECKBOX(/datum/menu/Settings/Sound, Toggle_Soundscape)()
|
||||
set name = "Hear/Silence Ambience"
|
||||
set category = "Preferences"
|
||||
set desc = "Toggles hearing ambient sound effects"
|
||||
prefs.toggles ^= SOUND_AMBIENCE
|
||||
prefs.save_preferences()
|
||||
if(prefs.toggles & SOUND_AMBIENCE)
|
||||
to_chat(src, "You will now hear ambient sounds.")
|
||||
set desc = "Hear Ambient Sound Effects"
|
||||
usr.client.prefs.toggles ^= SOUND_AMBIENCE
|
||||
usr.client.prefs.save_preferences()
|
||||
if(usr.client.prefs.toggles & SOUND_AMBIENCE)
|
||||
to_chat(usr, "You will now hear ambient sounds.")
|
||||
else
|
||||
to_chat(src, "You will no longer hear ambient sounds.")
|
||||
src << sound(null, repeat = 0, wait = 0, volume = 0, channel = 1)
|
||||
src << sound(null, repeat = 0, wait = 0, volume = 0, channel = 2)
|
||||
SSblackbox.add_details("preferences_verb","Toggle Ambience|[prefs.toggles & SOUND_AMBIENCE]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
to_chat(usr, "You will no longer hear ambient sounds.")
|
||||
usr << sound(null, repeat = 0, wait = 0, volume = 0, channel = 1)
|
||||
usr << sound(null, repeat = 0, wait = 0, volume = 0, channel = 2)
|
||||
SSblackbox.add_details("preferences_verb","Toggle Ambience|[usr.client.prefs.toggles & SOUND_AMBIENCE]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
/datum/menu/Settings/Sound/Toggle_Soundscape/Get_checked(client/C)
|
||||
return C.prefs.toggles & SOUND_AMBIENCE
|
||||
|
||||
// This needs a toggle because you people are awful and spammed terrible music
|
||||
/client/verb/toggle_instruments()
|
||||
set name = "Hear/Silence Instruments"
|
||||
|
||||
TOGGLE_CHECKBOX(/datum/menu/Settings/Sound, toggle_ship_ambience)()
|
||||
set name = "Hear/Silence Ship Ambience"
|
||||
set category = "Preferences"
|
||||
set desc = "Toggles hearing musical instruments like the violin and piano"
|
||||
prefs.toggles ^= SOUND_INSTRUMENTS
|
||||
prefs.save_preferences()
|
||||
if(prefs.toggles & SOUND_INSTRUMENTS)
|
||||
to_chat(src, "You will now hear people playing musical instruments.")
|
||||
set desc = "Hear Ship Ambience Roar"
|
||||
usr.client.prefs.toggles ^= SOUND_SHIP_AMBIENCE
|
||||
usr.client.prefs.save_preferences()
|
||||
if(usr.client.prefs.toggles & SOUND_SHIP_AMBIENCE)
|
||||
to_chat(usr, "You will now hear ship ambience.")
|
||||
else
|
||||
to_chat(src, "You will no longer hear musical instruments.")
|
||||
SSblackbox.add_details("preferences_verb","Toggle Instruments|[prefs.toggles & SOUND_INSTRUMENTS]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
to_chat(usr, "You will no longer hear ship ambience.")
|
||||
usr << sound(null, repeat = 0, wait = 0, volume = 0, channel = 2)
|
||||
usr.client.ambience_playing = 0
|
||||
SSblackbox.add_details("preferences_verb", "Toggle Ship Ambience|[usr.client.prefs.toggles & SOUND_SHIP_AMBIENCE]") //If you are copy-pasting this, I bet you read this comment expecting to see the same thing :^)
|
||||
/datum/menu/Settings/Sound/toggle_ship_ambience/Get_checked(client/C)
|
||||
return C.prefs.toggles & SOUND_SHIP_AMBIENCE
|
||||
|
||||
//Lots of people get headaches from the normal ship ambience, this is to prevent that
|
||||
/client/verb/toggle_ship_ambience()
|
||||
set name = "Hear/Silence Ship Ambience"
|
||||
|
||||
TOGGLE_CHECKBOX(/datum/menu/Settings/Sound, toggle_announcement_sound)()
|
||||
set name = "Hear/Silence Announcements"
|
||||
set category = "Preferences"
|
||||
set desc = "Toggles hearing generalized ship ambience, no matter your area."
|
||||
prefs.toggles ^= SOUND_SHIP_AMBIENCE
|
||||
prefs.save_preferences()
|
||||
if(prefs.toggles & SOUND_SHIP_AMBIENCE)
|
||||
to_chat(src, "You will now hear ship ambience.")
|
||||
set desc = "Hear Announcement Sound"
|
||||
usr.client.prefs.toggles ^= SOUND_ANNOUNCEMENTS
|
||||
to_chat(usr, "You will now [(usr.client.prefs.toggles & SOUND_ANNOUNCEMENTS) ? "hear announcement sounds" : "no longer hear announcements"].")
|
||||
usr.client.prefs.save_preferences()
|
||||
SSblackbox.add_details("preferences_verb","Toggle Announcement Sound|[usr.client.prefs.toggles & SOUND_ANNOUNCEMENTS]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
/datum/menu/Settings/Sound/toggle_announcement_sound/Get_checked(client/C)
|
||||
return C.prefs.toggles & SOUND_ANNOUNCEMENTS
|
||||
|
||||
|
||||
TOGGLE_CHECKBOX(/datum/menu/Settings/Sound, toggleprayersounds)()
|
||||
set name = "Hear/Silence Prayer Sounds"
|
||||
set category = "Preferences"
|
||||
set desc = "Hear Prayer Sounds"
|
||||
usr.client.prefs.toggles ^= SOUND_PRAYERS
|
||||
usr.client.prefs.save_preferences()
|
||||
if(usr.client.prefs.toggles & SOUND_PRAYERS)
|
||||
to_chat(usr, "You will now hear prayer sounds.")
|
||||
else
|
||||
to_chat(src, "You will no longer hear ship ambience.")
|
||||
src << sound(null, repeat = 0, wait = 0, volume = 0, channel = 2)
|
||||
src.ambience_playing = 0
|
||||
SSblackbox.add_details("preferences_verb", "Toggle Ship Ambience|[prefs.toggles & SOUND_SHIP_AMBIENCE]") //If you are copy-pasting this, I bet you read this comment expecting to see the same thing :^)
|
||||
to_chat(usr, "You will no longer prayer sounds.")
|
||||
SSblackbox.add_details("admin_toggle", "Toggle Prayer Sounds|[usr.client.prefs.toggles & SOUND_PRAYERS]")
|
||||
/datum/menu/Settings/Sound/toggleprayersounds/Get_checked(client/C)
|
||||
return C.prefs.toggles & SOUND_PRAYERS
|
||||
|
||||
|
||||
/datum/menu/Settings/Sound/verb/stop_client_sounds()
|
||||
set name = "Stop Sounds"
|
||||
set category = "Preferences"
|
||||
set desc = "Stop Current Sounds"
|
||||
usr << sound(null)
|
||||
SSblackbox.add_details("preferences_verb","Stop Self Sounds") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
|
||||
TOGGLE_CHECKBOX(/datum/menu/Settings, listen_ooc)()
|
||||
set name = "Show/Hide OOC"
|
||||
set category = "Preferences"
|
||||
set desc = "Show OOC Chat"
|
||||
usr.client.prefs.chat_toggles ^= CHAT_OOC
|
||||
usr.client.prefs.save_preferences()
|
||||
to_chat(usr, "You will [(usr.client.prefs.chat_toggles & CHAT_OOC) ? "now" : "no longer"] see messages on the OOC channel.")
|
||||
SSblackbox.add_details("preferences_verb","Toggle Seeing OOC|[usr.client.prefs.chat_toggles & CHAT_OOC]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
/datum/menu/Settings/listen_ooc/Get_checked(client/C)
|
||||
return C.prefs.chat_toggles & CHAT_OOC
|
||||
|
||||
|
||||
GLOBAL_LIST_INIT(ghost_forms, list("ghost","ghostking","ghostian2","skeleghost","ghost_red","ghost_black", \
|
||||
"ghost_blue","ghost_yellow","ghost_green","ghost_pink", \
|
||||
@@ -246,13 +333,6 @@ GLOBAL_LIST_INIT(ghost_orbits, list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS
|
||||
prefs.save_preferences()
|
||||
SSblackbox.add_details("preferences_verb","Toggle Intent Selection|[prefs.toggles & INTENT_STYLE]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/setup_character()
|
||||
set name = "Game Preferences"
|
||||
set category = "Preferences"
|
||||
set desc = "Allows you to access the Setup Character screen. Changes to your character won't take effect until next round, but other changes will."
|
||||
prefs.current_tab = 1
|
||||
prefs.ShowChoices(usr)
|
||||
|
||||
/client/verb/toggle_ghost_hud_pref()
|
||||
set name = "Toggle Ghost HUD"
|
||||
set category = "Preferences"
|
||||
@@ -278,15 +358,6 @@ GLOBAL_LIST_INIT(ghost_orbits, list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS
|
||||
to_chat(src, "<span class='notice'>You will no longer examine things you click on.</span>")
|
||||
SSblackbox.add_details("preferences_verb","Toggle Ghost Inquisitiveness|[prefs.inquisitive_ghost]")
|
||||
|
||||
/client/verb/toggle_announcement_sound()
|
||||
set name = "Hear/Silence Announcements"
|
||||
set category = "Preferences"
|
||||
set desc = ".Toggles hearing Central Command, Captain, VOX, and other announcement sounds"
|
||||
prefs.toggles ^= SOUND_ANNOUNCEMENTS
|
||||
to_chat(src, "You will now [(prefs.toggles & SOUND_ANNOUNCEMENTS) ? "hear announcement sounds" : "no longer hear announcements"].")
|
||||
prefs.save_preferences()
|
||||
SSblackbox.add_details("preferences_verb","Toggle Announcement Sound|[prefs.toggles & SOUND_ANNOUNCEMENTS]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
//Admin Preferences
|
||||
/client/proc/toggleadminhelpsound()
|
||||
set name = "Hear/Silence Adminhelps"
|
||||
@@ -338,14 +409,3 @@ GLOBAL_LIST_INIT(ghost_orbits, list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS
|
||||
to_chat(src, "You will [(prefs.chat_toggles & CHAT_PRAYER) ? "now" : "no longer"] see prayerchat.")
|
||||
SSblackbox.add_details("admin_toggle","Toggle Prayer Visibility|[prefs.chat_toggles & CHAT_PRAYER]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/verb/toggleprayersounds()
|
||||
set name = "Hear/Silence Prayer Sounds"
|
||||
set category = "Preferences"
|
||||
set desc = "Toggles hearing pray sounds."
|
||||
prefs.toggles ^= SOUND_PRAYERS
|
||||
prefs.save_preferences()
|
||||
if(prefs.toggles & SOUND_PRAYERS)
|
||||
to_chat(src, "You will now hear prayer sounds.")
|
||||
else
|
||||
to_chat(src, "You will no longer prayer sounds.")
|
||||
SSblackbox.add_details("admin_toggle", "Toggle Prayer Sounds|[prefs.toggles & SOUND_PRAYERS]")
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
return
|
||||
if(confirm == "Yes")
|
||||
suiciding = 1
|
||||
log_game("[key_name(src)] (job: [job ? "[job]" : "None"]) commited suicide at [get_area(src)].")
|
||||
message_admins("[key_name(src)] (job: [job ? "[job]" : "None"]) commited suicide at [get_area(src)].")
|
||||
log_game("[key_name(src)] (job: [job ? "[job]" : "None"]) committed suicide at [get_area(src)].")
|
||||
message_admins("[key_name(src)] (job: [job ? "[job]" : "None"]) committed suicide at [get_area(src)].")
|
||||
var/obj/item/held_item = get_active_held_item()
|
||||
if(held_item)
|
||||
var/damagetype = held_item.suicide_act(src)
|
||||
|
||||
@@ -161,7 +161,9 @@
|
||||
/obj/item/clothing/obj_break(damage_flag)
|
||||
if(!damaged_clothes)
|
||||
update_clothes_damaged_state(TRUE)
|
||||
to_chat(usr, "<span class='notice'>Your [src] starts to fall apart!")
|
||||
if(ismob(loc)) //It's not important enough to warrant a message if nobody's wearing it
|
||||
var/mob/M = loc
|
||||
M.visible_message("<span class='warning'>[M]'s [name] starts to fall apart!", "<span class='warning'>Your [name] starts to fall apart!")
|
||||
|
||||
/obj/item/clothing/proc/update_clothes_damaged_state(damaging = TRUE)
|
||||
var/index = "\ref[initial(icon)]-[initial(icon_state)]"
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
vision_flags = 0
|
||||
darkness_view = 2
|
||||
invis_view = SEE_INVISIBLE_LIVING
|
||||
lighting_alpha = null
|
||||
to_chat(user, "<span class='notice'>You toggle the goggles' scanning mode to \[T-Ray].</span>")
|
||||
else
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
/obj/item/clothing/head/collectable/paper
|
||||
name = "collectable paper hat"
|
||||
desc = "What looks like an ordinary paper hat is actually a rare and valuable collector's edition paper hat. Keep away from water, fire, and Librarians."
|
||||
desc = "What looks like an ordinary paper hat is actually a rare and valuable collector's edition paper hat. Keep away from water, fire, and Curators."
|
||||
icon_state = "paper"
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head
|
||||
|
||||
@@ -158,4 +158,5 @@
|
||||
name = "treasure hunter's fedora"
|
||||
desc = "You got red text today kid, but it doesn't mean you have to like it."
|
||||
icon_state = "curator"
|
||||
armor = list(melee = 25, bullet = 5, laser = 25, energy = 10, bomb = 0, bio = 0, rad = 0, fire = 30, acid = 50)
|
||||
armor = list(melee = 25, bullet = 5, laser = 25, energy = 10, bomb = 0, bio = 0, rad = 0, fire = 30, acid = 50)
|
||||
pockets = /obj/item/weapon/storage/internal/pocket/small
|
||||
@@ -326,9 +326,6 @@
|
||||
disable_flight(1)
|
||||
if(!suit)
|
||||
disable_flight(1)
|
||||
if(!resync)
|
||||
addtimer(CALLBACK(src, .proc/resync), 600)
|
||||
resync = 1
|
||||
if(!wearer) //Oh god our user fell off!
|
||||
disable_flight(1)
|
||||
if(!pressure && brake)
|
||||
@@ -340,12 +337,6 @@
|
||||
stabilizer = FALSE
|
||||
usermessage("Warning: Sensor data is not being recieved from flight shoes. Stabilizers and airbrake modules OFFLINE!", 2)
|
||||
|
||||
//Resync the suit
|
||||
/obj/item/device/flightpack/proc/resync()
|
||||
resync = FALSE
|
||||
suit.resync()
|
||||
|
||||
//How fast should the wearer be?
|
||||
/obj/item/device/flightpack/proc/update_slowdown()
|
||||
if(!flight)
|
||||
suit.slowdown = slowdown_ground
|
||||
@@ -356,20 +347,11 @@
|
||||
/obj/item/device/flightpack/process()
|
||||
if(!suit || (processing_mode == FLIGHTSUIT_PROCESSING_NONE))
|
||||
return FALSE
|
||||
update_slowdown()
|
||||
update_icon()
|
||||
check_conditions()
|
||||
calculate_momentum_speed()
|
||||
momentum_drift()
|
||||
handle_boost()
|
||||
handle_damage()
|
||||
handle_flight()
|
||||
|
||||
/obj/item/device/flightpack/proc/handle_flight()
|
||||
if(!flight)
|
||||
return FALSE
|
||||
if(wearer)
|
||||
wearer.float(TRUE)
|
||||
|
||||
/obj/item/device/flightpack/proc/handle_damage()
|
||||
if(crash_damage)
|
||||
@@ -424,7 +406,6 @@
|
||||
if(boost_charge < boost_maxcharge)
|
||||
boost_charge = Clamp(boost_charge+boost_chargerate, 0, boost_maxcharge)
|
||||
|
||||
|
||||
/obj/item/device/flightpack/proc/cycle_power()
|
||||
if(powersetting < powersetting_high)
|
||||
powersetting++
|
||||
@@ -654,6 +635,8 @@
|
||||
wearer.movement_type |= FLYING
|
||||
wearer.pass_flags |= flight_passflags
|
||||
usermessage("ENGAGING FLIGHT ENGINES.")
|
||||
update_slowdown()
|
||||
wearer.floating = TRUE
|
||||
wearer.visible_message("<font color='blue' size='2'>[wearer]'s flight engines activate as they lift into the air!</font>")
|
||||
//I DONT HAVE SOUND EFFECTS YET playsound(
|
||||
flight = TRUE
|
||||
@@ -670,6 +653,8 @@
|
||||
momentum_x = 0
|
||||
momentum_y = 0
|
||||
usermessage("DISENGAGING FLIGHT ENGINES.")
|
||||
update_slowdown()
|
||||
wearer.floating = FALSE
|
||||
wearer.visible_message("<font color='blue' size='2'>[wearer] drops to the ground as their flight engines cut out!</font>")
|
||||
//NO SOUND YET playsound(
|
||||
ion_trail.stop()
|
||||
@@ -678,6 +663,9 @@
|
||||
flight = FALSE
|
||||
if(suit.shoes)
|
||||
suit.shoes.toggle(FALSE)
|
||||
if(isturf(wearer.loc))
|
||||
var/turf/T = wearer.loc
|
||||
T.Entered(src)
|
||||
else
|
||||
if(override_safe)
|
||||
disable_flight(TRUE)
|
||||
@@ -749,11 +737,13 @@
|
||||
wearer.visible_message("<span class='notice'>[wearer.name]'s flightpack engines flare in intensity as they are rocketed forward by the immense thrust!</span>")
|
||||
boost = TRUE
|
||||
update_slowdown()
|
||||
update_icon()
|
||||
|
||||
/obj/item/device/flightpack/proc/deactivate_booster()
|
||||
usermessage("Boosters disengaged!")
|
||||
boost = FALSE
|
||||
update_slowdown()
|
||||
update_icon()
|
||||
|
||||
/obj/item/device/flightpack/proc/enable_airbrake()
|
||||
if(wearer)
|
||||
|
||||
@@ -182,7 +182,7 @@
|
||||
item_state = "curator"
|
||||
blood_overlay_type = "coat"
|
||||
body_parts_covered = CHEST|ARMS
|
||||
allowed = list(/obj/item/weapon/tank/internals/emergency_oxygen, /obj/item/weapon/melee/curator_whip)
|
||||
allowed = list(/obj/item/weapon/tank/internals, /obj/item/weapon/melee/curator_whip)
|
||||
armor = list(melee = 25, bullet = 10, laser = 25, energy = 10, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 45)
|
||||
cold_protection = CHEST|ARMS
|
||||
heat_protection = CHEST|ARMS
|
||||
|
||||
@@ -137,7 +137,7 @@
|
||||
can_adjust = 1
|
||||
alt_covers_chest = 1
|
||||
|
||||
/obj/item/clothing/under/rank/librarian
|
||||
/obj/item/clothing/under/rank/curator
|
||||
name = "sensible suit"
|
||||
desc = "It's very... sensible."
|
||||
icon_state = "red_suit"
|
||||
@@ -145,7 +145,7 @@
|
||||
item_color = "red_suit"
|
||||
can_adjust = 0
|
||||
|
||||
/obj/item/clothing/under/rank/librarian/curator
|
||||
/obj/item/clothing/under/rank/curator/treasure_hunter
|
||||
name = "treasure hunter uniform"
|
||||
desc = "A rugged uniform suitable for treasure hunting."
|
||||
icon_state = "curator"
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
var/scanning = 0
|
||||
var/list/log = list()
|
||||
origin_tech = "engineering=4;biotech=2;programming=5"
|
||||
var/range = 8
|
||||
var/view_check = TRUE
|
||||
|
||||
/obj/item/device/detective_scanner/attack_self(mob/user)
|
||||
if(log.len && !scanning)
|
||||
@@ -43,7 +45,7 @@
|
||||
log = list()
|
||||
scanning = 0
|
||||
|
||||
/obj/item/device/detective_scanner/pre_attackby(atom/A, mob/user, params)
|
||||
/obj/item/device/detective_scanner/afterattack(atom/A, mob/user, params)
|
||||
scan(A, user)
|
||||
return FALSE
|
||||
|
||||
@@ -51,9 +53,7 @@
|
||||
set waitfor = 0
|
||||
if(!scanning)
|
||||
// Can remotely scan objects and mobs.
|
||||
if(!in_range(A, user) && !(A in view(world.view, user)))
|
||||
return
|
||||
if(loc != user)
|
||||
if((get_dist(A, user) > range) || (!(A in view(range, user)) && view_check) || (loc != user))
|
||||
return
|
||||
|
||||
scanning = 1
|
||||
|
||||
@@ -6,7 +6,7 @@ GLOBAL_VAR_INIT(total_runtimes_skipped, 0)
|
||||
if(!istype(E)) //Something threw an unusual exception
|
||||
log_world("\[[time_stamp()]] Uncaught exception: [E]")
|
||||
return ..()
|
||||
|
||||
|
||||
var/static/list/error_last_seen = list()
|
||||
var/static/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*/
|
||||
@@ -107,9 +107,8 @@ GLOBAL_VAR_INIT(total_runtimes_skipped, 0)
|
||||
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 = GLOB.runtime_diary
|
||||
..(E)
|
||||
world.log = GLOB.world_runtime_log
|
||||
..(E)
|
||||
|
||||
world.log = null
|
||||
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
"sodiumchloride" = list("saltshakersmall", "salt shaker", "Salt. From space oceans, presumably"),
|
||||
"blackpepper" = list("peppermillsmall", "pepper mill", "Often used to flavor food or make people sneeze"),
|
||||
"cornoil" = list("oliveoil", "corn oil bottle", "A delicious oil used in cooking. Made from corn"),
|
||||
"sugar" = list("emptycondiment", "sugar bottle", "Tasty spacey sugar!"))
|
||||
"sugar" = list("emptycondiment", "sugar bottle", "Tasty spacey sugar!"),
|
||||
"mayonnaise" = list("mayonnaise", "mayonnaise jar", "An oily condiment made from egg yolks."))
|
||||
var/originalname = "condiment" //Can't use initial(name) for this. This stores the name set by condimasters.
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/condiment/attack(mob/M, mob/user, def_zone)
|
||||
@@ -207,6 +208,13 @@
|
||||
list_reagents = list("soysauce" = 50)
|
||||
possible_states = list()
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/condiment/mayonnaise
|
||||
name = "mayonnaise"
|
||||
desc = "An oily condiment made from egg yolks."
|
||||
icon_state = "mayonnaise"
|
||||
list_reagents = list("mayonnaise" = 50)
|
||||
possible_states = list()
|
||||
|
||||
|
||||
|
||||
//Food packs. To easily apply deadly toxi... delicious sauces to your food!
|
||||
|
||||
@@ -468,3 +468,11 @@
|
||||
list_reagents = list("nutriment" = 3, "vitamin" = 2, "sodiumchloride" = 5)
|
||||
bonus_reagents = list("sodiumchloride" = 10)
|
||||
tastes = list("bran" = 4, "raisins" = 3, "salt" = 1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/butter
|
||||
name = "stick of butter"
|
||||
desc = "A stick of delicious, golden, fatty goodness."
|
||||
icon_state = "butter"
|
||||
list_reagents = list("nutriment" = 5)
|
||||
filling_color = "#FFD700"
|
||||
tastes = list("butter" = 1)
|
||||
@@ -13,8 +13,8 @@
|
||||
filling_color = "#D2691E"
|
||||
tastes = list("donut" = 1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/donut/New()
|
||||
..()
|
||||
/obj/item/weapon/reagent_containers/food/snacks/donut/Initialize()
|
||||
. = ..()
|
||||
if(prob(30))
|
||||
icon_state = "donut2"
|
||||
name = "frosted donut"
|
||||
@@ -28,8 +28,8 @@
|
||||
bitesize = 10
|
||||
tastes = list("donut" = 3, "chaos" = 1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/donut/chaos/New()
|
||||
..()
|
||||
/obj/item/weapon/reagent_containers/food/snacks/donut/chaos/Initialize()
|
||||
. = ..()
|
||||
extra_reagent = pick("nutriment", "capsaicin", "frostoil", "krokodil", "plasma", "cocoa", "slimejelly", "banana", "berryjuice", "omnizine")
|
||||
reagents.add_reagent("[extra_reagent]", 3)
|
||||
bonus_reagents = list("[extra_reagent]" = 3, "sugar" = 1)
|
||||
@@ -48,8 +48,8 @@
|
||||
extra_reagent = "berryjuice"
|
||||
tastes = list("jelly" = 1, "donut" = 3)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/donut/jelly/New()
|
||||
..()
|
||||
/obj/item/weapon/reagent_containers/food/snacks/donut/jelly/Initialize()
|
||||
. = ..()
|
||||
if(extra_reagent)
|
||||
reagents.add_reagent("[extra_reagent]", 3)
|
||||
if(prob(30))
|
||||
@@ -210,13 +210,13 @@
|
||||
filling_color = "#F0E68C"
|
||||
tastes = list("mushroom" = 1, "biscuit" = 1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/plumphelmetbiscuit/New()
|
||||
/obj/item/weapon/reagent_containers/food/snacks/plumphelmetbiscuit/Initialize()
|
||||
var/fey = prob(10)
|
||||
if(fey)
|
||||
name = "exceptional plump helmet biscuit"
|
||||
desc = "Microwave is taken by a fey mood! It has cooked an exceptional plump helmet biscuit!"
|
||||
bonus_reagents = list("omnizine" = 5, "nutriment" = 1, "vitamin" = 1)
|
||||
..()
|
||||
. = ..()
|
||||
if(fey)
|
||||
reagents.add_reagent("omnizine", 5)
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
break
|
||||
|
||||
if(!input_plate)
|
||||
GLOB.diary << "a [src] didn't find an input plate."
|
||||
GLOB.world_game_log << "a [src] didn't find an input plate."
|
||||
return
|
||||
|
||||
/obj/machinery/gibber/autogibber/Bumped(atom/A)
|
||||
|
||||
@@ -111,6 +111,7 @@
|
||||
for(var/datum/plant_gene/trait/trait in seed.genes)
|
||||
trait.on_squash(src, target)
|
||||
|
||||
reagents.reaction(T)
|
||||
for(var/A in T)
|
||||
reagents.reaction(A)
|
||||
|
||||
|
||||
@@ -50,17 +50,22 @@
|
||||
/obj/item/weapon/grown/nettle/pickup(mob/living/user)
|
||||
..()
|
||||
if(!iscarbon(user))
|
||||
return 0
|
||||
return FALSE
|
||||
var/mob/living/carbon/C = user
|
||||
if(C.gloves)
|
||||
return 0
|
||||
return FALSE
|
||||
if(ishuman(C))
|
||||
var/mob/living/carbon/human/H = C
|
||||
if(H.dna && H.dna.species)
|
||||
if(PIERCEIMMUNE in H.dna.species.species_traits)
|
||||
return FALSE
|
||||
var/hit_zone = (C.held_index_to_dir(C.active_hand_index) == "l" ? "l_":"r_") + "arm"
|
||||
var/obj/item/bodypart/affecting = C.get_bodypart(hit_zone)
|
||||
if(affecting)
|
||||
if(affecting.receive_damage(0, force))
|
||||
C.update_damage_overlays()
|
||||
to_chat(C, "<span class='userdanger'>The nettle burns your bare hand!</span>")
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/obj/item/weapon/grown/nettle/afterattack(atom/A as mob|obj, mob/user,proximity)
|
||||
if(!proximity) return
|
||||
|
||||
@@ -459,7 +459,7 @@ GLOBAL_VAR_CONST(access_away_generic4, 208)
|
||||
|
||||
/proc/get_all_jobs()
|
||||
return list("Assistant", "Captain", "Head of Personnel", "Bartender", "Cook", "Botanist", "Quartermaster", "Cargo Technician",
|
||||
"Shaft Miner", "Clown", "Mime", "Janitor", "Librarian", "Lawyer", "Chaplain", "Chief Engineer", "Station Engineer",
|
||||
"Shaft Miner", "Clown", "Mime", "Janitor", "Curator", "Lawyer", "Chaplain", "Chief Engineer", "Station Engineer",
|
||||
"Atmospheric Technician", "Chief Medical Officer", "Medical Doctor", "Chemist", "Geneticist", "Virologist",
|
||||
"Research Director", "Scientist", "Roboticist", "Head of Security", "Warden", "Detective", "Security Officer")
|
||||
|
||||
|
||||
@@ -112,11 +112,11 @@ Mime
|
||||
H.mind.miming = 1
|
||||
|
||||
/*
|
||||
Librarian
|
||||
Curator
|
||||
*/
|
||||
/datum/job/librarian
|
||||
title = "Librarian"
|
||||
flag = LIBRARIAN
|
||||
/datum/job/curator
|
||||
title = "Curator"
|
||||
flag = CURATOR
|
||||
department_head = list("Head of Personnel")
|
||||
department_flag = CIVILIAN
|
||||
faction = "Station"
|
||||
@@ -125,33 +125,35 @@ Librarian
|
||||
supervisors = "the head of personnel"
|
||||
selection_color = "#dddddd"
|
||||
|
||||
outfit = /datum/outfit/job/librarian
|
||||
outfit = /datum/outfit/job/curator
|
||||
|
||||
access = list(GLOB.access_library)
|
||||
minimal_access = list(GLOB.access_library)
|
||||
minimal_access = list(GLOB.access_library, GLOB.access_construction,GLOB.access_mining_station)
|
||||
|
||||
/datum/outfit/job/librarian
|
||||
name = "Librarian"
|
||||
jobtype = /datum/job/librarian
|
||||
/datum/outfit/job/curator
|
||||
name = "Curator"
|
||||
jobtype = /datum/job/curator
|
||||
|
||||
belt = /obj/item/device/pda/librarian
|
||||
uniform = /obj/item/clothing/under/rank/librarian
|
||||
belt = /obj/item/device/pda/curator
|
||||
uniform = /obj/item/clothing/under/rank/curator
|
||||
l_hand = /obj/item/weapon/storage/bag/books
|
||||
r_pocket = /obj/item/weapon/barcodescanner
|
||||
r_pocket = /obj/item/key/displaycase
|
||||
l_pocket = /obj/item/device/laser_pointer
|
||||
backpack_contents = list(
|
||||
/obj/item/soapstone = 1
|
||||
/obj/item/weapon/melee/curator_whip = 1,
|
||||
/obj/item/soapstone = 1,
|
||||
/obj/item/weapon/barcodescanner = 1
|
||||
)
|
||||
|
||||
|
||||
/datum/outfit/job/librarian/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
..()
|
||||
|
||||
if(visualsOnly)
|
||||
return
|
||||
|
||||
H.grant_all_languages(omnitongue=TRUE)
|
||||
|
||||
|
||||
/datum/outfit/job/curator/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
..()
|
||||
|
||||
if(visualsOnly)
|
||||
return
|
||||
|
||||
H.grant_all_languages(omnitongue=TRUE)
|
||||
|
||||
/*
|
||||
Lawyer
|
||||
*/
|
||||
|
||||
@@ -39,7 +39,7 @@ GLOBAL_LIST_INIT(civilian_positions, list(
|
||||
"Botanist",
|
||||
"Cook",
|
||||
"Janitor",
|
||||
"Librarian",
|
||||
"Curator",
|
||||
"Lawyer",
|
||||
"Chaplain",
|
||||
"Clown",
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
var/speed = 300
|
||||
var/correctness = 85
|
||||
var/willpower = 98
|
||||
if(U.job in list("Librarian")) // the librarian is both faster, and more accurate than normal crew members at research
|
||||
if(U.job in list("Curator")) // the curator is both faster, and more accurate than normal crew members at research
|
||||
speed = 45
|
||||
correctness = 100
|
||||
willpower = 100
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
------------
|
||||
A place for the crew to go, relax, and enjoy a good book.
|
||||
Aspiring authors can even self publish and, if they're lucky
|
||||
convince the on-staff Librarian to submit it to the Archives
|
||||
convince the on-staff Curator to submit it to the Archives
|
||||
to be chronicled in history forever - some say even persisting
|
||||
through alternate dimensions.
|
||||
|
||||
@@ -49,12 +49,12 @@
|
||||
|
||||
// Ideas for the future
|
||||
// ---------------------
|
||||
// - Visitor's computer should be able to search the current in-round library inventory (that the Librarian has stocked and checked in)
|
||||
// - Visitor's computer should be able to search the current in-round library inventory (that the Curator has stocked and checked in)
|
||||
// -- Give computer other features like an Instant Messenger application, or the ability to edit, save, and print documents.
|
||||
// - Admin interface directly tied to the Archive DB. Right now there's no way to delete uploaded books in-game.
|
||||
// -- If this gets implemented, allow Librarians to "tag" or "suggest" books to be deleted. The DB ID of the tagged books gets saved to a text file (or another table in the DB maybe?).
|
||||
// -- If this gets implemented, allow Curators to "tag" or "suggest" books to be deleted. The DB ID of the tagged books gets saved to a text file (or another table in the DB maybe?).
|
||||
// The admin interface would automatically take these IDs and SELECT them all from the DB to be displayed along with a Delete link to drop the row from the table.
|
||||
// - When the game sets up and the round begins, have it automatically pick random books from the DB to populate the library with. Even if the Librarian is a useless fuck there are at least a few books around.
|
||||
// - When the game sets up and the round begins, have it automatically pick random books from the DB to populate the library with. Even if the Curator is a useless fuck there are at least a few books around.
|
||||
// - Allow books to be "hollowed out" like the Chaplain's Bible, allowing you to store one pocket-sized item inside.
|
||||
// - Make books/book cases burn when exposed to flame.
|
||||
// - Make book binder hackable.
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
as instructions and/or memes for the next generation of spessmen.
|
||||
|
||||
Limited in location to station_z only. Can be smashed out or exploded,
|
||||
but only permamently removed with the librarian's soapstone.
|
||||
but only permamently removed with the curator's soapstone.
|
||||
*/
|
||||
|
||||
/obj/item/soapstone/infinite
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
GLOBAL_LIST_INIT(LIGHTING_CORNER_DIAGONAL, list(NORTHEAST, SOUTHEAST, SOUTHWEST, NORTHWEST))
|
||||
|
||||
/datum/lighting_corner
|
||||
var/list/turf/masters = list()
|
||||
var/list/datum/light_source/affecting = list() // Light sources affecting us.
|
||||
var/list/turf/masters
|
||||
var/list/datum/light_source/affecting // Light sources affecting us.
|
||||
var/active = FALSE // TRUE if one of our masters has dynamic lighting.
|
||||
|
||||
var/x = 0
|
||||
@@ -25,11 +25,9 @@ GLOBAL_LIST_INIT(LIGHTING_CORNER_DIAGONAL, list(NORTHEAST, SOUTHEAST, SOUTHWEST,
|
||||
var/cache_b = LIGHTING_SOFT_THRESHOLD
|
||||
var/cache_mx = 0
|
||||
|
||||
var/update_gen = 0
|
||||
|
||||
/datum/lighting_corner/New(var/turf/new_turf, var/diagonal)
|
||||
. = ..()
|
||||
|
||||
masters = list()
|
||||
masters[new_turf] = turn(diagonal, 180)
|
||||
z = new_turf.z
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ GLOBAL_LIST_EMPTY(all_lighting_objects) // Global list of lighting objects.
|
||||
anchored = TRUE
|
||||
|
||||
icon = LIGHTING_ICON
|
||||
icon_state = "transparent"
|
||||
color = LIGHTING_BASE_MATRIX
|
||||
plane = LIGHTING_PLANE
|
||||
mouse_opacity = 0
|
||||
@@ -16,7 +17,7 @@ GLOBAL_LIST_EMPTY(all_lighting_objects) // Global list of lighting objects.
|
||||
|
||||
var/needs_update = FALSE
|
||||
|
||||
/atom/movable/lighting_object/Initialize(mapload, var/no_update = FALSE)
|
||||
/atom/movable/lighting_object/Initialize(mapload)
|
||||
. = ..()
|
||||
verbs.Cut()
|
||||
GLOB.all_lighting_objects += src
|
||||
@@ -28,10 +29,8 @@ GLOBAL_LIST_EMPTY(all_lighting_objects) // Global list of lighting objects.
|
||||
for(var/turf/open/space/S in RANGE_TURFS(1, src)) //RANGE_TURFS is in code\__HELPERS\game.dm
|
||||
S.update_starlight()
|
||||
|
||||
if (no_update)
|
||||
return
|
||||
|
||||
update()
|
||||
needs_update = TRUE
|
||||
GLOB.lighting_update_objects += src
|
||||
|
||||
/atom/movable/lighting_object/Destroy(var/force)
|
||||
if (force)
|
||||
@@ -69,10 +68,17 @@ GLOBAL_LIST_EMPTY(all_lighting_objects) // Global list of lighting objects.
|
||||
|
||||
// See LIGHTING_CORNER_DIAGONAL in lighting_corner.dm for why these values are what they are.
|
||||
var/static/datum/lighting_corner/dummy/dummy_lighting_corner = new
|
||||
var/datum/lighting_corner/cr = T.corners[3] || dummy_lighting_corner
|
||||
var/datum/lighting_corner/cg = T.corners[2] || dummy_lighting_corner
|
||||
var/datum/lighting_corner/cb = T.corners[4] || dummy_lighting_corner
|
||||
var/datum/lighting_corner/ca = T.corners[1] || dummy_lighting_corner
|
||||
|
||||
var/list/corners = T.corners
|
||||
var/datum/lighting_corner/cr = dummy_lighting_corner
|
||||
var/datum/lighting_corner/cg = dummy_lighting_corner
|
||||
var/datum/lighting_corner/cb = dummy_lighting_corner
|
||||
var/datum/lighting_corner/ca = dummy_lighting_corner
|
||||
if (corners) //done this way for speed
|
||||
cr = corners[3] || dummy_lighting_corner
|
||||
cg = corners[2] || dummy_lighting_corner
|
||||
cb = corners[4] || dummy_lighting_corner
|
||||
ca = corners[1] || dummy_lighting_corner
|
||||
|
||||
var/max = max(cr.cache_mx, cg.cache_mx, cb.cache_mx, ca.cache_mx)
|
||||
|
||||
|
||||
@@ -8,6 +8,6 @@
|
||||
if(!IS_DYNAMIC_LIGHTING(T))
|
||||
continue
|
||||
|
||||
new/atom/movable/lighting_object(T, TRUE)
|
||||
new/atom/movable/lighting_object(T)
|
||||
CHECK_TICK
|
||||
CHECK_TICK
|
||||
|
||||
@@ -26,22 +26,15 @@
|
||||
|
||||
var/applied = FALSE // Whether we have applied our light yet or not.
|
||||
|
||||
var/vis_update // Whether we should smartly recalculate visibility. and then only update tiles that became (in)visible to us.
|
||||
var/needs_update // Whether we are queued for an update.
|
||||
var/force_update
|
||||
var/needs_update = LIGHTING_NO_UPDATE // Whether we are queued for an update.
|
||||
|
||||
|
||||
/datum/light_source/New(var/atom/owner, var/atom/top)
|
||||
source_atom = owner // Set our new owner.
|
||||
if (!source_atom.light_sources)
|
||||
source_atom.light_sources = list()
|
||||
|
||||
source_atom.light_sources += src // Add us to the lights of our owner.
|
||||
LAZYADD(source_atom.light_sources, src)
|
||||
top_atom = top
|
||||
if (top_atom != source_atom)
|
||||
if (!top.light_sources)
|
||||
top.light_sources = list()
|
||||
|
||||
top_atom.light_sources += src
|
||||
LAZYADD(top_atom.light_sources, src)
|
||||
|
||||
source_turf = top_atom
|
||||
pixel_turf = get_turf_pixel(top_atom) || source_turf
|
||||
@@ -52,20 +45,18 @@
|
||||
|
||||
parse_light_color()
|
||||
|
||||
effect_str = list()
|
||||
affecting_turfs = list()
|
||||
|
||||
update()
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/light_source/Destroy(force)
|
||||
force_update()
|
||||
remove_lum()
|
||||
if (source_atom)
|
||||
source_atom.light_sources -= src
|
||||
LAZYREMOVE(source_atom.light_sources, src)
|
||||
|
||||
if (top_atom)
|
||||
top_atom.light_sources -= src
|
||||
LAZYREMOVE(top_atom.light_sources, src)
|
||||
|
||||
. = ..()
|
||||
if(!force)
|
||||
return QDEL_HINT_IWILLGC
|
||||
@@ -73,79 +64,34 @@
|
||||
// Yes this doesn't align correctly on anything other than 4 width tabs.
|
||||
// If you want it to go switch everybody to elastic tab stops.
|
||||
// Actually that'd be great if you could!
|
||||
#define EFFECT_UPDATE \
|
||||
if (!needs_update) \
|
||||
{ \
|
||||
GLOB.lighting_update_lights += src; \
|
||||
needs_update = TRUE; \
|
||||
}
|
||||
#define EFFECT_UPDATE(level) \
|
||||
if (needs_update == LIGHTING_NO_UPDATE) \
|
||||
GLOB.lighting_update_lights += src; \
|
||||
if (needs_update < level) \
|
||||
needs_update = level; \
|
||||
|
||||
|
||||
// This proc will cause the light source to update the top atom, and add itself to the update queue.
|
||||
/datum/light_source/proc/update(var/atom/new_top_atom)
|
||||
// This top atom is different.
|
||||
if (new_top_atom && new_top_atom != top_atom)
|
||||
if(top_atom != source_atom && top_atom.light_sources) // Remove ourselves from the light sources of that top atom.
|
||||
top_atom.light_sources -= src
|
||||
LAZYREMOVE(top_atom.light_sources, src)
|
||||
|
||||
top_atom = new_top_atom
|
||||
|
||||
if (top_atom != source_atom)
|
||||
LAZYADD(top_atom.light_sources, src) // Add ourselves to the light sources of our new top atom.
|
||||
|
||||
EFFECT_UPDATE
|
||||
EFFECT_UPDATE(LIGHTING_CHECK_UPDATE)
|
||||
|
||||
// Will force an update without checking if it's actually needed.
|
||||
/datum/light_source/proc/force_update()
|
||||
force_update = 1
|
||||
|
||||
EFFECT_UPDATE
|
||||
EFFECT_UPDATE(LIGHTING_FORCE_UPDATE)
|
||||
|
||||
// Will cause the light source to recalculate turfs that were removed or added to visibility only.
|
||||
/datum/light_source/proc/vis_update()
|
||||
vis_update = 1
|
||||
|
||||
EFFECT_UPDATE
|
||||
|
||||
// Will check if we actually need to update, and update any variables that may need to be updated.
|
||||
/datum/light_source/proc/check()
|
||||
if (!source_atom || !light_range || !light_power)
|
||||
qdel(src)
|
||||
return 1
|
||||
|
||||
if (!top_atom)
|
||||
top_atom = source_atom
|
||||
. = 1
|
||||
|
||||
if (isturf(top_atom))
|
||||
if (source_turf != top_atom)
|
||||
source_turf = top_atom
|
||||
pixel_turf = source_turf
|
||||
. = 1
|
||||
else if (top_atom.loc != source_turf)
|
||||
source_turf = top_atom.loc
|
||||
pixel_turf = get_turf_pixel(top_atom)
|
||||
. = 1
|
||||
else
|
||||
var/P = get_turf_pixel(top_atom)
|
||||
if (P != pixel_turf)
|
||||
. = 1
|
||||
pixel_turf = get_turf_pixel(top_atom)
|
||||
|
||||
if (source_atom.light_power != light_power)
|
||||
light_power = source_atom.light_power
|
||||
. = 1
|
||||
|
||||
if (source_atom.light_range != light_range)
|
||||
light_range = source_atom.light_range
|
||||
. = 1
|
||||
|
||||
if (light_range && light_power && !applied)
|
||||
. = 1
|
||||
|
||||
if (source_atom.light_color != light_color)
|
||||
light_color = source_atom.light_color
|
||||
parse_light_color()
|
||||
. = 1
|
||||
EFFECT_UPDATE(LIGHTING_VIS_UPDATE)
|
||||
|
||||
// Decompile the hexadecimal colour into lumcounts of each perspective.
|
||||
/datum/light_source/proc/parse_light_color()
|
||||
@@ -164,48 +110,47 @@
|
||||
// As such this all gets counted as a single line.
|
||||
// The braces and semicolons are there to be able to do this on a single line.
|
||||
#define LUM_FALLOFF(C, T) (1 - CLAMP01(sqrt((C.x - T.x) ** 2 + (C.y - T.y) ** 2 + LIGHTING_HEIGHT) / max(1, light_range)))
|
||||
#define APPLY_CORNER(C) \
|
||||
. = LUM_FALLOFF(C, pixel_turf); \
|
||||
\
|
||||
. *= light_power; \
|
||||
\
|
||||
effect_str[C] = .; \
|
||||
\
|
||||
C.update_lumcount \
|
||||
( \
|
||||
. * applied_lum_r, \
|
||||
. * applied_lum_g, \
|
||||
. * applied_lum_b \
|
||||
|
||||
#define APPLY_CORNER(C) \
|
||||
. = LUM_FALLOFF(C, pixel_turf); \
|
||||
. *= light_power; \
|
||||
var/OLD = effect_str[C]; \
|
||||
\
|
||||
effect_str[C] = .; \
|
||||
\
|
||||
C.update_lumcount \
|
||||
( \
|
||||
(. * lum_r) - (OLD * applied_lum_r), \
|
||||
(. * lum_g) - (OLD * applied_lum_g), \
|
||||
(. * lum_b) - (OLD * applied_lum_b) \
|
||||
);
|
||||
|
||||
// I don't need to explain what this does, do I?
|
||||
#define REMOVE_CORNER(C) \
|
||||
. = -effect_str[C]; \
|
||||
C.update_lumcount \
|
||||
( \
|
||||
. * applied_lum_r, \
|
||||
. * applied_lum_g, \
|
||||
. * applied_lum_b \
|
||||
|
||||
#define REMOVE_CORNER(C) \
|
||||
. = -effect_str[C]; \
|
||||
C.update_lumcount \
|
||||
( \
|
||||
. * applied_lum_r, \
|
||||
. * applied_lum_g, \
|
||||
. * applied_lum_b \
|
||||
);
|
||||
|
||||
// This is the define used to calculate falloff.
|
||||
|
||||
|
||||
/*
|
||||
/datum/light_source/proc/apply_lum()
|
||||
var/static/update_gen = 1
|
||||
applied = 1
|
||||
|
||||
// Keep track of the last applied lum values so that the lighting can be reversed
|
||||
applied_lum_r = lum_r
|
||||
applied_lum_g = lum_g
|
||||
applied_lum_b = lum_b
|
||||
var/thing
|
||||
var/datum/lighting_corner/C
|
||||
var/corners = list()
|
||||
LAZYINITLIST(effect_str)
|
||||
FOR_DVIEW(var/turf/T, light_range+1, source_turf, INVISIBILITY_LIGHTING)
|
||||
if (!T.lighting_corners_initialised)
|
||||
T.generate_missing_corners()
|
||||
var/list/turf_corners = T.get_corners()
|
||||
|
||||
for (thing in T.get_corners())
|
||||
for (thing in turf_corners)
|
||||
C = thing
|
||||
if (C.update_gen == update_gen)
|
||||
continue
|
||||
@@ -220,9 +165,13 @@
|
||||
APPLY_CORNER(C)
|
||||
|
||||
LAZYADD(T.affecting_lights, src)
|
||||
affecting_turfs += T
|
||||
LAZYADD(affecting_turfs, T)
|
||||
FOR_DVIEW_END
|
||||
update_gen++
|
||||
applied_lum_r = lum_r
|
||||
applied_lum_g = lum_g
|
||||
applied_lum_b = lum_b
|
||||
*/
|
||||
|
||||
/datum/light_source/proc/remove_lum()
|
||||
applied = FALSE
|
||||
@@ -231,7 +180,7 @@
|
||||
var/turf/T = thing
|
||||
LAZYREMOVE(T.affecting_lights, src)
|
||||
|
||||
affecting_turfs.Cut()
|
||||
affecting_turfs = null
|
||||
|
||||
var/datum/lighting_corner/C
|
||||
for (thing in effect_str)
|
||||
@@ -240,30 +189,93 @@
|
||||
|
||||
LAZYREMOVE(C.affecting, src)
|
||||
|
||||
effect_str.Cut()
|
||||
effect_str = null
|
||||
|
||||
/datum/light_source/proc/recalc_corner(var/datum/lighting_corner/C)
|
||||
if (effect_str.Find(C)) // Already have one.
|
||||
LAZYINITLIST(effect_str)
|
||||
if (effect_str[C]) // Already have one.
|
||||
REMOVE_CORNER(C)
|
||||
effect_str[C] = 0
|
||||
|
||||
APPLY_CORNER(C)
|
||||
UNSETEMPTY(effect_str)
|
||||
|
||||
/datum/light_source/proc/update_corners()
|
||||
var/update = FALSE
|
||||
|
||||
if (!source_atom || QDELETED(source_atom))
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
if (source_atom.light_power != light_power)
|
||||
light_power = source_atom.light_power
|
||||
update = TRUE
|
||||
|
||||
if (source_atom.light_range != light_range)
|
||||
light_range = source_atom.light_range
|
||||
update = TRUE
|
||||
|
||||
if (!top_atom)
|
||||
top_atom = source_atom
|
||||
update = TRUE
|
||||
|
||||
if (!light_range || !light_power)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
if (isturf(top_atom))
|
||||
if (source_turf != top_atom)
|
||||
source_turf = top_atom
|
||||
pixel_turf = source_turf
|
||||
update = TRUE
|
||||
else if (top_atom.loc != source_turf)
|
||||
source_turf = top_atom.loc
|
||||
pixel_turf = get_turf_pixel(top_atom)
|
||||
update = TRUE
|
||||
else
|
||||
var/P = get_turf_pixel(top_atom)
|
||||
if (P != pixel_turf)
|
||||
pixel_turf = P
|
||||
update = TRUE
|
||||
|
||||
if (!isturf(source_turf))
|
||||
if (applied)
|
||||
remove_lum()
|
||||
return
|
||||
|
||||
if (light_range && light_power && !applied)
|
||||
update = TRUE
|
||||
|
||||
if (source_atom.light_color != light_color)
|
||||
light_color = source_atom.light_color
|
||||
parse_light_color()
|
||||
update = TRUE
|
||||
|
||||
else if (applied_lum_r != lum_r || applied_lum_g != lum_g || applied_lum_b != lum_b)
|
||||
update = TRUE
|
||||
|
||||
if (update)
|
||||
needs_update = LIGHTING_CHECK_UPDATE
|
||||
applied = TRUE
|
||||
else if (needs_update == LIGHTING_CHECK_UPDATE)
|
||||
return //nothing's changed
|
||||
|
||||
/datum/light_source/proc/smart_vis_update()
|
||||
var/list/datum/lighting_corner/corners = list()
|
||||
var/list/turf/turfs = list()
|
||||
var/thing
|
||||
var/datum/lighting_corner/C
|
||||
var/turf/T
|
||||
if (source_turf)
|
||||
var/oldlum = source_turf.luminosity
|
||||
source_turf.luminosity = Ceiling(light_range)
|
||||
for(T in view(Ceiling(light_range), source_turf))
|
||||
for (thing in T.get_corners(source_turf))
|
||||
C = thing
|
||||
corners[C] = 0
|
||||
turfs += T
|
||||
source_turf.luminosity = oldlum
|
||||
|
||||
FOR_DVIEW(T, light_range+1, source_turf, 0)
|
||||
if (!T.lighting_corners_initialised)
|
||||
T.generate_missing_corners()
|
||||
for (thing in T.get_corners(source_turf))
|
||||
C = thing
|
||||
corners[C] = 0
|
||||
turfs += T
|
||||
FOR_DVIEW_END
|
||||
|
||||
LAZYINITLIST(affecting_turfs)
|
||||
var/list/L = turfs - affecting_turfs // New turfs, add us to the affecting lights of them.
|
||||
affecting_turfs += L
|
||||
for (thing in L)
|
||||
@@ -276,22 +288,45 @@
|
||||
T = thing
|
||||
LAZYREMOVE(T.affecting_lights, src)
|
||||
|
||||
LAZYINITLIST(effect_str)
|
||||
if (needs_update == LIGHTING_VIS_UPDATE)
|
||||
for (thing in corners - effect_str) // New corners
|
||||
C = thing
|
||||
LAZYADD(C.affecting, src)
|
||||
if (!C.active)
|
||||
effect_str[C] = 0
|
||||
continue
|
||||
APPLY_CORNER(C)
|
||||
else
|
||||
L = corners - effect_str
|
||||
for (thing in L) // New corners
|
||||
C = thing
|
||||
LAZYADD(C.affecting, src)
|
||||
if (!C.active)
|
||||
effect_str[C] = 0
|
||||
continue
|
||||
APPLY_CORNER(C)
|
||||
|
||||
for (thing in corners - L) // Existing corners
|
||||
C = thing
|
||||
if (!C.active)
|
||||
effect_str[C] = 0
|
||||
continue
|
||||
APPLY_CORNER(C)
|
||||
|
||||
for (thing in corners - effect_str) // New corners
|
||||
C = thing
|
||||
LAZYADD(C.affecting, src)
|
||||
if (!C.active)
|
||||
effect_str[C] = 0
|
||||
continue
|
||||
|
||||
APPLY_CORNER(C)
|
||||
|
||||
for (thing in effect_str - corners) // Old, now gone, corners.
|
||||
L = effect_str - corners
|
||||
for (thing in L) // Old, now gone, corners.
|
||||
C = thing
|
||||
REMOVE_CORNER(C)
|
||||
LAZYREMOVE(C.affecting, src)
|
||||
effect_str -= C
|
||||
effect_str -= L
|
||||
|
||||
applied_lum_r = lum_r
|
||||
applied_lum_g = lum_g
|
||||
applied_lum_b = lum_b
|
||||
|
||||
UNSETEMPTY(effect_str)
|
||||
UNSETEMPTY(affecting_turfs)
|
||||
|
||||
#undef EFFECT_UPDATE
|
||||
#undef LUM_FALLOFF
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
return
|
||||
|
||||
var/area/A = loc
|
||||
if (!IS_DYNAMIC_LIGHTING(A))
|
||||
if (!IS_DYNAMIC_LIGHTING(A) && !light_sources)
|
||||
return
|
||||
|
||||
if (!lighting_corners_initialised)
|
||||
@@ -113,12 +113,18 @@
|
||||
lighting_clear_overlay()
|
||||
|
||||
/turf/proc/get_corners()
|
||||
if (!IS_DYNAMIC_LIGHTING(src) && !light_sources)
|
||||
return null
|
||||
if (!lighting_corners_initialised)
|
||||
generate_missing_corners()
|
||||
if (has_opaque_atom)
|
||||
return null // Since this proc gets used in a for loop, null won't be looped though.
|
||||
|
||||
return corners
|
||||
|
||||
/turf/proc/generate_missing_corners()
|
||||
if (!IS_DYNAMIC_LIGHTING(src) && !light_sources)
|
||||
return
|
||||
lighting_corners_initialised = TRUE
|
||||
if (!corners)
|
||||
corners = list(null, null, null, null)
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
desc = "It's watching you suspiciously."
|
||||
|
||||
/obj/structure/closet/crate/necropolis/tendril/PopulateContents()
|
||||
var/loot = rand(1,25)
|
||||
var/loot = rand(1,26)
|
||||
switch(loot)
|
||||
if(1)
|
||||
new /obj/item/device/shared_storage/red(src)
|
||||
@@ -33,7 +33,7 @@
|
||||
if(9)
|
||||
new /obj/item/organ/brain/alien(src)
|
||||
if(10)
|
||||
new /obj/item/organ/heart/cursed(src)
|
||||
new /obj/item/organ/heart/cursed/wizard(src)
|
||||
if(11)
|
||||
new /obj/item/ship_in_a_bottle(src)
|
||||
if(12)
|
||||
@@ -65,6 +65,8 @@
|
||||
new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor(src)
|
||||
if(25)
|
||||
new /obj/item/weapon/spellbook/oneuse/summonitem(src)
|
||||
if(26)
|
||||
new /obj/item/book_of_babel(src)
|
||||
|
||||
|
||||
|
||||
@@ -343,6 +345,24 @@
|
||||
add_fingerprint(usr)
|
||||
|
||||
|
||||
|
||||
|
||||
//Book of Babel
|
||||
|
||||
/obj/item/book_of_babel
|
||||
name = "Book of Babel"
|
||||
desc = "An ancient tome written in countless tongues."
|
||||
icon = 'icons/obj/library.dmi'
|
||||
icon_state = "book1"
|
||||
w_class = 2
|
||||
|
||||
/obj/item/book_of_babel/attack_self(mob/user)
|
||||
to_chat(user, "You flip through the pages of the book, quickly and conveniently learning every language in existence. Somewhat less conveniently, the aging book crumbles to dust in the process. Whoops.")
|
||||
user.grant_all_languages(omnitongue=TRUE)
|
||||
new /obj/effect/decal/cleanable/ash(get_turf(user))
|
||||
qdel(src)
|
||||
|
||||
|
||||
//Boat
|
||||
|
||||
/obj/vehicle/lavaboat
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
if(D.make_reagents.len)
|
||||
return 0
|
||||
|
||||
var/build_amount = 1
|
||||
var/build_amount = 0
|
||||
|
||||
for(var/mat_id in D.materials)
|
||||
var/M = D.materials[mat_id]
|
||||
@@ -93,7 +93,15 @@
|
||||
if(!M || !redemption_mat)
|
||||
return 0
|
||||
|
||||
build_amount = min(build_amount, round(redemption_mat.amount / M))
|
||||
var/smeltable_sheets = round(redemption_mat.amount / M)
|
||||
|
||||
if(!smeltable_sheets)
|
||||
return 0
|
||||
|
||||
if(!build_amount)
|
||||
build_amount = smeltable_sheets
|
||||
|
||||
build_amount = min(build_amount, smeltable_sheets)
|
||||
|
||||
return build_amount
|
||||
|
||||
@@ -152,6 +160,7 @@
|
||||
if(exchange_parts(user, W))
|
||||
return
|
||||
if(default_pry_open(W))
|
||||
materials.retrieve_all()
|
||||
return
|
||||
if(default_unfasten_wrench(user, W))
|
||||
return
|
||||
|
||||
@@ -193,9 +193,7 @@
|
||||
qdel(voucher)
|
||||
|
||||
/obj/machinery/mineral/equipment_vendor/ex_act(severity, target)
|
||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
do_sparks(5, TRUE, src)
|
||||
if(prob(50 / severity) && severity < 3)
|
||||
qdel(src)
|
||||
|
||||
|
||||
@@ -3,9 +3,16 @@
|
||||
INITIALIZE_IMMEDIATE(/mob/dead)
|
||||
|
||||
/mob/dead/Initialize()
|
||||
. = ..()
|
||||
if(initialized)
|
||||
stack_trace("Warning: [src]([type]) initialized multiple times!")
|
||||
tag = "mob_[next_mob_id++]"
|
||||
GLOB.mob_list += src
|
||||
|
||||
prepare_huds()
|
||||
|
||||
if(config.cross_allowed)
|
||||
verbs += /mob/dead/proc/server_hop
|
||||
return INITIALIZE_HINT_NORMAL
|
||||
|
||||
/mob/dead/dust() //ghosts can't be vaporised.
|
||||
return
|
||||
|
||||
@@ -16,12 +16,6 @@
|
||||
var/mob/living/new_character //for instant transfer once the round is set up
|
||||
|
||||
/mob/dead/new_player/Initialize()
|
||||
if(initialized)
|
||||
stack_trace("Warning: [src]([type]) initialized multiple times!")
|
||||
initialized = TRUE
|
||||
tag = "mob_[next_mob_id++]"
|
||||
GLOB.mob_list += src
|
||||
|
||||
if(client && SSticker.state == GAME_STATE_STARTUP)
|
||||
var/obj/screen/splash/S = new(client, TRUE, TRUE)
|
||||
S.Fade(TRUE)
|
||||
@@ -30,7 +24,10 @@
|
||||
loc = pick(GLOB.newplayer_start)
|
||||
else
|
||||
loc = locate(1,1,1)
|
||||
return INITIALIZE_HINT_NORMAL
|
||||
. = ..()
|
||||
|
||||
/mob/dead/new_player/prepare_huds()
|
||||
return
|
||||
|
||||
/mob/dead/new_player/proc/new_player_panel()
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
|
||||
var/deadchat_name
|
||||
|
||||
/mob/dead/observer/Initialize()
|
||||
invisibility = GLOB.observer_default_invisibility
|
||||
set_invisibility(GLOB.observer_default_invisibility)
|
||||
|
||||
verbs += /mob/dead/observer/proc/dead_tele
|
||||
|
||||
@@ -118,6 +118,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
|
||||
animate(src, pixel_y = 2, time = 10, loop = -1)
|
||||
|
||||
grant_all_languages()
|
||||
GLOB.dead_mob_list += src
|
||||
..()
|
||||
|
||||
/mob/dead/observer/narsie_act()
|
||||
@@ -787,13 +788,25 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
if(!invisibility)
|
||||
to_chat(user, "It seems extremely obvious.")
|
||||
|
||||
/mob/dead/observer/proc/set_invisibility(value)
|
||||
invisibility = value
|
||||
if(!value)
|
||||
set_light(1, 2)
|
||||
else
|
||||
set_light(0, 0)
|
||||
|
||||
// Ghosts have no momentum, being massless ectoplasm
|
||||
/mob/dead/observer/Process_Spacemove(movement_dir)
|
||||
return 1
|
||||
|
||||
/mob/dead/observer/vv_edit_var(var_name, var_value)
|
||||
. = ..()
|
||||
if(var_name == "invisibility")
|
||||
set_invisibility(invisibility) // updates light
|
||||
|
||||
/proc/set_observer_default_invisibility(amount, message=null)
|
||||
for(var/mob/dead/observer/G in GLOB.player_list)
|
||||
G.invisibility = amount
|
||||
G.set_invisibility(amount)
|
||||
if(message)
|
||||
to_chat(G, message)
|
||||
GLOB.observer_default_invisibility = amount
|
||||
|
||||
@@ -35,22 +35,21 @@
|
||||
blood_volume += 0.1 // regenerate blood VERY slowly
|
||||
|
||||
//Effects of bloodloss
|
||||
var/word = pick("dizzy","woozy","faint")
|
||||
switch(blood_volume)
|
||||
if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE)
|
||||
if(prob(5))
|
||||
to_chat(src, "<span class='warning'>You feel [pick("dizzy","woozy","faint")].</span>")
|
||||
to_chat(src, "<span class='warning'>You feel [word].</span>")
|
||||
adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.01, 1))
|
||||
if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY)
|
||||
adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1))
|
||||
if(prob(5))
|
||||
blur_eyes(6)
|
||||
var/word = pick("dizzy","woozy","faint")
|
||||
to_chat(src, "<span class='warning'>You feel very [word].</span>")
|
||||
if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD)
|
||||
adjustOxyLoss(5)
|
||||
if(prob(15))
|
||||
Paralyse(rand(1,3))
|
||||
var/word = pick("dizzy","woozy","faint")
|
||||
to_chat(src, "<span class='warning'>You feel extremely [word].</span>")
|
||||
if(0 to BLOOD_VOLUME_SURVIVE)
|
||||
death()
|
||||
@@ -70,7 +69,7 @@
|
||||
|
||||
bleed_rate = max(bleed_rate - 0.5, temp_bleed)//if no wounds, other bleed effects (heparin) naturally decreases
|
||||
|
||||
if(bleed_rate && !bleedsuppress)
|
||||
if(bleed_rate && !bleedsuppress && !(status_flags & FAKEDEATH))
|
||||
bleed(bleed_rate)
|
||||
|
||||
//Makes a blood drop, leaking amt units of blood from the mob
|
||||
|
||||
@@ -87,6 +87,8 @@
|
||||
owner.adjustFireLoss(-heal_amt)
|
||||
owner.adjustOxyLoss(-heal_amt)
|
||||
owner.adjustCloneLoss(-heal_amt)
|
||||
else
|
||||
owner.adjustPlasma(plasma_rate * 0.1)
|
||||
|
||||
/obj/item/organ/alien/plasmavessel/Insert(mob/living/carbon/M, special = 0)
|
||||
..()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/mob/living/proc/alien_talk(message, shown_name = name)
|
||||
/mob/living/proc/alien_talk(message, shown_name = real_name)
|
||||
log_say("[key_name(src)] : [message]")
|
||||
message = trim(message)
|
||||
if(!message) return
|
||||
|
||||
@@ -484,7 +484,7 @@
|
||||
adjustBruteLoss(3)
|
||||
else
|
||||
if(T)
|
||||
T.add_vomit_floor(src, 0)//toxic barf looks different
|
||||
T.add_vomit_floor(src, toxic)//toxic barf looks different
|
||||
nutrition -= lost_nutrition
|
||||
adjustToxLoss(-3)
|
||||
T = get_step(T, dir)
|
||||
@@ -492,6 +492,16 @@
|
||||
break
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/proc/spew_organ(power = 5)
|
||||
if(!internal_organs.len)
|
||||
return //Guess we're out of organs
|
||||
var/obj/item/organ/guts = pick(internal_organs)
|
||||
var/turf/T = get_turf(src)
|
||||
guts.Remove(src)
|
||||
guts.forceMove(T)
|
||||
var/atom/throw_target = get_edge_target_turf(guts, dir)
|
||||
guts.throw_at(throw_target, power, 4, src)
|
||||
|
||||
|
||||
/mob/living/carbon/fully_replace_character_name(oldname,newname)
|
||||
..()
|
||||
|
||||
@@ -119,9 +119,7 @@
|
||||
visible_message("<span class='danger'>The [M.name] has shocked [src]!</span>", \
|
||||
"<span class='userdanger'>The [M.name] has shocked [src]!</span>")
|
||||
|
||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
do_sparks(5, TRUE, src)
|
||||
var/power = M.powerlevel + rand(0,3)
|
||||
Weaken(power)
|
||||
if(stuttering < power)
|
||||
|
||||
@@ -68,6 +68,17 @@
|
||||
if(!isnum(text2num(params)))
|
||||
return message
|
||||
|
||||
/datum/emote/sound/carbon/snap
|
||||
key = "snap"
|
||||
key_third_person = "snaps"
|
||||
message = "snaps their fingers."
|
||||
muzzle_ignore = TRUE
|
||||
restraint_check = TRUE
|
||||
emote_type = EMOTE_AUDIBLE
|
||||
sound = 'sound/effects/snap01.ogg'
|
||||
mob_type_allowed_typecache = list(/mob/living/carbon/)
|
||||
|
||||
|
||||
/datum/emote/living/carbon/sign/signal
|
||||
key = "signal"
|
||||
key_third_person = "signals"
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
diff a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm (rejected hunks)
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
dna.species.spec_death(gibbed, src)
|
||||
|
||||
- if(SSticker && SSticker.mode)
|
||||
+ if(SSticker.HasRoundStarted())
|
||||
SSblackbox.ReportDeath(src)
|
||||
if(mind && mind.devilinfo)
|
||||
INVOKE_ASYNC(mind.devilinfo, /datum/devilinfo.proc/beginResurrectionCheck, src)
|
||||
@@ -171,5 +171,8 @@
|
||||
dna.species.mutant_bodyparts -= "wingsopen"
|
||||
dna.species.mutant_bodyparts |= "wings"
|
||||
update_body()
|
||||
if(isturf(loc))
|
||||
var/turf/T = loc
|
||||
T.Entered(src)
|
||||
|
||||
//Ayy lmao
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
if(stat == DEAD || (status_flags & FAKEDEATH))
|
||||
appears_dead = 1
|
||||
if(suiciding)
|
||||
msg += "<span class='warning'>[t_He] appear[p_s()] to have commited suicide... there is no hope of recovery.</span>\n"
|
||||
msg += "<span class='warning'>[t_He] appear[p_s()] to have committed suicide... there is no hope of recovery.</span>\n"
|
||||
if(hellbound)
|
||||
msg += "<span class='warning'>[t_His] soul seems to have been ripped out of [t_his] body. Revival is impossible.</span>\n"
|
||||
msg += "<span class='deadsay'>[t_He] [t_is] limp and unresponsive; there are no signs of life"
|
||||
|
||||
@@ -119,6 +119,8 @@
|
||||
var/obj/item/thing = C.get_item_by_slot(slot_id)
|
||||
if(thing && (!thing.species_exception || !is_type_in_list(src,thing.species_exception)))
|
||||
C.dropItemToGround(thing)
|
||||
if(C.hud_used)
|
||||
C.hud_used.update_locked_slots()
|
||||
|
||||
// this needs to be FIRST because qdel calls update_body which checks if we have DIGITIGRADE legs or not and if not then removes DIGITIGRADE from species_traits
|
||||
if(("legs" in C.dna.species.mutant_bodyparts) && C.dna.features["legs"] == "Digitigrade Legs")
|
||||
@@ -352,7 +354,7 @@
|
||||
var/datum/sprite_accessory/undershirt/undershirt = GLOB.undershirt_list[H.undershirt]
|
||||
if(undershirt)
|
||||
if(H.dna.species.sexes && H.gender == FEMALE)
|
||||
standing += wear_female_version(undershirt.icon_state, undershirt.icon, -BODY_LAYER)
|
||||
standing += wear_female_version(undershirt.icon_state, undershirt.icon, BODY_LAYER)
|
||||
else
|
||||
standing += mutable_appearance(undershirt.icon, undershirt.icon_state, -BODY_LAYER)
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
punchdamagelow = 5
|
||||
punchdamagehigh = 14
|
||||
punchstunthreshold = 11 //about 40% chance to stun
|
||||
no_equip = list(slot_wear_mask, slot_wear_suit, slot_gloves, slot_shoes, slot_w_uniform)
|
||||
no_equip = list(slot_wear_mask, slot_wear_suit, slot_gloves, slot_shoes, slot_w_uniform, slot_s_store)
|
||||
nojumpsuit = 1
|
||||
sexes = 1
|
||||
damage_overlay_type = ""
|
||||
@@ -20,6 +20,7 @@
|
||||
dangerous_existence = TRUE
|
||||
limbs_id = "golem"
|
||||
fixed_mut_color = "aaa"
|
||||
mutant_organs = list(/obj/item/organ/adamantine_resonator)
|
||||
var/info_text = "As an <span class='danger'>Iron Golem</span>, you don't have any special traits."
|
||||
|
||||
var/prefix = "Iron"
|
||||
@@ -54,8 +55,9 @@
|
||||
name = "Adamantine Golem"
|
||||
id = "adamantine golem"
|
||||
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/golem/adamantine
|
||||
mutant_organs = list(/obj/item/organ/adamantine_resonator, /obj/item/organ/vocal_cords/adamantine)
|
||||
fixed_mut_color = "4ed"
|
||||
info_text = "As an <span class='danger'>Adamantine Golem</span>, you don't have any special traits."
|
||||
info_text = "As an <span class='danger'>Adamantine Golem</span>, you possess special vocal cords allowing you to \"resonate\" messages to all golems."
|
||||
prefix = "Adamantine"
|
||||
|
||||
//Explodes on death
|
||||
@@ -71,14 +73,14 @@
|
||||
prefix = "Plasma"
|
||||
special_names = list("Flood","Fire","Bar","Man")
|
||||
|
||||
/datum/species/golem/plasma/spec_life(mob/living/carbon/human/H)
|
||||
if(H.bodytemperature > 900 && H.on_fire)
|
||||
explosion(get_turf(H),1,2,4,flame_range = 5)
|
||||
if(H)
|
||||
H.gib()
|
||||
if(H.fire_stacks < 2) //flammable
|
||||
H.adjust_fire_stacks(1)
|
||||
..()
|
||||
/datum/species/golem/plasma/spec_life(mob/living/carbon/human/H)
|
||||
if(H.bodytemperature > 900 && H.on_fire)
|
||||
explosion(get_turf(H),1,2,4,flame_range = 5)
|
||||
if(H)
|
||||
H.gib()
|
||||
if(H.fire_stacks < 2) //flammable
|
||||
H.adjust_fire_stacks(1)
|
||||
..()
|
||||
|
||||
//Harder to hurt
|
||||
/datum/species/golem/diamond
|
||||
@@ -505,7 +507,7 @@
|
||||
sexes = FALSE
|
||||
info_text = "As a <span class='danger'>Runic Golem</span>, you possess eldritch powers granted by the Elder God Nar'Sie."
|
||||
species_traits = list(NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOFIRE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER) //no mutcolors
|
||||
prefix = "Runic"
|
||||
prefix = "Runic"
|
||||
|
||||
var/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift/golem/phase_shift
|
||||
var/obj/effect/proc_holder/spell/targeted/abyssal_gaze/abyssal_gaze
|
||||
@@ -643,4 +645,19 @@
|
||||
|
||||
if(P.is_hot())
|
||||
visible_message("<span class='danger'>[src] bursts into flames!</span>")
|
||||
fire_act()
|
||||
|
||||
fire_act()
|
||||
/datum/species/golem/plastic
|
||||
name = "Plastic"
|
||||
id = "plastic golem"
|
||||
prefix = "Plastic"
|
||||
fixed_mut_color = "fff"
|
||||
info_text = "As a <span class='danger'>Plastic Golem</span>, you are capable of ventcrawling, and passing through plastic flaps."
|
||||
|
||||
/datum/species/golem/plastic/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
||||
. = ..()
|
||||
C.ventcrawler = VENTCRAWLER_NUDE
|
||||
|
||||
/datum/species/golem/plastic/on_species_loss(mob/living/carbon/C)
|
||||
. = ..()
|
||||
C.ventcrawler = initial(C.ventcrawler)
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
//Holopad
|
||||
if(istype(ai.current, /obj/machinery/holopad))
|
||||
var/obj/machinery/holopad/H = ai.current
|
||||
H.move_hologram(ai)
|
||||
H.move_hologram(ai, T)
|
||||
|
||||
/mob/camera/aiEye/Move()
|
||||
return 0
|
||||
|
||||
@@ -1143,7 +1143,7 @@
|
||||
M.visible_message("<span class='boldwarning'>Unfortunately, [M] just can't seem to hold onto [src]!</span>")
|
||||
return
|
||||
if(iscarbon(M) && (!riding_datum.equip_buckle_inhands(M, 1)))
|
||||
M.visible_message("<span class='boldwarning'>[M] can't climb onto [src] because his hands are full!</span>")
|
||||
M.visible_message("<span class='boldwarning'>[M] can't climb onto [src] because [M.p_their()] hands are full!</span>")
|
||||
return
|
||||
. = ..(M, force, check_loc)
|
||||
|
||||
|
||||
@@ -287,17 +287,13 @@
|
||||
to_chat(user, "<span class='warning'>The welder must be on for this task!</span>")
|
||||
else
|
||||
if(W.force) //if force is non-zero
|
||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
do_sparks(5, TRUE, src)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bot/bullet_act(obj/item/projectile/Proj)
|
||||
if(Proj && (Proj.damage_type == BRUTE || Proj.damage_type == BURN))
|
||||
if(prob(75) && Proj.damage > 0)
|
||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
do_sparks(5, TRUE, src)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/bot/emp_act(severity)
|
||||
|
||||
@@ -259,9 +259,7 @@
|
||||
if(prob(50))
|
||||
new /obj/item/bodypart/l_arm/robot(Tsec)
|
||||
|
||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
do_sparks(3, TRUE, src)
|
||||
..()
|
||||
|
||||
/obj/machinery/bot_core/cleanbot
|
||||
|
||||
@@ -390,9 +390,7 @@ Auto Patrol[]"},
|
||||
if(lasercolor == "r")
|
||||
new /obj/item/clothing/suit/redtag(Tsec)
|
||||
|
||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
do_sparks(3, TRUE, src)
|
||||
|
||||
new /obj/effect/decal/cleanable/oil(loc)
|
||||
..()
|
||||
|
||||
@@ -381,9 +381,7 @@
|
||||
var/obj/item/stack/tile/plasteel/T = new (Tsec)
|
||||
T.amount = 1
|
||||
|
||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
do_sparks(3, TRUE, src)
|
||||
..()
|
||||
|
||||
/obj/machinery/bot_core/floorbot
|
||||
|
||||
@@ -530,9 +530,7 @@
|
||||
if(emagged && prob(25))
|
||||
playsound(loc, 'sound/voice/minsult.ogg', 50, 0)
|
||||
|
||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
do_sparks(3, TRUE, src)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/proc/declare(crit_patient)
|
||||
|
||||
@@ -719,9 +719,7 @@
|
||||
cell.update_icon()
|
||||
cell = null
|
||||
|
||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
do_sparks(3, TRUE, src)
|
||||
|
||||
new /obj/effect/decal/cleanable/oil(loc)
|
||||
..()
|
||||
|
||||
@@ -397,9 +397,7 @@ Auto Patrol: []"},
|
||||
if(prob(50))
|
||||
new /obj/item/bodypart/l_arm/robot(Tsec)
|
||||
|
||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
do_sparks(3, TRUE, src)
|
||||
|
||||
new /obj/effect/decal/cleanable/oil(loc)
|
||||
..()
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
var/obj/item/inventory_head
|
||||
var/obj/item/inventory_mask
|
||||
gold_core_spawnable = 2
|
||||
devourable = TRUE
|
||||
|
||||
/mob/living/simple_animal/crab/Life()
|
||||
..()
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
speed = 0
|
||||
maxHealth = 25
|
||||
health = 25
|
||||
devourable = TRUE
|
||||
|
||||
harm_intent_damage = 8
|
||||
obj_damage = 50
|
||||
|
||||
@@ -53,7 +53,5 @@
|
||||
ranged = 1
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot/death(gibbed)
|
||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
do_sparks(3, TRUE, src)
|
||||
..(1)
|
||||
@@ -0,0 +1,85 @@
|
||||
/mob/living/simple_animal/hostile/jungle
|
||||
vision_range = 5
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
faction = list("jungle")
|
||||
weather_immunities = list("acid")
|
||||
obj_damage = 30
|
||||
environment_smash = 2
|
||||
minbodytemp = 0
|
||||
maxbodytemp = 450
|
||||
response_help = "pokes"
|
||||
response_disarm = "shoves"
|
||||
response_harm = "strikes"
|
||||
status_flags = 0
|
||||
a_intent = INTENT_HARM
|
||||
see_in_dark = 4
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
|
||||
|
||||
|
||||
//Mega arachnid
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mega_arachnid
|
||||
name = "mega arachnid"
|
||||
desc = "Though physically imposing, it prefers to ambush its prey, and it will only engage with an already crippled opponent."
|
||||
melee_damage_lower = 30
|
||||
melee_damage_upper = 30
|
||||
maxHealth = 300
|
||||
health = 300
|
||||
speed = 1
|
||||
ranged = 1
|
||||
pixel_x = -16
|
||||
move_to_delay = 10
|
||||
aggro_vision_range = 9
|
||||
speak_emote = list("chitters")
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
ranged_cooldown_time = 60
|
||||
projectiletype = /obj/item/projectile/mega_arachnid
|
||||
projectilesound = 'sound/weapons/pierce.ogg'
|
||||
icon = 'icons/mob/jungle/arachnid.dmi'
|
||||
icon_state = "arachnid"
|
||||
icon_living = "arachnid"
|
||||
icon_dead = "dead_purple"
|
||||
alpha = 50
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mega_arachnid/Life()
|
||||
..()
|
||||
if(target && ranged_cooldown > world.time && iscarbon(target))
|
||||
var/mob/living/carbon/C = target
|
||||
if(!C.legcuffed && C.health < 50)
|
||||
retreat_distance = 9
|
||||
minimum_distance = 9
|
||||
alpha = 125
|
||||
return
|
||||
retreat_distance = 0
|
||||
minimum_distance = 0
|
||||
alpha = 255
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mega_arachnid/Aggro()
|
||||
..()
|
||||
alpha = 255
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/mega_arachnid/LoseAggro()
|
||||
..()
|
||||
alpha = 50
|
||||
|
||||
/obj/item/projectile/mega_arachnid
|
||||
name = "flesh snare"
|
||||
nodamage = 1
|
||||
damage = 0
|
||||
icon_state = "tentacle_end"
|
||||
|
||||
/obj/item/projectile/mega_arachnid/on_hit(atom/target, blocked = 0)
|
||||
if(iscarbon(target) && blocked < 100)
|
||||
var/obj/item/weapon/restraints/legcuffs/beartrap/mega_arachnid/B = new /obj/item/weapon/restraints/legcuffs/beartrap/mega_arachnid(get_turf(target))
|
||||
B.Crossed(target)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/restraints/legcuffs/beartrap/mega_arachnid
|
||||
name = "fleshy restraints"
|
||||
desc = "Used by mega arachnids to immobilize their prey."
|
||||
flags = DROPDEL
|
||||
icon_state = "tentacle_end"
|
||||
icon = 'icons/obj/projectiles.dmi'
|
||||
@@ -40,6 +40,7 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/ghost/Initialize()
|
||||
. = ..()
|
||||
set_light(1, 2)
|
||||
if(!random)
|
||||
give_hair()
|
||||
else
|
||||
@@ -60,4 +61,4 @@
|
||||
ghost_facial_hair = mutable_appearance('icons/mob/human_face.dmi', "facial_[ghost_facial_hair_style]", -HAIR_LAYER)
|
||||
ghost_facial_hair.alpha = 200
|
||||
ghost_facial_hair.color = ghost_facial_hair_color
|
||||
add_overlay(ghost_facial_hair)
|
||||
add_overlay(ghost_facial_hair)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
response_disarm = "shoos"
|
||||
response_harm = "stomps on"
|
||||
emote_see = list("jiggles", "bounces in place")
|
||||
speak_emote = list("telepathically chirps")
|
||||
speak_emote = list("blorbles")
|
||||
bubble_icon = "slime"
|
||||
initial_languages = list(/datum/language/common, /datum/language/slime)
|
||||
|
||||
@@ -31,10 +31,10 @@
|
||||
|
||||
see_in_dark = 8
|
||||
|
||||
verb_say = "telepathically chirps"
|
||||
verb_ask = "telepathically asks"
|
||||
verb_exclaim = "telepathically cries"
|
||||
verb_yell = "telephatically cries"
|
||||
verb_say = "blorbles"
|
||||
verb_ask = "inquisitively blorbles"
|
||||
verb_exclaim = "loudly blorbles"
|
||||
verb_yell = "loudly blorbles"
|
||||
|
||||
// canstun and canweaken don't affect slimes because they ignore stun and weakened variables
|
||||
// for the sake of cleanliness, though, here they are.
|
||||
|
||||
@@ -351,6 +351,8 @@
|
||||
/mob/proc/spin(spintime, speed)
|
||||
set waitfor = 0
|
||||
var/D = dir
|
||||
if((spintime < 1)||(speed < 1)||!spintime||!speed)
|
||||
return
|
||||
while(spintime >= speed)
|
||||
sleep(speed)
|
||||
switch(D)
|
||||
|
||||
@@ -497,9 +497,7 @@
|
||||
var/turf/T = get_turf(src)
|
||||
var/obj/structure/cable/N = T.get_cable_node()
|
||||
if (prob(50) && electrocute_mob(usr, N, N, 1, TRUE))
|
||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
do_sparks(5, TRUE, src)
|
||||
return
|
||||
C.use(10)
|
||||
to_chat(user, "<span class='notice'>You add cables to the APC frame.</span>")
|
||||
@@ -1181,9 +1179,7 @@
|
||||
/obj/machinery/power/apc/proc/shock(mob/user, prb)
|
||||
if(!prob(prb))
|
||||
return 0
|
||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
do_sparks(5, TRUE, src)
|
||||
if(isalien(user))
|
||||
return 0
|
||||
if(electrocute_mob(user, src, src, 1, TRUE))
|
||||
|
||||
@@ -156,9 +156,7 @@ By design, d1 is the smallest direction and d2 is the highest
|
||||
if(!prob(prb))
|
||||
return 0
|
||||
if (electrocute_mob(user, powernet, src, siemens_coeff))
|
||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
do_sparks(5, TRUE, src)
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
@@ -28,11 +28,12 @@
|
||||
|
||||
|
||||
/obj/machinery/power/generator/Initialize(mapload)
|
||||
. = ..()
|
||||
. = ..()
|
||||
var/obj/machinery/atmospherics/components/binary/circulator/circpath = /obj/machinery/atmospherics/components/binary/circulator
|
||||
cold_circ = locate(circpath) in get_step(src, cold_dir)
|
||||
hot_circ = locate(circpath) in get_step(src, hot_dir)
|
||||
connect_to_network()
|
||||
SSair.atmos_machinery += src
|
||||
|
||||
if(cold_circ)
|
||||
switch(cold_dir)
|
||||
@@ -55,6 +56,9 @@
|
||||
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/power/generator/Destroy()
|
||||
SSair.atmos_machinery -= src
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/generator/update_icon()
|
||||
|
||||
@@ -63,21 +67,20 @@
|
||||
else
|
||||
cut_overlays()
|
||||
|
||||
if(lastgenlev != 0)
|
||||
add_overlay("teg-op[lastgenlev]")
|
||||
var/L = min(round(lastgenlev/100000),11)
|
||||
if(L != 0)
|
||||
add_overlay(image('icons/obj/power.dmi', "teg-op[L]"))
|
||||
|
||||
add_overlay("teg-oc[lastcirc]")
|
||||
add_overlay("teg-oc[lastcirc]")
|
||||
|
||||
|
||||
#define GENRATE 800 // generator output coefficient from Q
|
||||
|
||||
/obj/machinery/power/generator/process()
|
||||
/obj/machinery/power/generator/process_atmos()
|
||||
|
||||
if(!cold_circ || !hot_circ)
|
||||
return
|
||||
|
||||
lastgen = 0
|
||||
|
||||
if(powernet)
|
||||
//to_chat(world, "cold_circ and hot_circ pass")
|
||||
|
||||
@@ -104,7 +107,7 @@
|
||||
var/energy_transfer = delta_temperature*hot_air_heat_capacity*cold_air_heat_capacity/(hot_air_heat_capacity+cold_air_heat_capacity)
|
||||
|
||||
var/heat = energy_transfer*(1-efficiency)
|
||||
lastgen = energy_transfer*efficiency
|
||||
lastgen += energy_transfer*efficiency
|
||||
|
||||
//to_chat(world, "lastgen = [lastgen]; heat = [heat]; delta_temperature = [delta_temperature]; hot_air_heat_capacity = [hot_air_heat_capacity]; cold_air_heat_capacity = [cold_air_heat_capacity];")
|
||||
|
||||
@@ -113,7 +116,7 @@
|
||||
|
||||
//to_chat(world, "POWER: [lastgen] W generated at [efficiency*100]% efficiency and sinks sizes [cold_air_heat_capacity], [hot_air_heat_capacity]")
|
||||
|
||||
add_avail(lastgen)
|
||||
//add_avail(lastgen) This is done in process now
|
||||
// update icon overlays only if displayed level has changed
|
||||
|
||||
if(hot_air)
|
||||
@@ -124,15 +127,23 @@
|
||||
var/datum/gas_mixture/cold_circ_air1 = cold_circ.AIR1
|
||||
cold_circ_air1.merge(cold_air)
|
||||
|
||||
var/genlev = max(0, min( round(11*lastgen / 100000), 11))
|
||||
update_icon()
|
||||
|
||||
var/circ = "[cold_circ && cold_circ.last_pressure_delta > 0 ? "1" : "0"][hot_circ && hot_circ.last_pressure_delta > 0 ? "1" : "0"]"
|
||||
if((genlev != lastgenlev) || (circ != lastcirc))
|
||||
lastgenlev = genlev
|
||||
if(circ != lastcirc)
|
||||
lastcirc = circ
|
||||
update_icon()
|
||||
|
||||
src.updateDialog()
|
||||
|
||||
/obj/machinery/power/generator/process()
|
||||
//Setting this number higher just makes the change in power output slower, it doesnt actualy reduce power output cause **math**
|
||||
var/power_output = round(lastgen / 10)
|
||||
add_avail(power_output)
|
||||
lastgenlev = power_output
|
||||
lastgen -= power_output
|
||||
..()
|
||||
|
||||
/obj/machinery/power/generator/attack_hand(mob/user)
|
||||
if(..())
|
||||
user << browse(null, "window=teg")
|
||||
@@ -151,7 +162,13 @@
|
||||
|
||||
t += "<div class='statusDisplay'>"
|
||||
|
||||
t += "Output: [round(lastgen)] W"
|
||||
var/displaygen = lastgenlev
|
||||
if(displaygen < 1000000) //less than a MW
|
||||
displaygen /= 1000
|
||||
t += "Output: [round(displaygen,0.01)] kW"
|
||||
else
|
||||
displaygen /= 1000000
|
||||
t += "Output: [round(displaygen,0.01)] MW"
|
||||
|
||||
t += "<BR>"
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
light_power = 0.7
|
||||
light_range = 15
|
||||
light_color = rgb(255, 0, 0)
|
||||
gender = FEMALE
|
||||
var/clashing = FALSE //If Nar-Sie is fighting Ratvar
|
||||
|
||||
/obj/singularity/narsie/large
|
||||
@@ -26,8 +27,8 @@
|
||||
grav_pull = 10
|
||||
consume_range = 12 //How many tiles out do we eat
|
||||
|
||||
/obj/singularity/narsie/large/New()
|
||||
..()
|
||||
/obj/singularity/narsie/large/Initialize()
|
||||
. = ..()
|
||||
send_to_playing_players("<span class='narsie'>NAR-SIE HAS RISEN</span>")
|
||||
send_to_playing_players(pick('sound/hallucinations/im_here1.ogg', 'sound/hallucinations/im_here2.ogg'))
|
||||
|
||||
|
||||
@@ -29,12 +29,12 @@
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
dangerous_possession = TRUE
|
||||
|
||||
/obj/singularity/New(loc, var/starting_energy = 50, var/temp = 0)
|
||||
/obj/singularity/Initialize(mapload, starting_energy = 50)
|
||||
//CARN: admin-alert for chuckle-fuckery.
|
||||
admin_investigate_setup()
|
||||
|
||||
src.energy = starting_energy
|
||||
..()
|
||||
. = ..()
|
||||
START_PROCESSING(SSobj, src)
|
||||
GLOB.poi_list |= src
|
||||
GLOB.singularities |= src
|
||||
|
||||
@@ -129,6 +129,7 @@
|
||||
|
||||
/obj/machinery/power/supermatter_shard/Initialize()
|
||||
. = ..()
|
||||
SSair.atmos_machinery += src
|
||||
countdown = new(src)
|
||||
countdown.start()
|
||||
GLOB.poi_list |= src
|
||||
@@ -139,6 +140,7 @@
|
||||
|
||||
/obj/machinery/power/supermatter_shard/Destroy()
|
||||
investigate_log("has been destroyed.", "supermatter")
|
||||
SSair.atmos_machinery -= src
|
||||
QDEL_NULL(radio)
|
||||
GLOB.poi_list -= src
|
||||
QDEL_NULL(countdown)
|
||||
@@ -181,7 +183,7 @@
|
||||
E.energy = power
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/power/supermatter_shard/process()
|
||||
/obj/machinery/power/supermatter_shard/process_atmos()
|
||||
var/turf/T = loc
|
||||
|
||||
if(isnull(T)) // We have a null turf...something is wrong, stop processing this entity.
|
||||
@@ -296,6 +298,7 @@
|
||||
|
||||
if(produces_gas)
|
||||
env.merge(removed)
|
||||
air_update_turf()
|
||||
|
||||
for(var/mob/living/carbon/human/l in view(src, HALLUCINATION_RANGE(power))) // If they can see it without mesons on. Bad on them.
|
||||
if(!istype(l.glasses, /obj/item/clothing/glasses/meson))
|
||||
|
||||
@@ -40,6 +40,11 @@ GLOBAL_LIST_INIT(blacklisted_tesla_types, typecacheof(list(/obj/machinery/atmosp
|
||||
var/energy_to_raise = 32
|
||||
var/energy_to_lower = -20
|
||||
|
||||
/obj/singularity/energy_ball/Initialize(mapload, starting_energy = 50, is_miniball = FALSE)
|
||||
. = ..()
|
||||
if(!is_miniball)
|
||||
set_light(10, 7, "#EEEEFF")
|
||||
|
||||
/obj/singularity/energy_ball/ex_act(severity, target)
|
||||
return
|
||||
|
||||
@@ -54,6 +59,11 @@ GLOBAL_LIST_INIT(blacklisted_tesla_types, typecacheof(list(/obj/machinery/atmosp
|
||||
|
||||
. = ..()
|
||||
|
||||
/obj/singularity/energy_ball/admin_investigate_setup()
|
||||
if(istype(loc, /obj/singularity/energy_ball))
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/singularity/energy_ball/process()
|
||||
if(!orbiting)
|
||||
handle_energy()
|
||||
@@ -117,7 +127,7 @@ GLOBAL_LIST_INIT(blacklisted_tesla_types, typecacheof(list(/obj/machinery/atmosp
|
||||
/obj/singularity/energy_ball/proc/new_mini_ball()
|
||||
if(!loc)
|
||||
return
|
||||
var/obj/singularity/energy_ball/EB = new(loc)
|
||||
var/obj/singularity/energy_ball/EB = new(loc, 0, TRUE)
|
||||
|
||||
EB.transform *= pick(0.3, 0.4, 0.5, 0.6, 0.7)
|
||||
var/icon/I = icon(icon,icon_state,dir)
|
||||
|
||||
@@ -191,7 +191,7 @@
|
||||
fire_sound = 'sound/magic/lightningbolt.ogg'
|
||||
e_cost = 200
|
||||
select_name = "stun"
|
||||
projectile_type = /obj/item/projectile/energy/tesla_revolver
|
||||
projectile_type = /obj/item/projectile/energy/tesla/revolver
|
||||
|
||||
/obj/item/ammo_casing/energy/gravityrepulse
|
||||
projectile_type = /obj/item/projectile/gravityrepulse
|
||||
|
||||
@@ -179,6 +179,8 @@
|
||||
return
|
||||
if(setAngle)
|
||||
Angle = setAngle
|
||||
var/old_pixel_x = pixel_x
|
||||
var/old_pixel_y = pixel_y
|
||||
if(!legacy) //new projectiles
|
||||
set waitfor = 0
|
||||
var/next_run = world.time
|
||||
@@ -201,29 +203,30 @@
|
||||
|
||||
var/Pixel_x=round((sin(Angle)+16*sin(Angle)*2), 1) //round() is a floor operation when only one argument is supplied, we don't want that here
|
||||
var/Pixel_y=round((cos(Angle)+16*cos(Angle)*2), 1)
|
||||
var/pixel_x_offset = pixel_x + Pixel_x
|
||||
var/pixel_y_offset = pixel_y + Pixel_y
|
||||
var/pixel_x_offset = old_pixel_x + Pixel_x
|
||||
var/pixel_y_offset = old_pixel_y + Pixel_y
|
||||
var/new_x = x
|
||||
var/new_y = y
|
||||
|
||||
while(pixel_x_offset > 16)
|
||||
pixel_x_offset -= 32
|
||||
pixel_x -= 32
|
||||
old_pixel_x -= 32
|
||||
new_x++// x++
|
||||
while(pixel_x_offset < -16)
|
||||
pixel_x_offset += 32
|
||||
pixel_x += 32
|
||||
old_pixel_x += 32
|
||||
new_x--
|
||||
|
||||
while(pixel_y_offset > 16)
|
||||
pixel_y_offset -= 32
|
||||
pixel_y -= 32
|
||||
old_pixel_y -= 32
|
||||
new_y++
|
||||
while(pixel_y_offset < -16)
|
||||
pixel_y_offset += 32
|
||||
pixel_y += 32
|
||||
old_pixel_y += 32
|
||||
new_y--
|
||||
|
||||
|
||||
pixel_x = old_pixel_x
|
||||
pixel_y = old_pixel_y
|
||||
step_towards(src, locate(new_x, new_y, z))
|
||||
next_run += max(world.tick_lag, speed)
|
||||
var/delay = next_run - world.time
|
||||
@@ -232,7 +235,9 @@
|
||||
pixel_y = pixel_y_offset
|
||||
else
|
||||
animate(src, pixel_x = pixel_x_offset, pixel_y = pixel_y_offset, time = max(1, (delay <= 3 ? delay - 1 : delay)), flags = ANIMATION_END_NOW)
|
||||
|
||||
old_pixel_x = pixel_x_offset
|
||||
old_pixel_y = pixel_y_offset
|
||||
|
||||
if(original && (original.layer>=2.75) || ismob(original))
|
||||
if(loc == get_turf(original))
|
||||
if(!(original in permutated))
|
||||
|
||||
@@ -159,44 +159,34 @@
|
||||
/obj/item/projectile/energy/bolt/large
|
||||
damage = 20
|
||||
|
||||
/obj/item/projectile/energy/tesla_revolver
|
||||
/obj/item/projectile/energy/tesla
|
||||
name = "tesla bolt"
|
||||
icon_state = "tesla_projectile"
|
||||
impact_effect_type = /obj/effect/overlay/temp/impact_effect/blue_laser
|
||||
var/chain
|
||||
|
||||
/obj/item/projectile/energy/tesla_revolver/fire(setAngle)
|
||||
/obj/item/projectile/energy/tesla/fire(setAngle)
|
||||
if(firer)
|
||||
chain = firer.Beam(src, icon_state = "lightning[rand(1, 12)]", time = INFINITY, maxdistance = INFINITY)
|
||||
..()
|
||||
|
||||
/obj/item/projectile/energy/tesla_revolver/on_hit(atom/target)
|
||||
. = ..()
|
||||
if(isliving(target))
|
||||
tesla_zap(src, 3, 10000)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/projectile/energy/tesla_revolver/Destroy()
|
||||
/obj/item/projectile/energy/tesla/Destroy()
|
||||
qdel(chain)
|
||||
return ..()
|
||||
|
||||
/obj/item/projectile/energy/tesla/revolver
|
||||
name = "energy orb"
|
||||
|
||||
/obj/item/projectile/energy/tesla_cannon
|
||||
name = "tesla bolt"
|
||||
icon_state = "tesla_projectile"
|
||||
impact_effect_type = /obj/effect/overlay/temp/impact_effect/blue_laser
|
||||
var/chain
|
||||
/obj/item/projectile/energy/tesla/revolver/on_hit(atom/target)
|
||||
. = ..()
|
||||
if(isliving(target))
|
||||
tesla_zap(target, 3, 10000)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/projectile/energy/tesla_cannon/fire(setAngle)
|
||||
if(firer)
|
||||
chain = firer.Beam(src, icon_state = "lightning[rand(1, 12)]", time = INFINITY, maxdistance = INFINITY)
|
||||
..()
|
||||
/obj/item/projectile/energy/tesla/cannon
|
||||
name = "tesla orb"
|
||||
|
||||
/obj/item/projectile/energy/tesla_cannon/on_hit(atom/target)
|
||||
/obj/item/projectile/energy/tesla/cannon/on_hit(atom/target)
|
||||
. = ..()
|
||||
tesla_zap(src, 3, 10000, explosive = FALSE, stun_mobs = FALSE)
|
||||
tesla_zap(target, 3, 10000, explosive = FALSE, stun_mobs = FALSE)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/projectile/energy/tesla_cannon/Destroy()
|
||||
qdel(chain)
|
||||
return ..()
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
active_power_usage = 100
|
||||
pass_flags = PASSTABLE
|
||||
resistance_flags = ACID_PROOF
|
||||
var/operating = 0
|
||||
var/operating = FALSE
|
||||
var/obj/item/weapon/reagent_containers/beaker = null
|
||||
var/limit = 10
|
||||
var/list/blend_items = list (
|
||||
@@ -38,7 +38,7 @@
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/wheat = list("flour" = -5),
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/oat = list("flour" = -5),
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/rice = list("rice" = -5),
|
||||
/obj/item/weapon/reagent_containers/food/snacks/donut/New = list("sprinkles" = -2, "sugar" = 1),
|
||||
/obj/item/weapon/reagent_containers/food/snacks/donut = list("sprinkles" = -2, "sugar" = 1),
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/cherries = list("cherryjelly" = 0),
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/bluecherries = list("bluecherryjelly" = 0),
|
||||
/obj/item/weapon/reagent_containers/food/snacks/egg = list("eggyolk" = -5),
|
||||
@@ -220,9 +220,12 @@
|
||||
[processing_chamber]<br>
|
||||
[beaker_contents]<hr>
|
||||
"}
|
||||
if (is_beaker_ready && !is_chamber_empty && !(stat & (NOPOWER|BROKEN)))
|
||||
dat += "<A href='?src=\ref[src];action=grind'>Grind the reagents</a><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=juice'>Juice the reagents</a><BR><BR>"
|
||||
if (is_beaker_ready)
|
||||
if(!is_chamber_empty && !(stat & (NOPOWER|BROKEN)))
|
||||
dat += "<A href='?src=\ref[src];action=grind'>Grind the reagents</a><BR>"
|
||||
dat += "<A href='?src=\ref[src];action=juice'>Juice the reagents</a><BR><BR>"
|
||||
else if (beaker.reagents.total_volume)
|
||||
dat += "<A href='?src=\ref[src];action=mix'>Mix the reagents</a><BR><BR>"
|
||||
if(holdingitems && holdingitems.len > 0)
|
||||
dat += "<A href='?src=\ref[src];action=eject'>Eject the reagents</a><BR>"
|
||||
if (beaker)
|
||||
@@ -248,6 +251,8 @@
|
||||
grind()
|
||||
if("juice")
|
||||
juice()
|
||||
if("mix")
|
||||
mix()
|
||||
if("eject")
|
||||
eject()
|
||||
if ("detach")
|
||||
@@ -327,11 +332,11 @@
|
||||
playsound(src.loc, 'sound/machines/juicer.ogg', 20, 1)
|
||||
var/offset = prob(50) ? -2 : 2
|
||||
animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 250) //start shaking
|
||||
operating = 1
|
||||
operating = TRUE
|
||||
updateUsrDialog()
|
||||
spawn(50)
|
||||
pixel_x = initial(pixel_x) //return to its spot after shaking
|
||||
operating = 0
|
||||
operating = FALSE
|
||||
updateUsrDialog()
|
||||
|
||||
//Snacks
|
||||
@@ -365,11 +370,11 @@
|
||||
playsound(src.loc, 'sound/machines/blender.ogg', 50, 1)
|
||||
var/offset = prob(50) ? -2 : 2
|
||||
animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 250) //start shaking
|
||||
operating = 1
|
||||
operating = TRUE
|
||||
updateUsrDialog()
|
||||
spawn(60)
|
||||
pixel_x = initial(pixel_x) //return to its spot after shaking
|
||||
operating = 0
|
||||
operating = FALSE
|
||||
updateUsrDialog()
|
||||
|
||||
//Snacks and Plants
|
||||
@@ -467,3 +472,33 @@
|
||||
break
|
||||
beaker.reagents.add_reagent(r_id, min(O.reagent_contents[r_id], space))
|
||||
remove_object(O)
|
||||
|
||||
/obj/machinery/reagentgrinder/proc/mix()
|
||||
|
||||
//For butter and other things that would change upon shaking or mixing
|
||||
power_change()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
if (!beaker)
|
||||
return
|
||||
playsound(src.loc, 'sound/machines/juicer.ogg', 20, 1)
|
||||
var/offset = prob(50) ? -2 : 2
|
||||
animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 250) //start shaking
|
||||
operating = TRUE
|
||||
updateUsrDialog()
|
||||
addtimer(CALLBACK(src, /obj/machinery/reagentgrinder/proc/mix_complete), 50)
|
||||
|
||||
/obj/machinery/reagentgrinder/proc/mix_complete()
|
||||
pixel_x = initial(pixel_x) //return to its spot after shaking
|
||||
operating = FALSE
|
||||
updateUsrDialog()
|
||||
if (beaker.reagents.total_volume)
|
||||
//Recipe to make Butter
|
||||
while(beaker.reagents.get_reagent_amount("milk") >= 15)
|
||||
beaker.reagents.remove_reagent("milk", 15)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/butter(src.loc)
|
||||
//Recipe to make Mayonnaise
|
||||
if (beaker.reagents.has_reagent("eggyolk"))
|
||||
var/amount = beaker.reagents.get_reagent_amount("eggyolk")
|
||||
beaker.reagents.remove_reagent("eggyolk", amount)
|
||||
beaker.reagents.add_reagent("mayonnaise", amount)
|
||||
@@ -966,7 +966,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
|
||||
glass_desc = "Only for the experienced. You think you see sand floating in the glass."
|
||||
|
||||
/datum/reagent/consumable/ethanol/bananahonk
|
||||
name = "Banana Mama"
|
||||
name = "Banana Honk"
|
||||
id = "bananahonk"
|
||||
description = "A drink from Clown Heaven."
|
||||
nutriment_factor = 1 * REAGENTS_METABOLISM
|
||||
|
||||
@@ -60,7 +60,10 @@
|
||||
// data for nutriment is one or more (flavour -> ratio)
|
||||
// where all the ratio values adds up to 1
|
||||
|
||||
var/list/taste_amounts = data.Copy()
|
||||
var/list/taste_amounts = list()
|
||||
if(data)
|
||||
taste_amounts = data.Copy()
|
||||
|
||||
counterlist_scale(taste_amounts, volume)
|
||||
|
||||
var/list/other_taste_amounts = newdata.Copy()
|
||||
@@ -524,6 +527,12 @@
|
||||
M.heal_bodypart_damage(3,1)
|
||||
..()
|
||||
|
||||
/datum/reagent/consumable/mayonnaise
|
||||
name = "Mayonnaise"
|
||||
id = "mayonnaise"
|
||||
description = "An white and oily mixture of mixed egg yolks."
|
||||
color = "#DFDFDF"
|
||||
taste_description = "mayonnaise"
|
||||
|
||||
////Lavaland Flora Reagents////
|
||||
|
||||
|
||||
@@ -347,10 +347,9 @@
|
||||
/datum/reagent/medicine/mine_salve/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1)
|
||||
if(iscarbon(M) && M.stat != DEAD)
|
||||
if(method in list(INGEST, VAPOR, INJECT))
|
||||
M.Stun(4)
|
||||
M.Weaken(4)
|
||||
M.nutrition -= 5
|
||||
if(show_message)
|
||||
to_chat(M, "<span class='warning'>Your stomach agonizingly cramps!</span>")
|
||||
to_chat(M, "<span class='warning'>Your stomach feels empty and cramps!</span>")
|
||||
else
|
||||
var/mob/living/carbon/C = M
|
||||
for(var/s in C.surgeries)
|
||||
@@ -962,8 +961,7 @@
|
||||
/datum/reagent/medicine/antitoxin/on_mob_life(mob/living/M)
|
||||
M.adjustToxLoss(-2*REM, 0)
|
||||
for(var/datum/reagent/toxin/R in M.reagents.reagent_list)
|
||||
if(R != src)
|
||||
M.reagents.remove_reagent(R.id,1)
|
||||
M.reagents.remove_reagent(R.id,1)
|
||||
..()
|
||||
. = 1
|
||||
|
||||
|
||||
@@ -189,7 +189,7 @@
|
||||
/datum/reagent/water/holywater/on_mob_life(mob/living/M)
|
||||
if(!data) data = 1
|
||||
data++
|
||||
M.jitteriness = max(M.jitteriness-5,0)
|
||||
M.jitteriness = min(M.jitteriness+4,10)
|
||||
if(data >= 30) // 12 units, 54 seconds @ metabolism 0.4 units & tick rate 1.8 sec
|
||||
if(!M.stuttering)
|
||||
M.stuttering = 1
|
||||
@@ -212,9 +212,9 @@
|
||||
SSticker.mode.remove_cultist(M.mind, 1, 1)
|
||||
else if(is_servant_of_ratvar(M))
|
||||
remove_servant_of_ratvar(M)
|
||||
holder.remove_reagent(id, volume) // maybe this is a little too perfect and a max() cap on the statuses would be better??
|
||||
M.jitteriness = 0
|
||||
M.stuttering = 0
|
||||
holder.remove_reagent(id, volume) // maybe this is a little too perfect and a max() cap on the statuses would be better??
|
||||
return
|
||||
holder.remove_reagent(id, 0.4) //fixed consumption to prevent balancing going out of whack
|
||||
|
||||
@@ -658,7 +658,7 @@
|
||||
taste_mult = 0 // apparently tasteless.
|
||||
|
||||
/datum/reagent/mercury/on_mob_life(mob/living/M)
|
||||
if(M.canmove && isspaceturf(M.loc))
|
||||
if(M.canmove && !isspaceturf(M.loc))
|
||||
step(M, pick(GLOB.cardinal))
|
||||
if(prob(5))
|
||||
M.emote(pick("twitch","drool","moan"))
|
||||
@@ -738,7 +738,7 @@
|
||||
taste_description = "metal"
|
||||
|
||||
/datum/reagent/lithium/on_mob_life(mob/living/M)
|
||||
if(M.canmove && isspaceturf(M.loc))
|
||||
if(M.canmove && !isspaceturf(M.loc))
|
||||
step(M, pick(GLOB.cardinal))
|
||||
if(prob(5))
|
||||
M.emote(pick("twitch","drool","moan"))
|
||||
@@ -1568,6 +1568,13 @@
|
||||
M.update_transform()
|
||||
..()
|
||||
|
||||
/datum/reagent/plastic_polymers
|
||||
name = "plastic polymers"
|
||||
id = "plastic_polymers"
|
||||
description = "the petroleum based components of plastic."
|
||||
color = "#f7eded"
|
||||
taste_description = "plastic"
|
||||
|
||||
/datum/reagent/glitter
|
||||
name = "generic glitter"
|
||||
id = "glitter"
|
||||
|
||||
@@ -648,6 +648,34 @@
|
||||
M.losebreath += 5
|
||||
return ..()
|
||||
|
||||
/datum/reagent/toxin/spewium
|
||||
name = "Spewium"
|
||||
id = "spewium"
|
||||
description = "A powerful emetic, causes uncontrollable vomiting. May result in vomiting organs at high doses."
|
||||
reagent_state = LIQUID
|
||||
color = "#2f6617" //A sickly green color
|
||||
metabolization_rate = REAGENTS_METABOLISM
|
||||
overdose_threshold = 29
|
||||
toxpwr = 0
|
||||
taste_description = "vomit"
|
||||
|
||||
/datum/reagent/toxin/spewium/on_mob_life(mob/living/M)
|
||||
.=..()
|
||||
if(current_cycle >=11 && prob(min(50,current_cycle)) && ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
H.vomit(lost_nutrition = 10, blood = prob(10), stun = prob(50), distance = rand(0,4), message = TRUE, toxic = prob(30))
|
||||
for(var/datum/reagent/toxin/R in M.reagents.reagent_list)
|
||||
if(R != src)
|
||||
H.reagents.remove_reagent(R.id,1)
|
||||
|
||||
/datum/reagent/toxin/spewium/overdose_process(mob/living/M)
|
||||
. = ..()
|
||||
if(current_cycle >=33 && prob(15) && ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
H.spew_organ()
|
||||
H.vomit(lost_nutrition = 0, blood = 1, stun = 1, distance = 4)
|
||||
to_chat(H, "<span class='userdanger'>You feel something lumpy come up as you vomit.</span>")
|
||||
|
||||
/datum/reagent/toxin/curare
|
||||
name = "Curare"
|
||||
id = "curare"
|
||||
|
||||
@@ -624,3 +624,14 @@
|
||||
id = "laughter"
|
||||
results = list("laughter" = 10) // Fuck it. I'm not touching this one.
|
||||
required_reagents = list("sugar" = 1, "banana" = 1)
|
||||
|
||||
/datum/chemical_reaction/plastic_polymers
|
||||
name = "plastic polymers"
|
||||
id = "plastic_polymers"
|
||||
required_reagents = list("oil" = 5, "sodiumchloride" = 2, "ash" = 3)
|
||||
required_temp = 374 //lazily consistent with soap & other crafted objects generically created with heat.
|
||||
|
||||
/datum/chemical_reaction/plastic_polymers/on_reaction(datum/reagents/holder, created_volume)
|
||||
var/location = get_turf(holder.my_atom)
|
||||
for(var/i in 1 to 10)
|
||||
new /obj/item/stack/sheet/plastic(location)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user