Merge remote-tracking branch 'refs/remotes/origin/master' into custom_roundstart_items
This commit is contained in:
@@ -13,6 +13,10 @@
|
||||
#define MC_AVERAGE_FAST(average, current) (0.7 * (average) + 0.3 * (current))
|
||||
#define MC_AVERAGE(average, current) (0.8 * (average) + 0.2 * (current))
|
||||
#define MC_AVERAGE_SLOW(average, current) (0.9 * (average) + 0.1 * (current))
|
||||
|
||||
#define MC_AVG_FAST_UP_SLOW_DOWN(average, current) (average > current ? MC_AVERAGE_SLOW(average, current) : MC_AVERAGE_FAST(average, current))
|
||||
#define MC_AVG_SLOW_UP_FAST_DOWN(average, current) (average < current ? MC_AVERAGE_SLOW(average, current) : MC_AVERAGE_FAST(average, current))
|
||||
|
||||
#define NEW_SS_GLOBAL(varname) if(varname != src){if(istype(varname)){Recover();qdel(varname);}varname = src;}
|
||||
|
||||
#define START_PROCESSING(Processor, Datum) if (!Datum.isprocessing) {Datum.isprocessing = 1;Processor.processing += Datum}
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
#define LIGHTING_BASE_MATRIX \
|
||||
list \
|
||||
( \
|
||||
LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \
|
||||
LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \
|
||||
LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \
|
||||
LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \
|
||||
1, 1, 1, 0, \
|
||||
1, 1, 1, 0, \
|
||||
1, 1, 1, 0, \
|
||||
1, 1, 1, 0, \
|
||||
0, 0, 0, 1 \
|
||||
) \
|
||||
|
||||
@@ -78,4 +78,11 @@
|
||||
#define DYNAMIC_LIGHTING_ENABLED 1 //dynamic lighting enabled
|
||||
#define DYNAMIC_LIGHTING_FORCED 2 //dynamic lighting enabled even if the area doesn't require power
|
||||
#define DYNAMIC_LIGHTING_IFSTARLIGHT 3 //dynamic lighting enabled only if starlight is.
|
||||
#define IS_DYNAMIC_LIGHTING(A) A.dynamic_lighting
|
||||
#define IS_DYNAMIC_LIGHTING(A) A.dynamic_lighting
|
||||
|
||||
|
||||
//code assumes higher numbers override lower numbers.
|
||||
#define LIGHTING_NO_UPDATE 0
|
||||
#define LIGHTING_VIS_UPDATE 1
|
||||
#define LIGHTING_CHECK_UPDATE 2
|
||||
#define LIGHTING_FORCE_UPDATE 3
|
||||
@@ -0,0 +1,3 @@
|
||||
#define CHECKBOX_NONE 0
|
||||
#define CHECKBOX_GROUP 1
|
||||
#define CHECKBOX_TOGGLE 2
|
||||
@@ -33,4 +33,8 @@
|
||||
#define STATUS_EFFECT_SIGILMARK /datum/status_effect/sigil_mark
|
||||
#define STATUS_EFFECT_BELLIGERENT /datum/status_effect/belligerent //forces the affected to walk, doing damage if they try to run
|
||||
|
||||
#define STATUS_EFFECT_MANIAMOTOR /datum/status_effect/maniamotor //disrupts, damages, and confuses the affected as long as they're in range of the motor
|
||||
#define MAX_MANIA_SEVERITY 100 //how high the mania severity can go
|
||||
#define MANIA_DAMAGE_TO_CONVERT 90 //how much damage is required before it'll convert affected targets
|
||||
|
||||
#define STATUS_EFFECT_HISWRATH /datum/status_effect/his_wrath //His Wrath.
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
diff a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm (rejected hunks)
|
||||
@@ -33,4 +33,8 @@
|
||||
#define STATUS_EFFECT_SIGILMARK /datum/status_effect/sigil_mark
|
||||
#define STATUS_EFFECT_BELLIGERENT /datum/status_effect/belligerent //forces the affected to walk, doing damage if they try to run
|
||||
|
||||
+#define STATUS_EFFECT_MANIAMOTOR /datum/status_effect/maniamotor //disrupts, damages, and confuses the affected as long as they're in range of the motor
|
||||
+#define MAX_MANIA_SEVERITY 100 //how high the mania severity can go
|
||||
+#define MANIA_DAMAGE_TO_CONVERT 90 //how much damage is required before it'll convert affected targets
|
||||
+
|
||||
#define STATUS_EFFECT_HISWRATH /datum/status_effect/his_wrath //His Wrath.
|
||||
@@ -457,6 +457,7 @@
|
||||
#define LAZYACCESS(L, I) (L ? (isnum(I) ? (I > 0 && I <= L.len ? L[I] : null) : L[I]) : null)
|
||||
#define LAZYLEN(L) length(L)
|
||||
#define LAZYCLEARLIST(L) if(L) L.Cut()
|
||||
#define SANITIZE_LIST(L) ( islist(L) ? L : list() )
|
||||
|
||||
/* Definining a counter as a series of key -> numeric value entries
|
||||
|
||||
|
||||
+17
-20
@@ -20,13 +20,13 @@
|
||||
/proc/log_admin(text)
|
||||
GLOB.admin_log.Add(text)
|
||||
if (config.log_admin)
|
||||
GLOB.diary << "\[[time_stamp()]]ADMIN: [text]"
|
||||
GLOB.world_game_log << "\[[time_stamp()]]ADMIN: [text]"
|
||||
|
||||
//Items using this proc are stripped from public logs - use with caution
|
||||
/proc/log_admin_private(text)
|
||||
GLOB.admin_log.Add(text)
|
||||
if (config.log_admin)
|
||||
GLOB.diary << "\[[time_stamp()]]ADMINPRIVATE: [text]"
|
||||
GLOB.world_game_log << "\[[time_stamp()]]ADMINPRIVATE: [text]"
|
||||
|
||||
/proc/log_adminsay(text)
|
||||
if (config.log_adminchat)
|
||||
@@ -38,67 +38,64 @@
|
||||
|
||||
/proc/log_game(text)
|
||||
if (config.log_game)
|
||||
GLOB.diary << "\[[time_stamp()]]GAME: [text]"
|
||||
GLOB.world_game_log << "\[[time_stamp()]]GAME: [text]"
|
||||
|
||||
/proc/log_vote(text)
|
||||
if (config.log_vote)
|
||||
GLOB.diary << "\[[time_stamp()]]VOTE: [text]"
|
||||
GLOB.world_game_log << "\[[time_stamp()]]VOTE: [text]"
|
||||
|
||||
/proc/log_access(text)
|
||||
if (config.log_access)
|
||||
GLOB.diary << "\[[time_stamp()]]ACCESS: [text]"
|
||||
GLOB.world_game_log << "\[[time_stamp()]]ACCESS: [text]"
|
||||
|
||||
/proc/log_say(text)
|
||||
if (config.log_say)
|
||||
GLOB.diary << "\[[time_stamp()]]SAY: [text]"
|
||||
GLOB.world_game_log << "\[[time_stamp()]]SAY: [text]"
|
||||
|
||||
/proc/log_prayer(text)
|
||||
if (config.log_prayer)
|
||||
GLOB.diary << "\[[time_stamp()]]PRAY: [text]"
|
||||
GLOB.world_game_log << "\[[time_stamp()]]PRAY: [text]"
|
||||
|
||||
/proc/log_law(text)
|
||||
if (config.log_law)
|
||||
GLOB.diary << "\[[time_stamp()]]LAW: [text]"
|
||||
GLOB.world_game_log << "\[[time_stamp()]]LAW: [text]"
|
||||
|
||||
/proc/log_ooc(text)
|
||||
if (config.log_ooc)
|
||||
GLOB.diary << "\[[time_stamp()]]OOC: [text]"
|
||||
GLOB.world_game_log << "\[[time_stamp()]]OOC: [text]"
|
||||
|
||||
/proc/log_whisper(text)
|
||||
if (config.log_whisper)
|
||||
GLOB.diary << "\[[time_stamp()]]WHISPER: [text]"
|
||||
GLOB.world_game_log << "\[[time_stamp()]]WHISPER: [text]"
|
||||
|
||||
/proc/log_emote(text)
|
||||
if (config.log_emote)
|
||||
GLOB.diary << "\[[time_stamp()]]EMOTE: [text]"
|
||||
GLOB.world_game_log << "\[[time_stamp()]]EMOTE: [text]"
|
||||
|
||||
/proc/log_attack(text)
|
||||
if (config.log_attack)
|
||||
GLOB.diaryofmeanpeople << "\[[time_stamp()]]ATTACK: [text]"
|
||||
GLOB.world_attack_log << "\[[time_stamp()]]ATTACK: [text]"
|
||||
|
||||
/proc/log_pda(text)
|
||||
if (config.log_pda)
|
||||
GLOB.diary << "\[[time_stamp()]]PDA: [text]"
|
||||
GLOB.world_game_log << "\[[time_stamp()]]PDA: [text]"
|
||||
|
||||
/proc/log_comment(text)
|
||||
if (config.log_pda)
|
||||
//reusing the PDA option because I really don't think news comments are worth a config option
|
||||
GLOB.diary << "\[[time_stamp()]]COMMENT: [text]"
|
||||
GLOB.world_game_log << "\[[time_stamp()]]COMMENT: [text]"
|
||||
|
||||
/proc/log_chat(text)
|
||||
if (config.log_pda)
|
||||
GLOB.diary << "\[[time_stamp()]]CHAT: [text]"
|
||||
GLOB.world_game_log << "\[[time_stamp()]]CHAT: [text]"
|
||||
|
||||
/proc/log_sql(text)
|
||||
if(config.sql_enabled)
|
||||
GLOB.diary << "\[[time_stamp()]]SQL: [text]"
|
||||
GLOB.world_game_log << "\[[time_stamp()]]SQL: [text]"
|
||||
|
||||
//This replaces world.log so it displays both in DD and the file
|
||||
/proc/log_world(text)
|
||||
if(config && config.log_runtimes)
|
||||
world.log = GLOB.runtime_diary
|
||||
world.log << text
|
||||
world.log = null
|
||||
GLOB.world_runtime_log << text
|
||||
world.log << text
|
||||
|
||||
// Helper procs for building detailed log lines
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
#define YOUNG 4
|
||||
|
||||
|
||||
/client/proc/join_date_check(y,m,d)
|
||||
var/datum/DBQuery/query_datediff = SSdbcore.NewQuery("SELECT DATEDIFF(Now(),'[y]-[m]-[d]')")
|
||||
|
||||
if(!query_datediff.Execute())
|
||||
return FALSE
|
||||
|
||||
if(query_datediff.NextRow())
|
||||
var/diff = text2num(query_datediff.item[1])
|
||||
if(config.use_account_age_for_jobs)
|
||||
player_age = max(0,diff) //So job code soesn't freak out if they are time traveling.
|
||||
if(diff < YOUNG)
|
||||
var/msg = "(IP: [address], ID: [computer_id]) is a new BYOND account made on [y]-[m]-[d]."
|
||||
if(diff < 0)
|
||||
msg += " They are also apparently from the future."
|
||||
message_admins("[key_name_admin(src)] [msg]")
|
||||
return TRUE
|
||||
#undef YOUNG
|
||||
|
||||
|
||||
/client/proc/findJoinDate()
|
||||
var/http[] = world.Export("http://byond.com/members/[src.ckey]?format=text")
|
||||
if(!http)
|
||||
log_world("Failed to connect to byond age check for [src.ckey]")
|
||||
return FALSE
|
||||
|
||||
var/F = file2text(http["CONTENT"])
|
||||
if(F)
|
||||
var/regex/R = regex("joined = \"(\\d{4})-(\\d{2})-(\\d{2})\"")
|
||||
if(!R.Find(F))
|
||||
CRASH("Age check regex failed")
|
||||
var/y = R.group[1]
|
||||
var/m = R.group[2]
|
||||
var/d = R.group[3]
|
||||
return join_date_check(y,m,d)
|
||||
@@ -24,4 +24,4 @@ GLOBAL_LIST_EMPTY(whitelisted_species_list)
|
||||
|
||||
/proc/log_mentor(text)
|
||||
GLOB.mentor_log.Add(text)
|
||||
GLOB.diary << "\[[time_stamp()]]MENTOR: [text]"
|
||||
GLOB.world_game_log << "\[[time_stamp()]]MENTOR: [text]"
|
||||
@@ -104,5 +104,6 @@ GLOBAL_LIST_INIT(maintenance_loot, list(
|
||||
/obj/item/weapon/storage/secure/briefcase = 3,
|
||||
/obj/item/weapon/storage/toolbox/artistic = 2,
|
||||
/obj/item/toy/eightball = 1,
|
||||
/obj/item/weapon/storage/daki = 3,
|
||||
"" = 3
|
||||
))
|
||||
|
||||
+33
-27
@@ -1,28 +1,34 @@
|
||||
GLOBAL_VAR(diary)
|
||||
GLOBAL_PROTECT(diary)
|
||||
GLOBAL_VAR(runtime_diary)
|
||||
GLOBAL_PROTECT(runtime_diary)
|
||||
GLOBAL_VAR(diaryofmeanpeople)
|
||||
GLOBAL_PROTECT(diaryofmeanpeople)
|
||||
GLOBAL_VAR(href_logfile)
|
||||
GLOBAL_PROTECT(href_logfile)
|
||||
|
||||
GLOBAL_LIST_EMPTY(bombers)
|
||||
GLOBAL_PROTECT(bombers)
|
||||
GLOBAL_LIST_EMPTY(admin_log)
|
||||
GLOBAL_PROTECT(admin_log)
|
||||
GLOBAL_LIST_EMPTY(lastsignalers) //keeps last 100 signals here in format: "[src] used \ref[src] @ location [src.loc]: [freq]/[code]"
|
||||
GLOBAL_PROTECT(lastsignalers)
|
||||
GLOBAL_LIST_EMPTY(lawchanges) //Stores who uploaded laws to which silicon-based lifeform, and what the law was
|
||||
GLOBAL_PROTECT(lawchanges)
|
||||
|
||||
GLOBAL_LIST_EMPTY(combatlog)
|
||||
GLOBAL_PROTECT(combatlog)
|
||||
GLOBAL_LIST_EMPTY(IClog)
|
||||
GLOBAL_PROTECT(IClog)
|
||||
GLOBAL_LIST_EMPTY(OOClog)
|
||||
GLOBAL_PROTECT(OOClog)
|
||||
GLOBAL_LIST_EMPTY(adminlog)
|
||||
GLOBAL_PROTECT(adminlog)
|
||||
|
||||
GLOBAL_VAR(log_directory)
|
||||
GLOBAL_PROTECT(log_directory)
|
||||
GLOBAL_VAR(world_game_log)
|
||||
GLOBAL_PROTECT(world_game_log)
|
||||
GLOBAL_VAR(world_runtime_log)
|
||||
GLOBAL_PROTECT(world_runtime_log)
|
||||
GLOBAL_VAR(world_attack_log)
|
||||
GLOBAL_PROTECT(world_attack_log)
|
||||
GLOBAL_VAR(world_href_log)
|
||||
GLOBAL_PROTECT(world_href_log)
|
||||
GLOBAL_VAR(round_id)
|
||||
GLOBAL_PROTECT(round_id)
|
||||
GLOBAL_VAR(config_error_log)
|
||||
GLOBAL_PROTECT(config_error_log)
|
||||
|
||||
GLOBAL_LIST_EMPTY(bombers)
|
||||
GLOBAL_PROTECT(bombers)
|
||||
GLOBAL_LIST_EMPTY(admin_log)
|
||||
GLOBAL_PROTECT(admin_log)
|
||||
GLOBAL_LIST_EMPTY(lastsignalers) //keeps last 100 signals here in format: "[src] used \ref[src] @ location [src.loc]: [freq]/[code]"
|
||||
GLOBAL_PROTECT(lastsignalers)
|
||||
GLOBAL_LIST_EMPTY(lawchanges) //Stores who uploaded laws to which silicon-based lifeform, and what the law was
|
||||
GLOBAL_PROTECT(lawchanges)
|
||||
|
||||
GLOBAL_LIST_EMPTY(combatlog)
|
||||
GLOBAL_PROTECT(combatlog)
|
||||
GLOBAL_LIST_EMPTY(IClog)
|
||||
GLOBAL_PROTECT(IClog)
|
||||
GLOBAL_LIST_EMPTY(OOClog)
|
||||
GLOBAL_PROTECT(OOClog)
|
||||
GLOBAL_LIST_EMPTY(adminlog)
|
||||
GLOBAL_PROTECT(adminlog)
|
||||
|
||||
GLOBAL_LIST_EMPTY(active_turfs_startlist)
|
||||
+80
-47
@@ -107,64 +107,112 @@
|
||||
|
||||
var/obj/item/W = get_active_held_item()
|
||||
|
||||
|
||||
if(W == A)
|
||||
W.attack_self(src)
|
||||
update_inv_hands()
|
||||
return
|
||||
|
||||
// operate three levels deep here (item in backpack in src; item in box in backpack in src, not any deeper)
|
||||
if(A.ClickAccessible(src, depth=INVENTORY_DEPTH))
|
||||
// No adjacency needed
|
||||
|
||||
//These are always reachable.
|
||||
//User itself, current loc, and user inventory
|
||||
if(DirectAccess(A))
|
||||
if(W)
|
||||
melee_item_attack_chain(src, W, A, params)
|
||||
melee_item_attack_chain(src,W,A,params)
|
||||
else
|
||||
if(ismob(A))
|
||||
changeNext_move(CLICK_CD_MELEE)
|
||||
UnarmedAttack(A)
|
||||
return
|
||||
|
||||
if(!isturf(loc)) // This is going to stop you from telekinesing from inside a closet, but I don't shed many tears for that
|
||||
|
||||
//Can't reach anything else in lockers or other weirdness
|
||||
if(!loc.AllowClick())
|
||||
return
|
||||
|
||||
// Allows you to click on a box's contents, if that box is on the ground, but no deeper than that
|
||||
if(isturf(A) || isturf(A.loc) || (A.loc && isturf(A.loc.loc)))
|
||||
if(Adjacent(A) || (W && CheckReach(src, A, W.reach))) //Adjacent or reaching attacks
|
||||
if(W)
|
||||
melee_item_attack_chain(src, W, A, params)
|
||||
else
|
||||
if(ismob(A))
|
||||
changeNext_move(CLICK_CD_MELEE)
|
||||
UnarmedAttack(A, 1)
|
||||
return
|
||||
else // non-adjacent click
|
||||
if(W)
|
||||
W.afterattack(A,src,0,params) // 0: not Adjacent
|
||||
else
|
||||
RangedAttack(A, params)
|
||||
//Standard reach turf to turf or reaching inside storage
|
||||
if(CanReach(A,W))
|
||||
if(W)
|
||||
melee_item_attack_chain(src,W,A,params)
|
||||
else
|
||||
if(ismob(A))
|
||||
changeNext_move(CLICK_CD_MELEE)
|
||||
UnarmedAttack(A,1)
|
||||
else
|
||||
if(W)
|
||||
W.afterattack(A,src,0,params)
|
||||
else
|
||||
RangedAttack(A,params)
|
||||
|
||||
/atom/movable/proc/CanReach(atom/target,obj/item/tool,view_only = FALSE)
|
||||
if(isturf(target) || isturf(target.loc) || DirectAccess(target)) //Directly accessible atoms
|
||||
if(Adjacent(target) || (tool && CheckToolReach(src, target, tool.reach))) //Adjacent or reaching attacks
|
||||
return TRUE
|
||||
else
|
||||
//Things inside storage insde another storage
|
||||
//Eg Contents of a box in a backpack
|
||||
var/atom/outer_storage = get_atom_on_turf(target)
|
||||
if(outer_storage == target) //whatever that is we don't want infinite loop.
|
||||
return FALSE
|
||||
if(outer_storage && CanReach(outer_storage,tool) && outer_storage.CanReachStorage(target,src,view_only ? STORAGE_VIEW_DEPTH : INVENTORY_DEPTH))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
//Can [target] in this container be reached by [user], can't be more than [depth] levels deep
|
||||
/atom/proc/CanReachStorage(atom/target,user,depth)
|
||||
return FALSE
|
||||
|
||||
/obj/item/weapon/storage/CanReachStorage(atom/target,user,depth)
|
||||
while(target && depth > 0)
|
||||
target = target.loc
|
||||
depth--
|
||||
if(target == src)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/atom/movable/proc/DirectAccess(atom/target)
|
||||
if(target == src)
|
||||
return TRUE
|
||||
if(target == loc)
|
||||
return TRUE
|
||||
|
||||
/mob/DirectAccess(atom/target)
|
||||
if(..())
|
||||
return TRUE
|
||||
if(target in contents) //This could probably use moving down and restricting to inventory only
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/DirectAccess(atom/target)
|
||||
if(..()) //Lightweight checks first
|
||||
return TRUE
|
||||
if(target in GetAllContents())
|
||||
return TRUE
|
||||
|
||||
/atom/proc/AllowClick()
|
||||
return FALSE
|
||||
|
||||
/turf/AllowClick()
|
||||
return TRUE
|
||||
|
||||
/proc/CheckReach(atom/movable/here, atom/movable/there, reach)
|
||||
/proc/CheckToolReach(atom/movable/here, atom/movable/there, reach)
|
||||
if(!here || !there)
|
||||
return
|
||||
switch(reach)
|
||||
if(0)
|
||||
return here.loc == there.loc
|
||||
return FALSE
|
||||
if(1)
|
||||
return here.Adjacent(there)
|
||||
return FALSE //here.Adjacent(there)
|
||||
if(2 to INFINITY)
|
||||
var/obj/dummy = new(get_turf(here)) //We'll try to move this every tick, failing if we can't
|
||||
var/obj/dummy = new(get_turf(here))
|
||||
dummy.pass_flags |= PASSTABLE
|
||||
dummy.invisibility = INVISIBILITY_ABSTRACT
|
||||
for(var/i in 1 to reach) //Limit it to that many tries
|
||||
var/turf/T = get_step(dummy, get_dir(dummy, there))
|
||||
if(dummy.loc == there.loc)
|
||||
if(dummy.CanReach(there))
|
||||
qdel(dummy)
|
||||
return 1
|
||||
if(there.density && dummy in range(1, there)) //For windows and suchlike
|
||||
qdel(dummy)
|
||||
return 1
|
||||
return TRUE
|
||||
if(!dummy.Move(T)) //we're blocked!
|
||||
qdel(dummy)
|
||||
return
|
||||
qdel(dummy)
|
||||
|
||||
// Default behavior: ignore double clicks (the second click that makes the doubleclick call already calls for a normal click)
|
||||
/mob/proc/DblClickOn(atom/A, params)
|
||||
@@ -304,21 +352,6 @@
|
||||
/atom/proc/CtrlShiftClick(mob/user)
|
||||
return
|
||||
|
||||
/*
|
||||
Helper to check can the mob click/access an item.
|
||||
Used by mob inventory and storage items.
|
||||
*/
|
||||
/atom/proc/ClickAccessible(mob/user, depth=1)
|
||||
if(src == user.loc || (src in user.contents))
|
||||
return TRUE
|
||||
|
||||
if(loc && depth > 1)
|
||||
return loc.ClickAccessible(user, depth-1)
|
||||
|
||||
/turf/ClickAccessible(mob/user, depth=1)
|
||||
return
|
||||
|
||||
|
||||
/*
|
||||
Misc helpers
|
||||
|
||||
|
||||
@@ -393,6 +393,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
|
||||
textlist += "<br>"
|
||||
else
|
||||
textlist += "Seconds until Ratvar's arrival: <b>[G.get_arrival_text(TRUE)]</b><br>"
|
||||
break
|
||||
if(unconverted_ais_exist)
|
||||
if(unconverted_ais_exist > 1)
|
||||
textlist += "<b>[unconverted_ais_exist] unconverted AIs exist!</b><br>"
|
||||
|
||||
@@ -43,10 +43,8 @@
|
||||
var/log_attack = 0 // log attack messages
|
||||
var/log_adminchat = 0 // log admin chat messages
|
||||
var/log_pda = 0 // log pda messages
|
||||
var/log_hrefs = 0 // log all links clicked in-game. Could be used for debugging and tracking down exploits
|
||||
var/log_twitter = 0 // log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases.
|
||||
var/log_world_topic = 0 // log all world.Topic() calls
|
||||
var/log_runtimes = FALSE // log runtimes into a file
|
||||
var/sql_enabled = 0 // for sql switching
|
||||
var/allow_admin_ooccolor = 0 // Allows admins with relevant permissions to have their own ooc colour
|
||||
var/allow_vote_restart = 0 // allow votes to restart
|
||||
@@ -129,6 +127,7 @@
|
||||
var/forbid_peaceborg = 0
|
||||
var/panic_bunker = 0 // prevents new people it hasn't seen before from connecting
|
||||
var/notify_new_player_age = 0 // how long do we notify admins of a new player
|
||||
var/notify_new_player_account_age = 0 // how long do we notify admins of a new byond account
|
||||
var/irc_first_connection_alert = 0 // do we notify the irc channel when somebody is connecting for the first time?
|
||||
|
||||
var/traitor_scaling_coeff = 6 //how much does the amount of players get divided by to determine traitors
|
||||
@@ -269,7 +268,7 @@
|
||||
|
||||
if(M.config_tag)
|
||||
if(!(M.config_tag in modes)) // ensure each mode is added only once
|
||||
GLOB.diary << "Adding game mode [M.name] ([M.config_tag]) to configuration."
|
||||
GLOB.config_error_log << "Adding game mode [M.name] ([M.config_tag]) to configuration."
|
||||
modes += M.config_tag
|
||||
mode_names[M.config_tag] = M.name
|
||||
probabilities[M.config_tag] = M.probability
|
||||
@@ -358,8 +357,6 @@
|
||||
log_adminchat = 1
|
||||
if("log_pda")
|
||||
log_pda = 1
|
||||
if("log_hrefs")
|
||||
log_hrefs = 1
|
||||
if("log_twitter")
|
||||
log_twitter = 1
|
||||
if("log_world_topic")
|
||||
@@ -476,6 +473,8 @@
|
||||
panic_bunker = 1
|
||||
if("notify_new_player_age")
|
||||
notify_new_player_age = text2num(value)
|
||||
if("notify_new_player_account_age")
|
||||
notify_new_player_account_age = text2num(value)
|
||||
if("irc_first_connection_alert")
|
||||
irc_first_connection_alert = 1
|
||||
if("check_randomizer")
|
||||
@@ -493,12 +492,6 @@
|
||||
ipintel_save_bad = text2num(value)
|
||||
if("aggressive_changelog")
|
||||
aggressive_changelog = 1
|
||||
if("log_runtimes")
|
||||
log_runtimes = TRUE
|
||||
var/newlog = file("data/logs/runtimes/runtime-[time2text(world.realtime, "YYYY-MM-DD")].log")
|
||||
if(GLOB.runtime_diary != newlog)
|
||||
world.log << "Now logging runtimes to data/logs/runtimes/runtime-[time2text(world.realtime, "YYYY-MM-DD")].log"
|
||||
GLOB.runtime_diary = newlog
|
||||
if("autoconvert_notes")
|
||||
autoconvert_notes = 1
|
||||
if("allow_webclient")
|
||||
@@ -542,7 +535,7 @@
|
||||
if("error_msg_delay")
|
||||
error_msg_delay = text2num(value)
|
||||
else
|
||||
GLOB.diary << "Unknown setting in configuration: '[name]'"
|
||||
GLOB.config_error_log << "Unknown setting in configuration: '[name]'"
|
||||
|
||||
else if(type == "game_options")
|
||||
switch(name)
|
||||
@@ -605,13 +598,13 @@
|
||||
if(mode_name in modes)
|
||||
continuous[mode_name] = 1
|
||||
else
|
||||
GLOB.diary << "Unknown continuous configuration definition: [mode_name]."
|
||||
GLOB.config_error_log << "Unknown continuous configuration definition: [mode_name]."
|
||||
if("midround_antag")
|
||||
var/mode_name = lowertext(value)
|
||||
if(mode_name in modes)
|
||||
midround_antag[mode_name] = 1
|
||||
else
|
||||
GLOB.diary << "Unknown midround antagonist configuration definition: [mode_name]."
|
||||
GLOB.config_error_log << "Unknown midround antagonist configuration definition: [mode_name]."
|
||||
if("midround_antag_time_check")
|
||||
midround_antag_time_check = text2num(value)
|
||||
if("midround_antag_life_check")
|
||||
@@ -627,9 +620,9 @@
|
||||
if(mode_name in modes)
|
||||
min_pop[mode_name] = text2num(mode_value)
|
||||
else
|
||||
GLOB.diary << "Unknown minimum population configuration definition: [mode_name]."
|
||||
GLOB.config_error_log << "Unknown minimum population configuration definition: [mode_name]."
|
||||
else
|
||||
GLOB.diary << "Incorrect minimum population configuration definition: [mode_name] [mode_value]."
|
||||
GLOB.config_error_log << "Incorrect minimum population configuration definition: [mode_name] [mode_value]."
|
||||
if("max_pop")
|
||||
var/pop_pos = findtext(value, " ")
|
||||
var/mode_name = null
|
||||
@@ -641,9 +634,9 @@
|
||||
if(mode_name in modes)
|
||||
max_pop[mode_name] = text2num(mode_value)
|
||||
else
|
||||
GLOB.diary << "Unknown maximum population configuration definition: [mode_name]."
|
||||
GLOB.config_error_log << "Unknown maximum population configuration definition: [mode_name]."
|
||||
else
|
||||
GLOB.diary << "Incorrect maximum population configuration definition: [mode_name] [mode_value]."
|
||||
GLOB.config_error_log << "Incorrect maximum population configuration definition: [mode_name] [mode_value]."
|
||||
if("shuttle_refuel_delay")
|
||||
shuttle_refuel_delay = text2num(value)
|
||||
if("show_game_type_odds")
|
||||
@@ -671,9 +664,9 @@
|
||||
if(prob_name in modes)
|
||||
probabilities[prob_name] = text2num(prob_value)
|
||||
else
|
||||
GLOB.diary << "Unknown game mode probability configuration definition: [prob_name]."
|
||||
GLOB.config_error_log << "Unknown game mode probability configuration definition: [prob_name]."
|
||||
else
|
||||
GLOB.diary << "Incorrect probability configuration definition: [prob_name] [prob_value]."
|
||||
GLOB.config_error_log << "Incorrect probability configuration definition: [prob_name] [prob_value]."
|
||||
|
||||
if("protect_roles_from_antagonist")
|
||||
protect_roles_from_antagonist = 1
|
||||
@@ -720,7 +713,7 @@
|
||||
// Value is in the form "LAWID,NUMBER"
|
||||
var/list/L = splittext(value, ",")
|
||||
if(L.len != 2)
|
||||
GLOB.diary << "Invalid LAW_WEIGHT: " + t
|
||||
GLOB.config_error_log << "Invalid LAW_WEIGHT: " + t
|
||||
continue
|
||||
var/lawid = L[1]
|
||||
var/weight = text2num(L[2])
|
||||
@@ -776,8 +769,8 @@
|
||||
mentors_mobname_only = 1
|
||||
if ("mentor_legacy_system")
|
||||
mentor_legacy_system = 1
|
||||
else
|
||||
GLOB.diary << "Unknown setting in configuration: '[name]'"
|
||||
// else
|
||||
// GLOB.config_error_log << "Adding game mode [M.name] ([M.config_tag]) to configuration."
|
||||
|
||||
fps = round(fps)
|
||||
if(fps <= 0)
|
||||
@@ -831,7 +824,7 @@
|
||||
maplist[currentmap.map_name] = currentmap
|
||||
currentmap = null
|
||||
else
|
||||
GLOB.diary << "Unknown command in map vote config: '[command]'"
|
||||
GLOB.config_error_log << "Unknown command in map vote config: '[command]'"
|
||||
|
||||
|
||||
/datum/configuration/proc/loadsql(filename)
|
||||
@@ -875,7 +868,7 @@
|
||||
if("feedback_tableprefix")
|
||||
global.sqlfdbktableprefix = value
|
||||
else
|
||||
GLOB.diary << "Unknown setting in configuration: '[name]'"
|
||||
GLOB.config_error_log << "Unknown setting in configuration: '[name]'"
|
||||
|
||||
/datum/configuration/proc/pick_mode(mode_name)
|
||||
// I wish I didn't have to instance the game modes in order to look up
|
||||
|
||||
@@ -52,6 +52,12 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars)
|
||||
/datum/controller/global_vars/Initialize()
|
||||
gvars_datum_init_order = list()
|
||||
gvars_datum_protected_varlist = list("gvars_datum_protected_varlist")
|
||||
|
||||
//See https://github.com/tgstation/tgstation/issues/26954
|
||||
for(var/I in typesof(/datum/controller/global_vars/proc))
|
||||
var/CLEANBOT_RETURNS = "[I]"
|
||||
pass(CLEANBOT_RETURNS)
|
||||
|
||||
for(var/I in vars - gvars_datum_in_built_vars)
|
||||
var/start_tick = world.time
|
||||
call(src, "InitGlobal[I]")()
|
||||
|
||||
@@ -280,7 +280,7 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
// because sleeps are processed in the order received, so longer sleeps are more likely to run first
|
||||
if (world.tick_usage > TICK_LIMIT_MC)
|
||||
sleep_delta += 2
|
||||
GLOB.CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING - (TICK_LIMIT_RUNNING * 0.5)
|
||||
GLOB.CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING * 0.5
|
||||
sleep(world.tick_lag * (processing + sleep_delta))
|
||||
continue
|
||||
|
||||
@@ -421,26 +421,31 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
else
|
||||
tick_precentage = tick_remaining
|
||||
|
||||
GLOB.CURRENT_TICKLIMIT = world.tick_usage + tick_precentage
|
||||
tick_precentage = max(tick_precentage*0.5, tick_precentage-queue_node.tick_overrun)
|
||||
|
||||
GLOB.CURRENT_TICKLIMIT = round(world.tick_usage + tick_precentage)
|
||||
|
||||
if (!(queue_node_flags & SS_TICKER))
|
||||
ran_non_ticker = TRUE
|
||||
ran = TRUE
|
||||
tick_usage = world.tick_usage
|
||||
|
||||
queue_node_paused = (queue_node.state == SS_PAUSED || queue_node.state == SS_PAUSING)
|
||||
last_type_processed = queue_node
|
||||
|
||||
queue_node.state = SS_RUNNING
|
||||
|
||||
tick_usage = world.tick_usage
|
||||
var/state = queue_node.ignite(queue_node_paused)
|
||||
tick_usage = world.tick_usage - tick_usage
|
||||
|
||||
if (state == SS_RUNNING)
|
||||
state = SS_IDLE
|
||||
current_tick_budget -= queue_node_priority
|
||||
tick_usage = world.tick_usage - tick_usage
|
||||
|
||||
|
||||
if (tick_usage < 0)
|
||||
tick_usage = 0
|
||||
|
||||
queue_node.tick_overrun = max(0, MC_AVG_FAST_UP_SLOW_DOWN(queue_node.tick_overrun, tick_usage-tick_precentage))
|
||||
queue_node.state = state
|
||||
|
||||
if (state == SS_PAUSED)
|
||||
@@ -467,13 +472,13 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
queue_node.times_fired++
|
||||
|
||||
if (queue_node_flags & SS_TICKER)
|
||||
queue_node.next_fire = world.time + (world.tick_lag * queue_node.wait)
|
||||
queue_node.next_fire = world.time + (world.tick_lag * (queue_node.wait + (queue_node.tick_overrun/100)))
|
||||
else if (queue_node_flags & SS_POST_FIRE_TIMING)
|
||||
queue_node.next_fire = world.time + queue_node.wait
|
||||
queue_node.next_fire = world.time + queue_node.wait + (world.tick_lag * (queue_node.tick_overrun/100))
|
||||
else if (queue_node_flags & SS_KEEP_TIMING)
|
||||
queue_node.next_fire += queue_node.wait
|
||||
else
|
||||
queue_node.next_fire = queue_node.queued_time + queue_node.wait
|
||||
queue_node.next_fire = queue_node.queued_time + queue_node.wait + (world.tick_lag * (queue_node.tick_overrun/100))
|
||||
|
||||
queue_node.queued_time = 0
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
var/next_fire = 0 //scheduled world.time for next fire()
|
||||
var/cost = 0 //average time to execute
|
||||
var/tick_usage = 0 //average tick usage
|
||||
var/tick_overrun = 0 //average tick overrun
|
||||
var/state = SS_IDLE //tracks the current state of the ss, running, paused, etc.
|
||||
var/paused_ticks = 0 //ticks this ss is taking to run right now.
|
||||
var/paused_tick_usage //total tick_usage of all of our runs while pausing this run
|
||||
@@ -168,7 +169,7 @@
|
||||
|
||||
|
||||
if(can_fire && !(SS_NO_FIRE in flags))
|
||||
msg = "[round(cost,1)]ms|[round(tick_usage,1)]%|[round(ticks,0.1)]\t[msg]"
|
||||
msg = "[round(cost,1)]ms|[round(tick_usage,1)]%([round(tick_overrun,1)]%)|[round(ticks,0.1)]\t[msg]"
|
||||
else
|
||||
msg = "OFFLINE\t[msg]"
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ SUBSYSTEM_DEF(blackbox)
|
||||
msg_cargo = SSblackbox.msg_cargo
|
||||
msg_other = SSblackbox.msg_other
|
||||
|
||||
|
||||
feedback = SSblackbox.feedback
|
||||
|
||||
//no touchie
|
||||
@@ -84,25 +85,13 @@ SUBSYSTEM_DEF(blackbox)
|
||||
if (!SSdbcore.Connect())
|
||||
return
|
||||
|
||||
var/round_id
|
||||
|
||||
var/datum/DBQuery/query_feedback_max_id = SSdbcore.NewQuery("SELECT MAX(round_id) AS round_id FROM [format_table_name("feedback")]")
|
||||
if(!query_feedback_max_id.Execute())
|
||||
return
|
||||
while (query_feedback_max_id.NextRow())
|
||||
round_id = query_feedback_max_id.item[1]
|
||||
|
||||
if (!isnum(round_id))
|
||||
round_id = text2num(round_id)
|
||||
round_id++
|
||||
|
||||
var/sqlrowlist = ""
|
||||
|
||||
for (var/datum/feedback_variable/FV in feedback)
|
||||
if (sqlrowlist != "")
|
||||
sqlrowlist += ", " //a comma (,) at the start of the first row to insert will trigger a SQL error
|
||||
|
||||
sqlrowlist += "(null, Now(), [round_id], \"[sanitizeSQL(FV.get_variable())]\", [FV.get_value()], \"[sanitizeSQL(FV.get_details())]\")"
|
||||
sqlrowlist += "(null, Now(), [GLOB.round_id], \"[sanitizeSQL(FV.get_variable())]\", [FV.get_value()], \"[sanitizeSQL(FV.get_details())]\")"
|
||||
|
||||
if (sqlrowlist == "")
|
||||
return
|
||||
|
||||
@@ -287,6 +287,8 @@ SUBSYSTEM_DEF(job)
|
||||
if(PopcapReached())
|
||||
RejectPlayer(player)
|
||||
|
||||
var/datum/job/validjob
|
||||
|
||||
// Loop through all jobs
|
||||
for(var/datum/job/job in shuffledoccupations) // SHUFFLE ME BABY
|
||||
if(!job)
|
||||
@@ -308,16 +310,24 @@ SUBSYSTEM_DEF(job)
|
||||
Debug("DO non-human failed, Player: [player], Job:[job.title]")
|
||||
continue
|
||||
|
||||
|
||||
// If the player wants that job on this level, then try give it to him.
|
||||
if(player.client.prefs.GetJobDepartment(job, level) & job.flag)
|
||||
|
||||
// If the job isn't filled
|
||||
if((job.current_positions < job.spawn_positions) || job.spawn_positions == -1)
|
||||
Debug("DO pass, Player: [player], Level:[level], Job:[job.title]")
|
||||
AssignRole(player, job.title)
|
||||
unassigned -= player
|
||||
break
|
||||
|
||||
validjob = job
|
||||
|
||||
//Is the Job empty? Stop Looking Then!
|
||||
if (!job.current_positions)
|
||||
break
|
||||
|
||||
//Assign us the last job we found
|
||||
if (validjob)
|
||||
Debug("DO pass, Player: [player], Level:[level], Job:[validjob.title]")
|
||||
AssignRole(player, validjob.title)
|
||||
unassigned -= player
|
||||
break
|
||||
|
||||
// Hand out random jobs to the people who didn't get any in the last check
|
||||
// Also makes sure that they got their preference correct
|
||||
|
||||
@@ -36,18 +36,10 @@ SUBSYSTEM_DEF(lighting)
|
||||
for (i in 1 to GLOB.lighting_update_lights.len)
|
||||
var/datum/light_source/L = GLOB.lighting_update_lights[i]
|
||||
|
||||
if (L.check() || QDELETED(L) || L.force_update)
|
||||
L.remove_lum()
|
||||
if (!QDELETED(L))
|
||||
L.apply_lum()
|
||||
L.update_corners()
|
||||
|
||||
else if (L.vis_update) //We smartly update only tiles that became (in) visible to use.
|
||||
L.smart_vis_update()
|
||||
L.needs_update = LIGHTING_NO_UPDATE
|
||||
|
||||
L.vis_update = FALSE
|
||||
L.force_update = FALSE
|
||||
L.needs_update = FALSE
|
||||
|
||||
if(init_tick_checks)
|
||||
CHECK_TICK
|
||||
else if (MC_TICK_CHECK)
|
||||
|
||||
@@ -150,7 +150,7 @@ SUBSYSTEM_DEF(pai)
|
||||
if(!(ROLE_PAI in G.client.prefs.be_special))
|
||||
continue
|
||||
//G << 'sound/misc/server-ready.ogg' //Alerting them to their consideration
|
||||
to_chat(G, "<span class='ghostalert'>Someone is requesting a pAI personality! Use the pAI button to submit yourself as one.</span>")
|
||||
to_chat(G, "<span class='ghostalert'>[user] is requesting a pAI personality! Use the pAI button to submit yourself as one.</span>")
|
||||
addtimer(CALLBACK(src, .proc/spam_again), spam_delay)
|
||||
var/list/available = list()
|
||||
for(var/datum/paiCandidate/c in SSpai.candidates)
|
||||
|
||||
@@ -9,7 +9,6 @@ SUBSYSTEM_DEF(persistence)
|
||||
|
||||
var/list/obj/structure/chisel_message/chisel_messages = list()
|
||||
var/list/saved_messages = list()
|
||||
var/savefile/chisel_messages_sav
|
||||
|
||||
var/savefile/trophy_sav
|
||||
var/list/saved_trophies = list()
|
||||
@@ -75,14 +74,14 @@ SUBSYSTEM_DEF(persistence)
|
||||
break //Who's been duping the bird?!
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/LoadChiselMessages()
|
||||
chisel_messages_sav = new /savefile("data/npc_saves/ChiselMessages.sav")
|
||||
var/savefile/chisel_messages_sav = new /savefile("data/npc_saves/ChiselMessages.sav")
|
||||
var/saved_json
|
||||
chisel_messages_sav[SSmapping.config.map_name] >> saved_json
|
||||
|
||||
if(!saved_json)
|
||||
return
|
||||
|
||||
var/saved_messages = json_decode(saved_json)
|
||||
var/list/saved_messages = json_decode(saved_json)
|
||||
|
||||
for(var/item in saved_messages)
|
||||
if(!islist(item))
|
||||
@@ -104,10 +103,10 @@ SUBSYSTEM_DEF(persistence)
|
||||
|
||||
var/obj/structure/chisel_message/M = new(T)
|
||||
|
||||
M.unpack(item)
|
||||
if(!M.loc)
|
||||
M.persists = FALSE
|
||||
qdel(M)
|
||||
if(!QDELETED(M))
|
||||
M.unpack(item)
|
||||
|
||||
log_world("Loaded [saved_messages.len] engraved messages on map [SSmapping.config.map_name]")
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/LoadTrophies()
|
||||
trophy_sav = new /savefile("data/npc_saves/TrophyItems.sav")
|
||||
@@ -175,9 +174,13 @@ SUBSYSTEM_DEF(persistence)
|
||||
secret_satchels[SSmapping.config.map_name] << old_secret_satchels
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/CollectChiselMessages()
|
||||
var/savefile/chisel_messages_sav = new /savefile("data/npc_saves/ChiselMessages.sav")
|
||||
|
||||
for(var/obj/structure/chisel_message/M in chisel_messages)
|
||||
saved_messages += list(M.pack())
|
||||
|
||||
log_world("Saved [saved_messages.len] engraved messages on map [SSmapping.config.map_name]")
|
||||
|
||||
chisel_messages_sav[SSmapping.config.map_name] << json_encode(saved_messages)
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/SaveChiselMessage(obj/structure/chisel_message/M)
|
||||
@@ -193,4 +196,4 @@ SUBSYSTEM_DEF(persistence)
|
||||
data["path"] = T.showpiece.type
|
||||
data["message"] = T.trophy_message
|
||||
data["placer_key"] = T.placer_key
|
||||
saved_trophies += list(data)
|
||||
saved_trophies += list(data)
|
||||
|
||||
@@ -75,10 +75,12 @@
|
||||
|
||||
if(GLOB.revdata.parentcommit)
|
||||
to_chat(src, "<b>Server revision compiled on:</b> [GLOB.revdata.date]")
|
||||
var/prefix = ""
|
||||
if(GLOB.revdata.testmerge.len)
|
||||
to_chat(src, GLOB.revdata.GetTestMergeInfo())
|
||||
to_chat(src, "Based off master commit:")
|
||||
to_chat(src, "<a href='[config.githuburl]/commit/[GLOB.revdata.parentcommit]'>[GLOB.revdata.parentcommit]</a>")
|
||||
prefix = "Based off master commit: "
|
||||
var/pc = GLOB.revdata.parentcommit
|
||||
to_chat(src, "[prefix]<a href='[config.githuburl]/commit/[pc]'>[copytext(pc, 1, min(length(pc), 7))]</a>")
|
||||
else
|
||||
to_chat(src, "Revision unknown")
|
||||
to_chat(src, "<b>Current Infomational Settings:</b>")
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
if(!dialed_holopads.len)
|
||||
calling_pad.say("Connection failure.")
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
testing("Holocall started")
|
||||
|
||||
@@ -104,19 +105,18 @@
|
||||
if(connected_holopad)
|
||||
CRASH("Multi-connection holocall")
|
||||
|
||||
connected_holopad = H
|
||||
for(var/I in dialed_holopads)
|
||||
if(I == H)
|
||||
continue
|
||||
var/obj/machinery/holopad/Holo = I
|
||||
LAZYREMOVE(Holo.holo_calls, src)
|
||||
dialed_holopads -= Holo
|
||||
Disconnect(I)
|
||||
|
||||
for(var/I in H.holo_calls)
|
||||
var/datum/holocall/HC = I
|
||||
if(HC != src)
|
||||
HC.Disconnect(H)
|
||||
|
||||
connected_holopad = H
|
||||
|
||||
if(!Check())
|
||||
return
|
||||
|
||||
|
||||
+1
-1
@@ -272,7 +272,7 @@
|
||||
creator.faction |= current.faction
|
||||
|
||||
if(creator.mind.special_role)
|
||||
message_admins("[key_name_admin(current)](<A HREF='?_src_=holder;adminmoreinfo=\ref[current]'>?</A>) has been created by [key_name_admin(creator)](<A HREF='?_src_=holder;adminmoreinfo=\ref[creator]'>?</A>), an antagonist.")
|
||||
message_admins("[ADMIN_LOOKUPFLW(current)] has been created by [ADMIN_LOOKUPFLW(creator)], an antagonist.")
|
||||
to_chat(current, "<span class='userdanger'>Despite your creators current allegiances, your true master remains [creator.real_name]. If their loyalities change, so do yours. This will never change unless your creator's body is destroyed.</span>")
|
||||
|
||||
/datum/mind/proc/show_memory(mob/recipient, window=1)
|
||||
|
||||
@@ -76,3 +76,89 @@
|
||||
/datum/status_effect/belligerent/on_remove()
|
||||
if(owner.m_intent == MOVE_INTENT_WALK)
|
||||
owner.toggle_move_intent()
|
||||
|
||||
|
||||
/datum/status_effect/maniamotor
|
||||
id = "maniamotor"
|
||||
duration = -1
|
||||
tick_interval = 10
|
||||
status_type = STATUS_EFFECT_MULTIPLE
|
||||
alert_type = null
|
||||
var/obj/structure/destructible/clockwork/powered/mania_motor/motor
|
||||
var/severity = 0 //goes up to a maximum of MAX_MANIA_SEVERITY
|
||||
var/warned_turnoff = FALSE //if we've warned that the motor is off
|
||||
var/warned_outofsight = FALSE //if we've warned that the target is out of sight of the motor
|
||||
var/static/list/mania_messages = list("Go nuts.", "Take a crack at crazy.", "Make a bid for insanity.", "Get kooky.", "Move towards mania.", "Become bewildered.", "Wax wild.", \
|
||||
"Go round the bend.", "Land in lunacy.", "Try dementia.", "Strive to get a screw loose.", "Advance forward.", "Approach the transmitter.", "Touch the antennae.", \
|
||||
"Move towards the mania motor.", "Come closer.", "Get over here already!", "Keep your eyes on the motor.")
|
||||
var/static/list/flee_messages = list("Oh, NOW you flee.", "Get back here!", "If you were smarter, you'd come back.", "Only fools run.", "You'll be back.")
|
||||
var/static/list/turnoff_messages = list("Why would they turn it-", "What are these idi-", "Fools, fools, all of-", "Are they trying to c-", "All this effort just f-")
|
||||
var/static/list/powerloss_messages = list("\"Oh, the id**ts di***t s***e en**** pow**...\"", "\"D*dn't **ey mak* an **te***c*i*n le**?\"", "\"The** f**ls for**t t* make a ***** *f-\"", \
|
||||
"\"No, *O, you **re so cl***-\"", "You hear a yell of frustration, cut off by static.")
|
||||
|
||||
/datum/status_effect/maniamotor/Destroy()
|
||||
motor = null
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/maniamotor/tick()
|
||||
var/is_servant = is_servant_of_ratvar(owner)
|
||||
var/span_part = severity > 50 ? "" : "_small" //let's save like one check
|
||||
if(QDELETED(motor))
|
||||
if(!is_servant)
|
||||
to_chat(owner, "<span class='sevtug[span_part]'>You feel a frustrated voice quietly fade from your mind...</span>")
|
||||
qdel(src)
|
||||
return
|
||||
if(!motor.active) //it being off makes it fall off much faster
|
||||
if(!is_servant && !warned_turnoff)
|
||||
if(motor.total_accessable_power() > motor.mania_cost)
|
||||
to_chat(owner, "<span class='sevtug[span_part]'>\"[text2ratvar(pick(turnoff_messages))]\"</span>")
|
||||
else
|
||||
to_chat(owner, "<span class='sevtug[span_part]'>[text2ratvar(pick(powerloss_messages))]</span>")
|
||||
warned_turnoff = TRUE
|
||||
severity = max(severity - 2, 0)
|
||||
if(!severity)
|
||||
qdel(src)
|
||||
return
|
||||
else
|
||||
if(prob(severity * 2))
|
||||
warned_turnoff = FALSE
|
||||
if(!(owner in viewers(7, motor))) //not being in range makes it fall off slightly faster
|
||||
if(!is_servant && !warned_outofsight)
|
||||
to_chat(owner, "<span class='sevtug[span_part]'>\"[text2ratvar(pick(flee_messages))]\"</span>")
|
||||
warned_outofsight = TRUE
|
||||
severity = max(severity - 1, 0)
|
||||
if(!severity)
|
||||
qdel(src)
|
||||
return
|
||||
else if(prob(severity * 2))
|
||||
warned_outofsight = FALSE
|
||||
if(is_servant) //heals servants of braindamage, hallucination, druggy, dizziness, and confusion
|
||||
if(owner.hallucination)
|
||||
owner.hallucination = 0
|
||||
if(owner.druggy)
|
||||
owner.adjust_drugginess(-owner.druggy)
|
||||
if(owner.dizziness)
|
||||
owner.dizziness = 0
|
||||
if(owner.confused)
|
||||
owner.confused = 0
|
||||
severity = 0
|
||||
else if(!owner.null_rod_check() && owner.stat != DEAD && severity)
|
||||
var/static/hum = get_sfx('sound/effects/screech.ogg') //same sound for every proc call
|
||||
if(owner.getToxLoss() > MANIA_DAMAGE_TO_CONVERT)
|
||||
if(is_eligible_servant(owner))
|
||||
to_chat(owner, "<span class='sevtug[span_part]'>\"[text2ratvar("You are mine and his, now.")]\"</span>")
|
||||
add_servant_of_ratvar(owner)
|
||||
owner.Paralyse(5)
|
||||
else
|
||||
if(prob(severity * 0.15))
|
||||
to_chat(owner, "<span class='sevtug[span_part]'>\"[text2ratvar(pick(mania_messages))]\"</span>")
|
||||
owner.playsound_local(get_turf(motor), hum, severity, 1)
|
||||
owner.adjust_drugginess(Clamp(max(severity * 0.075, 1), 0, max(0, 50 - owner.druggy))) //7.5% of severity per second, minimum 1
|
||||
if(owner.hallucination < 50)
|
||||
owner.hallucination = min(owner.hallucination + max(severity * 0.075, 1), 50) //7.5% of severity per second, minimum 1
|
||||
if(owner.dizziness < 50)
|
||||
owner.dizziness = min(owner.dizziness + round(severity * 0.05, 1), 50) //5% of severity per second above 10 severity
|
||||
if(owner.confused < 25)
|
||||
owner.confused = min(owner.confused + round(severity * 0.025, 1), 25) //2.5% of severity per second above 20 severity
|
||||
owner.adjustToxLoss(severity * 0.02, TRUE, TRUE) //2% of severity per second
|
||||
severity--
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
diff a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm (rejected hunks)
|
||||
@@ -108,20 +108,6 @@
|
||||
to_chat(owner, "<span class='sevtug[span_part]'>You feel a frustrated voice quietly fade from your mind...</span>")
|
||||
qdel(src)
|
||||
return
|
||||
- if(!(owner in viewers(7, motor))) //not being in range makes it fall off much faster
|
||||
- if(!is_servant && !warned_outofsight)
|
||||
- to_chat(owner, "<span class='sevtug[span_part]'>\"[text2ratvar(pick(flee_messages))]\"</span>")
|
||||
- warned_outofsight = TRUE
|
||||
- if(severity)
|
||||
- severity--
|
||||
- if(!severity)
|
||||
- qdel(src)
|
||||
- return
|
||||
- else
|
||||
- qdel(src)
|
||||
- return
|
||||
- else if(prob(severity * 2))
|
||||
- warned_outofsight = FALSE
|
||||
if(!motor.active) //it being off makes it fall off much faster
|
||||
if(!is_servant && !warned_turnoff)
|
||||
if(motor.total_accessable_power() > motor.mania_cost)
|
||||
@@ -129,20 +115,24 @@
|
||||
else
|
||||
to_chat(owner, "<span class='sevtug[span_part]'>[text2ratvar(pick(powerloss_messages))]</span>")
|
||||
warned_turnoff = TRUE
|
||||
- if(severity)
|
||||
- severity--
|
||||
+ severity = max(severity - 2, 0)
|
||||
+ if(!severity)
|
||||
+ qdel(src)
|
||||
+ return
|
||||
+ else
|
||||
+ if(prob(severity * 2))
|
||||
+ warned_turnoff = FALSE
|
||||
+ if(!(owner in viewers(7, motor))) //not being in range makes it fall off slightly faster
|
||||
+ if(!is_servant && !warned_outofsight)
|
||||
+ to_chat(owner, "<span class='sevtug[span_part]'>\"[text2ratvar(pick(flee_messages))]\"</span>")
|
||||
+ warned_outofsight = TRUE
|
||||
+ severity = max(severity - 1, 0)
|
||||
if(!severity)
|
||||
qdel(src)
|
||||
return
|
||||
- else
|
||||
- qdel(src)
|
||||
- return
|
||||
- else if(prob(severity * 2))
|
||||
- warned_turnoff = FALSE
|
||||
+ else if(prob(severity * 2))
|
||||
+ warned_outofsight = FALSE
|
||||
if(is_servant) //heals servants of braindamage, hallucination, druggy, dizziness, and confusion
|
||||
- var/brainloss = owner.getBrainLoss()
|
||||
- if(brainloss)
|
||||
- owner.adjustBrainLoss(-brainloss)
|
||||
if(owner.hallucination)
|
||||
owner.hallucination = 0
|
||||
if(owner.druggy)
|
||||
@@ -163,14 +153,12 @@
|
||||
if(prob(severity * 0.15))
|
||||
to_chat(owner, "<span class='sevtug[span_part]'>\"[text2ratvar(pick(mania_messages))]\"</span>")
|
||||
owner.playsound_local(get_turf(motor), hum, severity, 1)
|
||||
- if(owner.getBrainLoss() <= 50)
|
||||
- owner.adjustBrainLoss(severity * 0.025) //2.5% of severity per second
|
||||
owner.adjust_drugginess(Clamp(max(severity * 0.075, 1), 0, max(0, 50 - owner.druggy))) //7.5% of severity per second, minimum 1
|
||||
if(owner.hallucination < 50)
|
||||
owner.hallucination = min(owner.hallucination + max(severity * 0.075, 1), 50) //7.5% of severity per second, minimum 1
|
||||
- if(owner.dizziness < 25)
|
||||
- owner.dizziness = min(owner.dizziness + Floor(severity * 0.025), 25) //2.5% of severity per second above 20 severity
|
||||
+ if(owner.dizziness < 50)
|
||||
+ owner.dizziness = min(owner.dizziness + round(severity * 0.05, 1), 50) //5% of severity per second above 10 severity
|
||||
if(owner.confused < 25)
|
||||
- owner.confused = min(owner.confused + Floor(severity * 0.025), 25) //2.5% of severity per second above 20 severity
|
||||
+ owner.confused = min(owner.confused + round(severity * 0.025, 1), 25) //2.5% of severity per second above 20 severity
|
||||
owner.adjustToxLoss(severity * 0.02, TRUE, TRUE) //2% of severity per second
|
||||
severity--
|
||||
@@ -106,3 +106,11 @@
|
||||
for(var/datum/status_effect/S in status_effects)
|
||||
if(initial(S1.id) == S.id)
|
||||
return S
|
||||
|
||||
/mob/living/proc/has_status_effect_list(effect) //returns a list of effects with matching IDs that the mod owns; use for effects there can be multiple of
|
||||
. = list()
|
||||
if(status_effects)
|
||||
var/datum/status_effect/S1 = effect
|
||||
for(var/datum/status_effect/S in status_effects)
|
||||
if(initial(S1.id) == S.id)
|
||||
. += S
|
||||
|
||||
@@ -274,6 +274,7 @@
|
||||
return
|
||||
|
||||
/atom/proc/ex_act(severity, target)
|
||||
set waitfor = FALSE
|
||||
contents_explosion(severity, target)
|
||||
|
||||
/atom/proc/blob_act(obj/structure/blob/B)
|
||||
|
||||
@@ -22,6 +22,12 @@
|
||||
else
|
||||
for(var/i in GLOB.clockwork_component_cache)
|
||||
.[i] = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*GLOB.clockwork_component_cache[i], 1)
|
||||
for(var/obj/structure/destructible/clockwork/massive/celestial_gateway/G in GLOB.all_clockwork_objects)
|
||||
if(G.still_needs_components())
|
||||
for(var/i in G.required_components)
|
||||
if(!G.required_components[i])
|
||||
. -= i
|
||||
break
|
||||
. = pickweight(.)
|
||||
|
||||
//returns a component name from a component id
|
||||
@@ -37,6 +43,8 @@
|
||||
return "Replicant Alloy"
|
||||
if(HIEROPHANT_ANSIBLE)
|
||||
return "Hierophant Ansible"
|
||||
else
|
||||
return null
|
||||
|
||||
//returns a component acronym from a component id
|
||||
/proc/get_component_acronym(id)
|
||||
@@ -51,6 +59,8 @@
|
||||
return "RA"
|
||||
if(HIEROPHANT_ANSIBLE)
|
||||
return "HA"
|
||||
else
|
||||
return null
|
||||
|
||||
//returns a component id from a component name
|
||||
/proc/get_component_id(name)
|
||||
@@ -65,6 +75,8 @@
|
||||
return REPLICANT_ALLOY
|
||||
if("Hierophant Ansible")
|
||||
return HIEROPHANT_ANSIBLE
|
||||
else
|
||||
return null
|
||||
|
||||
//returns a component spanclass from a component id
|
||||
/proc/get_component_span(id)
|
||||
@@ -121,6 +133,8 @@
|
||||
return /obj/effect/overlay/temp/ratvar/component/alloy
|
||||
if(HIEROPHANT_ANSIBLE)
|
||||
return /obj/effect/overlay/temp/ratvar/component/ansible
|
||||
else
|
||||
return null
|
||||
|
||||
//returns a type for a component from a component id
|
||||
/proc/get_component_type(id)
|
||||
@@ -134,4 +148,6 @@
|
||||
if(REPLICANT_ALLOY)
|
||||
return /obj/item/clockwork/component/replicant_alloy
|
||||
if(HIEROPHANT_ANSIBLE)
|
||||
return /obj/item/clockwork/component/hierophant_ansible
|
||||
return /obj/item/clockwork/component/hierophant_ansible
|
||||
else
|
||||
return null
|
||||
@@ -218,22 +218,22 @@
|
||||
/datum/clockwork_scripture/create_object/mania_motor
|
||||
descname = "Powered Structure, Area Denial"
|
||||
name = "Mania Motor"
|
||||
desc = "Creates a mania motor which will cause brain damage and hallucinations in nearby non-Servant humans. It will also try to convert humans directly adjecent to the motor."
|
||||
desc = "Creates a mania motor which causes minor damage and a variety of negative mental effects in nearby non-Servant humans, potentially up to and including conversion."
|
||||
invocations = list("May this transmitter...", "...break the will of all who oppose us!")
|
||||
channel_time = 80
|
||||
consumed_components = list(GEIS_CAPACITOR = 5, REPLICANT_ALLOY = 2, HIEROPHANT_ANSIBLE = 2)
|
||||
object_path = /obj/structure/destructible/clockwork/powered/mania_motor
|
||||
creator_message = "<span class='brass'>You form a mania motor which will cause brain damage and hallucinations in nearby humans while active.</span>"
|
||||
creator_message = "<span class='brass'>You form a mania motor, which causes minor damage and negative mental effects in non-Servants.</span>"
|
||||
observer_message = "<span class='warning'>A two-pronged machine rises from the ground!</span>"
|
||||
invokers_required = 2
|
||||
multiple_invokers_used = TRUE
|
||||
usage_tip = "Eligible non-Servant humans next to the motor will be converted at an additional power cost. It will also cure hallucinations and brain damage in nearby Servants."
|
||||
usage_tip = "It will also cure hallucinations and brain damage in nearby Servants."
|
||||
tier = SCRIPTURE_APPLICATION
|
||||
one_per_tile = TRUE
|
||||
primary_component = GEIS_CAPACITOR
|
||||
sort_priority = 8
|
||||
quickbind = TRUE
|
||||
quickbind_desc = "Creates a Mania Motor, which can convert adjacent non-Servants with power."
|
||||
quickbind_desc = "Creates a Mania Motor, which causes minor damage and negative mental effects in non-Servants."
|
||||
|
||||
|
||||
//Tinkerer's Daemon: Creates an efficient machine that rapidly produces components at a power cost.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
//Mania Motor: A pair of antenna that, while active, cause braindamage and hallucinations in nearby human mobs.
|
||||
//Mania Motor: A pair of antenna that, while active, cause a variety of negative mental effects in nearby human mobs.
|
||||
/obj/structure/destructible/clockwork/powered/mania_motor
|
||||
name = "mania motor"
|
||||
desc = "A pair of antenna with what appear to be sockets around the base. It reminds you of an antlion."
|
||||
clockwork_desc = "A transmitter that allows Sevtug to whisper into the minds of nearby non-servants, causing hallucinations and brain damage as long as it remains powered."
|
||||
clockwork_desc = "A transmitter that allows Sevtug to whisper into the minds of nearby non-servants, causing a variety of negative mental effects, up to and including conversion."
|
||||
icon_state = "mania_motor_inactive"
|
||||
active_icon = "mania_motor"
|
||||
inactive_icon = "mania_motor_inactive"
|
||||
@@ -16,22 +16,11 @@
|
||||
/obj/item/clockwork/alloy_shards/small = 2, \
|
||||
/obj/item/clockwork/component/geis_capacitor/antennae = 1)
|
||||
var/mania_cost = 150
|
||||
var/convert_cost = 150
|
||||
var/static/list/mania_messages = list("Go nuts.", "Take a crack at crazy.", "Make a bid for insanity.", "Get kooky.", "Move towards mania.", "Become bewildered.", "Wax wild.", \
|
||||
"Go round the bend.", "Land in lunacy.", "Try dementia.", "Strive to get a screw loose.")
|
||||
var/static/list/compel_messages = list("Come closer.", "Approach the transmitter.", "Touch the antennae.", "I always have to deal with idiots. Move towards the mania motor.", \
|
||||
"Advance forward and place your head between the antennae - that's all it's good for.", "If you were smarter, you'd be over here already.", "Move FORWARD, you fool.")
|
||||
var/static/list/convert_messages = list("You won't do. Go to sleep while I tell these nitwits how to convert you.", "You are insufficient. I must instruct these idiots in the art of conversion.", \
|
||||
"Oh of course, someone we can't convert. These servants are fools.", "How hard is it to use a Sigil, anyway? All it takes is dragging someone onto it.", \
|
||||
"How do they fail to use a Sigil of Accession, anyway?", "Why is it that all servants are this inept?", "It's quite likely you'll be stuck here for a while.")
|
||||
var/static/list/close_messages = list("Well, you can't reach the motor from THERE, you moron.", "Interesting location. I'd prefer if you went somewhere you could ACTUALLY TOUCH THE ANTENNAE!", \
|
||||
"Amazing. You somehow managed to wedge yourself somewhere you can't actually reach the motor from.", "Such a show of idiocy is unparalleled. Perhaps I should put you on display?", \
|
||||
"Did you do this on purpose? I can't imagine you doing so accidentally. Oh, wait, I can.", "How is it that such smart creatures can still do something AS STUPID AS THIS!")
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mania_motor/examine(mob/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
to_chat(user, "<span class='sevtug_small'>It requires <b>[mania_cost]W</b> to run, and at least <b>[convert_cost]W</b> to attempt to convert humans adjacent to it.</span>")
|
||||
to_chat(user, "<span class='sevtug_small'>It requires <b>[mania_cost]W</b> to run.</span>")
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mania_motor/forced_disable(bad_effects)
|
||||
if(active)
|
||||
@@ -60,82 +49,17 @@
|
||||
if(!try_use_power(mania_cost))
|
||||
forced_disable(FALSE)
|
||||
return
|
||||
var/turf/T = get_turf(src)
|
||||
var/hum = get_sfx('sound/effects/screech.ogg') //like playsound, same sound for everyone affected
|
||||
var/efficiency = get_efficiency_mod()
|
||||
for(var/mob/living/carbon/human/H in viewers(7, src))
|
||||
if(is_servant_of_ratvar(H)) //heals servants of braindamage, hallucination, druggy, dizziness, and confusion
|
||||
var/brainloss = H.getBrainLoss()
|
||||
if(brainloss)
|
||||
H.adjustBrainLoss(-brainloss)
|
||||
if(H.hallucination)
|
||||
H.hallucination = 0
|
||||
if(H.druggy)
|
||||
H.adjust_drugginess(-H.druggy)
|
||||
if(H.dizziness)
|
||||
H.dizziness = 0
|
||||
if(H.confused)
|
||||
H.confused = 0
|
||||
else if(!H.null_rod_check() && H.stat != DEAD)
|
||||
var/distance = 0 + get_dist(T, get_turf(H))
|
||||
var/falloff_distance = min((110) - distance * 10, 80)
|
||||
var/sound_distance = falloff_distance * 0.5
|
||||
var/targetbrainloss = H.getBrainLoss()
|
||||
if(distance > 3 && prob(falloff_distance * 0.5))
|
||||
to_chat(H, "<span class='sevtug_small'>\"[text2ratvar(pick(mania_messages))]\"</span>")
|
||||
if(distance <= 1)
|
||||
if(!H.Adjacent(src))
|
||||
to_chat(H, "<span class='sevtug'>\"[text2ratvar(pick(close_messages))]\"</span>")
|
||||
H.playsound_local(T, hum, sound_distance, 1)
|
||||
else if(!try_use_power(convert_cost))
|
||||
visible_message("<span class='warning'>[src]'s antennae fizzle quietly.</span>")
|
||||
playsound(src, 'sound/effects/light_flicker.ogg', 50, 1)
|
||||
else
|
||||
H.playsound_local(T, hum, 80, 1)
|
||||
if(!H.stat)
|
||||
if(H.getBrainLoss() < 100)
|
||||
H.adjustBrainLoss(20 * efficiency)
|
||||
H.visible_message("<span class='warning'>[H] reaches out and touches [src].</span>", "<span class='sevtug'>You touch [src] involuntarily.</span>")
|
||||
else
|
||||
H.Paralyse(3)
|
||||
else if(is_eligible_servant(H))
|
||||
to_chat(H, "<span class='sevtug'>\"[text2ratvar("You are mine and his, now.")]\"</span>")
|
||||
add_servant_of_ratvar(H)
|
||||
H.Paralyse(5)
|
||||
else
|
||||
H.playsound_local(T, hum, sound_distance, 1)
|
||||
switch(distance)
|
||||
if(0 to 3)
|
||||
if(prob(falloff_distance * 0.5))
|
||||
if(prob(falloff_distance))
|
||||
to_chat(H, "<span class='sevtug_small'>\"[text2ratvar(pick(mania_messages))]\"</span>")
|
||||
else
|
||||
to_chat(H, "<span class='sevtug'>\"[text2ratvar(pick(compel_messages))]\"</span>")
|
||||
if(targetbrainloss <= 40)
|
||||
H.adjustBrainLoss(3 * efficiency)
|
||||
H.adjust_drugginess(Clamp(7 * efficiency, 0, 50 - H.druggy))
|
||||
H.hallucination = min(H.hallucination + (7 * efficiency), 50)
|
||||
H.dizziness = min(H.dizziness + (3 * efficiency), 20)
|
||||
H.confused = min(H.confused + (3 * efficiency), 20)
|
||||
if(3 to 5)
|
||||
if(targetbrainloss <= 20)
|
||||
H.adjustBrainLoss(2 * efficiency)
|
||||
H.adjust_drugginess(Clamp(5 * efficiency, 0, 25 - H.druggy))
|
||||
H.hallucination = min(H.hallucination + (5 * efficiency), 25)
|
||||
H.dizziness = min(H.dizziness + (2 * efficiency), 10)
|
||||
H.confused = min(H.confused + (2 * efficiency), 10)
|
||||
if(5 to 6)
|
||||
if(targetbrainloss <= 10)
|
||||
H.adjustBrainLoss(1 * efficiency)
|
||||
H.adjust_drugginess(Clamp(2 * efficiency, 0, 20 - H.druggy))
|
||||
H.hallucination = min(H.hallucination + (2 * efficiency), 20)
|
||||
H.dizziness = min(H.dizziness + (2 * efficiency), 5)
|
||||
H.confused = min(H.confused + (2 * efficiency), 5)
|
||||
if(6 to 7)
|
||||
if(targetbrainloss <= 5)
|
||||
H.adjustBrainLoss(1 * efficiency)
|
||||
H.adjust_drugginess(Clamp(2 * efficiency, 0, 10 - H.druggy))
|
||||
H.hallucination = min(H.hallucination + (2 * efficiency), 10)
|
||||
if(7 to INFINITY)
|
||||
H.adjust_drugginess(Clamp(2 * efficiency, 0, 5 - H.druggy))
|
||||
H.hallucination = min(H.hallucination + (2 * efficiency), 5)
|
||||
if(is_servant_of_ratvar(H))
|
||||
continue
|
||||
var/list/effects = H.has_status_effect_list(STATUS_EFFECT_MANIAMOTOR)
|
||||
var/datum/status_effect/maniamotor/M
|
||||
for(var/datum/status_effect/maniamotor/MM in effects)
|
||||
if(MM.motor == src)
|
||||
M = MM
|
||||
break
|
||||
if(!M)
|
||||
M = H.apply_status_effect(STATUS_EFFECT_MANIAMOTOR)
|
||||
M.motor = src
|
||||
M.severity = Clamp(M.severity + ((11 - get_dist(src, H)) * efficiency * efficiency), 0, MAX_MANIA_SEVERITY)
|
||||
|
||||
@@ -148,8 +148,7 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
|
||||
/obj/effect/rune/proc/fail_invoke()
|
||||
//This proc contains the effects of a rune if it is not invoked correctly, through either invalid wording or not enough cultists. By default, it's just a basic fizzle.
|
||||
visible_message("<span class='warning'>The markings pulse with a \
|
||||
small flash of red light, then fall dark.</span>")
|
||||
visible_message("<span class='warning'>The markings pulse with a small flash of red light, then fall dark.</span>")
|
||||
var/oldcolor = color
|
||||
color = rgb(255, 0, 0)
|
||||
animate(src, color = oldcolor, time = 5)
|
||||
@@ -309,10 +308,11 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
A.forceMove(target)
|
||||
if(movedsomething)
|
||||
..()
|
||||
visible_message("<span class='warning'>There is a sharp crack of inrushing air, and everything above the rune disappears!</span>")
|
||||
visible_message("<span class='warning'>There is a sharp crack of inrushing air, and everything above the rune disappears!</span>", null, "<i>You hear a sharp crack.</i>")
|
||||
to_chat(user, "<span class='cult'>You[moveuserlater ? "r vision blurs, and you suddenly appear somewhere else":" send everything above the rune away"].</span>")
|
||||
if(moveuserlater)
|
||||
user.forceMove(target)
|
||||
target.visible_message("<span class='warning'>There is a boom of outrushing air as something appears above the rune!</span>", null, "<i>You hear a boom.</i>")
|
||||
else
|
||||
fail_invoke()
|
||||
|
||||
|
||||
@@ -147,9 +147,10 @@
|
||||
if(is_blocked_turf(target, TRUE))
|
||||
to_chat(user, "<span class='warning'>The target rune is blocked. Attempting to teleport to it would be massively unwise.</span>")
|
||||
return ..(user, 0)
|
||||
user.visible_message("<span class='warning'>Dust flows from [user]'s hand, and [user.p_they()] disappear in a flash of red light!</span>", \
|
||||
"<span class='cultitalic'>You speak the words of the talisman and find yourself somewhere else!</span>")
|
||||
user.visible_message("<span class='warning'>Dust flows from [user]'s hand, and [user.p_they()] disappear with a sharp crack!</span>", \
|
||||
"<span class='cultitalic'>You speak the words of the talisman and find yourself somewhere else!</span>", "<i>You hear a sharp crack.</i>")
|
||||
user.forceMove(target)
|
||||
target.visible_message("<span class='warning'>There is a boom of outrushing air as something appears above the rune!</span>", null, "<i>You hear a boom.</i>")
|
||||
return ..()
|
||||
|
||||
|
||||
|
||||
@@ -85,7 +85,6 @@
|
||||
SSblackbox.set_details("game_mode","[SSticker.mode]")
|
||||
if(GLOB.revdata.commit)
|
||||
SSblackbox.set_details("revision","[GLOB.revdata.commit]")
|
||||
SSblackbox.set_details("server_ip","[world.internet_address]:[world.port]")
|
||||
if(report)
|
||||
addtimer(CALLBACK(src, .proc/send_intercept, 0), rand(waittime_l, waittime_h))
|
||||
generate_station_goals()
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#define DOM_BLOCKED_SPAM_CAP 6
|
||||
|
||||
/obj/machinery/dominator
|
||||
name = "dominator"
|
||||
desc = "A visibly sinister device. Looks like you can break it if you hit it enough."
|
||||
@@ -13,9 +15,20 @@
|
||||
var/datum/gang/gang
|
||||
var/operating = 0 //0=standby or broken, 1=takeover
|
||||
var/warned = 0 //if this device has set off the warning at <3 minutes yet
|
||||
var/spam_prevention = DOM_BLOCKED_SPAM_CAP //first message is immediate
|
||||
var/datum/effect_system/spark_spread/spark_system
|
||||
var/obj/effect/countdown/dominator/countdown
|
||||
|
||||
/proc/dominator_excessive_walls(atom/A)
|
||||
var/open = 0
|
||||
for(var/turf/T in circleviewturfs(center=A,radius=3))
|
||||
if(!istype(T, /turf/closed))
|
||||
open++
|
||||
if(open < 40)
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/dominator/tesla_act()
|
||||
qdel(src)
|
||||
|
||||
@@ -48,6 +61,16 @@
|
||||
if(gang && gang.is_dominating)
|
||||
var/time_remaining = gang.domination_time_remaining()
|
||||
if(time_remaining > 0)
|
||||
if(dominator_excessive_walls(src))
|
||||
gang.domination_timer += 2
|
||||
playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0)
|
||||
if(spam_prevention < DOM_BLOCKED_SPAM_CAP)
|
||||
spam_prevention++
|
||||
else
|
||||
gang.message_gangtools("Warning: There are too many walls around your gang's dominator, its signal is being blocked!")
|
||||
say("Error: Takeover signal is currently blocked! There are too many walls within 3 standard units of this device.")
|
||||
spam_prevention = 0
|
||||
return
|
||||
. = TRUE
|
||||
playsound(loc, 'sound/items/timer.ogg', 10, 0)
|
||||
if(!warned && (time_remaining < 180))
|
||||
|
||||
@@ -312,7 +312,9 @@ GLOBAL_LIST_INIT(gang_colors_pool, list("red","orange","yellow","green","blue","
|
||||
G.domination(0.5)
|
||||
priority_announce("Multiple station takeover attempts have made simultaneously. Conflicting takeover attempts appears to have restarted.","Network Alert")
|
||||
else
|
||||
var/datum/gang/G = winners[1]
|
||||
G.is_dominating = FALSE
|
||||
SSticker.mode.explosion_in_progress = 1
|
||||
SSticker.station_explosion_cinematic(1)
|
||||
SSticker.station_explosion_cinematic(1,"gang war", null)
|
||||
SSticker.mode.explosion_in_progress = 0
|
||||
SSticker.force_ending = pick(winners)
|
||||
SSticker.force_ending = TRUE
|
||||
|
||||
@@ -305,7 +305,11 @@
|
||||
if(obj.density)
|
||||
to_chat(user, "<span class='warning'>There's not enough room here!</span>")
|
||||
return FALSE
|
||||
|
||||
|
||||
if(dominator_excessive_walls(user))
|
||||
to_chat(user, "span class='warning'>The <b>dominator</b> will not function here! The <b>dominator</b> requires an open space within three standard units so that walls do not interfere with the signal.</span>")
|
||||
return FALSE
|
||||
|
||||
if(!(usrarea.type in gang.territory|gang.territory_new))
|
||||
to_chat(user, "<span class='warning'>The <b>dominator</b> can be spawned only on territory controlled by your gang!</span>")
|
||||
return FALSE
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
explanation_text = "Your brain is broken... you can only communicate in"
|
||||
|
||||
/datum/objective/abductee/speech/New()
|
||||
var/style = pick(list("pantomime", "rhyme", "haiku", "extended metaphors", "riddles", "extremely literal terms", "sound effects", "military jargon"))
|
||||
var/style = pick(list("pantomime", "rhyme", "haiku", "extended metaphors", "riddles", "extremely literal terms", "sound effects", "military jargon", "three word sentences"))
|
||||
explanation_text+= " [style]."
|
||||
|
||||
/datum/objective/abductee/capture
|
||||
@@ -146,3 +146,25 @@
|
||||
|
||||
/datum/objective/abductee/sixthsense
|
||||
explanation_text = "You died back there and went to heaven... or is it hell? No one here seems to know they're dead. Convince them, and maybe you can escape this limbo."
|
||||
|
||||
/datum/objective/abductee/toupefallacy
|
||||
explanation_text = "There are alien parasites masquerading as people's hair. Save people from this invasion."
|
||||
|
||||
/datum/objective/abductee/everyoneisthesame
|
||||
explanation_text = "There is only one other person in existence, he is just really good at pretending to be multiple people."
|
||||
|
||||
/datum/objective/abductee/forbiddennumber
|
||||
explanation_text = "Numbers, how do they work?" //Shouldn't ever see this.
|
||||
|
||||
/datum/objective/abductee/forbiddennumber/New()
|
||||
var/number = rand(2,10)
|
||||
explanation_text = "Ignore anything in a set of [number], they don't exist."
|
||||
|
||||
/datum/objective/abductee/foreignname
|
||||
explanation_text = "No matter how they say it, other people keep mispronouncing your name. Be sure to correct them whenever possible."
|
||||
|
||||
/datum/objective/abductee/pairoff
|
||||
explanation_text = "Being alone and in large groups are both frightening. Try to be alone with only one other person whenever possible."
|
||||
|
||||
/datum/objective/abductee/takeblame
|
||||
explanation_text = "Try to get formally executed for a crime you didn't commit, without a false confession."
|
||||
|
||||
@@ -116,12 +116,13 @@
|
||||
else
|
||||
dat += "<h3>Subject Status : </h3>"
|
||||
dat += "[occupant.name] => "
|
||||
switch(occupant.stat)
|
||||
if(0)
|
||||
var/mob/living/mob_occupant = occupant
|
||||
switch(mob_occupant.stat)
|
||||
if(CONSCIOUS)
|
||||
dat += "<span class='good'>Conscious</span>"
|
||||
if(1)
|
||||
if(UNCONSCIOUS)
|
||||
dat += "<span class='average'>Unconscious</span>"
|
||||
else
|
||||
else // DEAD
|
||||
dat += "<span class='bad'>Deceased</span>"
|
||||
dat += "<br>"
|
||||
dat += "[flash]"
|
||||
@@ -146,9 +147,11 @@
|
||||
if(href_list["close"])
|
||||
close_machine()
|
||||
return
|
||||
if(occupant && occupant.stat != DEAD)
|
||||
if(href_list["experiment"])
|
||||
flash = Experiment(occupant,href_list["experiment"])
|
||||
if(occupant)
|
||||
var/mob/living/mob_occupant = occupant
|
||||
if(mob_occupant.stat != DEAD)
|
||||
if(href_list["experiment"])
|
||||
flash = Experiment(occupant,href_list["experiment"])
|
||||
updateUsrDialog()
|
||||
add_fingerprint(usr)
|
||||
|
||||
|
||||
@@ -79,7 +79,8 @@
|
||||
/obj/machinery/sleeper/close_machine(mob/user)
|
||||
if((isnull(user) || istype(user)) && state_open && !panel_open)
|
||||
..(user)
|
||||
if(occupant && occupant.stat != DEAD)
|
||||
var/mob/living/mob_occupant = occupant
|
||||
if(mob_occupant && mob_occupant.stat != DEAD)
|
||||
to_chat(occupant, "<span class='notice'><b>You feel cool air surround you. You go numb as your senses turn inward.</b></span>")
|
||||
|
||||
/obj/machinery/sleeper/emp_act(severity)
|
||||
@@ -128,27 +129,30 @@
|
||||
data["chems"] += list(list("name" = R.name, "id" = R.id, "allowed" = chem_allowed(chem)))
|
||||
|
||||
data["occupant"] = list()
|
||||
if(occupant)
|
||||
data["occupant"]["name"] = occupant.name
|
||||
data["occupant"]["stat"] = occupant.stat
|
||||
data["occupant"]["health"] = occupant.health
|
||||
data["occupant"]["maxHealth"] = occupant.maxHealth
|
||||
var/mob/living/mob_occupant = occupant
|
||||
if(mob_occupant)
|
||||
data["occupant"]["name"] = mob_occupant.name
|
||||
data["occupant"]["stat"] = mob_occupant.stat
|
||||
data["occupant"]["health"] = mob_occupant.health
|
||||
data["occupant"]["maxHealth"] = mob_occupant.maxHealth
|
||||
data["occupant"]["minHealth"] = HEALTH_THRESHOLD_DEAD
|
||||
data["occupant"]["bruteLoss"] = occupant.getBruteLoss()
|
||||
data["occupant"]["oxyLoss"] = occupant.getOxyLoss()
|
||||
data["occupant"]["toxLoss"] = occupant.getToxLoss()
|
||||
data["occupant"]["fireLoss"] = occupant.getFireLoss()
|
||||
data["occupant"]["cloneLoss"] = occupant.getCloneLoss()
|
||||
data["occupant"]["brainLoss"] = occupant.getBrainLoss()
|
||||
data["occupant"]["bruteLoss"] = mob_occupant.getBruteLoss()
|
||||
data["occupant"]["oxyLoss"] = mob_occupant.getOxyLoss()
|
||||
data["occupant"]["toxLoss"] = mob_occupant.getToxLoss()
|
||||
data["occupant"]["fireLoss"] = mob_occupant.getFireLoss()
|
||||
data["occupant"]["cloneLoss"] = mob_occupant.getCloneLoss()
|
||||
data["occupant"]["brainLoss"] = mob_occupant.getBrainLoss()
|
||||
data["occupant"]["reagents"] = list()
|
||||
if(occupant.reagents.reagent_list.len)
|
||||
for(var/datum/reagent/R in occupant.reagents.reagent_list)
|
||||
for(var/datum/reagent/R in mob_occupant.reagents.reagent_list)
|
||||
data["occupant"]["reagents"] += list(list("name" = R.name, "volume" = R.volume))
|
||||
return data
|
||||
|
||||
/obj/machinery/sleeper/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
var/mob/living/mob_occupant = occupant
|
||||
|
||||
switch(action)
|
||||
if("door")
|
||||
if(state_open)
|
||||
@@ -158,9 +162,9 @@
|
||||
. = TRUE
|
||||
if("inject")
|
||||
var/chem = params["chem"]
|
||||
if(!is_operational() || !occupant)
|
||||
if(!is_operational() || !mob_occupant)
|
||||
return
|
||||
if(occupant.health < min_health && chem != "epinephrine")
|
||||
if(mob_occupant.health < min_health && chem != "epinephrine")
|
||||
return
|
||||
if(inject_chem(chem))
|
||||
. = TRUE
|
||||
@@ -177,10 +181,11 @@
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/sleeper/proc/chem_allowed(chem)
|
||||
if(!occupant)
|
||||
var/mob/living/mob_occupant = occupant
|
||||
if(!mob_occupant)
|
||||
return
|
||||
var/amount = occupant.reagents.get_reagent_amount(chem) + 10 <= 20 * efficiency
|
||||
var/occ_health = occupant.health > min_health || chem == "epinephrine"
|
||||
var/amount = mob_occupant.reagents.get_reagent_amount(chem) + 10 <= 20 * efficiency
|
||||
var/occ_health = mob_occupant.health > min_health || chem == "epinephrine"
|
||||
return amount && occ_health
|
||||
|
||||
/obj/machinery/sleeper/proc/reset_chem_buttons()
|
||||
|
||||
@@ -121,10 +121,12 @@
|
||||
|
||||
/obj/machinery/clonepod/examine(mob/user)
|
||||
..()
|
||||
var/mob/living/mob_occupant = occupant
|
||||
if(mess)
|
||||
to_chat(user, "It's filled with blood and viscera. You swear you can see it moving...")
|
||||
if (is_operational() && (!isnull(occupant)) && (occupant.stat != DEAD))
|
||||
to_chat(user, "Current clone cycle is [round(get_completion())]% complete.")
|
||||
if(is_operational() && mob_occupant)
|
||||
if(mob_occupant.stat != DEAD)
|
||||
to_chat(user, "Current clone cycle is [round(get_completion())]% complete.")
|
||||
|
||||
/obj/machinery/clonepod/return_air()
|
||||
// We want to simulate the clone not being in contact with
|
||||
@@ -136,7 +138,10 @@
|
||||
return GM
|
||||
|
||||
/obj/machinery/clonepod/proc/get_completion()
|
||||
. = (100 * ((occupant.health + 100) / (heal_level + 100)))
|
||||
. = FALSE
|
||||
var/mob/living/mob_occupant = occupant
|
||||
if(mob_occupant)
|
||||
. = (100 * ((mob_occupant.health + 100) / (heal_level + 100)))
|
||||
|
||||
/obj/machinery/clonepod/attack_ai(mob/user)
|
||||
return examine(user)
|
||||
@@ -172,11 +177,11 @@
|
||||
|
||||
var/mob/living/carbon/human/H = new /mob/living/carbon/human(src)
|
||||
|
||||
if(clonemind.changeling)
|
||||
var/obj/item/organ/brain/B = H.getorganslot("brain")
|
||||
B.vital = FALSE
|
||||
B.decoy_override = TRUE
|
||||
|
||||
if(clonemind.changeling)
|
||||
var/obj/item/organ/brain/B = H.getorganslot("brain")
|
||||
B.vital = FALSE
|
||||
B.decoy_override = TRUE
|
||||
|
||||
H.hardset_dna(ui, se, H.real_name, null, mrace, features)
|
||||
|
||||
if(efficiency > 2)
|
||||
@@ -204,13 +209,13 @@
|
||||
|
||||
clonemind.transfer_to(H)
|
||||
|
||||
if(grab_ghost_when == CLONER_FRESH_CLONE)
|
||||
H.grab_ghost()
|
||||
to_chat(H, "<span class='notice'><b>Consciousness slowly creeps over you as your body regenerates.</b><br><i>So this is what cloning feels like?</i></span>")
|
||||
if(grab_ghost_when == CLONER_FRESH_CLONE)
|
||||
H.grab_ghost()
|
||||
to_chat(H, "<span class='notice'><b>Consciousness slowly creeps over you as your body regenerates.</b><br><i>So this is what cloning feels like?</i></span>")
|
||||
|
||||
if(grab_ghost_when == CLONER_MATURE_CLONE)
|
||||
H.ghostize(TRUE) //Only does anything if they were still in their old body and not already a ghost
|
||||
to_chat(H.get_ghost(TRUE), "<span class='notice'>Your body is beginning to regenerate in a cloning pod. You will become conscious when it is complete.</span>")
|
||||
H.ghostize(TRUE) //Only does anything if they were still in their old body and not already a ghost
|
||||
to_chat(H.get_ghost(TRUE), "<span class='notice'>Your body is beginning to regenerate in a cloning pod. You will become conscious when it is complete.</span>")
|
||||
|
||||
if(H)
|
||||
H.faction |= factions
|
||||
@@ -223,25 +228,26 @@
|
||||
|
||||
//Grow clones to maturity then kick them out. FREELOADERS
|
||||
/obj/machinery/clonepod/process()
|
||||
var/mob/living/mob_occupant = occupant
|
||||
|
||||
if(!is_operational()) //Autoeject if power is lost
|
||||
if (occupant)
|
||||
if(mob_occupant)
|
||||
go_out()
|
||||
connected_message("Clone Ejected: Loss of power.")
|
||||
|
||||
else if((occupant) && (occupant.loc == src))
|
||||
if((occupant.stat == DEAD) || (occupant.suiciding) || occupant.hellbound) //Autoeject corpses and suiciding dudes.
|
||||
else if(mob_occupant && (mob_occupant.loc == src))
|
||||
if((mob_occupant.stat == DEAD) || (mob_occupant.suiciding) || mob_occupant.hellbound) //Autoeject corpses and suiciding dudes.
|
||||
connected_message("Clone Rejected: Deceased.")
|
||||
SPEAK("The cloning of [occupant.real_name] has been \
|
||||
SPEAK("The cloning of [mob_occupant.real_name] has been \
|
||||
aborted due to unrecoverable tissue failure.")
|
||||
go_out()
|
||||
|
||||
else if(occupant.cloneloss > (100 - heal_level))
|
||||
occupant.Paralyse(4)
|
||||
else if(mob_occupant.cloneloss > (100 - heal_level))
|
||||
mob_occupant.Paralyse(4)
|
||||
|
||||
//Slowly get that clone healed and finished.
|
||||
occupant.adjustCloneLoss(-((speed_coeff/2) * config.damage_multiplier))
|
||||
var/progress = CLONE_INITIAL_DAMAGE - occupant.getCloneLoss()
|
||||
mob_occupant.adjustCloneLoss(-((speed_coeff/2) * config.damage_multiplier))
|
||||
var/progress = CLONE_INITIAL_DAMAGE - mob_occupant.getCloneLoss()
|
||||
// To avoid the default cloner making incomplete clones
|
||||
progress += (100 - MINIMUM_HEAL_LEVEL)
|
||||
var/milestone = CLONE_INITIAL_DAMAGE / flesh_number
|
||||
@@ -252,24 +258,24 @@
|
||||
var/obj/item/I = pick_n_take(unattached_flesh)
|
||||
if(isorgan(I))
|
||||
var/obj/item/organ/O = I
|
||||
O.Insert(occupant)
|
||||
O.Insert(mob_occupant)
|
||||
else if(isbodypart(I))
|
||||
var/obj/item/bodypart/BP = I
|
||||
BP.attach_limb(occupant)
|
||||
BP.attach_limb(mob_occupant)
|
||||
|
||||
//Premature clones may have brain damage.
|
||||
occupant.adjustBrainLoss(-((speed_coeff/2) * config.damage_multiplier))
|
||||
mob_occupant.adjustBrainLoss(-((speed_coeff/2) * config.damage_multiplier))
|
||||
|
||||
check_brine()
|
||||
|
||||
use_power(7500) //This might need tweaking.
|
||||
|
||||
else if((occupant.cloneloss <= (100 - heal_level)))
|
||||
else if((mob_occupant.cloneloss <= (100 - heal_level)))
|
||||
connected_message("Cloning Process Complete.")
|
||||
SPEAK("The cloning cycle of [occupant.real_name] is complete.")
|
||||
SPEAK("The cloning cycle of [mob_occupant.real_name] is complete.")
|
||||
go_out()
|
||||
|
||||
else if ((!occupant) || (occupant.loc != src))
|
||||
else if (!mob_occupant || mob_occupant.loc != src)
|
||||
occupant = null
|
||||
if (!mess && !panel_open)
|
||||
icon_state = "pod_0"
|
||||
@@ -305,16 +311,19 @@
|
||||
to_chat(user, "<font color = #666633>-% Successfully stored \ref[P.buffer] [P.buffer.name] in buffer %-</font color>")
|
||||
return
|
||||
|
||||
var/mob/living/mob_occupant = occupant
|
||||
if(W.GetID())
|
||||
if(!check_access(W))
|
||||
to_chat(user, "<span class='danger'>Access Denied.</span>")
|
||||
return
|
||||
if(!(occupant || mess))
|
||||
if(!(mob_occupant || mess))
|
||||
to_chat(user, "<span class='danger'>Error: Pod has no occupant.</span>")
|
||||
return
|
||||
else
|
||||
connected_message("Authorized Ejection")
|
||||
SPEAK("An authorized ejection of [clonemind.name] has occurred.")
|
||||
|
||||
SPEAK("An authorized ejection of [clonemind.name] has occurred.")
|
||||
|
||||
to_chat(user, "<span class='notice'>You force an emergency ejection. </span>")
|
||||
go_out()
|
||||
else
|
||||
@@ -339,54 +348,63 @@
|
||||
|
||||
/obj/machinery/clonepod/proc/go_out()
|
||||
countdown.stop()
|
||||
var/mob/living/mob_occupant = occupant
|
||||
|
||||
if(mess) //Clean that mess and dump those gibs!
|
||||
mess = FALSE
|
||||
new /obj/effect/gibspawner/generic(loc)
|
||||
new /obj/effect/gibspawner/generic(loc)
|
||||
audible_message("<span class='italics'>You hear a splat.</span>")
|
||||
icon_state = "pod_0"
|
||||
return
|
||||
|
||||
if(!occupant)
|
||||
if(!mob_occupant)
|
||||
return
|
||||
|
||||
if(grab_ghost_when == CLONER_MATURE_CLONE)
|
||||
occupant.grab_ghost()
|
||||
to_chat(occupant, "<span class='notice'><b>There is a bright flash!</b><br><i>You feel like a new being.</i></span>")
|
||||
occupant.flash_act()
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if(grab_ghost_when == CLONER_MATURE_CLONE)
|
||||
mob_occupant.grab_ghost()
|
||||
to_chat(occupant, "<span class='notice'><b>There is a bright flash!</b><br><i>You feel like a new being.</i></span>")
|
||||
mob_occupant.flash_act()
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
occupant.forceMove(T)
|
||||
icon_state = "pod_0"
|
||||
occupant.domutcheck(1) //Waiting until they're out before possible monkeyizing. The 1 argument forces powers to manifest.
|
||||
mob_occupant.domutcheck(1) //Waiting until they're out before possible monkeyizing. The 1 argument forces powers to manifest.
|
||||
|
||||
occupant = null
|
||||
|
||||
/obj/machinery/clonepod/proc/malfunction()
|
||||
if(occupant)
|
||||
var/mob/living/mob_occupant = occupant
|
||||
if(mob_occupant)
|
||||
connected_message("Critical Error!")
|
||||
SPEAK("Critical error! Please contact a Thinktronic Systems \
|
||||
technician, as your warranty may be affected.")
|
||||
mess = TRUE
|
||||
for(var/obj/item/O in unattached_flesh)
|
||||
qdel(O)
|
||||
|
||||
for(var/obj/item/O in unattached_flesh)
|
||||
qdel(O)
|
||||
|
||||
icon_state = "pod_g"
|
||||
if(occupant.mind != clonemind)
|
||||
clonemind.transfer_to(occupant)
|
||||
occupant.grab_ghost() // We really just want to make you suffer.
|
||||
flash_color(occupant, flash_color="#960000", flash_time=100)
|
||||
to_chat(occupant, "<span class='warning'><b>Agony blazes across your consciousness as your body is torn apart.</b><br><i>Is this what dying is like? Yes it is.</i></span>")
|
||||
if(mob_occupant.mind != clonemind)
|
||||
clonemind.transfer_to(mob_occupant)
|
||||
mob_occupant.grab_ghost() // We really just want to make you suffer.
|
||||
flash_color(mob_occupant, flash_color="#960000", flash_time=100)
|
||||
to_chat(mob_occupant, "<span class='warning'><b>Agony blazes across your consciousness as your body is torn apart.</b><br><i>Is this what dying is like? Yes it is.</i></span>")
|
||||
playsound(src.loc, 'sound/machines/warning-buzzer.ogg', 50, 0)
|
||||
occupant << sound('sound/hallucinations/veryfar_noise.ogg',0,1,50)
|
||||
QDEL_IN(occupant, 40)
|
||||
mob_occupant << sound('sound/hallucinations/veryfar_noise.ogg',0,1,50)
|
||||
QDEL_IN(mob_occupant, 40)
|
||||
|
||||
/obj/machinery/clonepod/relaymove(mob/user)
|
||||
if(user.stat == CONSCIOUS)
|
||||
go_out()
|
||||
|
||||
/obj/machinery/clonepod/emp_act(severity)
|
||||
if((occupant || mess) && prob(100/(severity*efficiency)))
|
||||
|
||||
var/mob/living/mob_occupant = occupant
|
||||
if(mob_occupant && prob(100/(severity*efficiency)))
|
||||
connected_message(Gibberish("EMP-caused Accidental Ejection", 0))
|
||||
SPEAK(Gibberish("Exposure to electromagnetic fields has caused the ejection of [clonemind.name] prematurely." ,0))
|
||||
SPEAK(Gibberish("Exposure to electromagnetic fields has caused the ejection of [mob_occupant.real_name] prematurely." ,0))
|
||||
|
||||
go_out()
|
||||
..()
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
diff a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm (rejected hunks)
|
||||
@@ -311,15 +311,15 @@
|
||||
to_chat(user, "<font color = #666633>-% Successfully stored \ref[P.buffer] [P.buffer.name] in buffer %-</font color>")
|
||||
return
|
||||
|
||||
+ var/mob/living/mob_occupant = occupant
|
||||
if(W.GetID())
|
||||
if(!check_access(W))
|
||||
to_chat(user, "<span class='danger'>Access Denied.</span>")
|
||||
return
|
||||
- if(!(occupant || mess))
|
||||
+ if(!(mob_occupant || mess))
|
||||
to_chat(user, "<span class='danger'>Error: Pod has no occupant.</span>")
|
||||
return
|
||||
else
|
||||
- var/mob/living/mob_occupant
|
||||
connected_message("Authorized Ejection")
|
||||
SPEAK("An authorized ejection of [clonemind.name] has occurred.")
|
||||
to_chat(user, "<span class='notice'>You force an emergency ejection. </span>")
|
||||
@@ -395,16 +395,10 @@
|
||||
go_out()
|
||||
|
||||
/obj/machinery/clonepod/emp_act(severity)
|
||||
-<<<<<<< HEAD
|
||||
- if((occupant || mess) && prob(100/(severity*efficiency)))
|
||||
- connected_message(Gibberish("EMP-caused Accidental Ejection", 0))
|
||||
- SPEAK(Gibberish("Exposure to electromagnetic fields has caused the ejection of [clonemind.name] prematurely." ,0))
|
||||
-=======
|
||||
- if(isliving(occupant) && prob(100/(severity*efficiency)))
|
||||
- var/mob/living/mob_occupant = occupant
|
||||
+ var/mob/living/mob_occupant = occupant
|
||||
+ if(mob_occupant && prob(100/(severity*efficiency)))
|
||||
connected_message(Gibberish("EMP-caused Accidental Ejection", 0))
|
||||
SPEAK(Gibberish("Exposure to electromagnetic fields has caused the ejection of [mob_occupant.real_name] prematurely." ,0))
|
||||
->>>>>>> Changes /obj/machinery to have atom/movable occupants
|
||||
go_out()
|
||||
..()
|
||||
|
||||
@@ -186,21 +186,23 @@
|
||||
// Scanner
|
||||
if (!isnull(src.scanner))
|
||||
|
||||
var/mob/living/scanner_occupant = scanner.occupant
|
||||
|
||||
dat += "<h3>Scanner Functions</h3>"
|
||||
|
||||
dat += "<div class='statusDisplay'>"
|
||||
if (!src.scanner.occupant)
|
||||
if(!scanner_occupant)
|
||||
dat += "Scanner Unoccupied"
|
||||
else if(loading)
|
||||
dat += "[src.scanner.occupant] => Scanning..."
|
||||
dat += "[scanner_occupant] => Scanning..."
|
||||
else
|
||||
if (src.scanner.occupant.ckey != scantemp_ckey)
|
||||
if(scanner_occupant.ckey != scantemp_ckey)
|
||||
scantemp = "Ready to Scan"
|
||||
scantemp_ckey = src.scanner.occupant.ckey
|
||||
dat += "[src.scanner.occupant] => [scantemp]"
|
||||
scantemp_ckey = scanner_occupant.ckey
|
||||
dat += "[scanner_occupant] => [scantemp]"
|
||||
dat += "</div>"
|
||||
|
||||
if (src.scanner.occupant)
|
||||
if(scanner_occupant)
|
||||
dat += "<a href='byond://?src=\ref[src];scan=1'>Start Scan</a>"
|
||||
dat += "<br><a href='byond://?src=\ref[src];lock=1'>[src.scanner.locked ? "Unlock Scanner" : "Lock Scanner"]</a>"
|
||||
else
|
||||
|
||||
@@ -113,7 +113,8 @@
|
||||
to_chat(R.connected_ai, "<br><br><span class='alert'>ALERT - Cyborg detonation detected: [R.name]</span><br>")
|
||||
R.ResetSecurityCodes()
|
||||
else
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[usr]'>FLW</A>) detonated [key_name(R, R.client)](<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[R.x];Y=[R.y];Z=[R.z]'>JMP</a>)!</span>")
|
||||
var/turf/T = get_turf(R)
|
||||
message_admins("<span class='notice'>[ADMIN_LOOKUPFLW(usr)] detonated [key_name(R, R.client)][ADMIN_JMP(T)]!</span>")
|
||||
log_game("\<span class='notice'>[key_name(usr)] detonated [key_name(R)]!</span>")
|
||||
if(R.connected_ai)
|
||||
to_chat(R.connected_ai, "<br><br><span class='alert'>ALERT - Cyborg detonation detected: [R.name]</span><br>")
|
||||
@@ -127,7 +128,7 @@
|
||||
if(can_control(usr, R))
|
||||
var/choice = input("Are you certain you wish to [R.canmove ? "lock down" : "release"] [R.name]?") in list("Confirm", "Abort")
|
||||
if(choice == "Confirm" && can_control(usr, R) && !..())
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[usr]'>FLW</A>) [R.canmove ? "locked down" : "released"] [key_name(R, R.client)](<A HREF='?_src_=holder;adminplayerobservefollow=\ref[R]'>FLW</A>)!</span>")
|
||||
message_admins("<span class='notice'>[ADMIN_LOOKUPFLW(usr)] [R.canmove ? "locked down" : "released"] [key_name(R, R.client)][ADMIN_LOOKUPFLW(R)]!</span>")
|
||||
log_game("[key_name(usr)] [R.canmove ? "locked down" : "released"] [key_name(R)]!")
|
||||
R.SetLockdown(!R.lockcharge)
|
||||
to_chat(R, "[!R.lockcharge ? "<span class='notice'>Your lockdown has been lifted!" : "<span class='alert'>You have been locked down!"]</span>")
|
||||
|
||||
@@ -105,13 +105,14 @@
|
||||
..()
|
||||
|
||||
// search for ghosts, if the corpse is empty and the scanner is connected to a cloner
|
||||
if(occupant)
|
||||
var/mob/living/mob_occupant = occupant
|
||||
if(mob_occupant)
|
||||
if(locate(/obj/machinery/computer/cloning, get_step(src, NORTH)) \
|
||||
|| locate(/obj/machinery/computer/cloning, get_step(src, SOUTH)) \
|
||||
|| locate(/obj/machinery/computer/cloning, get_step(src, EAST)) \
|
||||
|| locate(/obj/machinery/computer/cloning, get_step(src, WEST)))
|
||||
if(!occupant.suiciding && !(occupant.disabilities & NOCLONE) && !occupant.hellbound)
|
||||
occupant.notify_ghost_cloning("Your corpse has been placed into a cloning scanner. Re-enter your corpse if you want to be cloned!", source = src)
|
||||
if(!mob_occupant.suiciding && !(mob_occupant.disabilities & NOCLONE) && !mob_occupant.hellbound)
|
||||
mob_occupant.notify_ghost_cloning("Your corpse has been placed into a cloning scanner. Re-enter your corpse if you want to be cloned!", source = src)
|
||||
|
||||
var/obj/machinery/computer/scan_consolenew/console
|
||||
for(dir in list(NORTH,EAST,SOUTH,WEST))
|
||||
@@ -157,4 +158,4 @@
|
||||
if(..(user,1,0)) //don't set the machine, since there's no dialog
|
||||
return
|
||||
|
||||
toggle_open(user)
|
||||
toggle_open(user)
|
||||
|
||||
@@ -136,13 +136,14 @@ The console is located at computer/gulag_teleporter.dm
|
||||
/obj/machinery/gulag_teleporter/proc/strip_occupant()
|
||||
if(linked_reclaimer)
|
||||
linked_reclaimer.stored_items[occupant] = list()
|
||||
for(var/obj/item/W in occupant)
|
||||
if(!is_type_in_typecache(W, required_items) && occupant.temporarilyRemoveItemFromInventory(W))
|
||||
var/mob/living/mob_occupant = occupant
|
||||
for(var/obj/item/W in mob_occupant)
|
||||
if(!is_type_in_typecache(W, required_items) && mob_occupant.temporarilyRemoveItemFromInventory(W))
|
||||
if(istype(W, /obj/item/weapon/restraints/handcuffs))
|
||||
W.forceMove(get_turf(src))
|
||||
continue
|
||||
if(linked_reclaimer)
|
||||
linked_reclaimer.stored_items[occupant] += W
|
||||
linked_reclaimer.stored_items[mob_occupant] += W
|
||||
linked_reclaimer.contents += W
|
||||
W.forceMove(linked_reclaimer)
|
||||
else
|
||||
|
||||
@@ -61,6 +61,7 @@ GLOBAL_LIST_EMPTY(holopads)
|
||||
/obj/machinery/holopad/Destroy()
|
||||
if(outgoing_call)
|
||||
LAZYADD(holo_calls, outgoing_call)
|
||||
outgoing_call = null
|
||||
|
||||
for(var/I in holo_calls)
|
||||
var/datum/holocall/HC = I
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
Overview:
|
||||
Used to create objects that need a per step proc call. Default definition of 'New()'
|
||||
Used to create objects that need a per step proc call. Default definition of 'Initialize()'
|
||||
stores a reference to src machine in global 'machines list'. Default definition
|
||||
of 'Del' removes reference to src machine in global 'machines list'.
|
||||
of 'Destroy' removes reference to src machine in global 'machines list'.
|
||||
|
||||
Class Variables:
|
||||
use_power (num)
|
||||
@@ -44,7 +44,7 @@ Class Variables:
|
||||
EMPED:16 -- temporary broken by EMP pulse
|
||||
|
||||
Class Procs:
|
||||
New() 'game/machinery/machine.dm'
|
||||
Initialize() 'game/machinery/machine.dm'
|
||||
|
||||
Destroy() 'game/machinery/machine.dm'
|
||||
|
||||
@@ -118,14 +118,15 @@ Class Procs:
|
||||
var/panel_open = 0
|
||||
var/state_open = 0
|
||||
var/critical_machine = FALSE //If this machine is critical to station operation and should have the area be excempted from power failures.
|
||||
var/mob/living/occupant = null
|
||||
var/list/occupant_typecache = list(/mob/living) // turned into typecache in Initialize
|
||||
var/atom/movable/occupant = null
|
||||
var/unsecuring_tool = /obj/item/weapon/wrench
|
||||
var/interact_open = 0 // Can the machine be interacted with when in maint/when the panel is open.
|
||||
var/interact_offline = 0 // Can the machine be interacted with while de-powered.
|
||||
var/speed_process = 0 // Process as fast as possible?
|
||||
|
||||
/obj/machinery/Initialize()
|
||||
if (!armor)
|
||||
if(!armor)
|
||||
armor = list(melee = 25, bullet = 10, laser = 10, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 70)
|
||||
. = ..()
|
||||
GLOB.machines += src
|
||||
@@ -135,6 +136,8 @@ Class Procs:
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
power_change()
|
||||
|
||||
occupant_typecache = typecacheof(occupant_typecache)
|
||||
|
||||
/obj/machinery/Destroy()
|
||||
GLOB.machines.Remove(src)
|
||||
if(!speed_process)
|
||||
@@ -176,16 +179,24 @@ Class Procs:
|
||||
L.update_canmove()
|
||||
occupant = null
|
||||
|
||||
/obj/machinery/proc/close_machine(mob/living/target = null)
|
||||
/obj/machinery/proc/close_machine(atom/movable/target = null)
|
||||
state_open = 0
|
||||
density = 1
|
||||
if(!target)
|
||||
for(var/mob/living/carbon/C in loc)
|
||||
if(C.buckled || C.has_buckled_mobs())
|
||||
for(var/am in loc)
|
||||
if(!is_type_in_typecache(am, occupant_typecache))
|
||||
continue
|
||||
else
|
||||
target = C
|
||||
if(target && !target.buckled && !target.has_buckled_mobs())
|
||||
var/atom/movable/AM = am
|
||||
if(AM.has_buckled_mobs())
|
||||
continue
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = am
|
||||
if(L.buckled)
|
||||
continue
|
||||
target = am
|
||||
|
||||
var/mob/living/mobtarget = target
|
||||
if(target && !target.has_buckled_mobs() && (!isliving(target) || !mobtarget.buckled))
|
||||
occupant = target
|
||||
target.forceMove(src)
|
||||
updateUsrDialog()
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#define TURRET_STUN 0
|
||||
#define TURRET_LETHAL 1
|
||||
|
||||
#define POPUP_ANIM_TIME 5
|
||||
#define POPDOWN_ANIM_TIME 5 //Be sure to change the icon animation at the same time or it'll look bad
|
||||
|
||||
/obj/machinery/porta_turret
|
||||
name = "turret"
|
||||
icon = 'icons/obj/turrets.dmi'
|
||||
@@ -422,7 +425,7 @@
|
||||
raising = 1
|
||||
if(cover)
|
||||
flick("popup", cover)
|
||||
sleep(10)
|
||||
sleep(POPUP_ANIM_TIME)
|
||||
raising = 0
|
||||
if(cover)
|
||||
cover.icon_state = "openTurretCover"
|
||||
@@ -438,7 +441,7 @@
|
||||
raising = 1
|
||||
if(cover)
|
||||
flick("popdown", cover)
|
||||
sleep(10)
|
||||
sleep(POPDOWN_ANIM_TIME)
|
||||
raising = 0
|
||||
if(cover)
|
||||
cover.icon_state = "turretCover"
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
var/atom/movable/AM = i
|
||||
var/obj/item/bodypart/head/as_head = AM
|
||||
var/obj/item/device/mmi/as_mmi = AM
|
||||
var/brain_holder = istype(AM, /obj/item/organ/brain) || (istype(as_head) && as_head.brain) || (istype(as_mmi) && as_mmi.brain)
|
||||
var/brain_holder = istype(AM, /obj/item/organ/brain) || (istype(as_head) && as_head.brain) || (istype(as_mmi) && as_mmi.brain) || istype(AM, /mob/living/brain)
|
||||
if(isliving(AM) || brain_holder)
|
||||
if(emagged)
|
||||
if(!brain_holder)
|
||||
|
||||
@@ -211,13 +211,13 @@
|
||||
uv = TRUE
|
||||
locked = TRUE
|
||||
update_icon()
|
||||
if(occupant)
|
||||
if(occupant)
|
||||
var/mob/living/mob_occupant = occupant
|
||||
if(uv_super)
|
||||
occupant.adjustFireLoss(rand(20, 36))
|
||||
mob_occupant.adjustFireLoss(rand(20, 36))
|
||||
else
|
||||
occupant.adjustFireLoss(rand(10, 16))
|
||||
if(iscarbon(occupant))
|
||||
occupant.emote("scream")
|
||||
mob_occupant.adjustFireLoss(rand(10, 16))
|
||||
mob_occupant.emote("scream")
|
||||
addtimer(CALLBACK(src, .proc/cook), 50)
|
||||
else
|
||||
uv_cycles = initial(uv_cycles)
|
||||
@@ -368,14 +368,15 @@
|
||||
else if(!helmet && !mask && !suit && !storage && !occupant)
|
||||
return
|
||||
else
|
||||
if(occupant)
|
||||
to_chat(occupant, "<span class='userdanger'>[src]'s confines grow warm, then hot, then scorching. You're being burned [!occupant.stat ? "alive" : "away"]!</span>")
|
||||
if(occupant)
|
||||
var/mob/living/mob_occupant = occupant
|
||||
to_chat(mob_occupant, "<span class='userdanger'>[src]'s confines grow warm, then hot, then scorching. You're being burned [!mob_occupant.stat ? "alive" : "away"]!</span>")
|
||||
cook()
|
||||
. = TRUE
|
||||
if("dispense")
|
||||
if(!state_open)
|
||||
return
|
||||
|
||||
|
||||
var/static/list/valid_items = list("helmet", "suit", "mask", "storage")
|
||||
var/item_name = params["item"]
|
||||
if(item_name in valid_items)
|
||||
|
||||
@@ -737,8 +737,8 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
|
||||
icon_state = "sustenance"
|
||||
products = list(/obj/item/weapon/reagent_containers/food/snacks/tofu = 24,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/ice = 12,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/candy_corn = 6,
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/waterbottle = 10)
|
||||
/obj/item/weapon/reagent_containers/food/snacks/candy_corn = 6,
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/waterbottle = 10)
|
||||
contraband = list(/obj/item/weapon/kitchen/knife = 6,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/coffee = 12,
|
||||
/obj/item/weapon/tank/internals/emergency_oxygen = 6,
|
||||
@@ -755,7 +755,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
|
||||
products = list(/obj/item/weapon/reagent_containers/food/drinks/soda_cans/cola = 10,/obj/item/weapon/reagent_containers/food/drinks/soda_cans/space_mountain_wind = 10,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/soda_cans/dr_gibb = 10,/obj/item/weapon/reagent_containers/food/drinks/soda_cans/starkist = 10,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/soda_cans/space_up = 10,/obj/item/weapon/reagent_containers/food/drinks/soda_cans/pwr_game = 10,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/soda_cans/lemon_lime = 10,/obj/item/weapon/reagent_containers/glass/beaker/waterbottle = 10)
|
||||
/obj/item/weapon/reagent_containers/food/drinks/soda_cans/lemon_lime = 10,/obj/item/weapon/reagent_containers/glass/beaker/waterbottle = 10)
|
||||
contraband = list(/obj/item/weapon/reagent_containers/food/drinks/soda_cans/thirteenloko = 6,/obj/item/weapon/reagent_containers/food/drinks/soda_cans/shamblers = 6)
|
||||
premium = list(/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/filled/nuka_cola = 1,/obj/item/weapon/reagent_containers/food/drinks/soda_cans/air = 1)
|
||||
refill_canister = /obj/item/weapon/vending_refill/cola
|
||||
@@ -1128,7 +1128,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
|
||||
/obj/item/clothing/head/beanie=1, /obj/item/clothing/head/beanie/black=1, /obj/item/clothing/head/beanie/red=1, /obj/item/clothing/head/beanie/green=1, /obj/item/clothing/head/beanie/darkblue=1,
|
||||
/obj/item/clothing/head/beanie/purple=1, /obj/item/clothing/head/beanie/yellow=1, /obj/item/clothing/head/beanie/orange=1, /obj/item/clothing/head/beanie/cyan=1, /obj/item/clothing/head/beanie/christmas=1,
|
||||
/obj/item/clothing/head/beanie/striped=1, /obj/item/clothing/head/beanie/stripedred=1, /obj/item/clothing/head/beanie/stripedblue=1, /obj/item/clothing/head/beanie/stripedgreen=1,
|
||||
/obj/item/clothing/suit/jacket/letterman_red=1)
|
||||
/obj/item/clothing/suit/jacket/letterman_red=1, /obj/item/clothing/head/hunter=2)
|
||||
contraband = list(/obj/item/clothing/under/syndicate/tacticool=1,/obj/item/clothing/mask/balaclava=1,/obj/item/clothing/head/ushanka=1,/obj/item/clothing/under/soviet=1,/obj/item/weapon/storage/belt/fannypack/black=2,/obj/item/clothing/suit/jacket/letterman_syndie=1,/obj/item/clothing/under/jabroni=1, /obj/item/clothing/suit/vapeshirt=1, /obj/item/clothing/under/geisha=1)
|
||||
premium = list(/obj/item/clothing/under/suit_jacket/checkered=1,/obj/item/clothing/head/mailman=1,/obj/item/clothing/under/rank/mailman=1,/obj/item/clothing/suit/jacket/leather=1,/obj/item/clothing/suit/jacket/leather/overcoat=1,/obj/item/clothing/under/pants/mustangjeans=1,/obj/item/clothing/neck/necklace/dope=3,/obj/item/clothing/suit/jacket/letterman_nanotrasen=1)
|
||||
refill_canister = /obj/item/weapon/vending_refill/clothing
|
||||
|
||||
@@ -337,8 +337,8 @@
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/proj_init(var/obj/item/weapon/grenade/flashbang/F)
|
||||
var/turf/T = get_turf(src)
|
||||
message_admins("[key_name(chassis.occupant, chassis.occupant.client)](<A HREF='?_src_=holder;adminmoreinfo=\ref[chassis.occupant]'>?</A>) fired a [src] in ([T.x],[T.y],[T.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>JMP</a>)",0,1)
|
||||
log_game("[key_name(chassis.occupant)] fired a [src] ([T.x],[T.y],[T.z])")
|
||||
message_admins("[ADMIN_LOOKUPFLW(chassis.occupant)] fired a [src] in [ADMIN_COORDJMP(T)]",0,1)
|
||||
log_game("[key_name(chassis.occupant)] fired a [src] [COORD(T)]")
|
||||
addtimer(CALLBACK(F, /obj/item/weapon/grenade/flashbang.proc/prime), det_time)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/clusterbang //Because I am a heartless bastard -Sieve //Heartless? for making the poor man's honkblast? - Kaze
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
name = "footprints"
|
||||
icon = 'icons/effects/footprints.dmi'
|
||||
icon_state = "nothingwhatsoever"
|
||||
desc = "where might they lead?"
|
||||
desc = "WHOSE FOOTPRINTS ARE THESE?"
|
||||
random_icon_states = null
|
||||
var/entered_dirs = 0
|
||||
var/exited_dirs = 0
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
/obj/effect/particle_effect/smoke/proc/spread_smoke()
|
||||
var/turf/t_loc = get_turf(src)
|
||||
if(!t_loc)
|
||||
return
|
||||
return
|
||||
var/list/newsmokes = list()
|
||||
for(var/turf/T in t_loc.GetAtmosAdjacentTurfs())
|
||||
var/obj/effect/particle_effect/smoke/foundsmoke = locate() in T //Don't spread smoke where there's already smoke!
|
||||
|
||||
@@ -611,6 +611,18 @@
|
||||
icon_state = "shieldsparkles"
|
||||
duration = 6
|
||||
|
||||
/obj/effect/overlay/temp/heart
|
||||
name = "heart"
|
||||
icon = 'icons/mob/animal.dmi'
|
||||
icon_state = "heart"
|
||||
duration = 25
|
||||
|
||||
/obj/effect/overlay/temp/heart/Initialize(mapload)
|
||||
. = ..()
|
||||
pixel_x = rand(-4,4)
|
||||
pixel_y = rand(-4,4)
|
||||
|
||||
animate(src, pixel_y = pixel_y + 32, alpha = 0, time = 25)
|
||||
|
||||
/obj/effect/overlay/palmtree_r
|
||||
name = "Palm tree"
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
return
|
||||
if (istype(M, /atom/movable))
|
||||
if(ismegafauna(M))
|
||||
message_admins("[M] (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</A>) has teleported through [src].")
|
||||
message_admins("[M] [ADMIN_FLW(M)] has teleported through [src].")
|
||||
do_teleport(M, target, precision) ///You will appear adjacent to the beacon
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
/proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1, ignorecap = 0, flame_range = 0 ,silent = 0, smoke = 1)
|
||||
/proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1, ignorecap = 0, flame_range, silent = 0, smoke = 1)
|
||||
set waitfor = 0
|
||||
src = null //so we don't abort once src is deleted
|
||||
epicenter = get_turf(epicenter)
|
||||
if(!epicenter)
|
||||
return
|
||||
|
||||
if(isnull(flame_range))
|
||||
flame_range = light_impact_range
|
||||
if(isnull(flash_range))
|
||||
flash_range = devastation_range
|
||||
|
||||
// Archive the uncapped explosion for the doppler array
|
||||
var/orig_dev_range = devastation_range
|
||||
var/orig_heavy_range = heavy_impact_range
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
desc = "An official document entrusting the governance of the station \
|
||||
and surrounding space to the Captain. "
|
||||
var/used = FALSE
|
||||
var/name_type = "station"
|
||||
|
||||
var/unlimited_uses = FALSE
|
||||
var/ignores_timeout = FALSE
|
||||
@@ -33,10 +34,10 @@
|
||||
|
||||
/obj/item/station_charter/attack_self(mob/living/user)
|
||||
if(used)
|
||||
to_chat(user, "This charter has already been used to name the station.")
|
||||
to_chat(user, "The [name_type] has already been named.")
|
||||
return
|
||||
if(!ignores_timeout && (world.time-SSticker.round_start_time > STATION_RENAME_TIME_LIMIT)) //5 minutes
|
||||
to_chat(user, "The crew has already settled into the shift. It probably wouldn't be good to rename the station right now.")
|
||||
to_chat(user, "The crew has already settled into the shift. It probably wouldn't be good to rename the [name_type] right now.")
|
||||
return
|
||||
if(response_timer_id)
|
||||
to_chat(user, "You're still waiting for approval from your employers about your proposed name change, it'd be best to wait for now.")
|
||||
@@ -60,7 +61,7 @@
|
||||
to_chat(user, "Your name has been sent to your employers for approval.")
|
||||
// Autoapproves after a certain time
|
||||
response_timer_id = addtimer(CALLBACK(src, .proc/rename_station, new_name, user.name, user.real_name, key_name(user)), approval_time, TIMER_STOPPABLE)
|
||||
to_chat(GLOB.admins, "<span class='adminnotice'><b><font color=orange>CUSTOM STATION RENAME:</font></b>[key_name_admin(user)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[user]'>?</A>) proposes to rename the station to [new_name] (will autoapprove in [approval_time / 10] seconds). [ADMIN_SMITE(user)] (<A HREF='?_src_=holder;reject_custom_name=\ref[src]'>REJECT</A>) (<a href='?_src_=holder;CentcommReply=\ref[user]'>RPLY</a>)</span>")
|
||||
to_chat(GLOB.admins, "<span class='adminnotice'><b><font color=orange>CUSTOM STATION RENAME:</font></b>[ADMIN_LOOKUPFLW(user)] proposes to rename the [name_type] to [new_name] (will autoapprove in [approval_time / 10] seconds). [ADMIN_SMITE(user)] (<A HREF='?_src_=holder;reject_custom_name=\ref[src]'>REJECT</A>) [ADMIN_CENTCOM_REPLY(user)]</span>")
|
||||
|
||||
/obj/item/station_charter/proc/reject_proposed(user)
|
||||
if(!user)
|
||||
@@ -94,4 +95,27 @@
|
||||
unlimited_uses = TRUE
|
||||
ignores_timeout = TRUE
|
||||
|
||||
|
||||
/obj/item/weapon/station_charter/flag
|
||||
name = "nanotrasen banner"
|
||||
icon = 'icons/obj/items.dmi'
|
||||
var/name_type = "planet"
|
||||
icon_state = "banner"
|
||||
item_state = "banner"
|
||||
desc = "A cunning device used to claim ownership of planets."
|
||||
w_class = 5
|
||||
force = 15
|
||||
|
||||
/obj/item/station_charter/flag/rename_station(designation, uname, ureal_name, ukey)
|
||||
set_station_name(designation)
|
||||
minor_announce("[ureal_name] has designated the planet as [station_name()]", "Captain's Banner", 0)
|
||||
log_game("[ukey] has renamed the planet as [station_name()].")
|
||||
name = "banner of [station_name()]"
|
||||
desc = "The banner bears the official coat of arms of Nanotrasen, signifying that [station_name()] has been claimed by Captain [uname] in the name of the company."
|
||||
SSblackbox.set_details("station_renames","[station_name()]")
|
||||
if(!unlimited_uses)
|
||||
used = TRUE
|
||||
|
||||
|
||||
|
||||
#undef STATION_RENAME_TIME_LIMIT
|
||||
|
||||
@@ -7,6 +7,7 @@ GLOBAL_LIST_EMPTY(GPS_list)
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
slot_flags = SLOT_BELT
|
||||
origin_tech = "materials=2;magnets=1;bluespace=2"
|
||||
unique_rename = TRUE
|
||||
var/gpstag = "COM0"
|
||||
var/emped = FALSE
|
||||
var/turf/locked_location
|
||||
@@ -135,10 +136,9 @@ GLOBAL_LIST_EMPTY(GPS_list)
|
||||
..()
|
||||
if(href_list["tag"] )
|
||||
var/a = input("Please enter desired tag.", name, gpstag) as text
|
||||
a = uppertext(copytext(sanitize(a), 1, 5))
|
||||
a = copytext(sanitize(a), 1, 20)
|
||||
if(in_range(src, usr))
|
||||
gpstag = a
|
||||
name = "global positioning system ([gpstag])"
|
||||
attack_self(usr)
|
||||
|
||||
/obj/item/device/gps/science
|
||||
|
||||
@@ -95,8 +95,8 @@
|
||||
"[user] activates \the [src]!", \
|
||||
"<span class='notice'>You activate \the [src].</span>",
|
||||
"<span class='italics'>You hear a click.</span>")
|
||||
message_admins("Power sink activated by [key_name_admin(user)](<A HREF='?_src_=holder;adminmoreinfo=\ref[user]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[user]'>FLW</A>) at ([x],[y],[z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)")
|
||||
log_game("Power sink activated by [key_name(user)] at ([x],[y],[z])")
|
||||
message_admins("Power sink activated by [ADMIN_LOOKUPFLW(user)] at [ADMIN_COORDJMP(src)]")
|
||||
log_game("Power sink activated by [key_name(user)] at [COORD(src)]")
|
||||
set_mode(OPERATING)
|
||||
|
||||
if(OPERATING)
|
||||
|
||||
@@ -296,6 +296,7 @@
|
||||
// --- Cold, emotionless machines. ---
|
||||
else if(isobj(M))
|
||||
jobname = "Machine"
|
||||
voice = capitalize(voice)
|
||||
|
||||
// --- Unidentifiable mob ---
|
||||
else
|
||||
|
||||
@@ -178,21 +178,21 @@
|
||||
|
||||
var/log_attacher = ""
|
||||
if(attacher)
|
||||
log_attacher = "(<A HREF='?_src_=holder;adminmoreinfo=\ref[attacher]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[attacher]'>FLW</A>)"
|
||||
log_attacher = "[ADMIN_QUE(attacher)] [ADMIN_FLW(attacher)]"
|
||||
|
||||
var/mob/mob = get_mob_by_key(src.fingerprintslast)
|
||||
var/last_touch_info = ""
|
||||
if(mob)
|
||||
last_touch_info = "(<A HREF='?_src_=holder;adminmoreinfo=\ref[mob]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[mob]'>FLW</A>)"
|
||||
last_touch_info = "[ADMIN_QUE(mob)] [ADMIN_FLW(mob)]"
|
||||
|
||||
var/log_str3 = " Last touched by: [key_name_admin(mob)]"
|
||||
|
||||
var/bomb_message = "[log_str1] <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[bombturf.x];Y=[bombturf.y];Z=[bombturf.z]'>[A.name]</a> [log_str2][log_attacher] [log_str3][last_touch_info]"
|
||||
var/bomb_message = "[log_str1] [A.name][ADMIN_JMP(bombturf)] [log_str2][log_attacher] [log_str3][last_touch_info]"
|
||||
|
||||
GLOB.bombers += bomb_message
|
||||
|
||||
message_admins(bomb_message, 0, 1)
|
||||
log_game("[log_str1] [A.name]([A.x],[A.y],[A.z]) [log_str2] [log_str3]")
|
||||
log_game("[log_str1] [A.name][COORD(bombturf)] [log_str2] [log_str3]")
|
||||
merge_gases()
|
||||
spawn(20) // In case one tank bursts
|
||||
for (var/i=0,i<5,i++)
|
||||
|
||||
@@ -155,8 +155,9 @@ GLOBAL_LIST_INIT(plasma_recipes, list ( \
|
||||
|
||||
/obj/item/stack/sheet/mineral/plasma/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
|
||||
if(W.is_hot() > 300)//If the temperature of the object is over 300, then ignite
|
||||
message_admins("Plasma sheets ignited by [key_name_admin(user)](<A HREF='?_src_=holder;adminmoreinfo=\ref[user]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[user]'>FLW</A>) in ([x],[y],[z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)",0,1)
|
||||
log_game("Plasma sheets ignited by [key_name(user)] in ([x],[y],[z])")
|
||||
var/turf/T = get_turf(src)
|
||||
message_admins("Plasma sheets ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_COORDJMP(T)]",0,1)
|
||||
log_game("Plasma sheets ignited by [key_name(user)] in [COORD(T)]")
|
||||
fire_act()
|
||||
else
|
||||
return ..()
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
|
||||
/obj/item/weapon/pie_cannon
|
||||
name = "pie cannon"
|
||||
desc = "Load cream pie for optimal results"
|
||||
force = 10
|
||||
icon_state = "piecannon"
|
||||
item_state = "powerfist"
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/pie/loaded = null
|
||||
|
||||
/obj/item/weapon/pie_cannon/attackby(obj/item/I, mob/living/L)
|
||||
if(istype(I, /obj/item/weapon/reagent_containers/food/snacks/pie))
|
||||
if(!loaded)
|
||||
L.transferItemToLoc(I, src)
|
||||
loaded = I
|
||||
to_chat(L, "<span class='notice'>You load the [I] into the [src]!</span>")
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/pie_cannon/afterattack(atom/target, mob/living/user, flag, params)
|
||||
if(!loaded)
|
||||
return ..()
|
||||
var/obj/item/projectile/pie/launched = new /obj/item/projectile/pie(src)
|
||||
launched.P = loaded
|
||||
loaded.forceMove(launched)
|
||||
launched.appearance = loaded.appearance
|
||||
loaded = null
|
||||
launched.preparePixelProjectile(target, get_turf(target), user, params, 0)
|
||||
launched.forceMove(get_turf(src))
|
||||
launched.fire()
|
||||
user.visible_message("<span class='danger'>[user] fires the [src] at [target]!</span>")
|
||||
|
||||
/obj/item/projectile/pie
|
||||
name = "pie"
|
||||
desc = "Think fast!"
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/pie/P = null
|
||||
|
||||
/obj/item/projectile/pie/on_hit(atom/A)
|
||||
. = ..()
|
||||
if(P)
|
||||
A.visible_message("<span class='danger'>[P] smashes into [A] at high velocity!</span>")
|
||||
P.forceMove(get_turf(A))
|
||||
P.throw_impact(A)
|
||||
if(ismovableatom(A))
|
||||
var/atom/movable/AM = A
|
||||
if(!AM.anchored)
|
||||
AM.throw_at(get_edge_target_turf(get_dir(src, AM), 3, 2))
|
||||
@@ -158,7 +158,7 @@
|
||||
if(lit)
|
||||
START_PROCESSING(SSobj, src)
|
||||
if(!warned_admins)
|
||||
message_admins("[key_name_admin(usr)]<A HREF='?_src_=holder;adminmoreinfo=\ref[usr]'>?</A> (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[usr]'>FLW</A>) has lit a flamethrower.")
|
||||
message_admins("[ADMIN_LOOKUPFLW(usr)] has lit a flamethrower.")
|
||||
warned_admins = 1
|
||||
if(href_list["amount"])
|
||||
throw_amount = throw_amount + text2num(href_list["amount"])
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
else if(clown_check(user))
|
||||
var/turf/bombturf = get_turf(src)
|
||||
var/area/A = get_area(bombturf)
|
||||
message_admins("[key_name_admin(usr)]<A HREF='?_src_=holder;adminmoreinfo=\ref[usr]'>?</A> (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[usr]'>FLW</A>) has primed a [name] for detonation at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[bombturf.x];Y=[bombturf.y];Z=[bombturf.z]'>[A.name] (JMP)</a>.")
|
||||
log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).")
|
||||
message_admins("[ADMIN_LOOKUPFLW(usr)] has primed a [name] for detonation at [A.name][ADMIN_JMP(bombturf)].")
|
||||
log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] [COORD(bombturf)].")
|
||||
to_chat(user, "<span class='warning'>You prime the [name]! [det_time / 10] second\s!</span>")
|
||||
playsound(user.loc, 'sound/weapons/armbomb.ogg', 60, 1)
|
||||
active = 1
|
||||
@@ -177,12 +177,12 @@
|
||||
var/mob/last = get_mob_by_ckey(nadeassembly.fingerprintslast)
|
||||
var/turf/T = get_turf(src)
|
||||
var/area/A = get_area(T)
|
||||
message_admins("grenade primed by an assembly, attached by [key_name_admin(M)]<A HREF='?_src_=holder;adminmoreinfo=\ref[M]'>(?)</A> (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</A>) and last touched by [key_name_admin(last)]<A HREF='?_src_=holder;adminmoreinfo=\ref[last]'>(?)</A> (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[last]'>FLW</A>) ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>[A.name] (JMP)</a>.")
|
||||
log_game("grenade primed by an assembly, attached by [key_name(M)] and last touched by [key_name(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] ([T.x], [T.y], [T.z])")
|
||||
message_admins("grenade primed by an assembly, attached by [ADMIN_LOOKUPFLW(M)] and last touched by [ADMIN_LOOKUPFLW(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] [ADMIN_JMP(T)]</a>.")
|
||||
log_game("grenade primed by an assembly, attached by [key_name(M)] and last touched by [key_name(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] [COORD(T)]")
|
||||
|
||||
var/turf/DT = get_turf(src)
|
||||
var/area/DA = get_area(DT)
|
||||
log_game("A grenade detonated at [DA.name] ([DT.x], [DT.y], [DT.z])")
|
||||
log_game("A grenade detonated at [DA.name] [COORD(DT)]")
|
||||
|
||||
update_mob()
|
||||
|
||||
|
||||
@@ -119,8 +119,8 @@
|
||||
qdel(src) //How?
|
||||
|
||||
/obj/item/weapon/grenade/plastic/suicide_act(mob/user)
|
||||
message_admins("[key_name_admin(user)](<A HREF='?_src_=holder;adminmoreinfo=\ref[user]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[user]'>FLW</A>) suicided with [src] at ([user.x],[user.y],[user.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)",0,1)
|
||||
message_admins("[key_name(user)] suicided with [src] at ([user.x],[user.y],[user.z])")
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] suicided with [src] at [ADMIN_COORDJMP(user)]",0,1)
|
||||
log_game("[key_name(user)] suicided with [src] at [COORD(user)]")
|
||||
user.visible_message("<span class='suicide'>[user] activates the [src] and holds it above [user.p_their()] head! It looks like [user.p_theyre()] going out with a bang!</span>")
|
||||
var/message_say = "FOR NO RAISIN!"
|
||||
if(user.mind)
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
active = TRUE
|
||||
var/turf/boomturf = get_turf(imp_in)
|
||||
var/area/A = get_area(boomturf)
|
||||
message_admins("[key_name_admin(imp_in)]<A HREF='?_src_=holder;adminmoreinfo=\ref[imp_in]'>?</A> (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[imp_in]'>FLW</A>) has activated their [name] at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[imp_in.x];Y=[imp_in.y];Z=[imp_in.z]'>[A.name] (JMP)</a>.")
|
||||
message_admins("[ADMIN_LOOKUPFLW(imp_in)] has activated their [name] at [A.name] [ADMIN_JMP(boomturf)].")
|
||||
//If the delay is short, just blow up already jeez
|
||||
if(delay <= 7)
|
||||
explosion(src,heavy,medium,weak,weak, flame_range = weak)
|
||||
|
||||
@@ -41,9 +41,10 @@
|
||||
data["open"] = state_open
|
||||
|
||||
data["occupant"] = list()
|
||||
if(occupant)
|
||||
data["occupant"]["name"] = occupant.name
|
||||
data["occupant"]["stat"] = occupant.stat
|
||||
if(occupant)
|
||||
var/mob/living/mob_occupant = occupant
|
||||
data["occupant"]["name"] = mob_occupant.name
|
||||
data["occupant"]["stat"] = mob_occupant.stat
|
||||
|
||||
data["special_name"] = special ? special_name : null
|
||||
data["ready_implants"] = ready_implants
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
var/brightness_on = 3
|
||||
|
||||
/obj/item/weapon/melee/energy/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
if(LAZYLEN(possible_colors))
|
||||
item_color = pick(possible_colors)
|
||||
switch(item_color)//Only run this check if the color was picked randomly, so that colors can be manually set for non-random colored energy weapons.
|
||||
@@ -183,8 +183,8 @@
|
||||
light_color = "#40ceff"
|
||||
possible_colors = null
|
||||
|
||||
/obj/item/weapon/melee/energy/sword/cyborg/saw/New()
|
||||
..()
|
||||
/obj/item/weapon/melee/energy/sword/cyborg/saw/Initialize()
|
||||
. = ..()
|
||||
icon_state = "esaw_0"
|
||||
item_color = null
|
||||
|
||||
@@ -207,19 +207,9 @@
|
||||
|
||||
|
||||
/obj/item/weapon/melee/energy/sword/saber/attackby(obj/item/weapon/W, mob/living/user, params)
|
||||
if(istype(W, /obj/item/weapon/melee/energy/sword/saber))
|
||||
to_chat(user, "<span class='notice'>You attach the ends of the two energy swords, making a single double-bladed weapon! You're cool.</span>")
|
||||
var/obj/item/weapon/melee/energy/sword/saber/other_esword = W
|
||||
var/obj/item/weapon/twohanded/dualsaber/newSaber = new(user.loc)
|
||||
if(hacked || other_esword.hacked)
|
||||
newSaber.hacked = TRUE
|
||||
newSaber.item_color = "rainbow"
|
||||
qdel(W)
|
||||
qdel(src)
|
||||
user.put_in_hands(newSaber)
|
||||
else if(istype(W, /obj/item/device/multitool))
|
||||
if(hacked == 0)
|
||||
hacked = 1
|
||||
if(istype(W, /obj/item/device/multitool))
|
||||
if(!hacked)
|
||||
hacked = TRUE
|
||||
item_color = "rainbow"
|
||||
to_chat(user, "<span class='warning'>RNBW_ENGAGE</span>")
|
||||
|
||||
@@ -253,14 +243,12 @@
|
||||
sharpness = IS_SHARP
|
||||
|
||||
//Most of the other special functions are handled in their own files. aka special snowflake code so kewl
|
||||
/obj/item/weapon/melee/energy/blade/New()
|
||||
/obj/item/weapon/melee/energy/blade/Initialize()
|
||||
. = ..()
|
||||
spark_system = new /datum/effect_system/spark_spread()
|
||||
spark_system.set_up(5, 0, src)
|
||||
spark_system.attach(src)
|
||||
|
||||
/obj/item/weapon/melee/energy/blade/dropped()
|
||||
..()
|
||||
|
||||
/obj/item/weapon/melee/energy/blade/attack_self(mob/user)
|
||||
return
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
|
||||
#define PCANNON_FIREALL 1
|
||||
#define PCANNON_FILO 2
|
||||
#define PCANNON_FIFO 3
|
||||
/obj/item/weapon/pneumatic_cannon
|
||||
name = "pneumatic cannon"
|
||||
desc = "A gas-powered cannon that can fire any object loaded into it."
|
||||
@@ -16,7 +20,15 @@
|
||||
var/gasPerThrow = 3 //How much gas is drawn from a tank's pressure to fire
|
||||
var/list/loadedItems = list() //The items loaded into the cannon that will be fired out
|
||||
var/pressureSetting = 1 //How powerful the cannon is - higher pressure = more gas but more powerful throws
|
||||
var/checktank = TRUE
|
||||
var/range_multiplier = 1
|
||||
var/throw_amount = 20 //How many items to throw per fire
|
||||
var/fire_mode = PCANNON_FIREALL
|
||||
var/automatic = FALSE
|
||||
var/clumsyCheck = TRUE
|
||||
|
||||
/obj/item/weapon/pneumatic_cannon/CanItemAutoclick()
|
||||
return automatic
|
||||
|
||||
/obj/item/weapon/pneumatic_cannon/examine(mob/user)
|
||||
..()
|
||||
@@ -30,6 +42,8 @@
|
||||
|
||||
|
||||
/obj/item/weapon/pneumatic_cannon/attackby(obj/item/weapon/W, mob/user, params)
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
return ..()
|
||||
if(istype(W, /obj/item/weapon/tank/internals))
|
||||
if(!tank)
|
||||
var/obj/item/weapon/tank/internals/IT = W
|
||||
@@ -55,19 +69,31 @@
|
||||
to_chat(user, "<span class='warning'>\The [src] can't hold any more items!</span>")
|
||||
else if(istype(W, /obj/item))
|
||||
var/obj/item/IW = W
|
||||
if((loadedWeightClass + IW.w_class) > maxWeightClass)
|
||||
to_chat(user, "<span class='warning'>\The [IW] won't fit into \the [src]!</span>")
|
||||
return
|
||||
if(IW.w_class > src.w_class)
|
||||
to_chat(user, "<span class='warning'>\The [IW] is too large to fit into \the [src]!</span>")
|
||||
return
|
||||
if(!user.transferItemToLoc(W, src))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You load \the [IW] into \the [src].</span>")
|
||||
loadedItems.Add(IW)
|
||||
loadedWeightClass += IW.w_class
|
||||
load_item(IW, user)
|
||||
|
||||
/obj/item/weapon/pneumatic_cannon/proc/can_load_item(obj/item/I, mob/user)
|
||||
if((loadedWeightClass + I.w_class) > maxWeightClass) //Only make messages if there's a user
|
||||
if(user)
|
||||
to_chat(user, "<span class='warning'>\The [I] won't fit into \the [src]!</span>")
|
||||
return FALSE
|
||||
if(I.w_class > w_class)
|
||||
if(user)
|
||||
to_chat(user, "<span class='warning'>\The [I] is too large to fit into \the [src]!</span>")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/weapon/pneumatic_cannon/proc/load_item(obj/item/I, mob/user)
|
||||
if(!can_load_item(I, user))
|
||||
return FALSE
|
||||
if(user) //Only use transfer proc if there's a user, otherwise just set loc.
|
||||
if(!user.transferItemToLoc(I, src))
|
||||
return FALSE
|
||||
to_chat(user, "<span class='notice'>You load \the [I] into \the [src].</span>")
|
||||
else
|
||||
I.forceMove(src)
|
||||
loadedItems += I
|
||||
loadedWeightClass += I.w_class
|
||||
return TRUE
|
||||
|
||||
/obj/item/weapon/pneumatic_cannon/afterattack(atom/target, mob/living/carbon/human/user, flag, params)
|
||||
if(flag && user.a_intent == INTENT_HARM) //melee attack
|
||||
@@ -76,7 +102,6 @@
|
||||
return
|
||||
Fire(user, target)
|
||||
|
||||
|
||||
/obj/item/weapon/pneumatic_cannon/proc/Fire(mob/living/carbon/human/user, var/atom/target)
|
||||
if(!istype(user) && !target)
|
||||
return
|
||||
@@ -90,13 +115,13 @@
|
||||
if(!loadedItems || !loadedWeightClass)
|
||||
to_chat(user, "<span class='warning'>\The [src] has nothing loaded.</span>")
|
||||
return
|
||||
if(!tank)
|
||||
if(!tank && checktank)
|
||||
to_chat(user, "<span class='warning'>\The [src] can't fire without a source of gas.</span>")
|
||||
return
|
||||
if(tank && !tank.air_contents.remove(gasPerThrow * pressureSetting))
|
||||
to_chat(user, "<span class='warning'>\The [src] lets out a weak hiss and doesn't react!</span>")
|
||||
return
|
||||
if(user.disabilities & CLUMSY && prob(75))
|
||||
if(user.disabilities & CLUMSY && prob(75) && clumsyCheck)
|
||||
user.visible_message("<span class='warning'>[user] loses their grip on [src], causing it to go off!</span>", "<span class='userdanger'>[src] slips out of your hands and goes off!</span>")
|
||||
user.drop_item()
|
||||
if(prob(10))
|
||||
@@ -109,17 +134,48 @@
|
||||
user.visible_message("<span class='danger'>[user] fires \the [src]!</span>", \
|
||||
"<span class='danger'>You fire \the [src]!</span>")
|
||||
add_logs(user, target, "fired at", src)
|
||||
var/turf/T = get_target(target, get_turf(src))
|
||||
playsound(src.loc, 'sound/weapons/sonic_jackhammer.ogg', 50, 1)
|
||||
for(var/obj/item/ITD in loadedItems) //Item To Discharge
|
||||
loadedItems.Remove(ITD)
|
||||
loadedWeightClass -= ITD.w_class
|
||||
ITD.throw_speed = pressureSetting * 2
|
||||
ITD.loc = get_turf(src)
|
||||
ITD.throw_at(target, pressureSetting * 5, pressureSetting * 2,user)
|
||||
fire_items(T, user)
|
||||
if(pressureSetting >= 3 && user)
|
||||
user.visible_message("<span class='warning'>[user] is thrown down by the force of the cannon!</span>", "<span class='userdanger'>[src] slams into your shoulder, knocking you down!")
|
||||
user.Weaken(3)
|
||||
|
||||
/obj/item/weapon/pneumatic_cannon/proc/fire_items(turf/target, mob/user)
|
||||
if(fire_mode == PCANNON_FIREALL)
|
||||
for(var/obj/item/ITD in loadedItems) //Item To Discharge
|
||||
if(!throw_item(target, ITD, user))
|
||||
break
|
||||
else
|
||||
for(var/i in 1 to throw_amount)
|
||||
if(!loadedItems.len)
|
||||
break
|
||||
var/obj/item/I
|
||||
if(fire_mode == PCANNON_FILO)
|
||||
I = loadedItems[loadedItems.len]
|
||||
else
|
||||
I = loadedItems[1]
|
||||
if(!throw_item(target, I, user))
|
||||
break
|
||||
|
||||
/obj/item/weapon/pneumatic_cannon/proc/throw_item(turf/target, obj/item/I, mob/user)
|
||||
if(!istype(I))
|
||||
return FALSE
|
||||
loadedItems -= I
|
||||
loadedWeightClass -= I.w_class
|
||||
I.forceMove(get_turf(src))
|
||||
I.throw_at(target, pressureSetting * 10 * range_multiplier, pressureSetting * 2, user)
|
||||
return TRUE
|
||||
|
||||
/obj/item/weapon/pneumatic_cannon/proc/get_target(turf/target, turf/starting)
|
||||
if(range_multiplier == 1)
|
||||
return target
|
||||
var/x_o = (target.x - starting.x)
|
||||
var/y_o = (target.y - starting.y)
|
||||
var/new_x = Clamp((starting.x + (x_o * range_multiplier)), 0, world.maxx)
|
||||
var/new_y = Clamp((starting.y + (y_o * range_multiplier)), 0, world.maxy)
|
||||
var/turf/newtarget = locate(new_x, new_y, starting.z)
|
||||
return newtarget
|
||||
|
||||
/obj/item/weapon/pneumatic_cannon/ghetto //Obtainable by improvised methods; more gas per use, less capacity, but smaller
|
||||
name = "improvised pneumatic cannon"
|
||||
@@ -164,3 +220,35 @@
|
||||
return
|
||||
add_overlay(tank.icon_state)
|
||||
src.update_icon()
|
||||
|
||||
/obj/item/weapon/pneumatic_cannon/proc/fill_with_type(type, amount)
|
||||
if(!ispath(type, /obj/item))
|
||||
return FALSE
|
||||
var/loaded = 0
|
||||
for(var/i in 1 to amount)
|
||||
var/obj/item/I = new type
|
||||
if(!load_item(I, null))
|
||||
qdel(I)
|
||||
return loaded
|
||||
loaded++
|
||||
CHECK_TICK
|
||||
return loaded
|
||||
|
||||
/obj/item/weapon/pneumatic_cannon/pie
|
||||
name = "pie cannon"
|
||||
desc = "Load cream pie for optimal results"
|
||||
force = 10
|
||||
icon_state = "piecannon"
|
||||
gasPerThrow = 0
|
||||
checktank = FALSE
|
||||
range_multiplier = 3
|
||||
fire_mode = PCANNON_FIFO
|
||||
throw_amount = 1
|
||||
maxWeightClass = 100 //50 pies. :^)
|
||||
clumsyCheck = FALSE
|
||||
|
||||
/obj/item/weapon/pneumatic_cannon/pie/can_load_item(obj/item/I, mob/user)
|
||||
if(istype(I, /obj/item/weapon/reagent_containers/food/snacks/pie))
|
||||
return ..()
|
||||
to_chat(user, "<span class='warning'>[src] only accepts pies!</span>")
|
||||
return FALSE
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
//////////////////////////////////
|
||||
//dakimakuras
|
||||
//////////////////////////////////
|
||||
|
||||
/obj/item/weapon/storage/daki
|
||||
name = "dakimakura"
|
||||
desc = "A large pillow depicting a girl in a compromising position. Featuring as many dimensions as you."
|
||||
icon = 'icons/obj/daki.dmi'
|
||||
icon_state = "daki_base"
|
||||
slot_flags = SLOT_BACK
|
||||
storage_slots = 3
|
||||
w_class = 4
|
||||
max_w_class = 3
|
||||
max_combined_w_class = 21
|
||||
var/cooldowntime = 20
|
||||
var/static/list/dakimakura_options = list("Callie","Casca","Chaika","Elisabeth","Foxy Grandpa","Haruko","Holo","Ian","Jolyne","Kurisu","Marie","Mugi","Nar'Sie","Patchouli","Plutia","Rei","Reisen","Naga","Squid","Squigly","Tomoko","Toriel","Umaru","Yaranaika","Yoko") //Kurisu is the ideal girl." - Me, Logos.
|
||||
|
||||
/obj/item/weapon/storage/daki/attack_self(mob/living/user)
|
||||
var/body_choice
|
||||
var/custom_name
|
||||
|
||||
if(icon_state == "daki_base")
|
||||
body_choice = input("Pick a body.") in dakimakura_options
|
||||
icon_state = "daki_[body_choice]"
|
||||
custom_name = stripped_input(user, "What's her name?")
|
||||
if(length(custom_name) > MAX_NAME_LEN)
|
||||
to_chat(user,"<span class='danger'>Name is too long!</span>")
|
||||
return FALSE
|
||||
if(custom_name)
|
||||
name = custom_name
|
||||
desc = "A large pillow depicting [custom_name] in a compromising position. Featuring as many dimensions as you."
|
||||
else
|
||||
switch(user.a_intent)
|
||||
if(INTENT_HELP)
|
||||
user.visible_message("<span class='notice'>[user] hugs the [name].</span>")
|
||||
playsound(src, "rustle", 50, 1, -5)
|
||||
if(INTENT_DISARM)
|
||||
user.visible_message("<span class='notice'>[user] kisses the [name].</span>")
|
||||
playsound(src, "rustle", 50, 1, -5)
|
||||
if(INTENT_GRAB)
|
||||
user.visible_message("<span class='warning'>[user] holds the [name]!</span>")
|
||||
playsound(src, 'sound/items/bikehorn.ogg', 50, 1)
|
||||
if(INTENT_HARM)
|
||||
user.visible_message("<span class='danger'>[user] punches the [name]!</span>")
|
||||
playsound(src, 'sound/effects/shieldbash.ogg', 50, 1)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
|
||||
////////////////////////////
|
||||
@@ -5,10 +5,6 @@
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
rustle_jimmies = FALSE
|
||||
|
||||
/obj/item/weapon/storage/internal/ClickAccessible(mob/user, depth=1)
|
||||
if(loc)
|
||||
return loc.ClickAccessible(user, depth)
|
||||
|
||||
/obj/item/weapon/storage/internal/Adjacent(A)
|
||||
if(loc)
|
||||
return loc.Adjacent(A)
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
return
|
||||
|
||||
// this must come before the screen objects only block, dunno why it wasn't before
|
||||
if(over_object == M && (src.ClickAccessible(M, depth=STORAGE_VIEW_DEPTH) || Adjacent(M)))
|
||||
if(over_object == M && M.CanReach(src,view_only = TRUE))
|
||||
orient2hud(M)
|
||||
if(M.s_active)
|
||||
M.s_active.close(M)
|
||||
|
||||
@@ -92,8 +92,7 @@
|
||||
new /obj/item/pizzabox/bomb
|
||||
|
||||
if("darklord") //20 tc + tk + summon item close enough for now
|
||||
new /obj/item/weapon/melee/energy/sword/saber(src)
|
||||
new /obj/item/weapon/melee/energy/sword/saber(src)
|
||||
new /obj/item/weapon/twohanded/dualsaber(src)
|
||||
new /obj/item/weapon/dnainjector/telemut/darkbundle(src)
|
||||
new /obj/item/clothing/suit/hooded/chaplain_hoodie(src)
|
||||
new /obj/item/weapon/card/id/syndicate(src)
|
||||
@@ -219,8 +218,8 @@
|
||||
new /obj/item/weapon/reagent_containers/glass/bottle/polonium(src)
|
||||
new /obj/item/weapon/reagent_containers/glass/bottle/venom(src)
|
||||
new /obj/item/weapon/reagent_containers/glass/bottle/neurotoxin2(src)
|
||||
new /obj/item/weapon/reagent_containers/glass/bottle/formaldehyde(src)
|
||||
new /obj/item/weapon/reagent_containers/glass/bottle/spewium(src)
|
||||
new /obj/item/weapon/reagent_containers/glass/bottle/formaldehyde(src)
|
||||
new /obj/item/weapon/reagent_containers/glass/bottle/spewium(src)
|
||||
new /obj/item/weapon/reagent_containers/glass/bottle/cyanide(src)
|
||||
new /obj/item/weapon/reagent_containers/glass/bottle/histamine(src)
|
||||
new /obj/item/weapon/reagent_containers/glass/bottle/initropidril(src)
|
||||
@@ -297,3 +296,10 @@
|
||||
/obj/item/weapon/storage/box/syndie_kit/mimery/PopulateContents()
|
||||
new /obj/item/weapon/spellbook/oneuse/mimery_blockade(src)
|
||||
new /obj/item/weapon/spellbook/oneuse/mimery_guns(src)
|
||||
|
||||
/obj/item/weapon/storage/box/syndie_kit/holoparasite
|
||||
name = "box"
|
||||
|
||||
/obj/item/weapon/storage/box/syndie_kit/holoparasite/PopulateContents()
|
||||
new /obj/item/weapon/guardiancreator/tech/choose/traitor(src)
|
||||
new /obj/item/weapon/paper/guardian(src)
|
||||
@@ -262,11 +262,11 @@
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 70)
|
||||
resistance_flags = FIRE_PROOF
|
||||
var/hacked = 0
|
||||
var/brightness_on = 6//TWICE AS BRIGHT AS A REGULAR ESWORD
|
||||
var/brightness_on = 6 //TWICE AS BRIGHT AS A REGULAR ESWORD
|
||||
var/list/possible_colors = list("red", "blue", "green", "purple")
|
||||
|
||||
/obj/item/weapon/twohanded/dualsaber/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
if(LAZYLEN(possible_colors))
|
||||
item_color = pick(possible_colors)
|
||||
switch(item_color)
|
||||
|
||||
@@ -390,7 +390,7 @@
|
||||
desc = "A chainsaw that has replaced your arm."
|
||||
icon_state = "chainsaw_on"
|
||||
item_state = "mounted_chainsaw"
|
||||
flags = NODROP | ABSTRACT
|
||||
flags = NODROP | ABSTRACT | DROPDEL
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
force = 21
|
||||
throwforce = 0
|
||||
@@ -400,10 +400,17 @@
|
||||
attack_verb = list("sawed", "torn", "cut", "chopped", "diced")
|
||||
hitsound = 'sound/weapons/chainsawhit.ogg'
|
||||
|
||||
/obj/item/weapon/mounted_chainsaw/dropped()
|
||||
..()
|
||||
/obj/item/weapon/mounted_chainsaw/Destroy()
|
||||
var/obj/item/bodypart/part
|
||||
new /obj/item/weapon/twohanded/required/chainsaw(get_turf(src))
|
||||
qdel(src)
|
||||
if(iscarbon(loc))
|
||||
var/mob/living/carbon/holder = loc
|
||||
var/index = holder.get_held_index_of_item(src)
|
||||
if(index)
|
||||
part = holder.hand_bodyparts[index]
|
||||
. = ..()
|
||||
if(part)
|
||||
part.drop_limb()
|
||||
|
||||
/obj/item/weapon/statuebust
|
||||
name = "bust"
|
||||
|
||||
@@ -106,6 +106,11 @@ LINEN BINS
|
||||
icon_state = "sheetrd"
|
||||
item_color = "director"
|
||||
|
||||
// for Free Golems.
|
||||
/obj/item/weapon/bedsheet/rd/royal_cape
|
||||
name = "Royal Cape of the Liberator"
|
||||
desc = "Majestic."
|
||||
|
||||
/obj/item/weapon/bedsheet/medical
|
||||
name = "medical blanket"
|
||||
desc = "It's a sterilized* blanket commonly used in the Medbay. *Sterilization is voided if a virologist is present onboard the station."
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
else
|
||||
new /obj/item/weapon/storage/backpack/satchel/cap(src)
|
||||
new /obj/item/clothing/neck/cloak/cap(src)
|
||||
new /obj/item/weapon/storage/daki(src)
|
||||
new /obj/item/weapon/storage/backpack/dufflebag/captain(src)
|
||||
new /obj/item/clothing/head/crown/fancy(src)
|
||||
new /obj/item/clothing/suit/captunic(src)
|
||||
|
||||
@@ -234,8 +234,9 @@
|
||||
|
||||
/obj/structure/falsewall/plasma/attackby(obj/item/weapon/W, mob/user, params)
|
||||
if(W.is_hot() > 300)
|
||||
message_admins("Plasma falsewall ignited by [key_name_admin(user)](<A HREF='?_src_=holder;adminmoreinfo=\ref[user]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[user]'>FLW</A>) in ([x],[y],[z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)",0,1)
|
||||
log_game("Plasma falsewall ignited by [key_name(user)] in ([x],[y],[z])")
|
||||
var/turf/T = get_turf(src)
|
||||
message_admins("Plasma falsewall ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_COORDJMP(T)]",0,1)
|
||||
log_game("Plasma falsewall ignited by [key_name(user)] in [COORD(T)]")
|
||||
burnbabyburn()
|
||||
else
|
||||
return ..()
|
||||
|
||||
@@ -188,8 +188,9 @@
|
||||
|
||||
/obj/structure/mineral_door/transparent/plasma/attackby(obj/item/weapon/W, mob/user, params)
|
||||
if(W.is_hot())
|
||||
message_admins("Plasma mineral door ignited by [key_name_admin(user)](<A HREF='?_src_=holder;adminmoreinfo=\ref[user]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[user]'>FLW</A>) in ([x],[y],[z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)",0,1)
|
||||
log_game("Plasma mineral door ignited by [key_name(user)] in ([x],[y],[z])")
|
||||
var/turf/T = get_turf(src)
|
||||
message_admins("Plasma mineral door ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_COORDJMP(T)]",0,1)
|
||||
log_game("Plasma mineral door ignited by [key_name(user)] in [COORD(T)]")
|
||||
TemperatureAct()
|
||||
else
|
||||
return ..()
|
||||
|
||||
@@ -163,18 +163,20 @@
|
||||
PlasmaBurn(500)
|
||||
burn = TRUE
|
||||
if(burn)
|
||||
var/turf/T = get_turf(src)
|
||||
if(Proj.firer)
|
||||
message_admins("Plasma statue ignited by [key_name_admin(Proj.firer)](<A HREF='?_src_=holder;adminmoreinfo=\ref[Proj.firer]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[Proj.firer]'>FLW</A>) in ([x],[y],[z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)",0,1)
|
||||
log_game("Plasma statue ignited by [key_name(Proj.firer)] in ([x],[y],[z])")
|
||||
message_admins("Plasma statue ignited by [ADMIN_LOOKUPFLW(Proj.firer)] in [ADMIN_COORDJMP(T)]",0,1)
|
||||
log_game("Plasma statue ignited by [key_name(Proj.firer)] in [COORD(T)]")
|
||||
else
|
||||
message_admins("Plasma statue ignited by [Proj]. No known firer.(<A HREF='?_src_=holder;adminmoreinfo=\ref[Proj.firer]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[Proj.firer]'>FLW</A>) in ([x],[y],[z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)",0,1)
|
||||
log_game("Plasma statue ignited by [Proj] in ([x],[y],[z]). No known firer.")
|
||||
message_admins("Plasma statue ignited by [Proj]. No known firer, in [ADMIN_COORDJMP(T)]",0,1)
|
||||
log_game("Plasma statue ignited by [Proj] in [COORD(T)]. No known firer.")
|
||||
..()
|
||||
|
||||
/obj/structure/statue/plasma/attackby(obj/item/weapon/W, mob/user, params)
|
||||
if(W.is_hot() > 300)//If the temperature of the object is over 300, then ignite
|
||||
message_admins("Plasma statue ignited by [key_name_admin(user)](<A HREF='?_src_=holder;adminmoreinfo=\ref[user]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[user]'>FLW</A>) in ([x],[y],[z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)",0,1)
|
||||
log_game("Plasma statue ignited by [key_name(user)] in ([x],[y],[z])")
|
||||
var/turf/T = get_turf(src)
|
||||
message_admins("Plasma statue ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_COORDJMP(T)]",0,1)
|
||||
log_game("Plasma statue ignited by [key_name(user)] in [COORD(T)]")
|
||||
ignite(W.is_hot())
|
||||
else
|
||||
return ..()
|
||||
|
||||
@@ -44,8 +44,8 @@
|
||||
|
||||
/turf/open/floor/mineral/plasma/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
|
||||
if(W.is_hot() > 300)//If the temperature of the object is over 300, then ignite
|
||||
message_admins("Plasma flooring was ignited by [key_name_admin(user)](<A HREF='?_src_=holder;adminmoreinfo=\ref[user]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[user]'>FLW</A>) in ([x],[y],[z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)",0,1)
|
||||
log_game("Plasma flooring was ignited by [key_name(user)] in ([x],[y],[z])")
|
||||
message_admins("Plasma flooring was ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_COORDJMP(src)]",0,1)
|
||||
log_game("Plasma flooring was ignited by [key_name(user)] in [COORD(src)]")
|
||||
ignite(W.is_hot())
|
||||
return
|
||||
..()
|
||||
|
||||
@@ -407,14 +407,14 @@
|
||||
if(z != 5)
|
||||
notify_admins = 1
|
||||
if(!triggered_by_explosion)
|
||||
message_admins("[key_name_admin(user)]<A HREF='?_src_=holder;adminmoreinfo=\ref[user]'>?</A> (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[user]'>FLW</A>) has triggered a gibtonite deposit reaction at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[bombturf.x];Y=[bombturf.y];Z=[bombturf.z]'>[A.name] (JMP)</a>.")
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] has triggered a gibtonite deposit reaction at [A.name] [ADMIN_JMP(bombturf)].")
|
||||
else
|
||||
message_admins("An explosion has triggered a gibtonite deposit reaction at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[bombturf.x];Y=[bombturf.y];Z=[bombturf.z]'>[A.name] (JMP)</a>.")
|
||||
message_admins("An explosion has triggered a gibtonite deposit reaction at [A.name] [ADMIN_JMP(bombturf)].")
|
||||
|
||||
if(!triggered_by_explosion)
|
||||
log_game("[key_name(user)] has triggered a gibtonite deposit reaction at [A.name] ([A.x], [A.y], [A.z]).")
|
||||
log_game("[key_name(user)] has triggered a gibtonite deposit reaction at [A.name] [ADMIN_JMP(bombturf)].")
|
||||
else
|
||||
log_game("An explosion has triggered a gibtonite deposit reaction at [A.name]([bombturf.x],[bombturf.y],[bombturf.z])")
|
||||
log_game("An explosion has triggered a gibtonite deposit reaction at [A.name] [COORD(bombturf)]")
|
||||
|
||||
countdown(notify_admins)
|
||||
|
||||
|
||||
@@ -101,8 +101,8 @@
|
||||
|
||||
/turf/closed/wall/mineral/plasma/attackby(obj/item/weapon/W, mob/user, params)
|
||||
if(W.is_hot() > 300)//If the temperature of the object is over 300, then ignite
|
||||
message_admins("Plasma wall ignited by [key_name_admin(user)](<A HREF='?_src_=holder;adminmoreinfo=\ref[user]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[user]'>FLW</A>) in ([x],[y],[z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)",0,1)
|
||||
log_game("Plasma wall ignited by [key_name(user)] in ([x],[y],[z])")
|
||||
message_admins("Plasma wall ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_COORDJMP(src)]",0,1)
|
||||
log_game("Plasma wall ignited by [key_name(user)] in [COORD(src)]")
|
||||
ignite(W.is_hot())
|
||||
return
|
||||
..()
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
icon_state = "sleeper"
|
||||
state_open = TRUE
|
||||
anchored = TRUE
|
||||
occupant_typecache = list(/mob/living/carbon/human) // turned into typecache in Initialize
|
||||
var/you_die_in_the_game_you_die_for_real = FALSE
|
||||
var/datum/effect_system/spark_spread/sparks
|
||||
var/mob/living/carbon/human/virtual_reality/vr_human
|
||||
@@ -92,11 +93,12 @@
|
||||
return
|
||||
switch(action)
|
||||
if("vr_connect")
|
||||
if(ishuman(occupant) && occupant.mind)
|
||||
var/mob/living/carbon/human/human_occupant = occupant
|
||||
if(human_occupant && human_occupant.mind)
|
||||
to_chat(occupant, "<span class='warning'>Transfering to virtual reality...</span>")
|
||||
if(vr_human)
|
||||
vr_human.revert_to_reality(FALSE, FALSE)
|
||||
occupant.mind.transfer_to(vr_human)
|
||||
human_occupant.mind.transfer_to(vr_human)
|
||||
vr_human.real_me = occupant
|
||||
to_chat(vr_human, "<span class='notice'>Transfer successful! you are now playing as [vr_human] in VR!</span>")
|
||||
SStgui.close_user_uis(vr_human, src)
|
||||
|
||||
@@ -71,16 +71,13 @@
|
||||
computerid = bancid
|
||||
ip = banip
|
||||
|
||||
var/datum/DBQuery/query_add_ban_get_id = SSdbcore.NewQuery("SELECT id FROM [format_table_name("player")] WHERE ckey = '[ckey]'")
|
||||
if(!query_add_ban_get_id.warn_execute())
|
||||
var/datum/DBQuery/query_add_ban_get_ckey = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ckey = '[ckey]'")
|
||||
if(!query_add_ban_get_ckey.warn_execute())
|
||||
return
|
||||
var/validckey = 0
|
||||
if(query_add_ban_get_id.NextRow())
|
||||
validckey = 1
|
||||
if(!validckey)
|
||||
if(!query_add_ban_get_ckey.NextRow())
|
||||
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 = ""
|
||||
|
||||
@@ -37,6 +37,11 @@
|
||||
else
|
||||
body += " \[<A href='?_src_=holder;revive=\ref[M]'>Heal</A>\] "
|
||||
|
||||
if(M.client)
|
||||
body += "<br>\[<b>First Seen:</b> [M.client.player_join_date]\]\[<b>Byond account registered on:</b> [M.client.account_join_date]\]"
|
||||
|
||||
|
||||
|
||||
body += "<br><br>\[ "
|
||||
body += "<a href='?_src_=vars;Vars=\ref[M]'>VV</a> - "
|
||||
body += "<a href='?_src_=holder;traitor=\ref[M]'>TP</a> - "
|
||||
@@ -804,7 +809,7 @@
|
||||
return 1
|
||||
|
||||
/client/proc/adminGreet(logout)
|
||||
if(SSticker.HasRoundStarted())
|
||||
if(SSticker.HasRoundStarted())
|
||||
var/string
|
||||
if(logout && config && config.announce_admin_logout)
|
||||
string = pick(
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -479,7 +479,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
|
||||
current_ticket.MessageNoRecipient(msg)
|
||||
current_ticket.TimeoutVerb()
|
||||
return
|
||||
else
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>Ticket not found, creating new one...</span>")
|
||||
else
|
||||
current_ticket.AddInteraction("[key_name_admin(usr)] opened a new ticket.")
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
diff a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm (rejected hunks)
|
||||
@@ -67,7 +67,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
|
||||
for(var/I in l2b)
|
||||
var/datum/admin_help/AH = I
|
||||
dat += "<span class='adminnotice'><span class='adminhelp'>Ticket #[AH.id]</span>: <A HREF='?_src_=holder;ahelp=\ref[AH];ahelp_action=ticket'>[AH.initiator_key_name]: [AH.name]</A></span><br>"
|
||||
-
|
||||
+
|
||||
usr << browse(dat.Join(), "window=ahelp_list[state];size=600x480")
|
||||
|
||||
//Tickets statpanel
|
||||
@@ -253,7 +253,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
|
||||
if(state == AHELP_ACTIVE)
|
||||
to_chat(usr, "<span class='warning'>This ticket is already open.</span>")
|
||||
return
|
||||
-
|
||||
+
|
||||
if(GLOB.ahelp_tickets.CKey2ActiveTicket(initiator_ckey))
|
||||
to_chat(usr, "<span class='warning'>This user already has an active ticket, cannot reopen this one.</span>")
|
||||
return
|
||||
@@ -310,7 +310,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
|
||||
RemoveActive()
|
||||
state = AHELP_RESOLVED
|
||||
GLOB.ahelp_tickets.ListInsert(src)
|
||||
-
|
||||
+
|
||||
if(initiator)
|
||||
initiator.giveadminhelpverb()
|
||||
|
||||
@@ -325,7 +325,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
|
||||
/datum/admin_help/proc/Reject(key_name = key_name_admin(usr))
|
||||
if(state != AHELP_ACTIVE)
|
||||
return
|
||||
-
|
||||
+
|
||||
if(initiator)
|
||||
initiator.giveadminhelpverb()
|
||||
|
||||
@@ -494,7 +494,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
|
||||
|
||||
if(!check_rights(R_ADMIN, TRUE))
|
||||
return
|
||||
-
|
||||
+
|
||||
var/browse_to
|
||||
|
||||
switch(input("Display which ticket list?") as null|anything in list("Active Tickets", "Closed Tickets", "Resolved Tickets"))
|
||||
@@ -506,7 +506,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
|
||||
browse_to = AHELP_RESOLVED
|
||||
else
|
||||
return
|
||||
-
|
||||
+
|
||||
GLOB.ahelp_tickets.BrowseTickets(browse_to)
|
||||
|
||||
//
|
||||
@@ -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
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
usr.client.images += preview
|
||||
if(alert(usr,"Confirm location.","Template Confirm","Yes","No") == "Yes")
|
||||
if(template.load(T, centered = TRUE))
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has placed a map template ([template.name]) at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>(JMP)</a></span>")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has placed a map template ([template.name]) at [ADMIN_COORDJMP(T)]</span>")
|
||||
else
|
||||
to_chat(usr, "Failed to place map")
|
||||
usr.client.images -= preview
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user