Merge branch 'master' into upstream-merge-26131
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
#define ANTAG_DATUM_CULT /datum/antagonist/cult
|
||||
#define ANTAG_DATUM_CLOCKCULT /datum/antagonist/clockcult
|
||||
#define ANTAG_DATUM_CLOCKCULT_SILENT /datum/antagonist/clockcult/silent
|
||||
@@ -1,2 +1,4 @@
|
||||
#define NO_STUTTER 1
|
||||
#define TONGUELESS_SPEECH 2
|
||||
#define LANGUAGE_HIDE_ICON_IF_UNDERSTOOD 4
|
||||
#define LANGUAGE_HIDE_ICON_IF_NOT_UNDERSTOOD 8
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#define MECHFAB 16 //Remember, objects utilising this flag should have construction_time and construction_cost vars.
|
||||
#define BIOGENERATOR 32 //Uses biomass
|
||||
#define LIMBGROWER 64 //Uses synthetic flesh
|
||||
#define SMELTER 128 //uses various minerals
|
||||
//Note: More then one of these can be added to a design but imprinter and lathe designs are incompatable.
|
||||
|
||||
//Modular computer/NTNet defines
|
||||
|
||||
@@ -14,5 +14,6 @@
|
||||
#define GC_QUEUED_FOR_HARD_DEL -2
|
||||
#define GC_CURRENTLY_BEING_QDELETED -3
|
||||
|
||||
#define QDELETED(X) (!X || X.gc_destroyed)
|
||||
#define QDELING(X) (X.gc_destroyed)
|
||||
#define QDELETED(X) (!X || QDELING(X))
|
||||
#define QDESTROYING(X) (!X || X.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)
|
||||
|
||||
@@ -20,6 +20,24 @@
|
||||
#define FLIGHTSUIT_PROCESSING_NONE 0
|
||||
#define FLIGHTSUIT_PROCESSING_FULL 1
|
||||
|
||||
#define INITIALIZATION_INSSATOMS 0 //New should not call Initialize
|
||||
#define INITIALIZATION_INNEW_MAPLOAD 1 //New should call Initialize(TRUE)
|
||||
#define INITIALIZATION_INNEW_REGULAR 2 //New should call Initialize(FALSE)
|
||||
|
||||
#define INITIALIZE_HINT_NORMAL 0 //Nothing happens
|
||||
#define INITIALIZE_HINT_LATELOAD 1 //Call LateInitialize
|
||||
#define INITIALIZE_HINT_QDEL 2 //Call qdel on the atom
|
||||
|
||||
//type and all subtypes should always call Initialize in New()
|
||||
#define INITIALIZE_IMMEDIATE(X) ##X/New(loc, ...){\
|
||||
..();\
|
||||
if(!initialized) {\
|
||||
args[1] = TRUE;\
|
||||
SSatoms.InitAtom(src, args);\
|
||||
}\
|
||||
}
|
||||
|
||||
|
||||
// Subsystem init_order, from highest priority to lowest priority
|
||||
// The numbers just define the ordering, they are meaningless otherwise.
|
||||
|
||||
|
||||
@@ -991,7 +991,7 @@ GLOBAL_LIST_EMPTY(friendly_animal_types)
|
||||
SET_SECONDARY_FLAG(src, FROZEN)
|
||||
|
||||
//Assumes already frozed
|
||||
obj/proc/make_unfrozen()
|
||||
/obj/proc/make_unfrozen()
|
||||
icon = initial(icon)
|
||||
name = replacetext(name, "frozen ", "")
|
||||
CLEAR_SECONDARY_FLAG(src, FROZEN)
|
||||
|
||||
@@ -582,7 +582,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
return 0
|
||||
|
||||
//Repopulates sortedAreas list
|
||||
/proc/SortAreas()
|
||||
/proc/repopulate_sorted_areas()
|
||||
GLOB.sortedAreas = list()
|
||||
|
||||
for(var/area/A in world)
|
||||
|
||||
@@ -11,6 +11,7 @@ GLOBAL_LIST_EMPTY(stealthminID) //reference list with IDs that store ckeys,
|
||||
|
||||
GLOBAL_LIST_EMPTY(player_list) //all mobs **with clients attached**. Excludes /mob/dead/new_player
|
||||
GLOBAL_LIST_EMPTY(mob_list) //all mobs, including clientless
|
||||
GLOBAL_LIST_EMPTY(mob_directory) //mob_id -> mob
|
||||
GLOBAL_LIST_EMPTY(living_mob_list) //all alive mobs, including clientless. Excludes /mob/dead/new_player
|
||||
GLOBAL_LIST_EMPTY(dead_mob_list) //all dead mobs, including clientless. Excludes /mob/dead/new_player
|
||||
GLOBAL_LIST_EMPTY(joined_player_list) //all clients that have joined the game at round-start or as a latejoin.
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
GLOBAL_LIST_INIT(ai_names, world.file2list("config/names/ai.txt"))
|
||||
GLOBAL_LIST_INIT(wizard_first, world.file2list("config/names/wizardfirst.txt"))
|
||||
GLOBAL_LIST_INIT(wizard_second, world.file2list("config/names/wizardsecond.txt"))
|
||||
GLOBAL_LIST_INIT(ninja_titles, world.file2list("config/names/ninjatitle.txt"))
|
||||
GLOBAL_LIST_INIT(ninja_names, world.file2list("config/names/ninjaname.txt"))
|
||||
GLOBAL_LIST_INIT(commando_names, world.file2list("config/names/death_commando.txt"))
|
||||
GLOBAL_LIST_INIT(first_names_male, world.file2list("config/names/first_male.txt"))
|
||||
GLOBAL_LIST_INIT(first_names_female, world.file2list("config/names/first_female.txt"))
|
||||
GLOBAL_LIST_INIT(last_names, world.file2list("config/names/last.txt"))
|
||||
GLOBAL_LIST_INIT(lizard_names_male, world.file2list("config/names/lizard_male.txt"))
|
||||
GLOBAL_LIST_INIT(lizard_names_female, world.file2list("config/names/lizard_female.txt"))
|
||||
GLOBAL_LIST_INIT(clown_names, world.file2list("config/names/clown.txt"))
|
||||
GLOBAL_LIST_INIT(mime_names, world.file2list("config/names/mime.txt"))
|
||||
GLOBAL_LIST_INIT(carp_names, world.file2list("config/names/carp.txt"))
|
||||
GLOBAL_LIST_INIT(golem_names, world.file2list("config/names/golem.txt"))
|
||||
GLOBAL_LIST_INIT(plasmaman_names, world.file2list("config/names/plasmaman.txt"))
|
||||
GLOBAL_LIST_INIT(posibrain_names, list("PBU","HIU","SINA","ARMA","OSI","HBL","MSO","RR","CHRI","CDB","HG","XSI","ORNG","GUN","KOR","MET","FRE","XIS","SLI","PKP","HOG","RZH","GOOF","MRPR","JJR","FIRC","INC","PHL","BGB","ANTR","MIW","WJ","JRD","CHOC","ANCL","JLLO","JNLG","KOS","TKRG","XAL","STLP","CBOS","DUNC","FXMC","DRSD","COI"))
|
||||
GLOBAL_LIST_INIT(ai_names, world.file2list("strings/names/ai.txt"))
|
||||
GLOBAL_LIST_INIT(wizard_first, world.file2list("strings/names/wizardfirst.txt"))
|
||||
GLOBAL_LIST_INIT(wizard_second, world.file2list("strings/names/wizardsecond.txt"))
|
||||
GLOBAL_LIST_INIT(ninja_titles, world.file2list("strings/names/ninjatitle.txt"))
|
||||
GLOBAL_LIST_INIT(ninja_names, world.file2list("strings/names/ninjaname.txt"))
|
||||
GLOBAL_LIST_INIT(commando_names, world.file2list("strings/names/death_commando.txt"))
|
||||
GLOBAL_LIST_INIT(first_names_male, world.file2list("strings/names/first_male.txt"))
|
||||
GLOBAL_LIST_INIT(first_names_female, world.file2list("strings/names/first_female.txt"))
|
||||
GLOBAL_LIST_INIT(last_names, world.file2list("strings/names/last.txt"))
|
||||
GLOBAL_LIST_INIT(lizard_names_male, world.file2list("strings/names/lizard_male.txt"))
|
||||
GLOBAL_LIST_INIT(lizard_names_female, world.file2list("strings/names/lizard_female.txt"))
|
||||
GLOBAL_LIST_INIT(clown_names, world.file2list("strings/names/clown.txt"))
|
||||
GLOBAL_LIST_INIT(mime_names, world.file2list("strings/names/mime.txt"))
|
||||
GLOBAL_LIST_INIT(carp_names, world.file2list("strings/names/carp.txt"))
|
||||
GLOBAL_LIST_INIT(golem_names, world.file2list("strings/names/golem.txt"))
|
||||
GLOBAL_LIST_INIT(plasmaman_names, world.file2list("strings/names/plasmaman.txt"))
|
||||
GLOBAL_LIST_INIT(posibrain_names, world.file2list("strings/names/posibrain.txt"))
|
||||
|
||||
|
||||
GLOBAL_LIST_INIT(verbs, world.file2list("config/names/verbs.txt"))
|
||||
GLOBAL_LIST_INIT(adjectives, world.file2list("config/names/adjectives.txt"))
|
||||
GLOBAL_LIST_INIT(verbs, world.file2list("strings/names/verbs.txt"))
|
||||
GLOBAL_LIST_INIT(adjectives, world.file2list("strings/names/adjectives.txt"))
|
||||
//loaded on startup because of "
|
||||
//would include in rsc if ' was used
|
||||
|
||||
@@ -544,7 +544,7 @@
|
||||
plane = SPLASHSCREEN_PLANE
|
||||
var/client/holder
|
||||
|
||||
/obj/screen/splash/New(client/C, visible, use_previous_title)
|
||||
/obj/screen/splash/New(client/C, visible, use_previous_title) //TODO: Make this use INITIALIZE_IMMEDIATE
|
||||
holder = C
|
||||
|
||||
if(!visible)
|
||||
|
||||
@@ -117,7 +117,7 @@ GLOBAL_VAR_INIT(dlooc_allowed, 1)
|
||||
prefs.chat_toggles ^= CHAT_LOOC
|
||||
prefs.save_preferences()
|
||||
src << "You will [(prefs.chat_toggles & CHAT_LOOC) ? "now" : "no longer"] see messages on the LOOC channel."
|
||||
feedback_add_details("admin_verb","TLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
SSblackbox.add_details("admin_verb","TLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/datum/admins/proc/togglelooc()
|
||||
set category = "Server"
|
||||
@@ -126,7 +126,7 @@ GLOBAL_VAR_INIT(dlooc_allowed, 1)
|
||||
toggle_looc()
|
||||
log_admin("[key_name(usr)] toggled LOOC.")
|
||||
message_admins("[key_name_admin(usr)] toggled LOOC.")
|
||||
feedback_add_details("admin_verb","TLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
SSblackbox.add_details("admin_verb","TLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/proc/toggle_looc(toggle = null)
|
||||
if(toggle != null) //if we're specifically en/disabling ooc
|
||||
@@ -146,7 +146,7 @@ GLOBAL_VAR_INIT(dlooc_allowed, 1)
|
||||
|
||||
log_admin("[key_name(usr)] toggled Dead LOOC.")
|
||||
message_admins("[key_name_admin(usr)] toggled Dead LOOC.")
|
||||
feedback_add_details("admin_verb","TDLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
SSblackbox.add_details("admin_verb","TDLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
|
||||
/mob/living/carbon/proc/has_penis()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/obj/item/weapon/gun/energy/laser/carbine
|
||||
name = "laser carbine"
|
||||
desc = "A ruggedized laser carbine featuring much higher capacity and improved handling when compared to a normal laser gun."
|
||||
icon = 'icons/obj/guns/cit_guns.dmi'
|
||||
icon_state = "lasernew"
|
||||
item_state = "laser"
|
||||
origin_tech = "combat=4;magnets=4"
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
|
||||
refill_canister = /obj/item/weapon/vending_refill/soviet
|
||||
|
||||
|
||||
#undef STANDARD_CHARGE
|
||||
#undef CONTRABAND_CHARGE
|
||||
#undef COIN_CHARGE
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
/obj/item/organ/genital/Initialize()
|
||||
. = ..()
|
||||
reagents = create_reagents(fluid_max_volume)
|
||||
if(!reagents)
|
||||
create_reagents(fluid_max_volume)
|
||||
update()
|
||||
|
||||
/obj/item/organ/genital/Destroy()
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
name = "Initializing..."
|
||||
var/target
|
||||
|
||||
/obj/effect/statclick/New(loc, text, target) //Don't port this to Initialize it's too critical
|
||||
INITIALIZE_IMMEDIATE(/obj/effect/statclick)
|
||||
|
||||
/obj/effect/statclick/Initialize(mapload, text, target) //Don't port this to Initialize it's too critical
|
||||
..()
|
||||
name = text
|
||||
src.target = target
|
||||
@@ -43,9 +45,9 @@
|
||||
switch(controller)
|
||||
if("Master")
|
||||
Recreate_MC()
|
||||
feedback_add_details("admin_verb","Restart Master Controller")
|
||||
SSblackbox.add_details("admin_verb","Restart Master Controller")
|
||||
if("Failsafe")
|
||||
new /datum/controller/failsafe()
|
||||
feedback_add_details("admin_verb","Restart Failsafe Controller")
|
||||
SSblackbox.add_details("admin_verb","Restart Failsafe Controller")
|
||||
|
||||
message_admins("Admin [key_name_admin(usr)] has restarted the [controller] controller.")
|
||||
|
||||
@@ -16,13 +16,14 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars)
|
||||
gvars_datum_in_built_vars = exclude_these.vars + list("gvars_datum_protected_varlist", "gvars_datum_in_built_vars", "gvars_datum_init_order")
|
||||
qdel(exclude_these)
|
||||
|
||||
log_world("[vars.len - gvars_datum_in_built_vars.len] global variables")
|
||||
|
||||
Initialize()
|
||||
|
||||
/datum/controller/global_vars/Destroy(force)
|
||||
stack_trace("Some fucker qdel'd the global holder!")
|
||||
if(!force)
|
||||
return QDEL_HINT_LETMELIVE
|
||||
|
||||
stack_trace("Some fucker deleted the global holder!")
|
||||
|
||||
QDEL_NULL(statclick)
|
||||
gvars_datum_protected_varlist.Cut()
|
||||
@@ -36,10 +37,7 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars)
|
||||
if(!statclick)
|
||||
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
|
||||
|
||||
var/static/num_globals
|
||||
if(!num_globals)
|
||||
num_globals = vars.len - gvars_datum_in_built_vars.len
|
||||
stat("Globals:", statclick.update("Count: [num_globals]"))
|
||||
stat("Globals:", statclick.update("Edit"))
|
||||
|
||||
/datum/controller/global_vars/can_vv_get(var_name)
|
||||
if(var_name in gvars_datum_protected_varlist)
|
||||
|
||||
+157
-110
@@ -1,111 +1,158 @@
|
||||
#define INITIALIZATION_INSSATOMS 0 //New should not call Initialize
|
||||
#define INITIALIZATION_INNEW_MAPLOAD 1 //New should call Initialize(TRUE)
|
||||
#define INITIALIZATION_INNEW_REGULAR 2 //New should call Initialize(FALSE)
|
||||
|
||||
SUBSYSTEM_DEF(atoms)
|
||||
name = "Atoms"
|
||||
#define BAD_INIT_QDEL_BEFORE 1
|
||||
#define BAD_INIT_DIDNT_INIT 2
|
||||
#define BAD_INIT_SLEPT 4
|
||||
#define BAD_INIT_NO_HINT 8
|
||||
|
||||
SUBSYSTEM_DEF(atoms)
|
||||
name = "Atoms"
|
||||
init_order = INIT_ORDER_ATOMS
|
||||
flags = SS_NO_FIRE
|
||||
|
||||
var/initialized = INITIALIZATION_INSSATOMS
|
||||
var/old_initialized
|
||||
|
||||
var/list/late_loaders
|
||||
|
||||
/datum/controller/subsystem/atoms/Initialize(timeofday)
|
||||
GLOB.fire_overlay.appearance_flags = RESET_COLOR
|
||||
setupGenetics() //to set the mutations' place in structural enzymes, so monkey.initialize() knows where to put the monkey mutation.
|
||||
initialized = INITIALIZATION_INNEW_MAPLOAD
|
||||
InitializeAtoms()
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/atoms/proc/InitializeAtoms(list/atoms = null)
|
||||
if(initialized == INITIALIZATION_INSSATOMS)
|
||||
return
|
||||
|
||||
initialized = INITIALIZATION_INNEW_MAPLOAD
|
||||
|
||||
var/static/list/NewQdelList = list()
|
||||
|
||||
if(atoms)
|
||||
for(var/I in atoms)
|
||||
var/atom/A = I
|
||||
if(!A.initialized) //this check is to make sure we don't call it twice on an object that was created in a previous Initialize call
|
||||
if(QDELETED(A))
|
||||
if(!(NewQdelList[A.type]))
|
||||
WARNING("Found new qdeletion in type [A.type]!")
|
||||
NewQdelList[A.type] = TRUE
|
||||
continue
|
||||
var/start_tick = world.time
|
||||
if(A.Initialize(TRUE))
|
||||
LAZYADD(late_loaders, A)
|
||||
if(start_tick != world.time)
|
||||
WARNING("[A]: [A.type] slept during it's Initialize!")
|
||||
CHECK_TICK
|
||||
testing("Initialized [atoms.len] atoms")
|
||||
else
|
||||
#ifdef TESTING
|
||||
var/count = 0
|
||||
#endif
|
||||
for(var/atom/A in world)
|
||||
if(!A.initialized) //this check is to make sure we don't call it twice on an object that was created in a previous Initialize call
|
||||
if(QDELETED(A))
|
||||
if(!(NewQdelList[A.type]))
|
||||
WARNING("Found new qdeletion in type [A.type]!")
|
||||
NewQdelList[A.type] = TRUE
|
||||
continue
|
||||
var/start_tick = world.time
|
||||
if(A.Initialize(TRUE))
|
||||
LAZYADD(late_loaders, A)
|
||||
#ifdef TESTING
|
||||
else
|
||||
++count
|
||||
#endif TESTING
|
||||
if(start_tick != world.time)
|
||||
WARNING("[A]: [A.type] slept during it's Initialize!")
|
||||
CHECK_TICK
|
||||
testing("Roundstart initialized [count] atoms")
|
||||
|
||||
initialized = INITIALIZATION_INNEW_REGULAR
|
||||
|
||||
for(var/I in late_loaders)
|
||||
var/atom/A = I
|
||||
var/start_tick = world.time
|
||||
A.Initialize(FALSE)
|
||||
if(start_tick != world.time)
|
||||
WARNING("[A]: [A.type] slept during it's Initialize!")
|
||||
CHECK_TICK
|
||||
testing("Late-initialized [LAZYLEN(late_loaders)] atoms")
|
||||
LAZYCLEARLIST(late_loaders)
|
||||
|
||||
/datum/controller/subsystem/atoms/proc/map_loader_begin()
|
||||
old_initialized = initialized
|
||||
initialized = INITIALIZATION_INSSATOMS
|
||||
|
||||
/datum/controller/subsystem/atoms/proc/map_loader_stop()
|
||||
initialized = old_initialized
|
||||
|
||||
/datum/controller/subsystem/atoms/Recover()
|
||||
initialized = SSatoms.initialized
|
||||
if(initialized == INITIALIZATION_INNEW_MAPLOAD)
|
||||
InitializeAtoms()
|
||||
old_initialized = SSatoms.old_initialized
|
||||
|
||||
/datum/controller/subsystem/atoms/proc/setupGenetics()
|
||||
var/list/avnums = new /list(DNA_STRUC_ENZYMES_BLOCKS)
|
||||
for(var/i=1, i<=DNA_STRUC_ENZYMES_BLOCKS, i++)
|
||||
avnums[i] = i
|
||||
CHECK_TICK
|
||||
|
||||
for(var/A in subtypesof(/datum/mutation/human))
|
||||
var/datum/mutation/human/B = new A()
|
||||
if(B.dna_block == NON_SCANNABLE)
|
||||
continue
|
||||
B.dna_block = pick_n_take(avnums)
|
||||
if(B.quality == POSITIVE)
|
||||
GLOB.good_mutations |= B
|
||||
else if(B.quality == NEGATIVE)
|
||||
GLOB.bad_mutations |= B
|
||||
else if(B.quality == MINOR_NEGATIVE)
|
||||
GLOB.not_good_mutations |= B
|
||||
CHECK_TICK
|
||||
flags = SS_NO_FIRE
|
||||
|
||||
var/initialized = INITIALIZATION_INSSATOMS
|
||||
var/old_initialized
|
||||
|
||||
var/list/late_loaders
|
||||
var/list/created_atoms
|
||||
|
||||
var/list/BadInitializeCalls = list()
|
||||
|
||||
/datum/controller/subsystem/atoms/Initialize(timeofday)
|
||||
GLOB.fire_overlay.appearance_flags = RESET_COLOR
|
||||
setupGenetics() //to set the mutations' place in structural enzymes, so monkey.initialize() knows where to put the monkey mutation.
|
||||
initialized = INITIALIZATION_INNEW_MAPLOAD
|
||||
InitializeAtoms()
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/atoms/proc/InitializeAtoms(list/atoms)
|
||||
if(initialized == INITIALIZATION_INSSATOMS)
|
||||
return
|
||||
|
||||
initialized = INITIALIZATION_INNEW_MAPLOAD
|
||||
|
||||
LAZYINITLIST(late_loaders)
|
||||
|
||||
var/count
|
||||
var/list/mapload_arg = list(TRUE)
|
||||
if(atoms)
|
||||
created_atoms = list()
|
||||
count = atoms.len
|
||||
for(var/I in atoms)
|
||||
var/atom/A = I
|
||||
if(!A.initialized)
|
||||
if(InitAtom(I, mapload_arg))
|
||||
atoms -= I
|
||||
CHECK_TICK
|
||||
else
|
||||
count = 0
|
||||
for(var/atom/A in world)
|
||||
if(!A.initialized)
|
||||
InitAtom(A, mapload_arg)
|
||||
++count
|
||||
CHECK_TICK
|
||||
|
||||
log_world("Initialized [count] atoms")
|
||||
|
||||
initialized = INITIALIZATION_INNEW_REGULAR
|
||||
|
||||
if(late_loaders.len)
|
||||
for(var/I in late_loaders)
|
||||
var/atom/A = I
|
||||
A.LateInitialize()
|
||||
testing("Late initialized [late_loaders.len] atoms")
|
||||
late_loaders.Cut()
|
||||
|
||||
if(atoms)
|
||||
. = created_atoms + atoms
|
||||
created_atoms = null
|
||||
|
||||
/datum/controller/subsystem/atoms/proc/InitAtom(atom/A, list/arguments)
|
||||
var/the_type = A.type
|
||||
if(QDELING(A))
|
||||
BadInitializeCalls[the_type] |= BAD_INIT_QDEL_BEFORE
|
||||
return TRUE
|
||||
|
||||
var/start_tick = world.time
|
||||
|
||||
var/result = A.Initialize(arglist(arguments))
|
||||
|
||||
if(start_tick != world.time)
|
||||
BadInitializeCalls[the_type] |= BAD_INIT_SLEPT
|
||||
|
||||
var/qdeleted = FALSE
|
||||
|
||||
if(result != INITIALIZE_HINT_NORMAL)
|
||||
switch(result)
|
||||
if(INITIALIZE_HINT_LATELOAD)
|
||||
if(arguments[1]) //mapload
|
||||
late_loaders += A
|
||||
else
|
||||
A.LateInitialize()
|
||||
if(INITIALIZE_HINT_QDEL)
|
||||
qdel(A)
|
||||
qdeleted = TRUE
|
||||
else
|
||||
BadInitializeCalls[the_type] |= BAD_INIT_NO_HINT
|
||||
|
||||
if(!A) //possible harddel
|
||||
qdeleted = TRUE
|
||||
else if(!A.initialized)
|
||||
BadInitializeCalls[the_type] |= BAD_INIT_DIDNT_INIT
|
||||
|
||||
return qdeleted || QDELETED(A)
|
||||
|
||||
/datum/controller/subsystem/atoms/proc/map_loader_begin()
|
||||
old_initialized = initialized
|
||||
initialized = INITIALIZATION_INSSATOMS
|
||||
|
||||
/datum/controller/subsystem/atoms/proc/map_loader_stop()
|
||||
initialized = old_initialized
|
||||
|
||||
/datum/controller/subsystem/atoms/Recover()
|
||||
initialized = SSatoms.initialized
|
||||
if(initialized == INITIALIZATION_INNEW_MAPLOAD)
|
||||
InitializeAtoms()
|
||||
old_initialized = SSatoms.old_initialized
|
||||
BadInitializeCalls = SSatoms.BadInitializeCalls
|
||||
|
||||
/datum/controller/subsystem/atoms/proc/setupGenetics()
|
||||
var/list/avnums = new /list(DNA_STRUC_ENZYMES_BLOCKS)
|
||||
for(var/i=1, i<=DNA_STRUC_ENZYMES_BLOCKS, i++)
|
||||
avnums[i] = i
|
||||
CHECK_TICK
|
||||
|
||||
for(var/A in subtypesof(/datum/mutation/human))
|
||||
var/datum/mutation/human/B = new A()
|
||||
if(B.dna_block == NON_SCANNABLE)
|
||||
continue
|
||||
B.dna_block = pick_n_take(avnums)
|
||||
if(B.quality == POSITIVE)
|
||||
GLOB.good_mutations |= B
|
||||
else if(B.quality == NEGATIVE)
|
||||
GLOB.bad_mutations |= B
|
||||
else if(B.quality == MINOR_NEGATIVE)
|
||||
GLOB.not_good_mutations |= B
|
||||
CHECK_TICK
|
||||
|
||||
/datum/controller/subsystem/atoms/proc/InitLog()
|
||||
. = ""
|
||||
for(var/path in BadInitializeCalls)
|
||||
. += "Path : [path] \n"
|
||||
var/fails = BadInitializeCalls[path]
|
||||
if(fails & BAD_INIT_DIDNT_INIT)
|
||||
. += "- Didn't call atom/Initialize()\n"
|
||||
if(fails & BAD_INIT_NO_HINT)
|
||||
. += "- Didn't return an Initialize hint\n"
|
||||
if(fails & BAD_INIT_QDEL_BEFORE)
|
||||
. += "- Qdel'd in New()\n"
|
||||
if(fails & BAD_INIT_SLEPT)
|
||||
. += "- Slept during Initialize()\n"
|
||||
|
||||
/datum/controller/subsystem/atoms/Shutdown()
|
||||
var/initlog = InitLog()
|
||||
if(initlog)
|
||||
log_world(initlog)
|
||||
|
||||
#undef BAD_INIT_QDEL_BEFORE
|
||||
#undef BAD_INIT_DIDNT_INIT
|
||||
#undef BAD_INIT_SLEPT
|
||||
#undef BAD_INIT_NO_HINT
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
GLOBAL_DATUM_INIT(blackbox, /datum/feedback, new)
|
||||
|
||||
//the feedback datum; stores all feedback
|
||||
/datum/feedback
|
||||
var/list/messages = list()
|
||||
var/list/messages_admin = list()
|
||||
SUBSYSTEM_DEF(blackbox)
|
||||
name = "Blackbox"
|
||||
wait = 6000
|
||||
flags = SS_NO_TICK_CHECK
|
||||
|
||||
var/list/msg_common = list()
|
||||
var/list/msg_science = list()
|
||||
@@ -15,21 +13,47 @@ GLOBAL_DATUM_INIT(blackbox, /datum/feedback, new)
|
||||
var/list/msg_syndicate = list()
|
||||
var/list/msg_service = list()
|
||||
var/list/msg_cargo = list()
|
||||
var/list/msg_other = list()
|
||||
|
||||
var/list/datum/feedback_variable/feedback = new()
|
||||
var/list/feedback = list() //list of datum/feedback_variable
|
||||
|
||||
/datum/feedback/proc/find_feedback_datum(variable)
|
||||
for (var/datum/feedback_variable/FV in feedback)
|
||||
if (FV.get_variable() == variable)
|
||||
return FV
|
||||
var/datum/feedback_variable/FV = new(variable)
|
||||
feedback += FV
|
||||
return FV
|
||||
//poll population
|
||||
/datum/controller/subsystem/blackbox/fire()
|
||||
if(!SSdbcore.Connect())
|
||||
return
|
||||
var/playercount = 0
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(M.client)
|
||||
playercount += 1
|
||||
var/admincount = GLOB.admins.len
|
||||
var/datum/DBQuery/query_record_playercount = SSdbcore.NewQuery("INSERT INTO [format_table_name("legacy_population")] (playercount, admincount, time, server_ip, server_port) VALUES ([playercount], [admincount], '[SQLtime()]', INET_ATON('[world.internet_address]'), '[world.port]')")
|
||||
query_record_playercount.Execute()
|
||||
|
||||
/datum/feedback/proc/get_round_feedback()
|
||||
return feedback
|
||||
/datum/controller/subsystem/blackbox/Recover()
|
||||
msg_common = SSblackbox.msg_common
|
||||
msg_science = SSblackbox.msg_science
|
||||
msg_command = SSblackbox.msg_command
|
||||
msg_medical = SSblackbox.msg_medical
|
||||
msg_engineering = SSblackbox.msg_engineering
|
||||
msg_security = SSblackbox.msg_security
|
||||
msg_deathsquad = SSblackbox.msg_deathsquad
|
||||
msg_syndicate = SSblackbox.msg_syndicate
|
||||
msg_service = SSblackbox.msg_service
|
||||
msg_cargo = SSblackbox.msg_cargo
|
||||
msg_other = SSblackbox.msg_other
|
||||
|
||||
/datum/feedback/proc/round_end_data_gathering()
|
||||
feedback = SSblackbox.feedback
|
||||
|
||||
//no touchie
|
||||
/datum/controller/subsystem/blackbox/can_vv_get(var_name)
|
||||
if(var_name == "feedback")
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/blackbox/vv_edit_var(var_name, var_value)
|
||||
return FALSE
|
||||
|
||||
/datum/controller/subsystem/blackbox/Shutdown()
|
||||
var/pda_msg_amt = 0
|
||||
var/rc_msg_amt = 0
|
||||
|
||||
@@ -39,30 +63,27 @@ GLOBAL_DATUM_INIT(blackbox, /datum/feedback, new)
|
||||
if (MS.rc_msgs.len > rc_msg_amt)
|
||||
rc_msg_amt = MS.rc_msgs.len
|
||||
|
||||
feedback_set_details("radio_usage","")
|
||||
set_details("radio_usage","")
|
||||
|
||||
feedback_add_details("radio_usage","COM-[msg_common.len]")
|
||||
feedback_add_details("radio_usage","SCI-[msg_science.len]")
|
||||
feedback_add_details("radio_usage","HEA-[msg_command.len]")
|
||||
feedback_add_details("radio_usage","MED-[msg_medical.len]")
|
||||
feedback_add_details("radio_usage","ENG-[msg_engineering.len]")
|
||||
feedback_add_details("radio_usage","SEC-[msg_security.len]")
|
||||
feedback_add_details("radio_usage","DTH-[msg_deathsquad.len]")
|
||||
feedback_add_details("radio_usage","SYN-[msg_syndicate.len]")
|
||||
feedback_add_details("radio_usage","SRV-[msg_service.len]")
|
||||
feedback_add_details("radio_usage","CAR-[msg_cargo.len]")
|
||||
feedback_add_details("radio_usage","OTH-[messages.len]")
|
||||
feedback_add_details("radio_usage","PDA-[pda_msg_amt]")
|
||||
feedback_add_details("radio_usage","RC-[rc_msg_amt]")
|
||||
add_details("radio_usage","COM-[msg_common.len]")
|
||||
add_details("radio_usage","SCI-[msg_science.len]")
|
||||
add_details("radio_usage","HEA-[msg_command.len]")
|
||||
add_details("radio_usage","MED-[msg_medical.len]")
|
||||
add_details("radio_usage","ENG-[msg_engineering.len]")
|
||||
add_details("radio_usage","SEC-[msg_security.len]")
|
||||
add_details("radio_usage","DTH-[msg_deathsquad.len]")
|
||||
add_details("radio_usage","SYN-[msg_syndicate.len]")
|
||||
add_details("radio_usage","SRV-[msg_service.len]")
|
||||
add_details("radio_usage","CAR-[msg_cargo.len]")
|
||||
add_details("radio_usage","OTH-[msg_other.len]")
|
||||
add_details("radio_usage","PDA-[pda_msg_amt]")
|
||||
add_details("radio_usage","RC-[rc_msg_amt]")
|
||||
|
||||
feedback_set_details("round_end","[time2text(world.realtime)]") //This one MUST be the last one that gets set.
|
||||
set_details("round_end","[time2text(world.realtime)]") //This one MUST be the last one that gets set.
|
||||
|
||||
//This proc is only to be called at round end.
|
||||
/datum/feedback/proc/save_all_data_to_sql()
|
||||
if (!feedback) return
|
||||
if (!SSdbcore.Connect())
|
||||
return
|
||||
|
||||
round_end_data_gathering() //round_end time logging and some other data processing
|
||||
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")]")
|
||||
@@ -89,69 +110,99 @@ GLOBAL_DATUM_INIT(blackbox, /datum/feedback, new)
|
||||
var/datum/DBQuery/query_feedback_save = SSdbcore.NewQuery("INSERT DELAYED IGNORE INTO [format_table_name("feedback")] VALUES " + sqlrowlist)
|
||||
query_feedback_save.Execute()
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/LogBroadcast(blackbox_msg, freq)
|
||||
switch(freq)
|
||||
if(1459)
|
||||
msg_common += blackbox_msg
|
||||
if(1351)
|
||||
msg_science += blackbox_msg
|
||||
if(1353)
|
||||
msg_command += blackbox_msg
|
||||
if(1355)
|
||||
msg_medical += blackbox_msg
|
||||
if(1357)
|
||||
msg_engineering += blackbox_msg
|
||||
if(1359)
|
||||
msg_security += blackbox_msg
|
||||
if(1441)
|
||||
msg_deathsquad += blackbox_msg
|
||||
if(1213)
|
||||
msg_syndicate += blackbox_msg
|
||||
if(1349)
|
||||
msg_service += blackbox_msg
|
||||
if(1347)
|
||||
msg_cargo += blackbox_msg
|
||||
else
|
||||
msg_other += blackbox_msg
|
||||
|
||||
/proc/feedback_set(variable,value)
|
||||
if(!GLOB.blackbox)
|
||||
return
|
||||
/datum/controller/subsystem/blackbox/proc/find_feedback_datum(variable)
|
||||
for(var/datum/feedback_variable/FV in feedback)
|
||||
if(FV.get_variable() == variable)
|
||||
return FV
|
||||
|
||||
var/datum/feedback_variable/FV = GLOB.blackbox.find_feedback_datum(variable)
|
||||
|
||||
if(!FV)
|
||||
return
|
||||
var/datum/feedback_variable/FV = new(variable)
|
||||
feedback += FV
|
||||
return FV
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/set_val(variable, value)
|
||||
var/datum/feedback_variable/FV = find_feedback_datum(variable)
|
||||
FV.set_value(value)
|
||||
|
||||
/proc/feedback_inc(variable,value)
|
||||
if(!GLOB.blackbox)
|
||||
return
|
||||
|
||||
var/datum/feedback_variable/FV = GLOB.blackbox.find_feedback_datum(variable)
|
||||
|
||||
if(!FV)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/inc(variable, value)
|
||||
var/datum/feedback_variable/FV = find_feedback_datum(variable)
|
||||
FV.inc(value)
|
||||
|
||||
/proc/feedback_dec(variable,value)
|
||||
if(!GLOB.blackbox)
|
||||
return
|
||||
|
||||
var/datum/feedback_variable/FV = GLOB.blackbox.find_feedback_datum(variable)
|
||||
|
||||
if(!FV)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/dec(variable,value)
|
||||
var/datum/feedback_variable/FV = find_feedback_datum(variable)
|
||||
FV.dec(value)
|
||||
|
||||
/proc/feedback_set_details(variable,details)
|
||||
if(!GLOB.blackbox)
|
||||
return
|
||||
|
||||
var/datum/feedback_variable/FV = GLOB.blackbox.find_feedback_datum(variable)
|
||||
|
||||
if(!FV)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/set_details(variable,details)
|
||||
var/datum/feedback_variable/FV = find_feedback_datum(variable)
|
||||
FV.set_details(details)
|
||||
|
||||
/proc/feedback_add_details(variable,details)
|
||||
if(!GLOB.blackbox)
|
||||
return
|
||||
|
||||
var/datum/feedback_variable/FV = GLOB.blackbox.find_feedback_datum(variable)
|
||||
|
||||
if(!FV)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/add_details(variable,details)
|
||||
var/datum/feedback_variable/FV = find_feedback_datum(variable)
|
||||
FV.add_details(details)
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/ReportDeath(mob/living/L)
|
||||
if(!SSdbcore.Connect())
|
||||
return
|
||||
if(!L || !L.key || !L.mind)
|
||||
return
|
||||
var/turf/T = get_turf(L)
|
||||
var/area/placeofdeath = get_area(T.loc)
|
||||
var/sqlname = sanitizeSQL(L.real_name)
|
||||
var/sqlkey = sanitizeSQL(L.ckey)
|
||||
var/sqljob = sanitizeSQL(L.mind.assigned_role)
|
||||
var/sqlspecial = sanitizeSQL(L.mind.special_role)
|
||||
var/sqlpod = sanitizeSQL(placeofdeath.name)
|
||||
var/laname
|
||||
var/lakey
|
||||
if(L.lastattacker && ismob(L.lastattacker))
|
||||
var/mob/LA = L.lastattacker
|
||||
laname = sanitizeSQL(LA.real_name)
|
||||
lakey = sanitizeSQL(LA.key)
|
||||
var/sqlgender = sanitizeSQL(L.gender)
|
||||
var/sqlbrute = sanitizeSQL(L.getBruteLoss())
|
||||
var/sqlfire = sanitizeSQL(L.getFireLoss())
|
||||
var/sqlbrain = sanitizeSQL(L.getBrainLoss())
|
||||
var/sqloxy = sanitizeSQL(L.getOxyLoss())
|
||||
var/sqltox = sanitizeSQL(L.getStaminaLoss())
|
||||
var/sqlclone = sanitizeSQL(L.getStaminaLoss())
|
||||
var/sqlstamina = sanitizeSQL(L.getStaminaLoss())
|
||||
var/coord = sanitizeSQL("[L.x], [L.y], [L.z]")
|
||||
var/map = sanitizeSQL(SSmapping.config.map_name)
|
||||
var/datum/DBQuery/query_report_death = SSdbcore.NewQuery("INSERT INTO [format_table_name("death")] (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, toxloss, cloneloss, staminaloss, coord, mapname, server_ip, server_port) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[SQLtime()]', '[laname]', '[lakey]', '[sqlgender]', [sqlbrute], [sqlfire], [sqlbrain], [sqloxy], [sqltox], [sqlclone], [sqlstamina], '[coord]', '[map]', INET_ATON('[world.internet_address]'), '[world.port]')")
|
||||
query_report_death.Execute()
|
||||
|
||||
|
||||
//feedback variable datum, for storing all kinds of data
|
||||
/datum/feedback_variable
|
||||
var/variable
|
||||
var/value
|
||||
var/details
|
||||
|
||||
/datum/feedback_variable/New(var/param_variable,var/param_value = 0)
|
||||
/datum/feedback_variable/New(param_variable, param_value = 0)
|
||||
variable = param_variable
|
||||
value = param_value
|
||||
|
||||
@@ -204,50 +255,3 @@ GLOBAL_DATUM_INIT(blackbox, /datum/feedback, new)
|
||||
|
||||
/datum/feedback_variable/proc/get_parsed()
|
||||
return list(variable,value,details)
|
||||
|
||||
//sql reporting procs
|
||||
/proc/sql_poll_population()
|
||||
if(!config.sql_enabled)
|
||||
return
|
||||
if(!SSdbcore.Connect())
|
||||
return
|
||||
var/playercount = 0
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(M.client)
|
||||
playercount += 1
|
||||
var/admincount = GLOB.admins.len
|
||||
var/datum/DBQuery/query_record_playercount = SSdbcore.NewQuery("INSERT INTO [format_table_name("legacy_population")] (playercount, admincount, time, server_ip, server_port) VALUES ([playercount], [admincount], '[SQLtime()]', INET_ATON('[world.internet_address]'), '[world.port]')")
|
||||
query_record_playercount.Execute()
|
||||
|
||||
/proc/sql_report_death(mob/living/L)
|
||||
if(!config.sql_enabled)
|
||||
return
|
||||
if(!SSdbcore.Connect())
|
||||
return
|
||||
if(!L || !L.key || !L.mind)
|
||||
return
|
||||
var/turf/T = get_turf(L)
|
||||
var/area/placeofdeath = get_area(T.loc)
|
||||
var/sqlname = sanitizeSQL(L.real_name)
|
||||
var/sqlkey = sanitizeSQL(L.ckey)
|
||||
var/sqljob = sanitizeSQL(L.mind.assigned_role)
|
||||
var/sqlspecial = sanitizeSQL(L.mind.special_role)
|
||||
var/sqlpod = sanitizeSQL(placeofdeath.name)
|
||||
var/laname
|
||||
var/lakey
|
||||
if(L.lastattacker && ismob(L.lastattacker))
|
||||
var/mob/LA = L.lastattacker
|
||||
laname = sanitizeSQL(LA.real_name)
|
||||
lakey = sanitizeSQL(LA.key)
|
||||
var/sqlgender = sanitizeSQL(L.gender)
|
||||
var/sqlbrute = sanitizeSQL(L.getBruteLoss())
|
||||
var/sqlfire = sanitizeSQL(L.getFireLoss())
|
||||
var/sqlbrain = sanitizeSQL(L.getBrainLoss())
|
||||
var/sqloxy = sanitizeSQL(L.getOxyLoss())
|
||||
var/sqltox = sanitizeSQL(L.getStaminaLoss())
|
||||
var/sqlclone = sanitizeSQL(L.getStaminaLoss())
|
||||
var/sqlstamina = sanitizeSQL(L.getStaminaLoss())
|
||||
var/coord = sanitizeSQL("[L.x], [L.y], [L.z]")
|
||||
var/map = sanitizeSQL(SSmapping.config.map_name)
|
||||
var/datum/DBQuery/query_report_death = SSdbcore.NewQuery("INSERT INTO [format_table_name("death")] (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, toxloss, cloneloss, staminaloss, coord, mapname, server_ip, server_port) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[SQLtime()]', '[laname]', '[lakey]', '[sqlgender]', [sqlbrute], [sqlfire], [sqlbrain], [sqloxy], [sqltox], [sqlclone], [sqlstamina], '[coord]', '[map]', INET_ATON('[world.internet_address]'), '[world.port]')")
|
||||
query_report_death.Execute()
|
||||
@@ -0,0 +1,512 @@
|
||||
diff a/code/controllers/subsystem/blackbox.dm b/code/controllers/subsystem/blackbox.dm (rejected hunks)
|
||||
@@ -1,253 +1,257 @@
|
||||
-GLOBAL_DATUM_INIT(blackbox, /datum/feedback, new)
|
||||
-
|
||||
-//the feedback datum; stores all feedback
|
||||
-/datum/feedback
|
||||
- var/list/messages = list()
|
||||
- var/list/messages_admin = list()
|
||||
-
|
||||
- var/list/msg_common = list()
|
||||
- var/list/msg_science = list()
|
||||
- var/list/msg_command = list()
|
||||
- var/list/msg_medical = list()
|
||||
- var/list/msg_engineering = list()
|
||||
- var/list/msg_security = list()
|
||||
- var/list/msg_deathsquad = list()
|
||||
- var/list/msg_syndicate = list()
|
||||
- var/list/msg_service = list()
|
||||
- var/list/msg_cargo = list()
|
||||
-
|
||||
- var/list/datum/feedback_variable/feedback = new()
|
||||
-
|
||||
-/datum/feedback/proc/find_feedback_datum(variable)
|
||||
- for (var/datum/feedback_variable/FV in feedback)
|
||||
- if (FV.get_variable() == variable)
|
||||
- return FV
|
||||
- var/datum/feedback_variable/FV = new(variable)
|
||||
- feedback += FV
|
||||
- return FV
|
||||
-
|
||||
-/datum/feedback/proc/get_round_feedback()
|
||||
- return feedback
|
||||
-
|
||||
-/datum/feedback/proc/round_end_data_gathering()
|
||||
- var/pda_msg_amt = 0
|
||||
- var/rc_msg_amt = 0
|
||||
-
|
||||
- for (var/obj/machinery/message_server/MS in GLOB.message_servers)
|
||||
- if (MS.pda_msgs.len > pda_msg_amt)
|
||||
- pda_msg_amt = MS.pda_msgs.len
|
||||
- if (MS.rc_msgs.len > rc_msg_amt)
|
||||
- rc_msg_amt = MS.rc_msgs.len
|
||||
-
|
||||
- feedback_set_details("radio_usage","")
|
||||
-
|
||||
- feedback_add_details("radio_usage","COM-[msg_common.len]")
|
||||
- feedback_add_details("radio_usage","SCI-[msg_science.len]")
|
||||
- feedback_add_details("radio_usage","HEA-[msg_command.len]")
|
||||
- feedback_add_details("radio_usage","MED-[msg_medical.len]")
|
||||
- feedback_add_details("radio_usage","ENG-[msg_engineering.len]")
|
||||
- feedback_add_details("radio_usage","SEC-[msg_security.len]")
|
||||
- feedback_add_details("radio_usage","DTH-[msg_deathsquad.len]")
|
||||
- feedback_add_details("radio_usage","SYN-[msg_syndicate.len]")
|
||||
- feedback_add_details("radio_usage","SRV-[msg_service.len]")
|
||||
- feedback_add_details("radio_usage","CAR-[msg_cargo.len]")
|
||||
- feedback_add_details("radio_usage","OTH-[messages.len]")
|
||||
- feedback_add_details("radio_usage","PDA-[pda_msg_amt]")
|
||||
- feedback_add_details("radio_usage","RC-[rc_msg_amt]")
|
||||
-
|
||||
- feedback_set_details("round_end","[time2text(world.realtime)]") //This one MUST be the last one that gets set.
|
||||
-
|
||||
-//This proc is only to be called at round end.
|
||||
-/datum/feedback/proc/save_all_data_to_sql()
|
||||
- if (!feedback) return
|
||||
-
|
||||
- round_end_data_gathering() //round_end time logging and some other data processing
|
||||
- if (!GLOB.dbcon.Connect()) return
|
||||
- var/round_id
|
||||
-
|
||||
- var/DBQuery/query_feedback_max_id = GLOB.dbcon.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())]\")"
|
||||
-
|
||||
- if (sqlrowlist == "")
|
||||
- return
|
||||
-
|
||||
- var/DBQuery/query_feedback_save = GLOB.dbcon.NewQuery("INSERT DELAYED IGNORE INTO [format_table_name("feedback")] VALUES " + sqlrowlist)
|
||||
- query_feedback_save.Execute()
|
||||
-
|
||||
-
|
||||
-/proc/feedback_set(variable,value)
|
||||
- if(!GLOB.blackbox)
|
||||
- return
|
||||
-
|
||||
- var/datum/feedback_variable/FV = GLOB.blackbox.find_feedback_datum(variable)
|
||||
-
|
||||
- if(!FV)
|
||||
- return
|
||||
-
|
||||
- FV.set_value(value)
|
||||
-
|
||||
-/proc/feedback_inc(variable,value)
|
||||
- if(!GLOB.blackbox)
|
||||
- return
|
||||
-
|
||||
- var/datum/feedback_variable/FV = GLOB.blackbox.find_feedback_datum(variable)
|
||||
-
|
||||
- if(!FV)
|
||||
- return
|
||||
-
|
||||
- FV.inc(value)
|
||||
-
|
||||
-/proc/feedback_dec(variable,value)
|
||||
- if(!GLOB.blackbox)
|
||||
- return
|
||||
-
|
||||
- var/datum/feedback_variable/FV = GLOB.blackbox.find_feedback_datum(variable)
|
||||
-
|
||||
- if(!FV)
|
||||
- return
|
||||
-
|
||||
- FV.dec(value)
|
||||
-
|
||||
-/proc/feedback_set_details(variable,details)
|
||||
- if(!GLOB.blackbox)
|
||||
- return
|
||||
-
|
||||
- var/datum/feedback_variable/FV = GLOB.blackbox.find_feedback_datum(variable)
|
||||
-
|
||||
- if(!FV)
|
||||
- return
|
||||
-
|
||||
- FV.set_details(details)
|
||||
-
|
||||
-/proc/feedback_add_details(variable,details)
|
||||
- if(!GLOB.blackbox)
|
||||
- return
|
||||
-
|
||||
- var/datum/feedback_variable/FV = GLOB.blackbox.find_feedback_datum(variable)
|
||||
-
|
||||
- if(!FV)
|
||||
- return
|
||||
-
|
||||
- FV.add_details(details)
|
||||
-
|
||||
-//feedback variable datum, for storing all kinds of data
|
||||
-/datum/feedback_variable
|
||||
- var/variable
|
||||
- var/value
|
||||
- var/details
|
||||
-
|
||||
-/datum/feedback_variable/New(var/param_variable,var/param_value = 0)
|
||||
- variable = param_variable
|
||||
- value = param_value
|
||||
-
|
||||
-/datum/feedback_variable/proc/inc(num = 1)
|
||||
- if (isnum(value))
|
||||
- value += num
|
||||
- else
|
||||
- value = text2num(value)
|
||||
- if (isnum(value))
|
||||
- value += num
|
||||
- else
|
||||
- value = num
|
||||
-
|
||||
-/datum/feedback_variable/proc/dec(num = 1)
|
||||
- if (isnum(value))
|
||||
- value -= num
|
||||
- else
|
||||
- value = text2num(value)
|
||||
- if (isnum(value))
|
||||
- value -= num
|
||||
- else
|
||||
- value = -num
|
||||
-
|
||||
-/datum/feedback_variable/proc/set_value(num)
|
||||
- if (isnum(num))
|
||||
- value = num
|
||||
-
|
||||
-/datum/feedback_variable/proc/get_value()
|
||||
- if (!isnum(value))
|
||||
- return 0
|
||||
- return value
|
||||
-
|
||||
-/datum/feedback_variable/proc/get_variable()
|
||||
- return variable
|
||||
-
|
||||
-/datum/feedback_variable/proc/set_details(text)
|
||||
- if (istext(text))
|
||||
- details = text
|
||||
-
|
||||
-/datum/feedback_variable/proc/add_details(text)
|
||||
- if (istext(text))
|
||||
- text = replacetext(text, " ", "_")
|
||||
- if (!details)
|
||||
- details = text
|
||||
- else
|
||||
- details += " [text]"
|
||||
-
|
||||
-/datum/feedback_variable/proc/get_details()
|
||||
- return details
|
||||
-
|
||||
-/datum/feedback_variable/proc/get_parsed()
|
||||
- return list(variable,value,details)
|
||||
-
|
||||
-//sql reporting procs
|
||||
-/proc/sql_poll_population()
|
||||
- if(!config.sql_enabled)
|
||||
- return
|
||||
- if(!GLOB.dbcon.Connect())
|
||||
- return
|
||||
- var/playercount = 0
|
||||
- for(var/mob/M in GLOB.player_list)
|
||||
- if(M.client)
|
||||
- playercount += 1
|
||||
- var/admincount = GLOB.admins.len
|
||||
- var/DBQuery/query_record_playercount = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("legacy_population")] (playercount, admincount, time, server_ip, server_port) VALUES ([playercount], [admincount], '[SQLtime()]', INET_ATON('[world.internet_address]'), '[world.port]')")
|
||||
- query_record_playercount.Execute()
|
||||
-
|
||||
-/proc/sql_report_death(mob/living/L)
|
||||
- if(!config.sql_enabled)
|
||||
- return
|
||||
- if(!GLOB.dbcon.Connect())
|
||||
- return
|
||||
- if(!L || !L.key || !L.mind)
|
||||
- return
|
||||
- var/turf/T = get_turf(L)
|
||||
- var/area/placeofdeath = get_area(T.loc)
|
||||
- var/sqlname = sanitizeSQL(L.real_name)
|
||||
- var/sqlkey = sanitizeSQL(L.ckey)
|
||||
- var/sqljob = sanitizeSQL(L.mind.assigned_role)
|
||||
- var/sqlspecial = sanitizeSQL(L.mind.special_role)
|
||||
- var/sqlpod = sanitizeSQL(placeofdeath.name)
|
||||
- var/laname
|
||||
- var/lakey
|
||||
- if(L.lastattacker && ismob(L.lastattacker))
|
||||
- var/mob/LA = L.lastattacker
|
||||
- laname = sanitizeSQL(LA.real_name)
|
||||
- lakey = sanitizeSQL(LA.key)
|
||||
- var/sqlgender = sanitizeSQL(L.gender)
|
||||
- var/sqlbrute = sanitizeSQL(L.getBruteLoss())
|
||||
- var/sqlfire = sanitizeSQL(L.getFireLoss())
|
||||
- var/sqlbrain = sanitizeSQL(L.getBrainLoss())
|
||||
- var/sqloxy = sanitizeSQL(L.getOxyLoss())
|
||||
- var/sqltox = sanitizeSQL(L.getStaminaLoss())
|
||||
- var/sqlclone = sanitizeSQL(L.getStaminaLoss())
|
||||
- var/sqlstamina = sanitizeSQL(L.getStaminaLoss())
|
||||
- var/coord = sanitizeSQL("[L.x], [L.y], [L.z]")
|
||||
- var/map = sanitizeSQL(SSmapping.config.map_name)
|
||||
- var/DBQuery/query_report_death = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("death")] (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, toxloss, cloneloss, staminaloss, coord, mapname, server_ip, server_port) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[SQLtime()]', '[laname]', '[lakey]', '[sqlgender]', [sqlbrute], [sqlfire], [sqlbrain], [sqloxy], [sqltox], [sqlclone], [sqlstamina], '[coord]', '[map]', INET_ATON('[world.internet_address]'), '[world.port]')")
|
||||
- query_report_death.Execute()
|
||||
+SUBSYSTEM_DEF(blackbox)
|
||||
+ name = "Blackbox"
|
||||
+ wait = 6000
|
||||
+ flags = SS_NO_TICK_CHECK
|
||||
+
|
||||
+ var/list/msg_common = list()
|
||||
+ var/list/msg_science = list()
|
||||
+ var/list/msg_command = list()
|
||||
+ var/list/msg_medical = list()
|
||||
+ var/list/msg_engineering = list()
|
||||
+ var/list/msg_security = list()
|
||||
+ var/list/msg_deathsquad = list()
|
||||
+ var/list/msg_syndicate = list()
|
||||
+ var/list/msg_service = list()
|
||||
+ var/list/msg_cargo = list()
|
||||
+ var/list/msg_other = list()
|
||||
+
|
||||
+ var/list/feedback = list() //list of datum/feedback_variable
|
||||
+
|
||||
+//poll population
|
||||
+/datum/controller/subsystem/blackbox/fire()
|
||||
+ if(!GLOB.dbcon.Connect())
|
||||
+ return
|
||||
+ var/playercount = 0
|
||||
+ for(var/mob/M in GLOB.player_list)
|
||||
+ if(M.client)
|
||||
+ playercount += 1
|
||||
+ var/admincount = GLOB.admins.len
|
||||
+ var/DBQuery/query_record_playercount = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("legacy_population")] (playercount, admincount, time, server_ip, server_port) VALUES ([playercount], [admincount], '[SQLtime()]', INET_ATON('[world.internet_address]'), '[world.port]')")
|
||||
+ query_record_playercount.Execute()
|
||||
+
|
||||
+/datum/controller/subsystem/blackbox/Recover()
|
||||
+ msg_common = SSblackbox.msg_common
|
||||
+ msg_science = SSblackbox.msg_science
|
||||
+ msg_command = SSblackbox.msg_command
|
||||
+ msg_medical = SSblackbox.msg_medical
|
||||
+ msg_engineering = SSblackbox.msg_engineering
|
||||
+ msg_security = SSblackbox.msg_security
|
||||
+ msg_deathsquad = SSblackbox.msg_deathsquad
|
||||
+ msg_syndicate = SSblackbox.msg_syndicate
|
||||
+ msg_service = SSblackbox.msg_service
|
||||
+ msg_cargo = SSblackbox.msg_cargo
|
||||
+ msg_other = SSblackbox.msg_other
|
||||
+
|
||||
+ feedback = SSblackbox.feedback
|
||||
+
|
||||
+//no touchie
|
||||
+/datum/controller/subsystem/blackbox/can_vv_get(var_name)
|
||||
+ if(var_name == "feedback")
|
||||
+ return FALSE
|
||||
+ return ..()
|
||||
+
|
||||
+/datum/controller/subsystem/blackbox/vv_edit_var(var_name, var_value)
|
||||
+ return FALSE
|
||||
+
|
||||
+/datum/controller/subsystem/blackbox/Shutdown()
|
||||
+ var/pda_msg_amt = 0
|
||||
+ var/rc_msg_amt = 0
|
||||
+
|
||||
+ for (var/obj/machinery/message_server/MS in GLOB.message_servers)
|
||||
+ if (MS.pda_msgs.len > pda_msg_amt)
|
||||
+ pda_msg_amt = MS.pda_msgs.len
|
||||
+ if (MS.rc_msgs.len > rc_msg_amt)
|
||||
+ rc_msg_amt = MS.rc_msgs.len
|
||||
+
|
||||
+ set_details("radio_usage","")
|
||||
+
|
||||
+ add_details("radio_usage","COM-[msg_common.len]")
|
||||
+ add_details("radio_usage","SCI-[msg_science.len]")
|
||||
+ add_details("radio_usage","HEA-[msg_command.len]")
|
||||
+ add_details("radio_usage","MED-[msg_medical.len]")
|
||||
+ add_details("radio_usage","ENG-[msg_engineering.len]")
|
||||
+ add_details("radio_usage","SEC-[msg_security.len]")
|
||||
+ add_details("radio_usage","DTH-[msg_deathsquad.len]")
|
||||
+ add_details("radio_usage","SYN-[msg_syndicate.len]")
|
||||
+ add_details("radio_usage","SRV-[msg_service.len]")
|
||||
+ add_details("radio_usage","CAR-[msg_cargo.len]")
|
||||
+ add_details("radio_usage","OTH-[msg_other.len]")
|
||||
+ add_details("radio_usage","PDA-[pda_msg_amt]")
|
||||
+ add_details("radio_usage","RC-[rc_msg_amt]")
|
||||
+
|
||||
+ set_details("round_end","[time2text(world.realtime)]") //This one MUST be the last one that gets set.
|
||||
+
|
||||
+ if (!GLOB.dbcon.Connect())
|
||||
+ return
|
||||
+
|
||||
+ var/round_id
|
||||
+
|
||||
+ var/DBQuery/query_feedback_max_id = GLOB.dbcon.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())]\")"
|
||||
+
|
||||
+ if (sqlrowlist == "")
|
||||
+ return
|
||||
+
|
||||
+ var/DBQuery/query_feedback_save = GLOB.dbcon.NewQuery("INSERT DELAYED IGNORE INTO [format_table_name("feedback")] VALUES " + sqlrowlist)
|
||||
+ query_feedback_save.Execute()
|
||||
+
|
||||
+/datum/controller/subsystem/blackbox/proc/LogBroadcast(blackbox_msg, freq)
|
||||
+ switch(freq)
|
||||
+ if(1459)
|
||||
+ msg_common += blackbox_msg
|
||||
+ if(1351)
|
||||
+ msg_science += blackbox_msg
|
||||
+ if(1353)
|
||||
+ msg_command += blackbox_msg
|
||||
+ if(1355)
|
||||
+ msg_medical += blackbox_msg
|
||||
+ if(1357)
|
||||
+ msg_engineering += blackbox_msg
|
||||
+ if(1359)
|
||||
+ msg_security += blackbox_msg
|
||||
+ if(1441)
|
||||
+ msg_deathsquad += blackbox_msg
|
||||
+ if(1213)
|
||||
+ msg_syndicate += blackbox_msg
|
||||
+ if(1349)
|
||||
+ msg_service += blackbox_msg
|
||||
+ if(1347)
|
||||
+ msg_cargo += blackbox_msg
|
||||
+ else
|
||||
+ msg_other += blackbox_msg
|
||||
+
|
||||
+/datum/controller/subsystem/blackbox/proc/find_feedback_datum(variable)
|
||||
+ for(var/datum/feedback_variable/FV in feedback)
|
||||
+ if(FV.get_variable() == variable)
|
||||
+ return FV
|
||||
+
|
||||
+ var/datum/feedback_variable/FV = new(variable)
|
||||
+ feedback += FV
|
||||
+ return FV
|
||||
+
|
||||
+/datum/controller/subsystem/blackbox/proc/set_val(variable, value)
|
||||
+ var/datum/feedback_variable/FV = find_feedback_datum(variable)
|
||||
+ FV.set_value(value)
|
||||
+
|
||||
+/datum/controller/subsystem/blackbox/proc/inc(variable, value)
|
||||
+ var/datum/feedback_variable/FV = find_feedback_datum(variable)
|
||||
+ FV.inc(value)
|
||||
+
|
||||
+/datum/controller/subsystem/blackbox/proc/dec(variable,value)
|
||||
+ var/datum/feedback_variable/FV = find_feedback_datum(variable)
|
||||
+ FV.dec(value)
|
||||
+
|
||||
+/datum/controller/subsystem/blackbox/proc/set_details(variable,details)
|
||||
+ var/datum/feedback_variable/FV = find_feedback_datum(variable)
|
||||
+ FV.set_details(details)
|
||||
+
|
||||
+/datum/controller/subsystem/blackbox/proc/add_details(variable,details)
|
||||
+ var/datum/feedback_variable/FV = find_feedback_datum(variable)
|
||||
+ FV.add_details(details)
|
||||
+
|
||||
+/datum/controller/subsystem/blackbox/proc/ReportDeath(mob/living/L)
|
||||
+ if(!GLOB.dbcon.Connect())
|
||||
+ return
|
||||
+ if(!L || !L.key || !L.mind)
|
||||
+ return
|
||||
+ var/turf/T = get_turf(L)
|
||||
+ var/area/placeofdeath = get_area(T.loc)
|
||||
+ var/sqlname = sanitizeSQL(L.real_name)
|
||||
+ var/sqlkey = sanitizeSQL(L.ckey)
|
||||
+ var/sqljob = sanitizeSQL(L.mind.assigned_role)
|
||||
+ var/sqlspecial = sanitizeSQL(L.mind.special_role)
|
||||
+ var/sqlpod = sanitizeSQL(placeofdeath.name)
|
||||
+ var/laname
|
||||
+ var/lakey
|
||||
+ if(L.lastattacker && ismob(L.lastattacker))
|
||||
+ var/mob/LA = L.lastattacker
|
||||
+ laname = sanitizeSQL(LA.real_name)
|
||||
+ lakey = sanitizeSQL(LA.key)
|
||||
+ var/sqlgender = sanitizeSQL(L.gender)
|
||||
+ var/sqlbrute = sanitizeSQL(L.getBruteLoss())
|
||||
+ var/sqlfire = sanitizeSQL(L.getFireLoss())
|
||||
+ var/sqlbrain = sanitizeSQL(L.getBrainLoss())
|
||||
+ var/sqloxy = sanitizeSQL(L.getOxyLoss())
|
||||
+ var/sqltox = sanitizeSQL(L.getStaminaLoss())
|
||||
+ var/sqlclone = sanitizeSQL(L.getStaminaLoss())
|
||||
+ var/sqlstamina = sanitizeSQL(L.getStaminaLoss())
|
||||
+ var/coord = sanitizeSQL("[L.x], [L.y], [L.z]")
|
||||
+ var/map = sanitizeSQL(SSmapping.config.map_name)
|
||||
+ var/DBQuery/query_report_death = GLOB.dbcon.NewQuery("INSERT INTO [format_table_name("death")] (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, toxloss, cloneloss, staminaloss, coord, mapname, server_ip, server_port) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[SQLtime()]', '[laname]', '[lakey]', '[sqlgender]', [sqlbrute], [sqlfire], [sqlbrain], [sqloxy], [sqltox], [sqlclone], [sqlstamina], '[coord]', '[map]', INET_ATON('[world.internet_address]'), '[world.port]')")
|
||||
+ query_report_death.Execute()
|
||||
+
|
||||
+
|
||||
+//feedback variable datum, for storing all kinds of data
|
||||
+/datum/feedback_variable
|
||||
+ var/variable
|
||||
+ var/value
|
||||
+ var/details
|
||||
+
|
||||
+/datum/feedback_variable/New(param_variable, param_value = 0)
|
||||
+ variable = param_variable
|
||||
+ value = param_value
|
||||
+
|
||||
+/datum/feedback_variable/proc/inc(num = 1)
|
||||
+ if (isnum(value))
|
||||
+ value += num
|
||||
+ else
|
||||
+ value = text2num(value)
|
||||
+ if (isnum(value))
|
||||
+ value += num
|
||||
+ else
|
||||
+ value = num
|
||||
+
|
||||
+/datum/feedback_variable/proc/dec(num = 1)
|
||||
+ if (isnum(value))
|
||||
+ value -= num
|
||||
+ else
|
||||
+ value = text2num(value)
|
||||
+ if (isnum(value))
|
||||
+ value -= num
|
||||
+ else
|
||||
+ value = -num
|
||||
+
|
||||
+/datum/feedback_variable/proc/set_value(num)
|
||||
+ if (isnum(num))
|
||||
+ value = num
|
||||
+
|
||||
+/datum/feedback_variable/proc/get_value()
|
||||
+ if (!isnum(value))
|
||||
+ return 0
|
||||
+ return value
|
||||
+
|
||||
+/datum/feedback_variable/proc/get_variable()
|
||||
+ return variable
|
||||
+
|
||||
+/datum/feedback_variable/proc/set_details(text)
|
||||
+ if (istext(text))
|
||||
+ details = text
|
||||
+
|
||||
+/datum/feedback_variable/proc/add_details(text)
|
||||
+ if (istext(text))
|
||||
+ text = replacetext(text, " ", "_")
|
||||
+ if (!details)
|
||||
+ details = text
|
||||
+ else
|
||||
+ details += " [text]"
|
||||
+
|
||||
+/datum/feedback_variable/proc/get_details()
|
||||
+ return details
|
||||
+
|
||||
+/datum/feedback_variable/proc/get_parsed()
|
||||
+ return list(variable,value,details)
|
||||
@@ -66,6 +66,9 @@ SUBSYSTEM_DEF(garbage)
|
||||
HandleToBeQueued()
|
||||
if(state == SS_RUNNING)
|
||||
HandleQueue()
|
||||
|
||||
if (state == SS_PAUSED) //make us wait again before the next run.
|
||||
state = SS_RUNNING
|
||||
|
||||
//If you see this proc high on the profile, what you are really seeing is the garbage collection/soft delete overhead in byond.
|
||||
//Don't attempt to optimize, not worth the effort.
|
||||
@@ -110,24 +113,9 @@ SUBSYSTEM_DEF(garbage)
|
||||
var/type = A.type
|
||||
testing("GC: -- \ref[A] | [type] was unable to be GC'd and was deleted --")
|
||||
didntgc["[type]"]++
|
||||
var/time = world.timeofday
|
||||
var/tick = world.tick_usage
|
||||
var/ticktime = world.time
|
||||
|
||||
HardDelete(A)
|
||||
tick = (world.tick_usage-tick+((world.time-ticktime)/world.tick_lag*100))
|
||||
|
||||
if (tick > highest_del_tickusage)
|
||||
highest_del_tickusage = tick
|
||||
time = world.timeofday - time
|
||||
if (!time && TICK_DELTA_TO_MS(tick) > 1)
|
||||
time = TICK_DELTA_TO_MS(tick)/100
|
||||
if (time > highest_del_time)
|
||||
highest_del_time = time
|
||||
if (time > 10)
|
||||
log_game("Error: [type]([refID]) took longer then 1 second to delete (took [time/10] seconds to delete)")
|
||||
message_admins("Error: [type]([refID]) took longer then 1 second to delete (took [time/10] seconds to delete).")
|
||||
postpone(time/5)
|
||||
break
|
||||
++delslasttick
|
||||
++totaldels
|
||||
else
|
||||
@@ -157,8 +145,28 @@ SUBSYSTEM_DEF(garbage)
|
||||
|
||||
//this is purely to seperate things profile wise.
|
||||
/datum/controller/subsystem/garbage/proc/HardDelete(datum/A)
|
||||
var/time = world.timeofday
|
||||
var/tick = world.tick_usage
|
||||
var/ticktime = world.time
|
||||
|
||||
var/type = A.type
|
||||
var/refID = "\ref[A]"
|
||||
|
||||
del(A)
|
||||
|
||||
|
||||
tick = (world.tick_usage-tick+((world.time-ticktime)/world.tick_lag*100))
|
||||
if (tick > highest_del_tickusage)
|
||||
highest_del_tickusage = tick
|
||||
time = world.timeofday - time
|
||||
if (!time && TICK_DELTA_TO_MS(tick) > 1)
|
||||
time = TICK_DELTA_TO_MS(tick)/100
|
||||
if (time > highest_del_time)
|
||||
highest_del_time = time
|
||||
if (time > 10)
|
||||
log_game("Error: [type]([refID]) took longer then 1 second to delete (took [time/10] seconds to delete)")
|
||||
message_admins("Error: [type]([refID]) took longer then 1 second to delete (took [time/10] seconds to delete).")
|
||||
postpone(time/5)
|
||||
|
||||
/datum/controller/subsystem/garbage/proc/HardQueue(datum/A)
|
||||
if (istype(A) && A.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)
|
||||
tobequeued += A
|
||||
@@ -211,7 +219,7 @@ SUBSYSTEM_DEF(garbage)
|
||||
if (QDEL_HINT_HARDDEL) //qdel should assume this object won't gc, and queue a hard delete using a hard reference to save time from the locate()
|
||||
SSgarbage.HardQueue(D)
|
||||
if (QDEL_HINT_HARDDEL_NOW) //qdel should assume this object won't gc, and hard del it post haste.
|
||||
del(D)
|
||||
SSgarbage.HardDelete(D)
|
||||
if (QDEL_HINT_FINDREFERENCE)//qdel will, if TESTING is enabled, display all references to this object, then queue the object for deletion.
|
||||
SSgarbage.QueueForQueuing(D)
|
||||
#ifdef TESTING
|
||||
|
||||
@@ -483,7 +483,7 @@ SUBSYSTEM_DEF(job)
|
||||
else level4++ //not selected
|
||||
|
||||
tmp_str += "HIGH=[level1]|MEDIUM=[level2]|LOW=[level3]|NEVER=[level4]|BANNED=[level5]|YOUNG=[level6]|-"
|
||||
feedback_add_details("job_preferences",tmp_str)
|
||||
SSblackbox.add_details("job_preferences",tmp_str)
|
||||
|
||||
/datum/controller/subsystem/job/proc/PopcapReached()
|
||||
if(config.hard_popcap || config.extreme_popcap)
|
||||
|
||||
@@ -18,6 +18,8 @@ SUBSYSTEM_DEF(mapping)
|
||||
var/list/shuttle_templates = list()
|
||||
var/list/shelter_templates = list()
|
||||
|
||||
var/loading_ruins = FALSE
|
||||
|
||||
/datum/controller/subsystem/mapping/PreInit()
|
||||
if(!config)
|
||||
#ifdef FORCE_MAP
|
||||
@@ -32,13 +34,13 @@ SUBSYSTEM_DEF(mapping)
|
||||
if(config.defaulted)
|
||||
to_chat(world, "<span class='boldannounce'>Unable to load next map config, defaulting to Box Station</span>")
|
||||
loadWorld()
|
||||
SortAreas()
|
||||
repopulate_sorted_areas()
|
||||
process_teleport_locs() //Sets up the wizard teleport locations
|
||||
preloadTemplates()
|
||||
// Pick a random away mission.
|
||||
createRandomZlevel()
|
||||
// Generate mining.
|
||||
|
||||
loading_ruins = TRUE
|
||||
var/mining_type = config.minetype
|
||||
if (mining_type == "lavaland")
|
||||
seedRuins(list(5), global.config.lavaland_budget, /area/lavaland/surface/outdoors, lava_ruins_templates)
|
||||
@@ -54,7 +56,8 @@ SUBSYSTEM_DEF(mapping)
|
||||
space_zlevels += i
|
||||
|
||||
seedRuins(space_zlevels, global.config.space_budget, /area/space, space_ruins_templates)
|
||||
|
||||
loading_ruins = FALSE
|
||||
repopulate_sorted_areas()
|
||||
// Set up Z-level transistions.
|
||||
setup_map_transitions()
|
||||
..()
|
||||
@@ -116,7 +119,7 @@ SUBSYSTEM_DEF(mapping)
|
||||
INIT_ANNOUNCE("Loading [config.map_name]...")
|
||||
TryLoadZ(config.GetFullMapPath(), FailedZs, ZLEVEL_STATION)
|
||||
INIT_ANNOUNCE("Loaded station in [(REALTIMEOFDAY - start_time)/10]s!")
|
||||
feedback_add_details("map_name", config.map_name)
|
||||
SSblackbox.add_details("map_name", config.map_name)
|
||||
|
||||
if(config.minetype != "lavaland")
|
||||
INIT_ANNOUNCE("WARNING: A map without lavaland set as it's minetype was loaded! This is being ignored! Update the maploader code!")
|
||||
@@ -144,31 +147,35 @@ SUBSYSTEM_DEF(mapping)
|
||||
mapvotes[global.config.defaultmap.map_name] += 1
|
||||
continue
|
||||
mapvotes[vote] += 1
|
||||
else
|
||||
for(var/M in global.config.maplist)
|
||||
mapvotes[M] = 1
|
||||
|
||||
//filter votes
|
||||
for (var/map in mapvotes)
|
||||
if (!map)
|
||||
mapvotes.Remove(map)
|
||||
if (!(map in global.config.maplist))
|
||||
mapvotes.Remove(map)
|
||||
continue
|
||||
var/datum/map_config/VM = global.config.maplist[map]
|
||||
if (!VM)
|
||||
mapvotes.Remove(map)
|
||||
continue
|
||||
if (VM.voteweight <= 0)
|
||||
mapvotes.Remove(map)
|
||||
continue
|
||||
if (VM.config_min_users > 0 && players < VM.config_min_users)
|
||||
mapvotes.Remove(map)
|
||||
continue
|
||||
if (VM.config_max_users > 0 && players > VM.config_max_users)
|
||||
mapvotes.Remove(map)
|
||||
continue
|
||||
//filter votes
|
||||
for (var/map in mapvotes)
|
||||
if (!map)
|
||||
mapvotes.Remove(map)
|
||||
if (!(map in global.config.maplist))
|
||||
mapvotes.Remove(map)
|
||||
continue
|
||||
var/datum/map_config/VM = global.config.maplist[map]
|
||||
if (!VM)
|
||||
mapvotes.Remove(map)
|
||||
continue
|
||||
if (VM.voteweight <= 0)
|
||||
mapvotes.Remove(map)
|
||||
continue
|
||||
if (VM.config_min_users > 0 && players < VM.config_min_users)
|
||||
mapvotes.Remove(map)
|
||||
continue
|
||||
if (VM.config_max_users > 0 && players > VM.config_max_users)
|
||||
mapvotes.Remove(map)
|
||||
continue
|
||||
|
||||
if(global.config.allow_map_voting)
|
||||
mapvotes[map] = mapvotes[map]*VM.voteweight
|
||||
|
||||
var/pickedmap = global.config.allow_map_voting ? pickweight(mapvotes) : pick(global.config.maplist)
|
||||
var/pickedmap = pickweight(mapvotes)
|
||||
if (!pickedmap)
|
||||
return
|
||||
var/datum/map_config/VM = global.config.maplist[pickedmap]
|
||||
|
||||
@@ -19,7 +19,7 @@ SUBSYSTEM_DEF(npcpool)
|
||||
/datum/controller/subsystem/npcpool/stat_entry()
|
||||
..("NPCS:[processing.len]|D:[needsDelegate.len]|A:[needsAssistant.len]|U:[canBeUsed.len]")
|
||||
|
||||
/datum/controller/subsystem/npcpool/proc/stop_processing(mob/living/carbon/human/interactive/I)
|
||||
/datum/controller/subsystem/npcpool/proc/stop_processing(mob/living/I)
|
||||
processing -= I
|
||||
currentrun -= I
|
||||
needsDelegate -= I
|
||||
|
||||
@@ -3,14 +3,20 @@
|
||||
SUBSYSTEM_DEF(ping)
|
||||
name = "Ping"
|
||||
wait = 6
|
||||
flags = SS_NO_INIT|SS_POST_FIRE_TIMING|SS_FIRE_IN_LOBBY
|
||||
flags = SS_POST_FIRE_TIMING|SS_FIRE_IN_LOBBY
|
||||
priority = 10
|
||||
var/list/currentrun
|
||||
|
||||
/datum/controller/subsystem/ping/Initialize()
|
||||
if (config.hub)
|
||||
world.visibility = 1
|
||||
..()
|
||||
|
||||
/datum/controller/subsystem/ping/fire(resumed = FALSE)
|
||||
if (!resumed)
|
||||
src.currentrun = GLOB.clients.Copy()
|
||||
|
||||
var/round_started = Master.round_started
|
||||
var/list/currentrun = src.currentrun
|
||||
while (length(currentrun))
|
||||
var/client/C = currentrun[currentrun.len]
|
||||
@@ -19,7 +25,15 @@ SUBSYSTEM_DEF(ping)
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
continue
|
||||
|
||||
if(round_started && C.is_afk(INACTIVITY_KICK))
|
||||
if(!istype(C.mob, /mob/dead))
|
||||
log_access("AFK: [key_name(C)]")
|
||||
to_chat(C, "<span class='danger'>You have been inactive for more than 10 minutes and have been disconnected.</span>")
|
||||
qdel(C)
|
||||
|
||||
winset(C, null, "command=.update_ping+[world.time+world.tick_lag*world.tick_usage/100]")
|
||||
|
||||
if (MC_TICK_CHECK) //one day, when ss13 has 1000 people per server, you guys are gonna be glad I added this tick check
|
||||
return
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
diff a/code/controllers/subsystem/server_maint.dm b/code/controllers/subsystem/server_maint.dm (rejected hunks)
|
||||
@@ -18,5 +18,3 @@ SUBSYSTEM_DEF(server_maint)
|
||||
to_chat(C, "<span class='danger'>You have been inactive for more than 10 minutes and have been disconnected.</span>")
|
||||
qdel(C)
|
||||
|
||||
- if(config.sql_enabled)
|
||||
- sql_poll_population()
|
||||
@@ -210,12 +210,10 @@ SUBSYSTEM_DEF(shuttle)
|
||||
var/emergency_reason = "\nNature of emergency:\n\n[call_reason]"
|
||||
var/security_num = seclevel2num(get_security_level())
|
||||
switch(security_num)
|
||||
if(SEC_LEVEL_GREEN)
|
||||
emergency.request(null, 2, signal_origin, html_decode(emergency_reason), 0)
|
||||
if(SEC_LEVEL_BLUE)
|
||||
emergency.request(null, 1, signal_origin, html_decode(emergency_reason), 0)
|
||||
if(SEC_LEVEL_RED,SEC_LEVEL_DELTA)
|
||||
emergency.request(null, signal_origin, html_decode(emergency_reason), 1) //There is a serious threat we gotta move no time to give them five minutes.
|
||||
else
|
||||
emergency.request(null, 0.5, signal_origin, html_decode(emergency_reason), 1) // There is a serious threat we gotta move no time to give them five minutes.
|
||||
emergency.request(null, signal_origin, html_decode(emergency_reason), 0)
|
||||
|
||||
log_game("[key_name(user)] has called the shuttle.")
|
||||
message_admins("[key_name_admin(user)] has called the shuttle.")
|
||||
@@ -274,7 +272,7 @@ SUBSYSTEM_DEF(shuttle)
|
||||
|
||||
if(callShuttle)
|
||||
if(EMERGENCY_IDLE_OR_RECALLED)
|
||||
emergency.request(null, 2.5)
|
||||
emergency.request(null, set_coefficient = 2.5)
|
||||
log_game("There is no means of calling the shuttle anymore. Shuttle automatically called.")
|
||||
message_admins("All the communications consoles were destroyed and all AIs are inactive. Shuttle called.")
|
||||
|
||||
|
||||
@@ -1,87 +1,49 @@
|
||||
//The Datum, Antagonist. Handles various antag things via a datum.
|
||||
/datum/antagonist
|
||||
var/mob/living/owner //who's our owner and accordingly an antagonist
|
||||
var/some_flufftext = "yer an antag larry"
|
||||
var/prevented_antag_datum_type //the type of antag datum that this datum can't coexist with; should probably be a list
|
||||
var/silent_update = FALSE //if we suppress messages during on_gain, apply_innate_effects, remove_innate_effects, and on_remove
|
||||
var/name = "Antagonist"
|
||||
|
||||
/datum/antagonist/New()
|
||||
if(!prevented_antag_datum_type)
|
||||
prevented_antag_datum_type = type
|
||||
var/datum/mind/owner //Mind that owns this datum
|
||||
|
||||
/datum/antagonist/Destroy()
|
||||
owner = null
|
||||
return ..()
|
||||
var/silent = FALSE //Silent will prevent the gain/lose texts to show
|
||||
|
||||
/datum/antagonist/proc/can_be_owned(mob/living/new_body)
|
||||
return new_body && !new_body.has_antag_datum(prevented_antag_datum_type, TRUE)
|
||||
var/can_coexist_with_others = TRUE //Whether or not the person will be able to have more than one datum
|
||||
var/list/typecache_datum_blacklist = list() //List of datums this type can't coexist with
|
||||
|
||||
/datum/antagonist/proc/give_to_body(mob/living/new_body) //tries to give an antag datum to a mob. cancels out if it can't be owned by the new body
|
||||
if(new_body && can_be_owned(new_body))
|
||||
new_body.antag_datums += src
|
||||
owner = new_body
|
||||
on_gain()
|
||||
. = src //return the datum if successful
|
||||
else
|
||||
qdel(src)
|
||||
. = FALSE
|
||||
|
||||
/datum/antagonist/proc/on_gain() //on initial gain of antag datum, do this. should only be called once per datum
|
||||
apply_innate_effects()
|
||||
if(!silent_update && some_flufftext)
|
||||
to_chat(owner, some_flufftext)
|
||||
/datum/antagonist/New(datum/mind/new_owner)
|
||||
. = ..()
|
||||
typecache_datum_blacklist = typecacheof(typecache_datum_blacklist)
|
||||
if(new_owner)
|
||||
owner = new_owner
|
||||
|
||||
/datum/antagonist/proc/apply_innate_effects() //applies innate effects to the owner, may be called multiple times due to mind transferral, but should only be called once per mob
|
||||
//antag huds would go here if antag huds were less completely unworkable as-is
|
||||
/datum/antagonist/proc/on_body_transfer(mob/living/old_body, mob/living/new_body)
|
||||
remove_innate_effects(old_body)
|
||||
apply_innate_effects(new_body)
|
||||
|
||||
/datum/antagonist/proc/remove_innate_effects() //removes innate effects from the owner, may be called multiple times due to mind transferral, but should only be called once per mob
|
||||
//also antag huds but see above antag huds a shit
|
||||
//This handles the application of antag huds/special abilities
|
||||
/datum/antagonist/proc/apply_innate_effects(mob/living/mob_override)
|
||||
return
|
||||
|
||||
/datum/antagonist/proc/on_remove() //totally removes the antag datum from the owner; can only be called once per owner
|
||||
//This handles the removal of antag huds/special abilities
|
||||
/datum/antagonist/proc/remove_innate_effects(mob/living/mob_override)
|
||||
return
|
||||
|
||||
//Proc called when the datum is given to a mind.
|
||||
/datum/antagonist/proc/on_gain()
|
||||
if(owner && owner.current)
|
||||
if(!silent)
|
||||
greet()
|
||||
apply_innate_effects()
|
||||
|
||||
/datum/antagonist/proc/on_removal()
|
||||
remove_innate_effects()
|
||||
owner.antag_datums -= src
|
||||
if(owner)
|
||||
owner.antag_datums -= src
|
||||
if(!silent && owner.current)
|
||||
farewell()
|
||||
qdel(src)
|
||||
|
||||
/datum/antagonist/proc/transfer_to_new_body(mob/living/new_body)
|
||||
remove_innate_effects()
|
||||
if(!islist(new_body.antag_datums))
|
||||
new_body.antag_datums = list()
|
||||
new_body.antag_datums += src
|
||||
owner.antag_datums -= src
|
||||
owner = new_body
|
||||
apply_innate_effects()
|
||||
/datum/antagonist/proc/greet()
|
||||
return
|
||||
|
||||
//mob var and helper procs/Destroy override
|
||||
/mob/living
|
||||
var/list/antag_datums
|
||||
|
||||
/mob/living/Destroy() //TODO: merge this with the living/Destroy() in code\modules\mob\living\living.dm (currently line 29)
|
||||
if(islist(antag_datums))
|
||||
for(var/i in antag_datums)
|
||||
qdel(i)
|
||||
antag_datums = null
|
||||
return ..()
|
||||
|
||||
/mob/living/proc/can_have_antag_datum(datum_type) //if we can have this specific antagonist datum; neccessary, but requires creating a new antag datum each time.
|
||||
var/datum/antagonist/D = new datum_type()
|
||||
. = D.can_be_owned(src) //we can't exactly cache the results, either, because conditions might change. avoid use? TODO: better proc
|
||||
qdel(D)
|
||||
|
||||
/mob/living/proc/gain_antag_datum(datum_type) //tries to give a mob a specific antagonist datum; returns the datum if successful.
|
||||
if(!islist(antag_datums))
|
||||
antag_datums = list()
|
||||
var/datum/antagonist/D = new datum_type()
|
||||
. = D.give_to_body(src)
|
||||
|
||||
/mob/living/proc/has_antag_datum(type, check_subtypes) //checks this mob for if it has the antagonist datum. can either check specific type or subtypes
|
||||
if(!islist(antag_datums))
|
||||
return FALSE
|
||||
for(var/i in antag_datums)
|
||||
var/datum/antagonist/D = i
|
||||
if(check_subtypes)
|
||||
if(istype(D, type))
|
||||
return D //if it finds the datum, will return it so you can mess with it
|
||||
else
|
||||
if(D.type == type)
|
||||
return D
|
||||
return FALSE
|
||||
/datum/antagonist/proc/farewell()
|
||||
return
|
||||
@@ -1,92 +1,57 @@
|
||||
//CLOCKCULT PROOF OF CONCEPT
|
||||
|
||||
/datum/antagonist/clockcultist
|
||||
prevented_antag_datum_type = /datum/antagonist/clockcultist
|
||||
some_flufftext = null
|
||||
/datum/antagonist/clockcult
|
||||
var/datum/action/innate/hierophant/hierophant_network = new()
|
||||
|
||||
/datum/antagonist/clockcultist/silent
|
||||
silent_update = TRUE
|
||||
/datum/antagonist/clockcult/silent
|
||||
silent = TRUE
|
||||
|
||||
/datum/antagonist/clockcultist/Destroy()
|
||||
/datum/antagonist/clockcult/Destroy()
|
||||
qdel(hierophant_network)
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/datum/antagonist/clockcultist/can_be_owned(mob/living/new_body)
|
||||
. = ..()
|
||||
if(.)
|
||||
. = is_eligible_servant(new_body)
|
||||
|
||||
/datum/antagonist/clockcultist/give_to_body(mob/living/new_body)
|
||||
if(iscyborg(new_body))
|
||||
var/mob/living/silicon/robot/R = new_body
|
||||
if(R.deployed)
|
||||
var/mob/living/silicon/ai/AI = R.mainframe
|
||||
R.undeploy()
|
||||
var/converted = add_servant_of_ratvar(AI, silent_update)
|
||||
to_chat(AI, "<span class='userdanger'>Anomaly Detected. Returned to core!</span>") //The AI needs to be in its core to properly be converted
|
||||
return converted
|
||||
if(!silent_update)
|
||||
if(issilicon(new_body))
|
||||
to_chat(new_body, "<span class='heavy_brass'>You are unable to compute this truth. Your vision glows a brilliant yellow, and all at once it comes to you. Ratvar, the Clockwork Justiciar, \
|
||||
lies in exile, derelict and forgotten in an unseen realm.</span>")
|
||||
else
|
||||
to_chat(new_body, "<span class='heavy_brass'>[iscarbon(new_body) ? "Your mind is racing! Your body feels incredibly light! ":""]Your world glows a brilliant yellow! All at once it comes to you. \
|
||||
Ratvar, the Clockwork Justiciar, lies in exile, derelict and forgotten in an unseen realm.</span>")
|
||||
. = ..()
|
||||
if(!silent_update && new_body)
|
||||
if(.)
|
||||
new_body.visible_message("<span class='heavy_brass'>[new_body]'s eyes glow a blazing yellow!</span>")
|
||||
to_chat(new_body, "<span class='heavy_brass'>Assist your new companions in their righteous efforts. Your goal is theirs, and theirs yours. You serve the Clockwork Justiciar above all else. \
|
||||
Perform his every whim without hesitation.</span>")
|
||||
else
|
||||
new_body.visible_message("<span class='boldwarning'>[new_body] seems to resist an unseen force!</span>")
|
||||
to_chat(new_body, "<span class='userdanger'>And yet, you somehow push it all away.</span>")
|
||||
|
||||
/datum/antagonist/clockcultist/on_gain()
|
||||
if(SSticker && SSticker.mode && owner.mind)
|
||||
SSticker.mode.servants_of_ratvar += owner.mind
|
||||
SSticker.mode.update_servant_icons_added(owner.mind)
|
||||
if(jobban_isbanned(owner, ROLE_SERVANT_OF_RATVAR))
|
||||
INVOKE_ASYNC(SSticker.mode, /datum/game_mode.proc/replace_jobbaned_player, owner, ROLE_SERVANT_OF_RATVAR, ROLE_SERVANT_OF_RATVAR)
|
||||
if(owner.mind)
|
||||
owner.mind.special_role = "Servant of Ratvar"
|
||||
owner.log_message("<font color=#BE8700>Has been converted to the cult of Ratvar!</font>", INDIVIDUAL_ATTACK_LOG)
|
||||
if(issilicon(owner))
|
||||
/datum/antagonist/clockcult/on_gain()
|
||||
if(!owner)
|
||||
return
|
||||
var/mob/living/current = owner.current
|
||||
if(!istype(current))
|
||||
return
|
||||
if(jobban_isbanned(current, ROLE_SERVANT_OF_RATVAR))
|
||||
addtimer(CALLBACK(SSticker.mode, /datum/game_mode.proc/replace_jobbaned_player, owner, ROLE_SERVANT_OF_RATVAR, ROLE_SERVANT_OF_RATVAR), 0)
|
||||
owner.current.log_message("<font color=#BE8700>Has been converted to the cult of Ratvar!</font>", INDIVIDUAL_ATTACK_LOG)
|
||||
if(issilicon(current))
|
||||
var/mob/living/silicon/S = owner
|
||||
if(iscyborg(S) && !silent_update)
|
||||
to_chat(S, "<span class='boldwarning'>You have been desynced from your master AI.\n\
|
||||
In addition, your onboard camera is no longer active and you have gained additional equipment, including a limited clockwork slab.</span>")
|
||||
if(iscyborg(S) && !silent)
|
||||
to_chat(S, "<span class='boldwarning'>You have been desynced from your master AI.</span>")
|
||||
to_chat(S, "<span class='boldwarning'>In addition, your onboard camera is no longer active and you have gained additional equipment, including a limited clockwork slab.</span>")
|
||||
if(isAI(S))
|
||||
to_chat(S, "<span class='boldwarning'>You are able to use your cameras to listen in on conversations.</span>")
|
||||
to_chat(S, "<span class='heavy_brass'>You can communicate with other servants by using the Hierophant Network action button in the upper left.</span>")
|
||||
else if(isbrain(owner) || isclockmob(owner))
|
||||
to_chat(owner, "<span class='nezbere'>You can communicate with other servants by using the Hierophant Network action button in the upper left.</span>")
|
||||
else if(isbrain(current) || isclockmob(current))
|
||||
to_chat(current, "<span class='nezbere'>You can communicate with other servants by using the Hierophant Network action button in the upper left.</span>")
|
||||
..()
|
||||
if(istype(SSticker.mode, /datum/game_mode/clockwork_cult))
|
||||
var/datum/game_mode/clockwork_cult/C = SSticker.mode
|
||||
C.present_tasks(owner) //Memorize the objectives
|
||||
|
||||
/datum/antagonist/clockcultist/apply_innate_effects()
|
||||
GLOB.all_clockwork_mobs += owner
|
||||
owner.faction |= "ratvar"
|
||||
owner.grant_language(/datum/language/ratvar)
|
||||
owner.update_action_buttons_icon() //because a few clockcult things are action buttons and we may be wearing/holding them for whatever reason, we need to update buttons
|
||||
if(issilicon(owner))
|
||||
var/mob/living/silicon/S = owner
|
||||
/datum/antagonist/clockcult/apply_innate_effects(mob/living/mob_override)
|
||||
. = ..()
|
||||
var/mob/living/current = owner.current
|
||||
if(istype(mob_override))
|
||||
current = mob_override
|
||||
GLOB.all_clockwork_mobs += current
|
||||
SSticker.mode.update_servant_icons_added(owner)
|
||||
current.faction |= "ratvar"
|
||||
current.grant_language(/datum/language/ratvar)
|
||||
current.update_action_buttons_icon() //because a few clockcult things are action buttons and we may be wearing/holding them for whatever reason, we need to update buttons
|
||||
if(issilicon(current))
|
||||
var/mob/living/silicon/S = current
|
||||
if(iscyborg(S))
|
||||
var/mob/living/silicon/robot/R = S
|
||||
if(!R.shell)
|
||||
R.UnlinkSelf()
|
||||
R.UnlinkSelf()
|
||||
R.module.rebuild_modules()
|
||||
else if(isAI(S))
|
||||
var/mob/living/silicon/ai/A = S
|
||||
A.can_be_carded = FALSE
|
||||
A.requires_power = POWER_REQ_CLOCKCULT
|
||||
var/list/AI_frame = list(mutable_appearance('icons/mob/clockwork_mobs.dmi', "aiframe")) //make the AI's cool frame
|
||||
for(var/d in GLOB.cardinal)
|
||||
AI_frame += image('icons/mob/clockwork_mobs.dmi', A, "eye[rand(1, 10)]", dir = d) //the eyes are randomly fast or slow
|
||||
A.add_overlay(AI_frame)
|
||||
if(!A.lacks_power())
|
||||
A.ai_restore_power()
|
||||
if(A.eyeobj)
|
||||
@@ -106,58 +71,55 @@
|
||||
hierophant_network.title = "Silicon"
|
||||
hierophant_network.span_for_name = "nezbere"
|
||||
hierophant_network.span_for_message = "brass"
|
||||
else if(isbrain(owner))
|
||||
hierophant_network.Grant(owner)
|
||||
else if(isbrain(current))
|
||||
hierophant_network.Grant(current)
|
||||
hierophant_network.title = "Vessel"
|
||||
hierophant_network.span_for_name = "nezbere"
|
||||
hierophant_network.span_for_message = "alloy"
|
||||
else if(isclockmob(owner))
|
||||
hierophant_network.Grant(owner)
|
||||
else if(isclockmob(current))
|
||||
hierophant_network.Grant(current)
|
||||
hierophant_network.title = "Construct"
|
||||
hierophant_network.span_for_name = "nezbere"
|
||||
hierophant_network.span_for_message = "brass"
|
||||
owner.throw_alert("clockinfo", /obj/screen/alert/clockwork/infodump)
|
||||
current.throw_alert("clockinfo", /obj/screen/alert/clockwork/infodump)
|
||||
if(!GLOB.clockwork_gateway_activated)
|
||||
owner.throw_alert("scripturereq", /obj/screen/alert/clockwork/scripture_reqs)
|
||||
..()
|
||||
current.throw_alert("scripturereq", /obj/screen/alert/clockwork/scripture_reqs)
|
||||
update_slab_info()
|
||||
|
||||
/datum/antagonist/clockcultist/remove_innate_effects()
|
||||
GLOB.all_clockwork_mobs -= owner
|
||||
owner.faction -= "ratvar"
|
||||
owner.remove_language(/datum/language/ratvar)
|
||||
owner.clear_alert("clockinfo")
|
||||
owner.clear_alert("scripturereq")
|
||||
for(var/datum/action/innate/function_call/F in owner.actions) //Removes any bound Ratvarian spears
|
||||
|
||||
/datum/antagonist/clockcult/remove_innate_effects(mob/living/mob_override)
|
||||
var/mob/living/current = owner.current
|
||||
if(istype(mob_override))
|
||||
current = mob_override
|
||||
GLOB.all_clockwork_mobs -= current
|
||||
current.faction -= "ratvar"
|
||||
current.remove_language(/datum/language/ratvar)
|
||||
current.clear_alert("clockinfo")
|
||||
current.clear_alert("scripturereq")
|
||||
for(var/datum/action/innate/function_call/F in owner.current.actions) //Removes any bound Ratvarian spears
|
||||
qdel(F)
|
||||
if(issilicon(owner))
|
||||
var/mob/living/silicon/S = owner
|
||||
if(issilicon(current))
|
||||
var/mob/living/silicon/S = current
|
||||
if(isAI(S))
|
||||
var/mob/living/silicon/ai/A = S
|
||||
A.can_be_carded = initial(A.can_be_carded)
|
||||
A.requires_power = initial(A.requires_power)
|
||||
A.cut_overlays()
|
||||
S.make_laws()
|
||||
S.update_icons()
|
||||
S.show_laws()
|
||||
var/mob/living/temp_owner = owner
|
||||
var/mob/living/temp_owner = current
|
||||
..()
|
||||
if(iscyborg(temp_owner))
|
||||
var/mob/living/silicon/robot/R = temp_owner
|
||||
R.module.rebuild_modules()
|
||||
if(temp_owner)
|
||||
temp_owner.update_action_buttons_icon() //because a few clockcult things are action buttons and we may be wearing/holding them, we need to update buttons
|
||||
update_slab_info()
|
||||
|
||||
/datum/antagonist/clockcultist/on_remove()
|
||||
if(!silent_update)
|
||||
owner.visible_message("<span class='big'>[owner] seems to have remembered their true allegiance!</span>", \
|
||||
/datum/antagonist/clockcult/on_removal()
|
||||
. = ..()
|
||||
if(!silent)
|
||||
owner.current.visible_message("<span class='big'>[owner] seems to have remembered their true allegiance!</span>", \
|
||||
"<span class='userdanger'>A cold, cold darkness flows through your mind, extinguishing the Justiciar's light and all of your memories as his servant.</span>")
|
||||
if(SSticker && SSticker.mode && owner.mind)
|
||||
SSticker.mode.servants_of_ratvar -= owner.mind
|
||||
SSticker.mode.update_servant_icons_removed(owner.mind)
|
||||
if(owner.mind)
|
||||
owner.mind.wipe_memory()
|
||||
owner.mind.special_role = null
|
||||
owner.log_message("<font color=#BE8700>Has renounced the cult of Ratvar!</font>", INDIVIDUAL_ATTACK_LOG)
|
||||
if(iscyborg(owner))
|
||||
to_chat(owner, "<span class='warning'>Despite your freedom from Ratvar's influence, you are still irreparably damaged and no longer possess certain functions such as AI linking.</span>")
|
||||
..()
|
||||
owner.current.log_message("<font color=#BE8700>Has renounced the cult of Ratvar!</font>", INDIVIDUAL_ATTACK_LOG)
|
||||
if(iscyborg(owner.current))
|
||||
to_chat(owner.current, "<span class='warning'>Despite your freedom from Ratvar's influence, you are still irreparably damaged and no longer possess certain functions such as AI linking.</span>")
|
||||
@@ -1,50 +1,33 @@
|
||||
/datum/antagonist/cultist
|
||||
prevented_antag_datum_type = /datum/antagonist/cultist
|
||||
some_flufftext = null
|
||||
var/datum/action/innate/cultcomm/communion = new()
|
||||
/datum/antagonist/cult
|
||||
var/datum/action/innate/cultcomm/communion = new
|
||||
|
||||
/datum/antagonist/cultist/Destroy()
|
||||
/datum/antagonist/cult/Destroy()
|
||||
qdel(communion)
|
||||
return ..()
|
||||
|
||||
/datum/antagonist/cultist/can_be_owned(mob/living/new_body)
|
||||
/datum/antagonist/cult/on_gain()
|
||||
. = ..()
|
||||
if(.)
|
||||
. = is_convertable_to_cult(new_body)
|
||||
if(!owner)
|
||||
return
|
||||
if(jobban_isbanned(owner.current, ROLE_CULTIST))
|
||||
addtimer(CALLBACK(SSticker.mode, /datum/game_mode.proc/replace_jobbaned_player, owner, ROLE_CULTIST, ROLE_CULTIST), 0)
|
||||
owner.current.log_message("<font color=#960000>Has been converted to the cult of Nar'Sie!</font>", INDIVIDUAL_ATTACK_LOG)
|
||||
|
||||
/datum/antagonist/cultist/on_gain()
|
||||
if(SSticker && SSticker.mode && owner.mind)
|
||||
SSticker.mode.cult += owner.mind
|
||||
SSticker.mode.update_cult_icons_added(owner.mind)
|
||||
if(istype(SSticker.mode, /datum/game_mode/cult))
|
||||
var/datum/game_mode/cult/C = SSticker.mode
|
||||
C.memorize_cult_objectives(owner.mind)
|
||||
if(jobban_isbanned(owner, ROLE_CULTIST))
|
||||
INVOKE_ASYNC(SSticker.mode, /datum/game_mode.proc/replace_jobbaned_player, owner, ROLE_CULTIST, ROLE_CULTIST)
|
||||
if(owner.mind)
|
||||
owner.mind.special_role = "Cultist"
|
||||
owner.log_message("<font color=#960000>Has been converted to the cult of Nar'Sie!</font>", INDIVIDUAL_ATTACK_LOG)
|
||||
..()
|
||||
|
||||
/datum/antagonist/cultist/apply_innate_effects()
|
||||
owner.faction |= "cult"
|
||||
owner.verbs += /mob/living/proc/cult_help
|
||||
/datum/antagonist/cult/apply_innate_effects()
|
||||
. = ..()
|
||||
owner.current.faction |= "cult"
|
||||
owner.current.verbs += /mob/living/proc/cult_help
|
||||
communion.Grant(owner)
|
||||
..()
|
||||
|
||||
/datum/antagonist/cultist/remove_innate_effects()
|
||||
owner.faction -= "cult"
|
||||
owner.verbs -= /mob/living/proc/cult_help
|
||||
..()
|
||||
/datum/antagonist/cult/remove_innate_effects()
|
||||
. = ..()
|
||||
owner.current.faction -= "cult"
|
||||
owner.current.verbs -= /mob/living/proc/cult_help
|
||||
|
||||
/datum/antagonist/cultist/on_remove()
|
||||
if(owner.mind)
|
||||
owner.mind.wipe_memory()
|
||||
if(SSticker && SSticker.mode)
|
||||
SSticker.mode.cult -= owner.mind
|
||||
SSticker.mode.update_cult_icons_removed(owner.mind)
|
||||
|
||||
/datum/antagonist/cult/on_removal()
|
||||
. = ..()
|
||||
to_chat(owner, "<span class='userdanger'>An unfamiliar white light flashes through your mind, cleansing the taint of the Dark One and all your memories as its servant.</span>")
|
||||
owner.log_message("<font color=#960000>Has renounced the cult of Nar'Sie!</font>", INDIVIDUAL_ATTACK_LOG)
|
||||
if(!silent_update)
|
||||
owner.visible_message("<span class='big'>[owner] looks like [owner.p_they()] just reverted to their old faith!</span>")
|
||||
..()
|
||||
owner.current.log_message("<font color=#960000>Has renounced the cult of Nar'Sie!</font>", INDIVIDUAL_ATTACK_LOG)
|
||||
if(!silent)
|
||||
owner.current.visible_message("<span class='big'>[owner] looks like [owner.current.p_they()] just reverted to their old faith!</span>")
|
||||
@@ -27,6 +27,7 @@
|
||||
. += "---"
|
||||
.["Call Proc"] = "?_src_=vars;proc_call=\ref[src]"
|
||||
.["Mark Object"] = "?_src_=vars;mark_object=\ref[src]"
|
||||
.["Delete"] = "?_src_=vars;delete=\ref[src]"
|
||||
|
||||
|
||||
/datum/proc/on_reagent_change()
|
||||
@@ -93,7 +94,6 @@
|
||||
CLONE:<font size='1'><a href='?_src_=vars;mobToDamage=[refid];adjustDamage=clone'>[M.getCloneLoss()]</a>
|
||||
BRAIN:<font size='1'><a href='?_src_=vars;mobToDamage=[refid];adjustDamage=brain'>[M.getBrainLoss()]</a>
|
||||
STAMINA:<font size='1'><a href='?_src_=vars;mobToDamage=[refid];adjustDamage=stamina'>[M.getStaminaLoss()]</a>
|
||||
AROUSAL:<font size='1'><a href='?_src_=vars;mobToDamage=[refid];adjustDamage=arousal'>[M.getArousalLoss()]</a>
|
||||
</font>
|
||||
"}
|
||||
else
|
||||
@@ -446,7 +446,7 @@
|
||||
var/list/L = value
|
||||
var/list/items = list()
|
||||
|
||||
if (L.len > 0 && !(name == "underlays" || name == "overlays" || L.len > 500))
|
||||
if (L.len > 0 && !(name == "underlays" || name == "overlays" || L.len > (IS_NORMAL_LIST(L) ? 50 : 150)))
|
||||
for (var/i in 1 to L.len)
|
||||
var/key = L[i]
|
||||
var/val
|
||||
@@ -526,6 +526,16 @@
|
||||
if(T)
|
||||
callproc_datum(T)
|
||||
|
||||
else if(href_list["delete"])
|
||||
if(!check_rights(R_DEBUG, 0))
|
||||
return
|
||||
|
||||
var/datum/D = locate(href_list["delete"])
|
||||
if(!D)
|
||||
to_chat(usr, "Unable to locate item!")
|
||||
admin_delete(D)
|
||||
href_list["datumrefresh"] = href_list["delete"]
|
||||
|
||||
else if(href_list["regenerateicons"])
|
||||
if(!check_rights(0))
|
||||
return
|
||||
@@ -1155,8 +1165,6 @@
|
||||
L.adjustCloneLoss(amount)
|
||||
if("stamina")
|
||||
L.adjustStaminaLoss(amount)
|
||||
if("arousal")
|
||||
L.adjustArousalLoss(amount)
|
||||
else
|
||||
to_chat(usr, "You caused an error. DEBUG: Text:[Text] Mob:[L]")
|
||||
return
|
||||
@@ -1167,3 +1175,4 @@
|
||||
message_admins(msg)
|
||||
admin_ticket_log(L, msg)
|
||||
href_list["datumrefresh"] = href_list["mobToDamage"]
|
||||
|
||||
|
||||
@@ -35,10 +35,6 @@
|
||||
var/msg = select_message_type(user)
|
||||
if(params && message_param)
|
||||
msg = select_param(user, params)
|
||||
if(findtext(msg, "their"))
|
||||
msg = replacetext(msg, "their", user.p_their())
|
||||
if(findtext(msg, "them"))
|
||||
msg = replacetext(msg, "them", user.p_them())
|
||||
if(findtext(msg, "%s"))
|
||||
msg = replacetext(msg, "%s", user.p_s())
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
for(var/line in testmerge)
|
||||
if(line)
|
||||
log_world("Test merge active of PR #[line]")
|
||||
feedback_add_details("testmerged_prs","[line]")
|
||||
SSblackbox.add_details("testmerged_prs","[line]")
|
||||
log_world("Based off master commit [parentcommit]")
|
||||
else
|
||||
log_world(parentcommit)
|
||||
@@ -105,13 +105,13 @@
|
||||
probs[ctag] = 1
|
||||
prob_sum += config.probabilities[ctag]
|
||||
if(current_odds_differ)
|
||||
src <<"<b>Game Mode Odds for current round:</b>"
|
||||
to_chat(src, "<b>Game Mode Odds for current round:</b>")
|
||||
for(var/ctag in probs)
|
||||
if(config.probabilities[ctag] > 0)
|
||||
var/percentage = round(config.probabilities[ctag] / prob_sum * 100, 0.1)
|
||||
to_chat(src, "[ctag] [percentage]%")
|
||||
|
||||
src <<"<b>All Game Mode Odds:</b>"
|
||||
to_chat(src, "<b>All Game Mode Odds:</b>")
|
||||
var/sum = 0
|
||||
for(var/ctag in config.probabilities)
|
||||
sum += config.probabilities[ctag]
|
||||
|
||||
@@ -657,7 +657,7 @@
|
||||
/obj/item/weapon/cqc_manual/attack_self(mob/living/carbon/human/user)
|
||||
if(!istype(user) || !user)
|
||||
return
|
||||
user <<"<span class='boldannounce'>You remember the basics of CQC.</span>"
|
||||
to_chat(user, "<span class='boldannounce'>You remember the basics of CQC.</span>")
|
||||
var/datum/martial_art/cqc/D = new(null)
|
||||
D.teach(user)
|
||||
user.drop_item()
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
return FALSE
|
||||
|
||||
//For spawning mineral sheets; internal use only
|
||||
/datum/material_container/proc/retrieve(sheet_amt, datum/material/M)
|
||||
/datum/material_container/proc/retrieve(sheet_amt, datum/material/M, target = null)
|
||||
if(!M.sheet_type)
|
||||
return 0
|
||||
if(sheet_amt > 0)
|
||||
@@ -149,26 +149,28 @@
|
||||
use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.id)
|
||||
sheet_amt -= MAX_STACK_SIZE
|
||||
if(round((sheet_amt * MINERAL_MATERIAL_AMOUNT) / MINERAL_MATERIAL_AMOUNT))
|
||||
new M.sheet_type(get_turf(owner), sheet_amt)
|
||||
var/obj/item/stack/sheet/s = new M.sheet_type(get_turf(owner), sheet_amt)
|
||||
if(target)
|
||||
s.forceMove(target)
|
||||
count += sheet_amt
|
||||
use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.id)
|
||||
return count
|
||||
return 0
|
||||
|
||||
/datum/material_container/proc/retrieve_sheets(sheet_amt, id)
|
||||
/datum/material_container/proc/retrieve_sheets(sheet_amt, id, target = null)
|
||||
if(materials[id])
|
||||
return retrieve(sheet_amt, materials[id])
|
||||
return retrieve(sheet_amt, materials[id], target)
|
||||
return 0
|
||||
|
||||
/datum/material_container/proc/retrieve_amount(amt, id)
|
||||
return retrieve_sheets(amount2sheet(amt), id)
|
||||
/datum/material_container/proc/retrieve_amount(amt, id, target)
|
||||
return retrieve_sheets(amount2sheet(amt), id, target)
|
||||
|
||||
/datum/material_container/proc/retrieve_all()
|
||||
/datum/material_container/proc/retrieve_all(target = null)
|
||||
var/result = 0
|
||||
var/datum/material/M
|
||||
for(var/MAT in materials)
|
||||
M = materials[MAT]
|
||||
result += retrieve_sheets(amount2sheet(M.amount), MAT)
|
||||
result += retrieve_sheets(amount2sheet(M.amount), MAT, target)
|
||||
return result
|
||||
|
||||
/datum/material_container/proc/has_space(amt = 0)
|
||||
|
||||
+51
-5
@@ -54,6 +54,7 @@
|
||||
var/linglink
|
||||
|
||||
var/miming = 0 // Mime's vow of silence
|
||||
var/list/antag_datums = list()
|
||||
var/antag_hud_icon_state = null //this mind's ANTAG_HUD should have this icon_state
|
||||
var/datum/atom_hud/antag/antag_hud = null //this mind's antag HUD
|
||||
var/datum/gang/gang_datum //Which gang this mind belongs to, if any
|
||||
@@ -86,13 +87,13 @@
|
||||
if(new_character.mind) //disassociate any mind currently in our new body's mind variable
|
||||
new_character.mind.current = null
|
||||
|
||||
if(istype(current) && islist(current.antag_datums)) //wow apparently current isn't always living good fucking job SOMEONE
|
||||
for(var/i in current.antag_datums)
|
||||
var/datum/antagonist/D = i
|
||||
D.transfer_to_new_body(new_character)
|
||||
var/datum/atom_hud/antag/hud_to_transfer = antag_hud//we need this because leave_hud() will clear this list
|
||||
var/mob/living/old_current = current
|
||||
current = new_character //associate ourself with our new body
|
||||
new_character.mind = src //and associate our new body with ourself
|
||||
for(var/a in antag_datums) //Makes sure all antag datums effects are applied in the new body
|
||||
var/datum/antagonist/A = a
|
||||
A.on_body_transfer(old_current, current)
|
||||
if(iscarbon(new_character))
|
||||
var/mob/living/carbon/C = new_character
|
||||
C.last_mind = src
|
||||
@@ -108,6 +109,51 @@
|
||||
/datum/mind/proc/wipe_memory()
|
||||
memory = null
|
||||
|
||||
// Datum antag mind procs
|
||||
/datum/mind/proc/add_antag_datum(datum_type, on_gain = TRUE)
|
||||
if(!datum_type)
|
||||
return
|
||||
if(!can_hold_antag_datum(datum_type))
|
||||
return
|
||||
var/datum/antagonist/A = new datum_type(src)
|
||||
antag_datums += A
|
||||
if(on_gain)
|
||||
A.on_gain()
|
||||
|
||||
/datum/mind/proc/remove_antag_datum(datum_type)
|
||||
if(!datum_type)
|
||||
return
|
||||
var/datum/antagonist/A = has_antag_datum(datum_type)
|
||||
if(A)
|
||||
A.on_removal()
|
||||
|
||||
/datum/mind/proc/remove_all_antag_datums() //For the Lazy amongst us.
|
||||
for(var/a in antag_datums)
|
||||
var/datum/antagonist/A = a
|
||||
A.on_removal()
|
||||
|
||||
/datum/mind/proc/has_antag_datum(datum_type, check_subtypes = TRUE)
|
||||
if(!datum_type)
|
||||
return
|
||||
. = FALSE
|
||||
for(var/a in antag_datums)
|
||||
var/datum/antagonist/A = a
|
||||
if(check_subtypes && istype(A, datum_type))
|
||||
return A
|
||||
else if(A.type == datum_type)
|
||||
return A
|
||||
|
||||
/datum/mind/proc/can_hold_antag_datum(datum_type)
|
||||
if(!datum_type)
|
||||
return
|
||||
. = TRUE
|
||||
if(has_antag_datum(datum_type))
|
||||
return FALSE
|
||||
for(var/i in antag_datums)
|
||||
var/datum/antagonist/A = i
|
||||
if(is_type_in_typecache(A, A.typecache_datum_blacklist))
|
||||
return FALSE
|
||||
|
||||
|
||||
/*
|
||||
Removes antag type's references from a mind.
|
||||
@@ -1143,7 +1189,7 @@
|
||||
log_admin("[key_name_admin(usr)] has made [current] unable to ascend as a devil.")
|
||||
return
|
||||
if(!ishuman(current) && !iscyborg(current))
|
||||
usr << "<span class='warning'>This only works on humans and cyborgs!</span>"
|
||||
to_chat(usr, "<span class='warning'>This only works on humans and cyborgs!</span>")
|
||||
return
|
||||
SSticker.mode.devils += src
|
||||
special_role = "devil"
|
||||
|
||||
@@ -43,6 +43,13 @@
|
||||
name = "Asteroid 5"
|
||||
description = "Oh my god, another giant rock!"
|
||||
|
||||
/datum/map_template/ruin/space/deep_storage
|
||||
id = "deep-storage"
|
||||
suffix = "deepstorage.dmm"
|
||||
name = "Survivalist Bunker"
|
||||
description = "Assume the best, prepare for the worst. Generally, you should do so by digging a three man heavily fortified bunker into a giant unused asteroid. \
|
||||
Then make it self sufficient, mask any evidence of construction, hook it covertly into the telecommunications network and hope for the best."
|
||||
|
||||
/datum/map_template/ruin/space/bigderelict1
|
||||
id = "bigderelict1"
|
||||
suffix = "bigderelict1.dmm"
|
||||
|
||||
@@ -72,6 +72,8 @@
|
||||
add_logs(owner, null, "gained Vanguard stun immunity")
|
||||
owner.add_stun_absorption("vanguard", 200, 1, "'s yellow aura momentarily intensifies!", "Your ward absorbs the stun!", " radiating with a soft yellow light!")
|
||||
owner.visible_message("<span class='warning'>[owner] begins to faintly glow!</span>", "<span class='brass'>You will absorb all stuns for the next twenty seconds.</span>")
|
||||
owner.SetStunned(0, FALSE)
|
||||
owner.SetWeakened(0)
|
||||
progbar = new(owner, duration, owner)
|
||||
progbar.bar.color = list("#FAE48C", "#FAE48C", "#FAE48C", rgb(0,0,0))
|
||||
progbar.update(duration - world.time)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
var/tick_interval = 10 //How many deciseconds between ticks, approximately. Leave at 10 for every second.
|
||||
var/mob/living/owner //The mob affected by the status effect.
|
||||
var/status_type = STATUS_EFFECT_UNIQUE //How many of the effect can be on one mob, and what happens when you try to add another
|
||||
var/on_remove_on_mob_delete = FALSE //if we call on_remove() when the mob is deleted
|
||||
var/alert_type = /obj/screen/alert/status_effect //the alert thrown by the status effect, contains name and description
|
||||
|
||||
/datum/status_effect/New(mob/living/new_owner)
|
||||
@@ -21,8 +22,9 @@
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
if(owner)
|
||||
owner.clear_alert(id)
|
||||
on_remove()
|
||||
LAZYREMOVE(owner.status_effects, src)
|
||||
on_remove()
|
||||
owner = null
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/proc/start_ticking()
|
||||
@@ -52,8 +54,8 @@
|
||||
|
||||
/datum/status_effect/proc/on_apply() //Called whenever the buff is applied.
|
||||
/datum/status_effect/proc/tick() //Called every tick.
|
||||
/datum/status_effect/proc/on_remove() //Called whenever the buff expires or is removed.
|
||||
/datum/status_effect/proc/be_replaced() //Called instead of on_remove when a status effect is replaced by itself
|
||||
/datum/status_effect/proc/on_remove() //Called whenever the buff expires or is removed; do note that at the point this is called, it is out of the owner's status_effects but owner is not yet null
|
||||
/datum/status_effect/proc/be_replaced() //Called instead of on_remove when a status effect is replaced by itself or when a status effect with on_remove_on_mob_delete = FALSE has its mob deleted
|
||||
owner.clear_alert(id)
|
||||
LAZYREMOVE(owner.status_effects, src)
|
||||
owner = null
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
|
||||
var/has_gravity = 0
|
||||
var/noteleport = 0 //Are you forbidden from teleporting to the area? (centcomm, mobs, wizard, hand teleporter)
|
||||
var/hidden = FALSE //Hides area from player Teleport function.
|
||||
var/safe = 0 //Is the area teleport-safe: no space / radiation / aggresive mobs / other dangers
|
||||
|
||||
var/no_air = null
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
icon_state = "Holodeck"
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
|
||||
flags = 0
|
||||
hidden = TRUE
|
||||
|
||||
var/obj/machinery/computer/holodeck/linked
|
||||
var/restricted = 0 // if true, program goes on emag list
|
||||
@@ -95,16 +96,15 @@
|
||||
/area/holodeck/rec_center/kobayashi
|
||||
name = "Holodeck - Kobayashi Maru"
|
||||
|
||||
/area/holodeck/rec_center/winterwonderland
|
||||
name = "Holodeck - Winter Wonderland"
|
||||
|
||||
// Bad programs
|
||||
|
||||
/area/holodeck/rec_center/burn
|
||||
name = "Holodeck - Atmospheric Burn Test"
|
||||
restricted = 1
|
||||
|
||||
/area/holodeck/rec_center/winterwonderland
|
||||
name = "Holodeck - Winter Wonderland"
|
||||
restricted = 1
|
||||
|
||||
/area/holodeck/rec_center/wildlife
|
||||
name = "Holodeck - Wildlife Simulation"
|
||||
restricted = 1
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
name = "\improper Unexplored Location"
|
||||
icon_state = "away"
|
||||
has_gravity = 1
|
||||
hidden = TRUE
|
||||
|
||||
|
||||
/area/ruin/unpowered
|
||||
|
||||
+20
-10
@@ -39,20 +39,21 @@
|
||||
|
||||
var/do_initialize = SSatoms.initialized
|
||||
if(do_initialize > INITIALIZATION_INSSATOMS)
|
||||
if(QDELETED(src))
|
||||
CRASH("Found new qdeletion in type [type]!")
|
||||
var/mapload = do_initialize == INITIALIZATION_INNEW_MAPLOAD
|
||||
args[1] = mapload
|
||||
if(Initialize(arglist(args)) && mapload)
|
||||
LAZYADD(SSatoms.late_loaders, src)
|
||||
args[1] = do_initialize == INITIALIZATION_INNEW_MAPLOAD
|
||||
if(SSatoms.InitAtom(src, args))
|
||||
//we were deleted
|
||||
return
|
||||
|
||||
var/list/created = SSatoms.created_atoms
|
||||
if(created)
|
||||
created += src
|
||||
|
||||
//Called after New if the map is being loaded. mapload = TRUE
|
||||
//Called from base of New if the map is being loaded. mapload = FALSE
|
||||
//This base must be called or derivatives must set initialized to TRUE to prevent repeat calls
|
||||
//Derivatives must not sleep
|
||||
//Returning TRUE while mapload is TRUE will cause the object to be initialized again with mapload = FALSE when everything else is done
|
||||
//(Useful for things that requires turfs to have air). This base may only be called once, however
|
||||
//This base must be called or derivatives must set initialized to TRUE
|
||||
//must not sleep
|
||||
//Other parameters are passed from New (excluding loc), this does not happen if mapload is TRUE
|
||||
//Must return an Initialize hint. Defined in __DEFINES/subsystems.dm
|
||||
|
||||
//Note: the following functions don't call the base for optimization and must copypasta:
|
||||
// /turf/Initialize
|
||||
@@ -75,7 +76,16 @@
|
||||
if (opacity && isturf(loc))
|
||||
var/turf/T = loc
|
||||
T.has_opaque_atom = TRUE // No need to recalculate it in this case, it's guaranteed to be on afterwards anyways.
|
||||
return INITIALIZE_HINT_NORMAL
|
||||
|
||||
//called if Initialize returns INITIALIZE_HINT_LATELOAD
|
||||
//This version shouldn't be called
|
||||
/atom/proc/LateInitialize()
|
||||
var/static/list/warned_types = list()
|
||||
if(!warned_types[type])
|
||||
WARNING("Old style LateInitialize behaviour detected in [type]!")
|
||||
warned_types[type] = TRUE
|
||||
Initialize(FALSE)
|
||||
|
||||
/atom/Destroy()
|
||||
if(alternate_appearances)
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
return ..()
|
||||
|
||||
/atom/movable/Initialize(mapload)
|
||||
..()
|
||||
. = ..()
|
||||
for(var/L in initial_languages)
|
||||
grant_language(L)
|
||||
|
||||
@@ -120,7 +120,7 @@
|
||||
|
||||
if(flags & CLEAN_ON_MOVE)
|
||||
clean_on_move()
|
||||
|
||||
|
||||
var/datum/proximity_monitor/proximity_monitor = src.proximity_monitor
|
||||
if(proximity_monitor)
|
||||
proximity_monitor.HandleMove()
|
||||
@@ -562,7 +562,7 @@
|
||||
return
|
||||
else
|
||||
var/turf/currentturf = get_turf(src)
|
||||
get(src, /mob) << "<span class='danger'>You can't help but feel that you just lost something back there...</span>"
|
||||
to_chat(get(src, /mob), "<span class='danger'>You can't help but feel that you just lost something back there...</span>")
|
||||
var/turf/targetturf = relocate()
|
||||
log_game("[src] has been moved out of bounds in [COORD(currentturf)]. Moving it to [COORD(targetturf)].")
|
||||
if(HAS_SECONDARY_FLAG(src, INFORM_ADMINS_ON_RELOCATE))
|
||||
@@ -627,4 +627,4 @@
|
||||
/atom/movable/proc/ConveyorMove(movedir)
|
||||
set waitfor = FALSE
|
||||
if(!anchored && has_gravity())
|
||||
step(src, movedir)
|
||||
step(src, movedir)
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
if(round_converted) //So badmin blobs later don't step on the dead natural blobs metaphorical toes
|
||||
..()
|
||||
if(blobwincount <= GLOB.blobs_legit.len)
|
||||
feedback_set_details("round_end_result","win - blob took over")
|
||||
SSblackbox.set_details("round_end_result","win - blob took over")
|
||||
to_chat(world, "<FONT size = 3><B>The blob has taken over the station!</B></FONT>")
|
||||
to_chat(world, "<B>The entire station was eaten by the Blob!</B>")
|
||||
log_game("Blob mode completed with a blob victory.")
|
||||
@@ -28,7 +28,7 @@
|
||||
SSticker.news_report = BLOB_WIN
|
||||
|
||||
else if(station_was_nuked)
|
||||
feedback_set_details("round_end_result","halfwin - nuke")
|
||||
SSblackbox.set_details("round_end_result","halfwin - nuke")
|
||||
to_chat(world, "<FONT size = 3><B>Partial Win: The station has been destroyed!</B></FONT>")
|
||||
to_chat(world, "<B>Directive 7-12 has been successfully carried out, preventing the Blob from spreading.</B>")
|
||||
log_game("Blob mode completed with a tie (station destroyed).")
|
||||
@@ -36,7 +36,7 @@
|
||||
SSticker.news_report = BLOB_NUKE
|
||||
|
||||
else if(!GLOB.blob_cores.len)
|
||||
feedback_set_details("round_end_result","loss - blob eliminated")
|
||||
SSblackbox.set_details("round_end_result","loss - blob eliminated")
|
||||
to_chat(world, "<FONT size = 3><B>The staff has won!</B></FONT>")
|
||||
to_chat(world, "<B>The alien organism has been eradicated from the station!</B>")
|
||||
log_game("Blob mode completed with a crew victory.")
|
||||
|
||||
@@ -254,19 +254,19 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
|
||||
for(var/datum/objective/objective in changeling.objectives)
|
||||
if(objective.check_completion())
|
||||
text += "<br><b>Objective #[count]</b>: [objective.explanation_text] <font color='green'><b>Success!</b></font>"
|
||||
feedback_add_details("changeling_objective","[objective.type]|SUCCESS")
|
||||
SSblackbox.add_details("changeling_objective","[objective.type]|SUCCESS")
|
||||
else
|
||||
text += "<br><b>Objective #[count]</b>: [objective.explanation_text] <span class='danger'>Fail.</span>"
|
||||
feedback_add_details("changeling_objective","[objective.type]|FAIL")
|
||||
SSblackbox.add_details("changeling_objective","[objective.type]|FAIL")
|
||||
changelingwin = 0
|
||||
count++
|
||||
|
||||
if(changelingwin)
|
||||
text += "<br><font color='green'><b>The changeling was successful!</b></font>"
|
||||
feedback_add_details("changeling_success","SUCCESS")
|
||||
SSblackbox.add_details("changeling_success","SUCCESS")
|
||||
else
|
||||
text += "<br><span class='boldannounce'>The changeling has failed.</span>"
|
||||
feedback_add_details("changeling_success","FAIL")
|
||||
SSblackbox.add_details("changeling_success","FAIL")
|
||||
text += "<br>"
|
||||
|
||||
to_chat(world, text)
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
/obj/effect/proc_holder/changeling/proc/on_purchase(mob/user, is_respec)
|
||||
if(!is_respec)
|
||||
feedback_add_details("changeling_power_purchase",name)
|
||||
SSblackbox.add_details("changeling_power_purchase",name)
|
||||
|
||||
/obj/effect/proc_holder/changeling/proc/on_refund(mob/user)
|
||||
return
|
||||
@@ -37,7 +37,7 @@
|
||||
return
|
||||
var/datum/changeling/c = user.mind.changeling
|
||||
if(sting_action(user, target))
|
||||
feedback_add_details("changeling_powers",name)
|
||||
SSblackbox.add_details("changeling_powers",name)
|
||||
sting_feedback(user, target)
|
||||
take_chemical_cost(c)
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
mind.changeling.purchasedpowers+=S
|
||||
S.on_purchase(src, is_respec)
|
||||
if(is_respec)
|
||||
feedback_add_details("changeling_power_purchase","Readapt")
|
||||
SSblackbox.add_details("changeling_power_purchase","Readapt")
|
||||
|
||||
var/mob/living/carbon/C = src //only carbons have dna now, so we have to typecaste
|
||||
if(ishuman(C))
|
||||
|
||||
@@ -42,13 +42,13 @@
|
||||
to_chat(target, "<span class='userdanger'>You feel a sharp stabbing pain!</span>")
|
||||
target.take_overall_damage(40)
|
||||
|
||||
feedback_add_details("changeling_powers","Absorb DNA|[i]")
|
||||
SSblackbox.add_details("changeling_powers","Absorb DNA|[i]")
|
||||
if(!do_mob(user, target, 150))
|
||||
to_chat(user, "<span class='warning'>Our absorption of [target] has been interrupted!</span>")
|
||||
changeling.isabsorbing = 0
|
||||
return
|
||||
|
||||
feedback_add_details("changeling_powers","Absorb DNA|4")
|
||||
SSblackbox.add_details("changeling_powers","Absorb DNA|4")
|
||||
user.visible_message("<span class='danger'>[user] sucks the fluids from [target]!</span>", "<span class='notice'>We have absorbed [target].</span>")
|
||||
to_chat(target, "<span class='userdanger'>You are absorbed by the changeling!</span>")
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
to_chat(target, "<font color=#800040><span class='boldannounce'>You can now communicate in the changeling hivemind, say \":g message\" to communicate!</span>")
|
||||
target.reagents.add_reagent("salbutamol", 40) // So they don't choke to death while you interrogate them
|
||||
sleep(1800)
|
||||
feedback_add_details("changeling_powers","Hivemind Link|[i]")
|
||||
SSblackbox.add_details("changeling_powers","Hivemind Link|[i]")
|
||||
if(!do_mob(user, target, 20))
|
||||
to_chat(user, "<span class='warning'>Our link with [target] has ended!</span>")
|
||||
changeling.islinking = 0
|
||||
|
||||
@@ -46,7 +46,7 @@ Credit where due:
|
||||
///////////
|
||||
|
||||
/proc/is_servant_of_ratvar(mob/living/M)
|
||||
return istype(M) && M.has_antag_datum(/datum/antagonist/clockcultist, TRUE)
|
||||
return istype(M) && M.mind && M.mind.has_antag_datum(ANTAG_DATUM_CLOCKCULT)
|
||||
|
||||
/proc/is_eligible_servant(mob/living/M)
|
||||
if(!istype(M))
|
||||
@@ -65,17 +65,21 @@ Credit where due:
|
||||
return FALSE
|
||||
|
||||
/proc/add_servant_of_ratvar(mob/living/L, silent = FALSE)
|
||||
var/update_type = /datum/antagonist/clockcultist
|
||||
if(!L || !L.mind)
|
||||
return
|
||||
var/update_type = ANTAG_DATUM_CLOCKCULT
|
||||
if(silent)
|
||||
update_type = /datum/antagonist/clockcultist/silent
|
||||
. = L.gain_antag_datum(update_type)
|
||||
update_type = ANTAG_DATUM_CLOCKCULT_SILENT
|
||||
. = L.mind.add_antag_datum(update_type)
|
||||
|
||||
/proc/remove_servant_of_ratvar(mob/living/L, silent = FALSE)
|
||||
var/datum/antagonist/clockcultist/clock_datum = L.has_antag_datum(/datum/antagonist/clockcultist, TRUE)
|
||||
if(!L || !L.mind)
|
||||
return
|
||||
var/datum/antagonist/clockcult/clock_datum = L.mind.has_antag_datum(/datum/antagonist/clockcult)
|
||||
if(!clock_datum)
|
||||
return FALSE
|
||||
clock_datum.silent_update = silent
|
||||
clock_datum.on_remove()
|
||||
clock_datum.silent = silent
|
||||
clock_datum.on_removal()
|
||||
return TRUE
|
||||
|
||||
///////////////
|
||||
@@ -194,7 +198,7 @@ Credit where due:
|
||||
var/datum/game_mode/clockwork_cult/C = SSticker.mode
|
||||
if(C.check_clockwork_victory())
|
||||
text += "<span class='large_brass'><b>Ratvar's servants have succeeded in fulfilling His goals!</b></span>"
|
||||
feedback_set_details("round_end_result", "win - servants completed their objective (summon ratvar)")
|
||||
SSblackbox.set_details("round_end_result", "win - servants completed their objective (summon ratvar)")
|
||||
else
|
||||
var/half_victory = FALSE
|
||||
var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = locate() in GLOB.all_clockwork_objects
|
||||
@@ -203,10 +207,10 @@ Credit where due:
|
||||
if(half_victory)
|
||||
text += "<span class='large_brass'><b>The crew escaped before Ratvar could rise, but the gateway \
|
||||
was successfully constructed!</b></span>"
|
||||
feedback_set_details("round_end_result", "halfwin - servants constructed the gateway but their objective was not completed (summon ratvar)")
|
||||
SSblackbox.set_details("round_end_result", "halfwin - servants constructed the gateway but their objective was not completed (summon ratvar)")
|
||||
else
|
||||
text += "<span class='userdanger'>Ratvar's servants have failed!</span>"
|
||||
feedback_set_details("round_end_result", "loss - servants failed their objective (summon ratvar)")
|
||||
SSblackbox.set_details("round_end_result", "loss - servants failed their objective (summon ratvar)")
|
||||
text += "<br><b>The servants' objective was:</b> <br>[CLOCKCULT_OBJECTIVE]"
|
||||
text += "<br>Ratvar's servants had <b>[GLOB.clockwork_caches]</b> Tinkerer's Caches."
|
||||
text += "<br><b>Construction Value(CV)</b> was: <b>[GLOB.clockwork_construction_value]</b>"
|
||||
|
||||
@@ -106,6 +106,6 @@ List of nuances:
|
||||
if(!whisper)
|
||||
L.say(message, "clock", spans, language=/datum/language/common)
|
||||
else
|
||||
L.whisper(message)
|
||||
L.whisper(message, "clock", spans, language=/datum/language/common)
|
||||
else
|
||||
AM.say(message, language=/datum/language/common)
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
|
||||
/obj/item/clockwork/slab/cyborg/medical //five scriptures, plus a spear
|
||||
quickbound = list(/datum/clockwork_scripture/ranged_ability/linked_vanguard, /datum/clockwork_scripture/ranged_ability/sentinels_compromise, \
|
||||
/datum/clockwork_scripture/create_object/vitality_matrix, /datum/clockwork_scripture/fellowship_armory, /datum/clockwork_scripture/create_object/mending_motor)
|
||||
/datum/clockwork_scripture/create_object/vitality_matrix, /datum/clockwork_scripture/channeled/mending_mantra, /datum/clockwork_scripture/fellowship_armory)
|
||||
|
||||
/obj/item/clockwork/slab/cyborg/security //four scriptures, plus a spear
|
||||
quickbound = list(/datum/clockwork_scripture/channeled/belligerent, /datum/clockwork_scripture/ranged_ability/judicial_marker, /datum/clockwork_scripture/channeled/taunting_tirade, \
|
||||
|
||||
@@ -86,7 +86,7 @@ Judgement: 12 servants, 5 caches, 300 CV, and any existing AIs are converted or
|
||||
else
|
||||
successful = TRUE
|
||||
if(slab && !slab.no_cost && !GLOB.ratvar_awakens) //if the slab exists and isn't debug and ratvar isn't up, log the scripture as being used
|
||||
feedback_add_details("clockcult_scripture_recited", name)
|
||||
SSblackbox.add_details("clockcult_scripture_recited", name)
|
||||
if(slab)
|
||||
slab.busy = null
|
||||
qdel(src)
|
||||
|
||||
@@ -214,28 +214,6 @@
|
||||
quickbind_desc = "Creates an Interdiction Lens, which drains power into nearby Sigils of Transmission."
|
||||
|
||||
|
||||
//Mending Motor: Creates a prism that will quickly heal mechanical servants/clockwork structures at a power cost
|
||||
/datum/clockwork_scripture/create_object/mending_motor
|
||||
descname = "Powered Structure, Repairs Other Structures"
|
||||
name = "Mending Motor"
|
||||
desc = "Creates a mechanized prism that will rapidly repair damaged clockwork constructs, converted cyborgs, and clockwork structures."
|
||||
invocations = list("May this prism...", "...mend our dents and scratches!")
|
||||
channel_time = 80
|
||||
consumed_components = list(VANGUARD_COGWHEEL = 3, GEIS_CAPACITOR = 1, REPLICANT_ALLOY = 1)
|
||||
object_path = /obj/structure/destructible/clockwork/powered/mending_motor
|
||||
creator_message = "<span class='brass'>You form a mending motor, which will rapidly repair damaged clockwork constructs, converted cyborgs, and clockwork structures.</span>"
|
||||
observer_message = "<span class='warning'>An onyx prism forms in midair and sprouts tendrils to support itself!</span>"
|
||||
invokers_required = 2
|
||||
multiple_invokers_used = TRUE
|
||||
usage_tip = "Powerful healing but power use is somewhat inefficient, though much better than a proselytizer."
|
||||
tier = SCRIPTURE_APPLICATION
|
||||
one_per_tile = TRUE
|
||||
primary_component = VANGUARD_COGWHEEL
|
||||
sort_priority = 7
|
||||
quickbind = TRUE
|
||||
quickbind_desc = "Creates a Mending Motor, which rapidly repairs constructs and structures at a power cost."
|
||||
|
||||
|
||||
//Mania Motor: Creates a malevolent transmitter that will broadcast the whispers of Sevtug into the minds of nearby nonservants, causing a variety of mental effects at a power cost.
|
||||
/datum/clockwork_scripture/create_object/mania_motor
|
||||
descname = "Powered Structure, Area Denial"
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
channel_time = 150
|
||||
consumed_components = list(BELLIGERENT_EYE = 3, VANGUARD_COGWHEEL = 3, GEIS_CAPACITOR = 3, REPLICANT_ALLOY = 6)
|
||||
usage_tip = "Ocular wardens will become empowered, clockwork proselytizers will require no alloy, tinkerer's daemons will produce twice as quickly, \
|
||||
and interdiction lenses, mending motors, mania motors, tinkerer's daemons, and clockwork obelisks will all require no power."
|
||||
and interdiction lenses, mania motors, tinkerer's daemons, and clockwork obelisks will all require no power."
|
||||
tier = SCRIPTURE_REVENANT
|
||||
primary_component = REPLICANT_ALLOY
|
||||
sort_priority = 4
|
||||
|
||||
@@ -69,6 +69,117 @@
|
||||
quickbind_desc = "Creates a Vitality Matrix, which drains non-Servants on it to heal Servants that cross it."
|
||||
|
||||
|
||||
//Mending Mantra: Channeled for up to ten times over twenty seconds to repair structures and heal allies
|
||||
/datum/clockwork_scripture/channeled/mending_mantra
|
||||
descname = "Channeled, Area Healing and Repair"
|
||||
name = "Mending Mantra"
|
||||
desc = "Repairs nearby structures and constructs. Servants wearing clockwork armor will also be healed. Channeled every two seconds for a maximum of twenty seconds."
|
||||
chant_invocations = list("Mend our dents!", "Heal our scratches!", "Repair our gears!")
|
||||
chant_amount = 10
|
||||
chant_interval = 20
|
||||
consumed_components = list(VANGUARD_COGWHEEL = 1, REPLICANT_ALLOY = 1)
|
||||
usage_tip = "This is a very effective way to rapidly reinforce a base after an attack."
|
||||
tier = SCRIPTURE_SCRIPT
|
||||
primary_component = VANGUARD_COGWHEEL
|
||||
sort_priority = 4
|
||||
quickbind = TRUE
|
||||
quickbind_desc = "Repairs nearby structures and constructs. Servants wearing clockwork armor will also be healed.<br><b>Maximum 10 chants.</b>"
|
||||
var/heal_attempts = 4
|
||||
var/heal_amount = 2.5
|
||||
var/static/list/damage_heal_order = list(BRUTE, BURN, OXY)
|
||||
var/static/list/heal_finish_messages = list("There, all mended!", "Try not to get too damaged.", "No more dents and scratches for you!", "Champions never die.", "All patched up.", \
|
||||
"Ah, child, it's okay now.", "Pain is temporary.", "What you do for the Justiciar is eternal.", "Bear this for me.", "Be strong, child.", "Please, be careful!", \
|
||||
"If you die, you will be remembered.")
|
||||
var/static/list/heal_target_typecache = typecacheof(list(
|
||||
/obj/structure/destructible/clockwork,
|
||||
/obj/machinery/door/airlock/clockwork,
|
||||
/obj/machinery/door/window/clockwork,
|
||||
/obj/structure/window/reinforced/clockwork,
|
||||
/obj/structure/table/reinforced/brass))
|
||||
var/static/list/ratvarian_armor_typecache = typecacheof(list(
|
||||
/obj/item/clothing/suit/armor/clockwork,
|
||||
/obj/item/clothing/head/helmet/clockwork,
|
||||
/obj/item/clothing/gloves/clockwork,
|
||||
/obj/item/clothing/shoes/clockwork))
|
||||
|
||||
/datum/clockwork_scripture/channeled/mending_mantra/chant_effects(chant_number)
|
||||
var/turf/T
|
||||
for(var/atom/movable/M in range(7, invoker))
|
||||
if(isliving(M))
|
||||
if(isclockmob(M) || istype(M, /mob/living/simple_animal/drone/cogscarab))
|
||||
var/mob/living/simple_animal/S = M
|
||||
if(S.health == S.maxHealth || S.stat == DEAD)
|
||||
continue
|
||||
T = get_turf(M)
|
||||
for(var/i in 1 to heal_attempts)
|
||||
if(S.health < S.maxHealth)
|
||||
S.adjustHealth(-heal_amount)
|
||||
new /obj/effect/overlay/temp/heal(T, "#1E8CE1")
|
||||
if(i == heal_attempts && S.health >= S.maxHealth) //we finished healing on the last tick, give them the message
|
||||
to_chat(S, "<span class='inathneq'>\"[text2ratvar(pick(heal_finish_messages))]\"</span>")
|
||||
break
|
||||
else
|
||||
to_chat(S, "<span class='inathneq'>\"[text2ratvar(pick(heal_finish_messages))]\"</span>")
|
||||
break
|
||||
else if(issilicon(M))
|
||||
var/mob/living/silicon/S = M
|
||||
if(S.health == S.maxHealth || S.stat == DEAD || !is_servant_of_ratvar(S))
|
||||
continue
|
||||
T = get_turf(M)
|
||||
for(var/i in 1 to heal_attempts)
|
||||
if(S.health < S.maxHealth)
|
||||
S.heal_ordered_damage(heal_amount, damage_heal_order)
|
||||
new /obj/effect/overlay/temp/heal(T, "#1E8CE1")
|
||||
if(i == heal_attempts && S.health >= S.maxHealth)
|
||||
to_chat(S, "<span class='inathneq'>\"[text2ratvar(pick(heal_finish_messages))]\"</span>")
|
||||
break
|
||||
else
|
||||
to_chat(S, "<span class='inathneq'>\"[text2ratvar(pick(heal_finish_messages))]\"</span>")
|
||||
break
|
||||
else if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.health == H.maxHealth || H.stat == DEAD || !is_servant_of_ratvar(H))
|
||||
continue
|
||||
T = get_turf(M)
|
||||
var/heal_ticks = 0 //one heal tick for each piece of ratvarian armor worn
|
||||
var/obj/item/I = H.get_item_by_slot(slot_wear_suit)
|
||||
if(is_type_in_typecache(I, ratvarian_armor_typecache))
|
||||
heal_ticks++
|
||||
I = H.get_item_by_slot(slot_head)
|
||||
if(is_type_in_typecache(I, ratvarian_armor_typecache))
|
||||
heal_ticks++
|
||||
I = H.get_item_by_slot(slot_gloves)
|
||||
if(is_type_in_typecache(I, ratvarian_armor_typecache))
|
||||
heal_ticks++
|
||||
I = H.get_item_by_slot(slot_shoes)
|
||||
if(is_type_in_typecache(I, ratvarian_armor_typecache))
|
||||
heal_ticks++
|
||||
if(heal_ticks)
|
||||
for(var/i in 1 to heal_ticks)
|
||||
if(H.health < H.maxHealth)
|
||||
H.heal_ordered_damage(heal_amount, damage_heal_order)
|
||||
new /obj/effect/overlay/temp/heal(T, "#1E8CE1")
|
||||
if(i == heal_ticks && H.health >= H.maxHealth)
|
||||
to_chat(H, "<span class='inathneq'>\"[text2ratvar(pick(heal_finish_messages))]\"</span>")
|
||||
break
|
||||
else
|
||||
to_chat(H, "<span class='inathneq'>\"[text2ratvar(pick(heal_finish_messages))]\"</span>")
|
||||
break
|
||||
else if(is_type_in_typecache(M, heal_target_typecache))
|
||||
var/obj/structure/destructible/clockwork/C = M
|
||||
if(C.obj_integrity == C.max_integrity || (istype(C) && !C.can_be_repaired))
|
||||
continue
|
||||
T = get_turf(M)
|
||||
for(var/i in 1 to heal_attempts)
|
||||
if(C.obj_integrity < C.max_integrity)
|
||||
C.obj_integrity = min(C.obj_integrity + 5, C.max_integrity)
|
||||
C.update_icon()
|
||||
new /obj/effect/overlay/temp/heal(T, "#1E8CE1")
|
||||
else
|
||||
break
|
||||
return TRUE
|
||||
|
||||
|
||||
//Sigil of Submission: Creates a sigil of submission, which converts one heretic above it after a delay.
|
||||
/datum/clockwork_scripture/create_object/sigil_of_submission
|
||||
descname = "Trap, Conversion"
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
//Mending Motor: A prism that consumes replicant alloy or power to repair nearby mechanical servants at a quick rate.
|
||||
/obj/structure/destructible/clockwork/powered/mending_motor
|
||||
name = "mending motor"
|
||||
desc = "A dark onyx prism, held in midair by spiraling tendrils of stone."
|
||||
clockwork_desc = "A powerful prism that rapidly repairs nearby mechanical servants and clockwork structures."
|
||||
icon_state = "mending_motor_inactive"
|
||||
active_icon = "mending_motor"
|
||||
inactive_icon = "mending_motor_inactive"
|
||||
unanchored_icon = "mending_motor_unwrenched"
|
||||
construction_value = 20
|
||||
max_integrity = 125
|
||||
obj_integrity = 125
|
||||
break_message = "<span class='warning'>The prism falls to the ground with a heavy thud!</span>"
|
||||
debris = list(/obj/item/clockwork/alloy_shards/small = 3, \
|
||||
/obj/item/clockwork/alloy_shards/medium = 1, \
|
||||
/obj/item/clockwork/alloy_shards/large = 1, \
|
||||
/obj/item/clockwork/component/vanguard_cogwheel/onyx_prism = 1)
|
||||
var/heal_attempts = 4
|
||||
var/heal_cost = MIN_CLOCKCULT_POWER*2
|
||||
var/static/list/damage_heal_order = list(BRUTE, BURN, OXY)
|
||||
var/static/list/heal_finish_messages = list("There, all mended!", "Try not to get too damaged.", "No more dents and scratches for you!", "Champions never die.", "All patched up.", \
|
||||
"Ah, child, it's okay now.")
|
||||
var/static/list/heal_failure_messages = list("Pain is temporary.", "What you do for the Justiciar is eternal.", "Bear this for me.", "Be strong, child.", "Please, be careful!", \
|
||||
"If you die, you will be remembered.")
|
||||
var/static/list/mending_motor_typecache = typecacheof(list(
|
||||
/obj/structure/destructible/clockwork,
|
||||
/obj/machinery/door/airlock/clockwork,
|
||||
/obj/machinery/door/window/clockwork,
|
||||
/obj/structure/window/reinforced/clockwork,
|
||||
/obj/structure/table/reinforced/brass))
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mending_motor/examine(mob/user)
|
||||
..()
|
||||
if(is_servant_of_ratvar(user) || isobserver(user))
|
||||
to_chat(user, "<span class='inathneq_small'>It requires at least <b>[heal_cost]W</b> to attempt to repair clockwork mobs, structures, or converted silicons.</span>")
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mending_motor/forced_disable(bad_effects)
|
||||
if(active)
|
||||
if(bad_effects)
|
||||
try_use_power(heal_cost)
|
||||
visible_message("<span class='warning'>[src] emits an airy chuckling sound and falls dark!</span>")
|
||||
toggle()
|
||||
return TRUE
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mending_motor/attack_hand(mob/living/user)
|
||||
if(user.canUseTopic(src, !issilicon(user), NO_DEXTERY) && is_servant_of_ratvar(user))
|
||||
if(total_accessable_power() < MIN_CLOCKCULT_POWER)
|
||||
to_chat(user, "<span class='warning'>[src] needs more power to function!</span>")
|
||||
return 0
|
||||
toggle(0, user)
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mending_motor/process()
|
||||
var/efficiency = get_efficiency_mod()
|
||||
for(var/atom/movable/M in range(7, src))
|
||||
var/turf/T
|
||||
if(isclockmob(M) || istype(M, /mob/living/simple_animal/drone/cogscarab))
|
||||
T = get_turf(M)
|
||||
var/mob/living/simple_animal/S = M
|
||||
if(S.health == S.maxHealth || S.stat == DEAD)
|
||||
continue
|
||||
for(var/i in 1 to heal_attempts)
|
||||
if(S.health < S.maxHealth)
|
||||
if(try_use_power(heal_cost))
|
||||
S.adjustHealth(-(8 * efficiency))
|
||||
new /obj/effect/overlay/temp/heal(T, "#1E8CE1")
|
||||
else
|
||||
to_chat(S, "<span class='inathneq'>\"[text2ratvar(pick(heal_failure_messages))]\"</span>")
|
||||
break
|
||||
else
|
||||
to_chat(S, "<span class='inathneq'>\"[text2ratvar(pick(heal_finish_messages))]\"</span>")
|
||||
break
|
||||
else if(is_type_in_typecache(M, mending_motor_typecache))
|
||||
T = get_turf(M)
|
||||
var/obj/structure/destructible/clockwork/C = M
|
||||
if(C.obj_integrity == C.max_integrity || (istype(C) && !C.can_be_repaired))
|
||||
continue
|
||||
for(var/i in 1 to heal_attempts)
|
||||
if(C.obj_integrity < C.max_integrity)
|
||||
if(try_use_power(heal_cost))
|
||||
C.obj_integrity = min(C.obj_integrity + (8 * efficiency), C.max_integrity)
|
||||
if(C == src)
|
||||
efficiency = get_efficiency_mod()
|
||||
C.update_icon()
|
||||
new /obj/effect/overlay/temp/heal(T, "#1E8CE1")
|
||||
else
|
||||
break
|
||||
else
|
||||
break
|
||||
else if(issilicon(M))
|
||||
T = get_turf(M)
|
||||
var/mob/living/silicon/S = M
|
||||
if(S.health == S.maxHealth || S.stat == DEAD || !is_servant_of_ratvar(S))
|
||||
continue
|
||||
for(var/i in 1 to heal_attempts)
|
||||
if(S.health < S.maxHealth)
|
||||
if(try_use_power(heal_cost))
|
||||
S.heal_ordered_damage(8 * efficiency, damage_heal_order)
|
||||
new /obj/effect/overlay/temp/heal(T, "#1E8CE1")
|
||||
else
|
||||
to_chat(S, "<span class='inathneq'>\"[text2ratvar(pick(heal_failure_messages))]\"</span>")
|
||||
break
|
||||
else
|
||||
to_chat(S, "<span class='inathneq'>\"[text2ratvar(pick(heal_finish_messages))]\"</span>")
|
||||
break
|
||||
. = ..()
|
||||
if(. < heal_cost)
|
||||
forced_disable(FALSE)
|
||||
@@ -40,8 +40,8 @@
|
||||
|
||||
/obj/structure/destructible/clockwork/massive/ratvar/attack_ghost(mob/dead/observer/O)
|
||||
var/alertresult = alert(O, "Embrace the Justiciar's light? You can no longer be cloned!",,"Yes", "No")
|
||||
if(alertresult == "No" || !O)
|
||||
return 0
|
||||
if(alertresult == "No" || QDELETED(O) || !istype(O) || !O.key)
|
||||
return FALSE
|
||||
var/mob/living/simple_animal/drone/cogscarab/ratvar/R = new/mob/living/simple_animal/drone/cogscarab/ratvar(get_turf(src))
|
||||
R.visible_message("<span class='heavy_brass'>[R] forms, and its eyes blink open, glowing bright red!</span>")
|
||||
R.key = O.key
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
var/list/cult_objectives = list()
|
||||
|
||||
/proc/iscultist(mob/living/M)
|
||||
return istype(M) && M.has_antag_datum(/datum/antagonist/cultist, TRUE)
|
||||
return istype(M) && M.mind && M.mind.has_antag_datum(ANTAG_DATUM_CULT)
|
||||
|
||||
/proc/is_sacrifice_target(datum/mind/mind)
|
||||
if(SSticker.mode.name == "cult")
|
||||
@@ -158,18 +158,18 @@
|
||||
/datum/game_mode/proc/add_cultist(datum/mind/cult_mind, stun) //BASE
|
||||
if (!istype(cult_mind))
|
||||
return 0
|
||||
if(cult_mind.current.gain_antag_datum(/datum/antagonist/cultist))
|
||||
if(cult_mind.add_antag_datum(ANTAG_DATUM_CULT))
|
||||
if(stun)
|
||||
cult_mind.current.Paralyse(5)
|
||||
return 1
|
||||
|
||||
/datum/game_mode/proc/remove_cultist(datum/mind/cult_mind, show_message = 1, stun)
|
||||
if(cult_mind.current)
|
||||
var/datum/antagonist/cultist/cult_datum = cult_mind.current.has_antag_datum(/datum/antagonist/cultist, TRUE)
|
||||
var/datum/antagonist/cult/cult_datum = cult_mind.has_antag_datum(ANTAG_DATUM_CULT)
|
||||
if(!cult_datum)
|
||||
return FALSE
|
||||
cult_datum.silent_update = show_message
|
||||
cult_datum.on_remove()
|
||||
cult_datum.silent = show_message
|
||||
cult_datum.on_removal()
|
||||
if(stun)
|
||||
cult_mind.current.Paralyse(5)
|
||||
return TRUE
|
||||
@@ -218,12 +218,12 @@
|
||||
/datum/game_mode/cult/declare_completion()
|
||||
|
||||
if(!check_cult_victory())
|
||||
feedback_set_details("round_end_result","win - cult win")
|
||||
feedback_set("round_end_result",acolytes_survived)
|
||||
SSblackbox.set_details("round_end_result","win - cult win")
|
||||
SSblackbox.set_val("round_end_result",acolytes_survived)
|
||||
to_chat(world, "<span class='greentext'>The cult has succeeded! Nar-sie has snuffed out another torch in the void!</span>")
|
||||
else
|
||||
feedback_set_details("round_end_result","loss - staff stopped the cult")
|
||||
feedback_set("round_end_result",acolytes_survived)
|
||||
SSblackbox.set_details("round_end_result","loss - staff stopped the cult")
|
||||
SSblackbox.set_val("round_end_result",acolytes_survived)
|
||||
to_chat(world, "<span class='redtext'>The staff managed to stop the cult! Dark words and heresy are no match for Nanotrasen's finest!</span>")
|
||||
|
||||
var/text = ""
|
||||
@@ -236,31 +236,31 @@
|
||||
if("survive")
|
||||
if(!check_survive())
|
||||
explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. ([acolytes_survived] escaped) <span class='greenannounce'>Success!</span>"
|
||||
feedback_add_details("cult_objective","cult_survive|SUCCESS|[acolytes_needed]")
|
||||
SSblackbox.add_details("cult_objective","cult_survive|SUCCESS|[acolytes_needed]")
|
||||
SSticker.news_report = CULT_ESCAPE
|
||||
else
|
||||
explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. ([acolytes_survived] escaped) <span class='boldannounce'>Fail.</span>"
|
||||
feedback_add_details("cult_objective","cult_survive|FAIL|[acolytes_needed]")
|
||||
SSblackbox.add_details("cult_objective","cult_survive|FAIL|[acolytes_needed]")
|
||||
SSticker.news_report = CULT_FAILURE
|
||||
if("sacrifice")
|
||||
if(sacrifice_target)
|
||||
if(sacrifice_target in GLOB.sacrificed)
|
||||
explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. <span class='greenannounce'>Success!</span>"
|
||||
feedback_add_details("cult_objective","cult_sacrifice|SUCCESS")
|
||||
SSblackbox.add_details("cult_objective","cult_sacrifice|SUCCESS")
|
||||
else if(sacrifice_target && sacrifice_target.current)
|
||||
explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. <span class='boldannounce'>Fail.</span>"
|
||||
feedback_add_details("cult_objective","cult_sacrifice|FAIL")
|
||||
SSblackbox.add_details("cult_objective","cult_sacrifice|FAIL")
|
||||
else
|
||||
explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. <span class='boldannounce'>Fail (Gibbed).</span>"
|
||||
feedback_add_details("cult_objective","cult_sacrifice|FAIL|GIBBED")
|
||||
SSblackbox.add_details("cult_objective","cult_sacrifice|FAIL|GIBBED")
|
||||
if("eldergod")
|
||||
if(!eldergod)
|
||||
explanation = "Summon Nar-Sie. <span class='greenannounce'>Success!</span>"
|
||||
feedback_add_details("cult_objective","cult_narsie|SUCCESS")
|
||||
SSblackbox.add_details("cult_objective","cult_narsie|SUCCESS")
|
||||
SSticker.news_report = CULT_SUMMON
|
||||
else
|
||||
explanation = "Summon Nar-Sie. <span class='boldannounce'>Fail.</span>"
|
||||
feedback_add_details("cult_objective","cult_narsie|FAIL")
|
||||
SSblackbox.add_details("cult_objective","cult_narsie|FAIL")
|
||||
SSticker.news_report = CULT_FAILURE
|
||||
|
||||
text += "<br><B>Objective #[obj_count]</B>: [explanation]"
|
||||
|
||||
@@ -247,7 +247,7 @@ This file contains the arcane tome files.
|
||||
var/obj/effect/rune/R = new rune_to_scribe(Turf, chosen_keyword)
|
||||
R.add_mob_blood(user)
|
||||
to_chat(user, "<span class='cult'>The [lowertext(R.cultist_name)] rune [R.cultist_desc]</span>")
|
||||
feedback_add_details("cult_runes_scribed", R.cultist_name)
|
||||
SSblackbox.add_details("cult_runes_scribed", R.cultist_name)
|
||||
|
||||
/obj/item/weapon/tome/proc/check_rune_turf(turf/T, mob/user)
|
||||
var/area/A = get_area(T)
|
||||
|
||||
@@ -287,7 +287,7 @@ GLOBAL_LIST_INIT(lawlorify, list (
|
||||
notify_ghosts("An arch devil has ascended in \the [A.name]. Reach out to the devil to be given a new shell for your soul.", source = owner.current, action=NOTIFY_ATTACK)
|
||||
sleep(50)
|
||||
if(!SSticker.mode.devil_ascended)
|
||||
SSshuttle.emergency.request(null, 0.3)
|
||||
SSshuttle.emergency.request(null, set_coefficient = 0.3)
|
||||
SSticker.mode.devil_ascended++
|
||||
form = ARCH_DEVIL
|
||||
|
||||
@@ -449,7 +449,7 @@ GLOBAL_LIST_INIT(lawlorify, list (
|
||||
A.convert_to_archdevil()
|
||||
else
|
||||
throw EXCEPTION("Unable to find a blobstart landmark for hellish resurrection")
|
||||
|
||||
|
||||
|
||||
/datum/devilinfo/proc/update_hud()
|
||||
if(istype(owner.current, /mob/living/carbon))
|
||||
|
||||
@@ -80,12 +80,12 @@
|
||||
report = config.intercept
|
||||
addtimer(CALLBACK(GLOBAL_PROC, .proc/display_roundstart_logout_report), ROUNDSTART_LOGOUT_REPORT_TIME)
|
||||
|
||||
feedback_set_details("round_start","[time2text(world.realtime)]")
|
||||
SSblackbox.set_details("round_start","[time2text(world.realtime)]")
|
||||
if(SSticker && SSticker.mode)
|
||||
feedback_set_details("game_mode","[SSticker.mode]")
|
||||
SSblackbox.set_details("game_mode","[SSticker.mode]")
|
||||
if(GLOB.revdata.commit)
|
||||
feedback_set_details("revision","[GLOB.revdata.commit]")
|
||||
feedback_set_details("server_ip","[world.internet_address]:[world.port]")
|
||||
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()
|
||||
@@ -246,17 +246,17 @@
|
||||
ghosts++
|
||||
|
||||
if(clients > 0)
|
||||
feedback_set("round_end_clients",clients)
|
||||
SSblackbox.set_val("round_end_clients",clients)
|
||||
if(ghosts > 0)
|
||||
feedback_set("round_end_ghosts",ghosts)
|
||||
SSblackbox.set_val("round_end_ghosts",ghosts)
|
||||
if(surviving_humans > 0)
|
||||
feedback_set("survived_human",surviving_humans)
|
||||
SSblackbox.set_val("survived_human",surviving_humans)
|
||||
if(surviving_total > 0)
|
||||
feedback_set("survived_total",surviving_total)
|
||||
SSblackbox.set_val("survived_total",surviving_total)
|
||||
if(escaped_humans > 0)
|
||||
feedback_set("escaped_human",escaped_humans)
|
||||
SSblackbox.set_val("escaped_human",escaped_humans)
|
||||
if(escaped_total > 0)
|
||||
feedback_set("escaped_total",escaped_total)
|
||||
SSblackbox.set_val("escaped_total",escaped_total)
|
||||
send2irc("Server", "Round just ended.")
|
||||
return 0
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
diff a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm (rejected hunks)
|
||||
@@ -81,12 +81,12 @@
|
||||
spawn (ROUNDSTART_LOGOUT_REPORT_TIME)
|
||||
display_roundstart_logout_report()
|
||||
|
||||
- feedback_set_details("round_start","[time2text(world.realtime)]")
|
||||
+ SSblackbox.set_details("round_start","[time2text(world.realtime)]")
|
||||
if(SSticker && SSticker.mode)
|
||||
- feedback_set_details("game_mode","[SSticker.mode]")
|
||||
+ SSblackbox.set_details("game_mode","[SSticker.mode]")
|
||||
if(GLOB.revdata.commit)
|
||||
- feedback_set_details("revision","[GLOB.revdata.commit]")
|
||||
- feedback_set_details("server_ip","[world.internet_address]:[world.port]")
|
||||
+ SSblackbox.set_details("revision","[GLOB.revdata.commit]")
|
||||
+ SSblackbox.set_details("server_ip","[world.internet_address]:[world.port]")
|
||||
if(report)
|
||||
spawn (rand(waittime_l, waittime_h))
|
||||
send_intercept(0)
|
||||
@@ -260,12 +260,12 @@ GLOBAL_LIST_INIT(gang_colors_pool, list("red","orange","yellow","green","blue","
|
||||
return
|
||||
if(!winner)
|
||||
to_chat(world, "<span class='redtext'>The station was [station_was_nuked ? "destroyed!" : "evacuated before a gang could claim it! The station wins!"]</span><br>")
|
||||
feedback_set_details("round_end_result","loss - gangs failed takeover")
|
||||
SSblackbox.set_details("round_end_result","loss - gangs failed takeover")
|
||||
|
||||
SSticker.news_report = GANG_LOSS
|
||||
else
|
||||
to_chat(world, "<span class='redtext'>The [winner.name] Gang successfully performed a hostile takeover of the station!</span><br>")
|
||||
feedback_set_details("round_end_result","win - gang domination complete")
|
||||
SSblackbox.set_details("round_end_result","win - gang domination complete")
|
||||
|
||||
SSticker.news_report = GANG_TAKEOVER
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
..()
|
||||
last_used = world.time
|
||||
|
||||
/obj/item/weapon/pen/gang/attack(mob/living/M, mob/user)
|
||||
/obj/item/weapon/pen/gang/attack(mob/living/M, mob/user, stealth = TRUE)
|
||||
if(!istype(M))
|
||||
return
|
||||
if(ishuman(M) && ishuman(user) && M.stat != DEAD)
|
||||
|
||||
@@ -556,7 +556,7 @@
|
||||
var/mob/living/silicon/ai/A = usr
|
||||
|
||||
if(A.stat == DEAD)
|
||||
A <<"You are already dead!" //Omae Wa Mou Shindeiru
|
||||
to_chat(A, "You are already dead!") //Omae Wa Mou Shindeiru
|
||||
return
|
||||
|
||||
for(var/datum/AI_Module/AM in possible_modules)
|
||||
|
||||
@@ -50,8 +50,8 @@
|
||||
else
|
||||
to_chat(world, "<span class='boldnotice'>Nobody survived the meteor storm!</span>")
|
||||
|
||||
feedback_set_details("round_end_result","end - evacuation")
|
||||
feedback_set("round_end_result",survivors)
|
||||
SSblackbox.set_details("round_end_result","end - evacuation")
|
||||
SSblackbox.set_val("round_end_result",survivors)
|
||||
|
||||
..()
|
||||
return 1
|
||||
|
||||
@@ -166,7 +166,7 @@
|
||||
var/obj/machinery/abductor/console/con = get_team_console(team_number)
|
||||
var/datum/objective/objective = team_objectives[team_number]
|
||||
if (con.experiment.points >= objective.target_amount)
|
||||
SSshuttle.emergency.request(null, 0.5)
|
||||
SSshuttle.emergency.request(null, set_coefficient = 0.5)
|
||||
finished = 1
|
||||
return ..()
|
||||
return ..()
|
||||
|
||||
@@ -14,6 +14,13 @@
|
||||
origin_tech = "magnets=7;biotech=4;powerstorage=4;abductor=4"
|
||||
armor = list(melee = 15, bullet = 15, laser = 15, energy = 15, bomb = 15, bio = 15, rad = 15, fire = 70, acid = 70)
|
||||
actions_types = list(/datum/action/item_action/hands_free/activate)
|
||||
allowed = list(
|
||||
/obj/item/device/abductor,
|
||||
/obj/item/weapon/abductor_baton,
|
||||
/obj/item/weapon/melee/baton,
|
||||
/obj/item/weapon/gun/energy,
|
||||
/obj/item/weapon/restraints/handcuffs
|
||||
)
|
||||
var/mode = VEST_STEALTH
|
||||
var/stealth_active = 0
|
||||
var/combat_cooldown = 10
|
||||
@@ -21,6 +28,11 @@
|
||||
var/stealth_armor = list(melee = 15, bullet = 15, laser = 15, energy = 15, bomb = 15, bio = 15, rad = 15, fire = 70, acid = 70)
|
||||
var/combat_armor = list(melee = 50, bullet = 50, laser = 50, energy = 50, bomb = 50, bio = 50, rad = 50, fire = 90, acid = 90)
|
||||
|
||||
/obj/item/clothing/suit/armor/abductor/vest/proc/toggle_nodrop()
|
||||
flags ^= NODROP
|
||||
if(ismob(loc))
|
||||
to_chat(loc, "<span class='notice'>Your vest is now [flags & NODROP ? "locked" : "unlocked"].</span>")
|
||||
|
||||
/obj/item/clothing/suit/armor/abductor/vest/proc/flip_mode()
|
||||
switch(mode)
|
||||
if(VEST_STEALTH)
|
||||
@@ -107,6 +119,18 @@
|
||||
if(combat_cooldown==initial(combat_cooldown))
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/clothing/suit/armor/abductor/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
for(var/obj/machinery/abductor/console/C in GLOB.machines)
|
||||
if(C.vest == src)
|
||||
C.vest = null
|
||||
break
|
||||
. = ..()
|
||||
|
||||
|
||||
/obj/item/device/abductor
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
|
||||
/obj/item/device/abductor/proc/AbductorCheck(user)
|
||||
if(isabductor(user))
|
||||
return TRUE
|
||||
@@ -114,14 +138,19 @@
|
||||
return FALSE
|
||||
|
||||
/obj/item/device/abductor/proc/ScientistCheck(user)
|
||||
if(!AbductorCheck(user))
|
||||
return FALSE
|
||||
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/datum/species/abductor/S = H.dna.species
|
||||
return S.scientist
|
||||
if(S.scientist)
|
||||
return TRUE
|
||||
to_chat(user, "<span class='warning'>You're not trained to use this!</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/item/device/abductor/gizmo
|
||||
name = "science tool"
|
||||
desc = "A dual-mode tool for retrieving specimens and scanning appearances. Scanning can be done through cameras."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "gizmo_scan"
|
||||
item_state = "silencer"
|
||||
origin_tech = "engineering=7;magnets=4;bluespace=4;abductor=3"
|
||||
@@ -130,11 +159,12 @@
|
||||
var/obj/machinery/abductor/console/console
|
||||
|
||||
/obj/item/device/abductor/gizmo/attack_self(mob/user)
|
||||
if(!AbductorCheck(user))
|
||||
return
|
||||
if(!ScientistCheck(user))
|
||||
to_chat(user, "<span class='warning'>You're not trained to use this!</span>")
|
||||
return
|
||||
if(!console)
|
||||
to_chat(user, "<span class='warning'>The device is not linked to console!</span>")
|
||||
return
|
||||
|
||||
if(mode == GIZMO_SCAN)
|
||||
mode = GIZMO_MARK
|
||||
icon_state = "gizmo_mark"
|
||||
@@ -144,11 +174,12 @@
|
||||
to_chat(user, "<span class='notice'>You switch the device to [mode==GIZMO_SCAN? "SCAN": "MARK"] MODE</span>")
|
||||
|
||||
/obj/item/device/abductor/gizmo/attack(mob/living/M, mob/user)
|
||||
if(!AbductorCheck(user))
|
||||
return
|
||||
if(!ScientistCheck(user))
|
||||
to_chat(user, "<span class='notice'>You're not trained to use this</span>")
|
||||
return
|
||||
if(!console)
|
||||
to_chat(user, "<span class='warning'>The device is not linked to console!</span>")
|
||||
return
|
||||
|
||||
switch(mode)
|
||||
if(GIZMO_SCAN)
|
||||
scan(M, user)
|
||||
@@ -159,11 +190,12 @@
|
||||
/obj/item/device/abductor/gizmo/afterattack(atom/target, mob/living/user, flag, params)
|
||||
if(flag)
|
||||
return
|
||||
if(!AbductorCheck(user))
|
||||
return
|
||||
if(!ScientistCheck(user))
|
||||
to_chat(user, "<span class='notice'>You're not trained to use this</span>")
|
||||
return
|
||||
if(!console)
|
||||
to_chat(user, "<span class='warning'>The device is not linked to console!</span>")
|
||||
return
|
||||
|
||||
switch(mode)
|
||||
if(GIZMO_SCAN)
|
||||
scan(target, user)
|
||||
@@ -172,9 +204,8 @@
|
||||
|
||||
/obj/item/device/abductor/gizmo/proc/scan(atom/target, mob/living/user)
|
||||
if(ishuman(target))
|
||||
if(console!=null)
|
||||
console.AddSnapshot(target)
|
||||
to_chat(user, "<span class='notice'>You scan [target] and add them to the database.</span>")
|
||||
console.AddSnapshot(target)
|
||||
to_chat(user, "<span class='notice'>You scan [target] and add them to the database.</span>")
|
||||
|
||||
/obj/item/device/abductor/gizmo/proc/mark(atom/target, mob/living/user)
|
||||
if(marked == target)
|
||||
@@ -198,11 +229,15 @@
|
||||
marked = target
|
||||
to_chat(user, "<span class='notice'>You finish preparing [target] for transport.</span>")
|
||||
|
||||
/obj/item/device/abductor/gizmo/Destroy()
|
||||
if(console)
|
||||
console.gizmo = null
|
||||
. = ..()
|
||||
|
||||
|
||||
/obj/item/device/abductor/silencer
|
||||
name = "abductor silencer"
|
||||
desc = "A compact device used to shut down communications equipment."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "silencer"
|
||||
item_state = "gizmo"
|
||||
origin_tech = "materials=4;programming=7;abductor=3"
|
||||
@@ -419,10 +454,10 @@ Congratulations! You are now trained for invasive xenobiology research!"}
|
||||
if(!C.handcuffed)
|
||||
C.handcuffed = new /obj/item/weapon/restraints/handcuffs/energy/used(C)
|
||||
C.update_handcuffed()
|
||||
to_chat(user, "<span class='notice'>You handcuff [C].</span>")
|
||||
to_chat(user, "<span class='notice'>You restrain [C].</span>")
|
||||
add_logs(user, C, "handcuffed")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You fail to handcuff [C].</span>")
|
||||
to_chat(user, "<span class='warning'>You fail to restrain [C].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[C] doesn't have two hands...</span>")
|
||||
|
||||
@@ -471,11 +506,11 @@ Congratulations! You are now trained for invasive xenobiology research!"}
|
||||
..()
|
||||
switch(mode)
|
||||
if(BATON_STUN)
|
||||
user <<"<span class='warning'>The baton is in stun mode.</span>"
|
||||
to_chat(user, "<span class='warning'>The baton is in stun mode.</span>")
|
||||
if(BATON_SLEEP)
|
||||
user <<"<span class='warning'>The baton is in sleep inducement mode.</span>"
|
||||
to_chat(user, "<span class='warning'>The baton is in sleep inducement mode.</span>")
|
||||
if(BATON_CUFF)
|
||||
user <<"<span class='warning'>The baton is in restraining mode.</span>"
|
||||
to_chat(user, "<span class='warning'>The baton is in restraining mode.</span>")
|
||||
if(BATON_PROBE)
|
||||
to_chat(user, "<span class='warning'>The baton is in probing mode.</span>")
|
||||
|
||||
|
||||
@@ -22,13 +22,13 @@
|
||||
if(console)
|
||||
var/obj/item/clothing/suit/armor/abductor/vest/V = locate() in H
|
||||
if(V)
|
||||
console.vest = V
|
||||
console.AddVest(V)
|
||||
V.flags |= NODROP
|
||||
|
||||
var/obj/item/device/abductor/gizmo/G = locate() in H.getBackSlot()
|
||||
if(G)
|
||||
console.gizmo = G
|
||||
G.console = console
|
||||
var/obj/item/weapon/storage/backpack/B = locate() in H
|
||||
if(B)
|
||||
for(var/obj/item/device/abductor/gizmo/G in B.contents)
|
||||
console.AddGizmo(G)
|
||||
|
||||
/datum/outfit/abductor/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
..()
|
||||
@@ -40,10 +40,10 @@
|
||||
name = "Abductor Agent"
|
||||
head = /obj/item/clothing/head/helmet/abductor
|
||||
suit = /obj/item/clothing/suit/armor/abductor/vest
|
||||
suit_store = /obj/item/weapon/abductor_baton
|
||||
belt = /obj/item/weapon/storage/belt/military/abductor/full
|
||||
|
||||
backpack_contents = list(
|
||||
/obj/item/weapon/abductor_baton = 1,
|
||||
/obj/item/weapon/gun/energy/alien = 1,
|
||||
/obj/item/device/abductor/silencer = 1
|
||||
)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
//Console
|
||||
|
||||
/obj/machinery/abductor/console
|
||||
name = "Abductor console"
|
||||
name = "abductor console"
|
||||
desc = "Ship command center."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "console"
|
||||
@@ -32,7 +32,7 @@
|
||||
var/dat = ""
|
||||
dat += "<H3> Abductsoft 3000 </H3>"
|
||||
|
||||
if(experiment != null)
|
||||
if(experiment)
|
||||
var/points = experiment.points
|
||||
var/credits = experiment.credits
|
||||
dat += "Collected Samples : [points] <br>"
|
||||
@@ -46,18 +46,18 @@
|
||||
else
|
||||
dat += "<span class='bad'>NO EXPERIMENT MACHINE DETECTED</span> <br>"
|
||||
|
||||
if(pad!=null)
|
||||
if(pad)
|
||||
dat += "<span class='bad'>Emergency Teleporter System.</span>"
|
||||
dat += "<span class='bad'>Consider using primary observation console first.</span>"
|
||||
dat += "<a href='?src=\ref[src];teleporter_send=1'>Activate Teleporter</A><br>"
|
||||
if(gizmo!=null && gizmo.marked!=null)
|
||||
if(gizmo && gizmo.marked)
|
||||
dat += "<a href='?src=\ref[src];teleporter_retrieve=1'>Retrieve Mark</A><br>"
|
||||
else
|
||||
dat += "<span class='linkOff'>Retrieve Mark</span><br>"
|
||||
else
|
||||
dat += "<span class='bad'>NO TELEPAD DETECTED</span></br>"
|
||||
|
||||
if(vest!=null)
|
||||
if(vest)
|
||||
dat += "<h4> Agent Vest Mode </h4><br>"
|
||||
var/mode = vest.mode
|
||||
if(mode == VEST_STEALTH)
|
||||
@@ -88,7 +88,8 @@
|
||||
else if(href_list["flip_vest"])
|
||||
FlipVest()
|
||||
else if(href_list["toggle_vest"])
|
||||
toggle_vest()
|
||||
if(vest)
|
||||
vest.toggle_nodrop()
|
||||
else if(href_list["select_disguise"])
|
||||
SelectDisguise()
|
||||
else if(href_list["dispense"])
|
||||
@@ -105,23 +106,22 @@
|
||||
Dispense(/obj/item/clothing/suit/armor/abductor/vest)
|
||||
updateUsrDialog()
|
||||
|
||||
|
||||
/obj/machinery/abductor/console/proc/TeleporterRetrieve()
|
||||
if(gizmo!=null && pad!=null && gizmo.marked)
|
||||
if(pad && gizmo && gizmo.marked)
|
||||
pad.Retrieve(gizmo.marked)
|
||||
|
||||
/obj/machinery/abductor/console/proc/TeleporterSend()
|
||||
if(pad!=null)
|
||||
if(pad)
|
||||
pad.Send()
|
||||
|
||||
/obj/machinery/abductor/console/proc/FlipVest()
|
||||
if(vest!=null)
|
||||
if(vest)
|
||||
vest.flip_mode()
|
||||
|
||||
/obj/machinery/abductor/console/proc/SelectDisguise(remote = 0)
|
||||
var/entry_name = input( "Choose Disguise", "Disguise") as null|anything in disguises
|
||||
var/datum/icon_snapshot/chosen = disguises[entry_name]
|
||||
if(chosen && (remote || in_range(usr,src)))
|
||||
if(chosen && vest && (remote || in_range(usr,src)))
|
||||
vest.SetDisguise(chosen)
|
||||
|
||||
/obj/machinery/abductor/console/proc/SetDroppoint(turf/open/location,user)
|
||||
@@ -135,10 +135,10 @@
|
||||
|
||||
|
||||
/obj/machinery/abductor/console/Initialize(mapload)
|
||||
if(mapload)
|
||||
return TRUE //wait for machines list
|
||||
..()
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/obj/machinery/abductor/console/LateInitialize()
|
||||
if(!team)
|
||||
return
|
||||
|
||||
@@ -169,36 +169,48 @@
|
||||
return
|
||||
disguises[entry.name] = entry
|
||||
|
||||
/obj/machinery/abductor/console/proc/AddGizmo(obj/item/device/abductor/gizmo/G)
|
||||
if(G == gizmo && G.console == src)
|
||||
return FALSE
|
||||
|
||||
if(G.console)
|
||||
G.console.gizmo = null
|
||||
|
||||
gizmo = G
|
||||
G.console = src
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/abductor/console/proc/AddVest(obj/item/clothing/suit/armor/abductor/vest/V)
|
||||
if(vest == V)
|
||||
return FALSE
|
||||
|
||||
for(var/obj/machinery/abductor/console/C in GLOB.machines)
|
||||
if(C.vest == V)
|
||||
C.vest = null
|
||||
break
|
||||
|
||||
vest = V
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/abductor/console/attackby(obj/O, mob/user, params)
|
||||
if(istype(O, /obj/item/device/abductor/gizmo))
|
||||
var/obj/item/device/abductor/gizmo/G = O
|
||||
if(istype(O, /obj/item/device/abductor/gizmo) && AddGizmo(O))
|
||||
to_chat(user, "<span class='notice'>You link the tool to the console.</span>")
|
||||
gizmo = G
|
||||
G.console = src
|
||||
else if(istype(O, /obj/item/clothing/suit/armor/abductor/vest))
|
||||
var/obj/item/clothing/suit/armor/abductor/vest/V = O
|
||||
else if(istype(O, /obj/item/clothing/suit/armor/abductor/vest) && AddVest(O))
|
||||
to_chat(user, "<span class='notice'>You link the vest to the console.</span>")
|
||||
if(istype(vest))
|
||||
if(vest.flags & NODROP)
|
||||
toggle_vest()
|
||||
vest = V
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
|
||||
/obj/machinery/abductor/console/proc/Dispense(item,cost=1)
|
||||
if(experiment && experiment.credits >= cost)
|
||||
experiment.credits -=cost
|
||||
say("Incoming supply!")
|
||||
var/drop_location = loc
|
||||
if(pad)
|
||||
flick("alien-pad", pad)
|
||||
new item(pad.loc)
|
||||
else
|
||||
new item(loc)
|
||||
drop_location = pad.loc
|
||||
new item(drop_location)
|
||||
|
||||
else
|
||||
say("Insufficent data!")
|
||||
|
||||
/obj/machinery/abductor/console/proc/toggle_vest()
|
||||
vest.flags ^= NODROP
|
||||
var/mob/M = vest.loc
|
||||
if(istype(M))
|
||||
to_chat(M, "<span class='notice'>[src] is now [vest.flags & NODROP ? "locked" : "unlocked"].</span>")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/obj/machinery/abductor/gland_dispenser
|
||||
name = "Replacement Organ Storage"
|
||||
name = "replacement organ storage"
|
||||
desc = "A tank filled with replacement organs."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "dispenser"
|
||||
@@ -49,7 +49,7 @@
|
||||
var/g_color = gland_colors[i]
|
||||
var/amount = amounts[i]
|
||||
dat += "<a class='box gland' style='background-color:[g_color]' href='?src=\ref[src];dispense=[i]'>[amount]</a>"
|
||||
if(item_count == 3) // Three boxes per line
|
||||
if(item_count == 4) // Four boxes per line
|
||||
dat +="</br></br>"
|
||||
item_count = 0
|
||||
var/datum/browser/popup = new(user, "glands", "Gland Dispenser", 200, 200)
|
||||
|
||||
@@ -47,8 +47,8 @@
|
||||
icon_state = "teleport"
|
||||
duration = 80
|
||||
|
||||
/obj/effect/overlay/temp/teleport_abductor/New()
|
||||
/obj/effect/overlay/temp/teleport_abductor/Initialize()
|
||||
. = ..()
|
||||
var/datum/effect_system/spark_spread/S = new
|
||||
S.set_up(10,0,loc)
|
||||
S.start()
|
||||
..()
|
||||
S.start()
|
||||
@@ -628,7 +628,7 @@ GLOBAL_VAR_INIT(total_borer_hosts_needed, 10)
|
||||
chemicals -= 250
|
||||
to_chat(src, "<span class='notice'>You send a jolt of energy to your host, reviving them!</span>")
|
||||
victim.grab_ghost(force = TRUE) //brings the host back, no eggscape
|
||||
victim <<"<span class='notice'>You bolt upright, gasping for breath!</span>"
|
||||
to_chat(victim, "<span class='notice'>You bolt upright, gasping for breath!</span>")
|
||||
|
||||
/mob/living/simple_animal/borer/verb/bond_brain()
|
||||
set category = "Borer"
|
||||
@@ -672,7 +672,7 @@ GLOBAL_VAR_INIT(total_borer_hosts_needed, 10)
|
||||
if(!bonding)
|
||||
return
|
||||
if(docile)
|
||||
src <<"<span class='warning'>You are feeling far too docile to do that.</span>"
|
||||
to_chat(src, "<span class='warning'>You are feeling far too docile to do that.</span>")
|
||||
return
|
||||
if(is_servant_of_ratvar(victim) || iscultist(victim) || victim.isloyal())
|
||||
to_chat(src, "<span class='warning'>[victim]'s mind seems to be blocked by some unknown force!</span>")
|
||||
|
||||
@@ -527,9 +527,9 @@
|
||||
icon_state = "disintegrate"
|
||||
duration = 10
|
||||
|
||||
/obj/effect/overlay/temp/swarmer/disintegration/New()
|
||||
playsound(src.loc, "sparks", 100, 1)
|
||||
..()
|
||||
/obj/effect/overlay/temp/swarmer/disintegration/Initialize()
|
||||
. = ..()
|
||||
playsound(loc, "sparks", 100, 1)
|
||||
|
||||
/obj/effect/overlay/temp/swarmer/dismantle
|
||||
icon_state = "dismantle"
|
||||
|
||||
@@ -107,10 +107,10 @@
|
||||
|
||||
/datum/game_mode/monkey/declare_completion()
|
||||
if(check_monkey_victory())
|
||||
feedback_set_details("round_end_result","win - monkey win")
|
||||
feedback_set("round_end_result",escaped_monkeys)
|
||||
SSblackbox.set_details("round_end_result","win - monkey win")
|
||||
SSblackbox.set_val("round_end_result",escaped_monkeys)
|
||||
to_chat(world, "<span class='userdanger'>The monkeys have overthrown their captors! Eeek eeeek!!</span>")
|
||||
else
|
||||
feedback_set_details("round_end_result","loss - staff stopped the monkeys")
|
||||
feedback_set("round_end_result",escaped_monkeys)
|
||||
SSblackbox.set_details("round_end_result","loss - staff stopped the monkeys")
|
||||
SSblackbox.set_val("round_end_result",escaped_monkeys)
|
||||
to_chat(world, "<span class='userdanger'>The staff managed to contain the monkey infestation!</span>")
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
playsound(user, 'sound/magic/Demon_consume.ogg', 50, 1)
|
||||
for(var/obj/effect/proc_holder/spell/knownspell in user.mind.spell_list)
|
||||
if(knownspell.type == /obj/effect/proc_holder/spell/bloodcrawl)
|
||||
user <<"<span class='warning'>...and you don't feel any different.</span>"
|
||||
to_chat(user, "<span class='warning'>...and you don't feel any different.</span>")
|
||||
qdel(src)
|
||||
return
|
||||
user.visible_message("<span class='warning'>[user]'s eyes flare a deep crimson!</span>", \
|
||||
|
||||
@@ -199,70 +199,70 @@
|
||||
|
||||
|
||||
if(nuke_off_station == NUKE_SYNDICATE_BASE)
|
||||
feedback_set_details("round_end_result","loss - syndicate nuked - disk secured")
|
||||
SSblackbox.set_details("round_end_result","loss - syndicate nuked - disk secured")
|
||||
to_chat(world, "<FONT size = 3><B>Humiliating Syndicate Defeat</B></FONT>")
|
||||
to_chat(world, "<B>The crew of [station_name()] gave [syndicate_name()] operatives back their bomb! The syndicate base was destroyed!</B> Next time, don't lose the nuke!")
|
||||
|
||||
SSticker.news_report = NUKE_SYNDICATE_BASE
|
||||
|
||||
else if(!disk_rescued && station_was_nuked && !syndies_didnt_escape)
|
||||
feedback_set_details("round_end_result","win - syndicate nuke")
|
||||
SSblackbox.set_details("round_end_result","win - syndicate nuke")
|
||||
to_chat(world, "<FONT size = 3><B>Syndicate Major Victory!</B></FONT>")
|
||||
to_chat(world, "<B>[syndicate_name()] operatives have destroyed [station_name()]!</B>")
|
||||
|
||||
SSticker.news_report = STATION_NUKED
|
||||
|
||||
else if (!disk_rescued && station_was_nuked && syndies_didnt_escape)
|
||||
feedback_set_details("round_end_result","halfwin - syndicate nuke - did not evacuate in time")
|
||||
SSblackbox.set_details("round_end_result","halfwin - syndicate nuke - did not evacuate in time")
|
||||
to_chat(world, "<FONT size = 3><B>Total Annihilation</B></FONT>")
|
||||
to_chat(world, "<B>[syndicate_name()] operatives destroyed [station_name()] but did not leave the area in time and got caught in the explosion.</B> Next time, don't lose the disk!")
|
||||
|
||||
SSticker.news_report = STATION_NUKED
|
||||
|
||||
else if (!disk_rescued && !station_was_nuked && nuke_off_station && !syndies_didnt_escape)
|
||||
feedback_set_details("round_end_result","halfwin - blew wrong station")
|
||||
SSblackbox.set_details("round_end_result","halfwin - blew wrong station")
|
||||
to_chat(world, "<FONT size = 3><B>Crew Minor Victory</B></FONT>")
|
||||
to_chat(world, "<B>[syndicate_name()] operatives secured the authentication disk but blew up something that wasn't [station_name()].</B> Next time, don't do that!")
|
||||
|
||||
SSticker.news_report = NUKE_MISS
|
||||
|
||||
else if (!disk_rescued && !station_was_nuked && nuke_off_station && syndies_didnt_escape)
|
||||
feedback_set_details("round_end_result","halfwin - blew wrong station - did not evacuate in time")
|
||||
SSblackbox.set_details("round_end_result","halfwin - blew wrong station - did not evacuate in time")
|
||||
to_chat(world, "<FONT size = 3><B>[syndicate_name()] operatives have earned Darwin Award!</B></FONT>")
|
||||
to_chat(world, "<B>[syndicate_name()] operatives blew up something that wasn't [station_name()] and got caught in the explosion.</B> Next time, don't do that!")
|
||||
|
||||
SSticker.news_report = NUKE_MISS
|
||||
|
||||
else if ((disk_rescued || SSshuttle.emergency.mode != SHUTTLE_ENDGAME) && are_operatives_dead())
|
||||
feedback_set_details("round_end_result","loss - evacuation - disk secured - syndi team dead")
|
||||
SSblackbox.set_details("round_end_result","loss - evacuation - disk secured - syndi team dead")
|
||||
to_chat(world, "<FONT size = 3><B>Crew Major Victory!</B></FONT>")
|
||||
to_chat(world, "<B>The Research Staff has saved the disk and killed the [syndicate_name()] Operatives</B>")
|
||||
|
||||
SSticker.news_report = OPERATIVES_KILLED
|
||||
|
||||
else if (disk_rescued)
|
||||
feedback_set_details("round_end_result","loss - evacuation - disk secured")
|
||||
SSblackbox.set_details("round_end_result","loss - evacuation - disk secured")
|
||||
to_chat(world, "<FONT size = 3><B>Crew Major Victory</B></FONT>")
|
||||
to_chat(world, "<B>The Research Staff has saved the disk and stopped the [syndicate_name()] Operatives!</B>")
|
||||
|
||||
SSticker.news_report = OPERATIVES_KILLED
|
||||
|
||||
else if (!disk_rescued && are_operatives_dead())
|
||||
feedback_set_details("round_end_result","halfwin - evacuation - disk not secured")
|
||||
SSblackbox.set_details("round_end_result","halfwin - evacuation - disk not secured")
|
||||
to_chat(world, "<FONT size = 3><B>Neutral Victory!</B></FONT>")
|
||||
to_chat(world, "<B>The Research Staff failed to secure the authentication disk but did manage to kill most of the [syndicate_name()] Operatives!</B>")
|
||||
|
||||
SSticker.news_report = OPERATIVE_SKIRMISH
|
||||
|
||||
else if (!disk_rescued && crew_evacuated)
|
||||
feedback_set_details("round_end_result","halfwin - detonation averted")
|
||||
SSblackbox.set_details("round_end_result","halfwin - detonation averted")
|
||||
to_chat(world, "<FONT size = 3><B>Syndicate Minor Victory!</B></FONT>")
|
||||
to_chat(world, "<B>[syndicate_name()] operatives survived the assault but did not achieve the destruction of [station_name()].</B> Next time, don't lose the disk!")
|
||||
|
||||
SSticker.news_report = OPERATIVE_SKIRMISH
|
||||
|
||||
else if (!disk_rescued && !crew_evacuated)
|
||||
feedback_set_details("round_end_result","halfwin - interrupted")
|
||||
SSblackbox.set_details("round_end_result","halfwin - interrupted")
|
||||
to_chat(world, "<FONT size = 3><B>Neutral Victory</B></FONT>")
|
||||
to_chat(world, "<B>Round was mysteriously interrupted!</B>")
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
U.hidden_uplink.telecrystals = CHALLENGE_TELECRYSTALS
|
||||
U.hidden_uplink.set_gamemode(/datum/game_mode/nuclear)
|
||||
config.shuttle_refuel_delay = max(config.shuttle_refuel_delay, CHALLENGE_SHUTTLE_DELAY)
|
||||
feedback_set("nuclear_challenge_mode",1)
|
||||
SSblackbox.set_val("nuclear_challenge_mode",1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/device/nuclear_challenge/proc/check_allowed(mob/living/user)
|
||||
|
||||
@@ -345,13 +345,13 @@
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
/datum/game_mode/revolution/declare_completion()
|
||||
if(finished == 1)
|
||||
feedback_set_details("round_end_result","win - heads killed")
|
||||
SSblackbox.set_details("round_end_result","win - heads killed")
|
||||
to_chat(world, "<span class='redtext'>The heads of staff were killed or exiled! The revolutionaries win!</span>")
|
||||
|
||||
SSticker.news_report = REVS_WIN
|
||||
|
||||
else if(finished == 2)
|
||||
feedback_set_details("round_end_result","loss - rev heads killed")
|
||||
SSblackbox.set_details("round_end_result","loss - rev heads killed")
|
||||
to_chat(world, "<span class='redtext'>The heads of staff managed to stop the revolution!</span>")
|
||||
|
||||
SSticker.news_report = REVS_LOSE
|
||||
|
||||
@@ -1,22 +1,24 @@
|
||||
/datum/game_mode/traitor/double_agents
|
||||
name = "double agents"
|
||||
config_tag = "double_agents"
|
||||
/datum/game_mode/traitor/internal_affairs
|
||||
name = "Internal Affairs"
|
||||
config_tag = "internal_affairs"
|
||||
employer = "Internal Affairs"
|
||||
required_players = 25
|
||||
required_enemies = 5
|
||||
recommended_enemies = 8
|
||||
reroll_friendly = 0
|
||||
traitor_name = "Nanotrasen Internal Affairs Agent"
|
||||
|
||||
traitors_possible = 10 //hard limit on traitors if scaling is turned off
|
||||
num_modifier = 4 // Four additional traitors
|
||||
|
||||
announce_text = "There are double agents trying to kill each other!\n\
|
||||
<span class='danger'>Traitors</span>: Eliminate your targets and protect yourself!\n\
|
||||
<span class='notice'>Crew</span>: Stop the double agents before they can cause too much mayhem."
|
||||
announce_text = "There are Nanotrasen Internal Affairs Agents trying to kill each other!\n\
|
||||
<span class='danger'>IAA</span>: Eliminate your targets and protect yourself!\n\
|
||||
<span class='notice'>Crew</span>: Stop the IAA agents before they can cause too much mayhem."
|
||||
|
||||
var/list/target_list = list()
|
||||
var/list/late_joining_list = list()
|
||||
|
||||
/datum/game_mode/traitor/double_agents/post_setup()
|
||||
/datum/game_mode/traitor/internal_affairs/post_setup()
|
||||
var/i = 0
|
||||
for(var/datum/mind/traitor in traitors)
|
||||
i++
|
||||
@@ -25,7 +27,7 @@
|
||||
target_list[traitor] = traitors[i + 1]
|
||||
..()
|
||||
|
||||
/datum/game_mode/traitor/double_agents/forge_traitor_objectives(datum/mind/traitor)
|
||||
/datum/game_mode/traitor/internal_affairs/forge_traitor_objectives(datum/mind/traitor)
|
||||
|
||||
if(target_list.len && target_list[traitor]) // Is a double agent
|
||||
|
||||
@@ -58,7 +60,7 @@
|
||||
..() // Give them standard objectives.
|
||||
return
|
||||
|
||||
/datum/game_mode/traitor/double_agents/add_latejoin_traitor(datum/mind/character)
|
||||
/datum/game_mode/traitor/internal_affairs/add_latejoin_traitor(datum/mind/character)
|
||||
|
||||
check_potential_agents()
|
||||
|
||||
@@ -87,7 +89,7 @@
|
||||
late_joining_list += character
|
||||
return
|
||||
|
||||
/datum/game_mode/traitor/double_agents/proc/check_potential_agents()
|
||||
/datum/game_mode/traitor/internal_affairs/proc/check_potential_agents()
|
||||
|
||||
for(var/M in late_joining_list)
|
||||
if(istype(M, /datum/mind))
|
||||
@@ -100,3 +102,18 @@
|
||||
|
||||
// If any check fails, remove them from our list
|
||||
late_joining_list -= M
|
||||
|
||||
|
||||
/datum/game_mode/traitor/internal_affairs/greet_traitor(datum/mind/traitor)
|
||||
var/crime = pick("distribution of contraband" , "unauthorized erotic action on duty", "embezzlement", "piloting under the influence", "dereliction of duty", "syndicate collaboration", "mutiny", "multiple homicides", "corporate espionage", "recieving bribes", "malpractice", "worship of prohbited life forms", "possession of profane texts", "murder", "arson", "insulting their manager", "grand theft", "conspiracy", "attempting to unionize", "vandalism", "gross incompetence")
|
||||
to_chat(traitor.current, "<B><font size=3 color=red>You are the [traitor_name].</font></B>")
|
||||
to_chat(traitor.current, "<B><font size=3 color=red>Your target is suspected of [crime], and you have been tasked with eliminating them by any means necessary to avoid a costly and embarrassing public trial.</font></B>")
|
||||
to_chat(traitor.current, "<B><font size=5 color=red>While you have a license to kill, unneeded property damage or loss of employee life will lead to your contract being terminated.</font></B>")
|
||||
to_chat(traitor.current, "<B><font size=3 color=red>For the sake of plausible deniability, you have been equipped with an array of captured Syndicate weaponry available via uplink.</font></B>")
|
||||
to_chat(traitor.current, "<B><font size=3 color=red>Finally, watch your back. Your target has friends in high places, and intel suggests someone may have taken out a contract of their own to protect them.</font></B>")
|
||||
traitor.announce_objectives()
|
||||
|
||||
|
||||
|
||||
/datum/game_mode/traitor/internal_affairs/give_codewords(mob/living/traitor_mob)
|
||||
return
|
||||
@@ -1,5 +1,6 @@
|
||||
/datum/game_mode
|
||||
var/traitor_name = "traitor"
|
||||
var/employer = "The Syndicate"
|
||||
var/list/datum/mind/traitors = list()
|
||||
|
||||
var/datum/mind/exchange_red
|
||||
@@ -213,7 +214,7 @@
|
||||
..()
|
||||
return//Traitors will be checked as part of check_extra_completion. Leaving this here as a reminder.
|
||||
|
||||
/proc/give_codewords(mob/living/traitor_mob)
|
||||
/datum/game_mode/proc/give_codewords(mob/living/traitor_mob)
|
||||
to_chat(traitor_mob, "<U><B>The Syndicate provided you with the following information on how to identify their agents:</B></U>")
|
||||
to_chat(traitor_mob, "<B>Code Phrase</B>: <span class='danger'>[GLOB.syndicate_code_phrase]</span>")
|
||||
to_chat(traitor_mob, "<B>Code Response</B>: <span class='danger'>[GLOB.syndicate_code_response]</span>")
|
||||
@@ -260,10 +261,10 @@
|
||||
for(var/datum/objective/objective in traitor.objectives)
|
||||
if(objective.check_completion())
|
||||
objectives += "<br><B>Objective #[count]</B>: [objective.explanation_text] <font color='green'><B>Success!</B></font>"
|
||||
feedback_add_details("traitor_objective","[objective.type]|SUCCESS")
|
||||
SSblackbox.add_details("traitor_objective","[objective.type]|SUCCESS")
|
||||
else
|
||||
objectives += "<br><B>Objective #[count]</B>: [objective.explanation_text] <font color='red'>Fail.</font>"
|
||||
feedback_add_details("traitor_objective","[objective.type]|FAIL")
|
||||
SSblackbox.add_details("traitor_objective","[objective.type]|FAIL")
|
||||
traitorwin = 0
|
||||
count++
|
||||
|
||||
@@ -283,10 +284,10 @@
|
||||
|
||||
if(traitorwin)
|
||||
text += "<br><font color='green'><B>The [special_role_text] was successful!</B></font>"
|
||||
feedback_add_details("traitor_success","SUCCESS")
|
||||
SSblackbox.add_details("traitor_success","SUCCESS")
|
||||
else
|
||||
text += "<br><font color='red'><B>The [special_role_text] has failed!</B></font>"
|
||||
feedback_add_details("traitor_success","FAIL")
|
||||
SSblackbox.add_details("traitor_success","FAIL")
|
||||
|
||||
text += "<br>"
|
||||
|
||||
@@ -335,7 +336,7 @@
|
||||
uplink_loc = R
|
||||
|
||||
if (!uplink_loc)
|
||||
to_chat(traitor_mob, "Unfortunately, the Syndicate wasn't able to get you an Uplink.")
|
||||
to_chat(traitor_mob, "Unfortunately, [employer] wasn't able to get you an Uplink.")
|
||||
. = 0
|
||||
else
|
||||
var/obj/item/device/uplink/U = new(uplink_loc)
|
||||
@@ -345,19 +346,19 @@
|
||||
if(uplink_loc == R)
|
||||
R.traitor_frequency = sanitize_frequency(rand(MIN_FREQ, MAX_FREQ))
|
||||
|
||||
to_chat(traitor_mob, "The Syndicate have cunningly disguised a Syndicate Uplink as your [R.name]. Simply dial the frequency [format_frequency(R.traitor_frequency)] to unlock its hidden features.")
|
||||
to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [R.name]. Simply dial the frequency [format_frequency(R.traitor_frequency)] to unlock its hidden features.")
|
||||
traitor_mob.mind.store_memory("<B>Radio Frequency:</B> [format_frequency(R.traitor_frequency)] ([R.name]).")
|
||||
|
||||
else if(uplink_loc == PDA)
|
||||
PDA.lock_code = "[rand(100,999)] [pick("Alpha","Bravo","Charlie","Delta","Echo","Foxtrot","Golf","Hotel","India","Juliet","Kilo","Lima","Mike","November","Oscar","Papa","Quebec","Romeo","Sierra","Tango","Uniform","Victor","Whiskey","X-ray","Yankee","Zulu")]"
|
||||
|
||||
to_chat(traitor_mob, "The Syndicate have cunningly disguised a Syndicate Uplink as your [PDA.name]. Simply enter the code \"[PDA.lock_code]\" into the ringtone select to unlock its hidden features.")
|
||||
to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [PDA.name]. Simply enter the code \"[PDA.lock_code]\" into the ringtone select to unlock its hidden features.")
|
||||
traitor_mob.mind.store_memory("<B>Uplink Passcode:</B> [PDA.lock_code] ([PDA.name]).")
|
||||
|
||||
else if(uplink_loc == P)
|
||||
P.traitor_unlock_degrees = rand(1, 360)
|
||||
|
||||
to_chat(traitor_mob, "The Syndicate have cunningly disguised a Syndicate Uplink as your [P.name]. Simply twist the top of the pen [P.traitor_unlock_degrees] from its starting position to unlock its hidden features.")
|
||||
to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [P.name]. Simply twist the top of the pen [P.traitor_unlock_degrees] from its starting position to unlock its hidden features.")
|
||||
traitor_mob.mind.store_memory("<B>Uplink Degrees:</B> [P.traitor_unlock_degrees] ([P.name]).")
|
||||
|
||||
if(!safety) // If they are not a rev. Can be added on to.
|
||||
|
||||
@@ -471,7 +471,7 @@
|
||||
else if(istype(I,/obj/item/weapon/bikehorn))
|
||||
to_chat(target, "<span class='userdanger'>HONK</span>")
|
||||
target << 'sound/items/AirHorn.ogg'
|
||||
target.adjustEarDamage(0,3)
|
||||
target.adjustEarDamage(0,3)
|
||||
GiveHint(target)
|
||||
cooldown = world.time +cooldown_time
|
||||
return
|
||||
@@ -630,6 +630,6 @@
|
||||
duration = 40
|
||||
pixel_x = 500
|
||||
|
||||
/obj/effect/overlay/temp/tornado/New(loc)
|
||||
..()
|
||||
/obj/effect/overlay/temp/tornado/Initialize()
|
||||
. = ..()
|
||||
animate(src, pixel_x = -500, time = 40)
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
|
||||
/datum/game_mode/wizard/raginmages/declare_completion()
|
||||
if(finished)
|
||||
feedback_set_details("round_end_result","loss - wizard killed")
|
||||
SSblackbox.set_details("round_end_result","loss - wizard killed")
|
||||
to_chat(world, "<FONT size=3><B>The crew has managed to hold off the wizard attack! The Space Wizards Federation has been taught a lesson they will not soon forget!</B></FONT>")
|
||||
..(1)
|
||||
|
||||
|
||||
@@ -57,10 +57,10 @@
|
||||
aspell.name = "Instant [aspell.name]"
|
||||
if(aspell.spell_level >= aspell.level_max)
|
||||
to_chat(user, "<span class='notice'>This spell cannot be strengthened any further.</span>")
|
||||
feedback_add_details("wizard_spell_improved", "[name]|[aspell.level]")
|
||||
SSblackbox.add_details("wizard_spell_improved", "[name]|[aspell.level]")
|
||||
return 1
|
||||
//No same spell found - just learn it
|
||||
feedback_add_details("wizard_spell_learned", name)
|
||||
SSblackbox.add_details("wizard_spell_learned", name)
|
||||
user.mind.AddSpell(S)
|
||||
to_chat(user, "<span class='notice'>You have learned [S.name].</span>")
|
||||
return 1
|
||||
@@ -253,7 +253,7 @@
|
||||
/datum/spellbook_entry/the_traps
|
||||
name = "The Traps!"
|
||||
spell_type = /obj/effect/proc_holder/spell/aoe_turf/conjure/the_traps
|
||||
category = "Offensive"
|
||||
category = "Defensive"
|
||||
cost = 1
|
||||
|
||||
|
||||
@@ -266,7 +266,7 @@
|
||||
|
||||
/datum/spellbook_entry/item/Buy(mob/living/carbon/human/user,obj/item/weapon/spellbook/book)
|
||||
new item_path(get_turf(user))
|
||||
feedback_add_details("wizard_spell_learned", name)
|
||||
SSblackbox.add_details("wizard_spell_learned", name)
|
||||
return 1
|
||||
|
||||
/datum/spellbook_entry/item/GetInfo()
|
||||
@@ -465,7 +465,7 @@
|
||||
return TRUE
|
||||
|
||||
/datum/spellbook_entry/summon/ghosts/Buy(mob/living/carbon/human/user, obj/item/weapon/spellbook/book)
|
||||
feedback_add_details("wizard_spell_learned", name)
|
||||
SSblackbox.add_details("wizard_spell_learned", name)
|
||||
new /datum/round_event/wizard/ghost()
|
||||
active = TRUE
|
||||
to_chat(user, "<span class='notice'>You have cast summon ghosts!</span>")
|
||||
@@ -482,7 +482,7 @@
|
||||
return (SSticker.mode.name != "ragin' mages" && !config.no_summon_guns)
|
||||
|
||||
/datum/spellbook_entry/summon/guns/Buy(mob/living/carbon/human/user,obj/item/weapon/spellbook/book)
|
||||
feedback_add_details("wizard_spell_learned", name)
|
||||
SSblackbox.add_details("wizard_spell_learned", name)
|
||||
rightandwrong(0, user, 25)
|
||||
active = 1
|
||||
playsound(get_turf(user), 'sound/magic/CastSummon.ogg', 50, 1)
|
||||
@@ -499,7 +499,7 @@
|
||||
return (SSticker.mode.name != "ragin' mages" && !config.no_summon_magic)
|
||||
|
||||
/datum/spellbook_entry/summon/magic/Buy(mob/living/carbon/human/user,obj/item/weapon/spellbook/book)
|
||||
feedback_add_details("wizard_spell_learned", name)
|
||||
SSblackbox.add_details("wizard_spell_learned", name)
|
||||
rightandwrong(1, user, 25)
|
||||
active = 1
|
||||
playsound(get_turf(user), 'sound/magic/CastSummon.ogg', 50, 1)
|
||||
@@ -517,7 +517,7 @@
|
||||
return (SSticker.mode.name != "ragin' mages" && !config.no_summon_events)
|
||||
|
||||
/datum/spellbook_entry/summon/events/Buy(mob/living/carbon/human/user,obj/item/weapon/spellbook/book)
|
||||
feedback_add_details("wizard_spell_learned", name)
|
||||
SSblackbox.add_details("wizard_spell_learned", name)
|
||||
summonevents()
|
||||
times++
|
||||
playsound(get_turf(user), 'sound/magic/CastSummon.ogg', 50, 1)
|
||||
|
||||
@@ -176,7 +176,7 @@
|
||||
|
||||
/datum/game_mode/wizard/declare_completion()
|
||||
if(finished)
|
||||
feedback_set_details("round_end_result","loss - wizard killed")
|
||||
SSblackbox.set_details("round_end_result","loss - wizard killed")
|
||||
to_chat(world, "<span class='userdanger'>The wizard[(wizards.len>1)?"s":""] has been killed by the crew! The Space Wizards Federation has been taught a lesson they will not soon forget!</span>")
|
||||
|
||||
SSticker.news_report = WIZARD_KILLED
|
||||
@@ -208,19 +208,19 @@
|
||||
for(var/datum/objective/objective in wizard.objectives)
|
||||
if(objective.check_completion())
|
||||
text += "<br><B>Objective #[count]</B>: [objective.explanation_text] <font color='green'><B>Success!</B></font>"
|
||||
feedback_add_details("wizard_objective","[objective.type]|SUCCESS")
|
||||
SSblackbox.add_details("wizard_objective","[objective.type]|SUCCESS")
|
||||
else
|
||||
text += "<br><B>Objective #[count]</B>: [objective.explanation_text] <font color='red'>Fail.</font>"
|
||||
feedback_add_details("wizard_objective","[objective.type]|FAIL")
|
||||
SSblackbox.add_details("wizard_objective","[objective.type]|FAIL")
|
||||
wizardwin = 0
|
||||
count++
|
||||
|
||||
if(wizard.current && wizard.current.stat!=2 && wizardwin)
|
||||
text += "<br><font color='green'><B>The wizard was successful!</B></font>"
|
||||
feedback_add_details("wizard_success","SUCCESS")
|
||||
SSblackbox.add_details("wizard_success","SUCCESS")
|
||||
else
|
||||
text += "<br><font color='red'><B>The wizard has failed!</B></font>"
|
||||
feedback_add_details("wizard_success","FAIL")
|
||||
SSblackbox.add_details("wizard_success","FAIL")
|
||||
if(wizard.spell_list.len>0)
|
||||
text += "<br><B>[wizard.name] used the following spells: </B>"
|
||||
var/i = 1
|
||||
|
||||
@@ -4,7 +4,21 @@
|
||||
icon = 'goon/icons/obj/goon_terminals.dmi'
|
||||
idle_power_usage = 100
|
||||
var/siphoning = FALSE
|
||||
var/last_warning = 0
|
||||
var/next_warning = 0
|
||||
var/obj/item/device/radio/radio
|
||||
var/radio_channel = "Common"
|
||||
var/minimum_time_between_warnings = 400
|
||||
|
||||
/obj/machinery/computer/bank_machine/Initialize(mapload)
|
||||
..()
|
||||
radio = new(src)
|
||||
radio.subspace_transmission = TRUE
|
||||
radio.canhear_range = 0
|
||||
radio.recalculateChannels()
|
||||
|
||||
/obj/machinery/computer/bank_machine/Destroy()
|
||||
QDEL_NULL(radio)
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/computer/bank_machine/attackby(obj/item/I, mob/user)
|
||||
var/value = 0
|
||||
@@ -32,18 +46,17 @@
|
||||
say("Station funds depleted. Halting siphon.")
|
||||
siphoning = FALSE
|
||||
else
|
||||
var/obj/item/stack/spacecash/c200/on_turf = locate() in src.loc
|
||||
if(on_turf && on_turf.amount < on_turf.max_amount)
|
||||
on_turf.amount++
|
||||
else
|
||||
new /obj/item/stack/spacecash/c200(get_turf(src))
|
||||
new /obj/item/stack/spacecash/c200(get_turf(src)) // will autostack
|
||||
playsound(src.loc, 'sound/items/poster_being_created.ogg', 100, 1)
|
||||
SSshuttle.points -= 200
|
||||
if(last_warning < world.time && prob(15))
|
||||
if(next_warning < world.time && prob(15))
|
||||
var/area/A = get_area(loc)
|
||||
minor_announce("Unauthorized credit withdrawal underway in [A.map_name]." , "Network Breach", TRUE)
|
||||
last_warning = world.time + 400
|
||||
var/message = "Unauthorized credit withdrawal underway in [A.map_name]!!"
|
||||
radio.talk_into(src, message, radio_channel, get_spans())
|
||||
next_warning = world.time + minimum_time_between_warnings
|
||||
|
||||
/obj/machinery/computer/bank_machine/get_spans()
|
||||
. = ..() | SPAN_ROBOT
|
||||
|
||||
/obj/machinery/computer/bank_machine/attack_hand(mob/user)
|
||||
if(..())
|
||||
@@ -67,8 +80,8 @@
|
||||
if(..())
|
||||
return
|
||||
if(href_list["siphon"])
|
||||
say("<span class='warning'>Siphon of station credits has begun!</span>")
|
||||
say("Siphon of station credits has begun!")
|
||||
siphoning = TRUE
|
||||
if(href_list["halt"])
|
||||
say("<span class='warning'>Station credit withdrawal halted.</span>")
|
||||
siphoning = FALSE
|
||||
say("Station credit withdrawal halted.")
|
||||
siphoning = FALSE
|
||||
|
||||
@@ -204,11 +204,13 @@
|
||||
|
||||
clonemind.transfer_to(H)
|
||||
|
||||
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)
|
||||
addtimer(CALLBACK(src, .proc/occupant_dreams), 100)
|
||||
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
|
||||
@@ -219,11 +221,6 @@
|
||||
attempting = FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/clonepod/proc/occupant_dreams()
|
||||
if(occupant)
|
||||
to_chat(occupant, "<span class='revennotice'>While your body grows, you have the strangest dream, like you can see yourself from the outside.</span>")
|
||||
occupant.ghostize(TRUE)
|
||||
|
||||
//Grow clones to maturity then kick them out. FREELOADERS
|
||||
/obj/machinery/clonepod/process()
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@
|
||||
if(!authenticated) //Check for emags
|
||||
var/obj/item/weapon/card/emag/E = usr.get_active_held_item()
|
||||
if(E && istype(E) && usr.Adjacent(src))
|
||||
usr << "<span class='warning'>You bypass [src]'s access requirements using your emag.</span>"
|
||||
to_chat(usr, "<span class='warning'>You bypass [src]'s access requirements using your emag.</span>")
|
||||
authenticated = TRUE
|
||||
log_activity("logged in") //Auth ID doesn't change, hinting that it was illicit
|
||||
if(href_list["log_out"])
|
||||
|
||||
@@ -234,7 +234,7 @@
|
||||
playsound(loc, 'sound/arcade/Win.ogg', 50, 1, extrarange = -3, falloff = 10)
|
||||
|
||||
if(emagged)
|
||||
feedback_inc("arcade_win_emagged")
|
||||
SSblackbox.inc("arcade_win_emagged")
|
||||
new /obj/effect/spawner/newbomb/timer/syndicate(loc)
|
||||
new /obj/item/clothing/head/collectable/petehat(loc)
|
||||
message_admins("[key_name_admin(usr)] has outbombed Cuban Pete and been awarded a bomb.")
|
||||
@@ -242,7 +242,7 @@
|
||||
Reset()
|
||||
emagged = 0
|
||||
else
|
||||
feedback_inc("arcade_win_normal")
|
||||
SSblackbox.inc("arcade_win_normal")
|
||||
prizevend()
|
||||
|
||||
else if (emagged && (turtle >= 4))
|
||||
@@ -264,10 +264,10 @@
|
||||
temp = "You have been drained! GAME OVER"
|
||||
playsound(loc, 'sound/arcade/Lose.ogg', 50, 1, extrarange = -3, falloff = 10)
|
||||
if(emagged)
|
||||
feedback_inc("arcade_loss_mana_emagged")
|
||||
SSblackbox.inc("arcade_loss_mana_emagged")
|
||||
usr.gib()
|
||||
else
|
||||
feedback_inc("arcade_loss_mana_normal")
|
||||
SSblackbox.inc("arcade_loss_mana_normal")
|
||||
|
||||
else if ((enemy_hp <= 10) && (enemy_mp > 4))
|
||||
temp = "[enemy_name] heals for 4 health!"
|
||||
@@ -286,10 +286,10 @@
|
||||
temp = "You have been crushed! GAME OVER"
|
||||
playsound(loc, 'sound/arcade/Lose.ogg', 50, 1, extrarange = -3, falloff = 10)
|
||||
if(emagged)
|
||||
feedback_inc("arcade_loss_hp_emagged")
|
||||
SSblackbox.inc("arcade_loss_hp_emagged")
|
||||
usr.gib()
|
||||
else
|
||||
feedback_inc("arcade_loss_hp_normal")
|
||||
SSblackbox.inc("arcade_loss_hp_normal")
|
||||
|
||||
blocked = FALSE
|
||||
return
|
||||
|
||||
@@ -304,17 +304,17 @@
|
||||
build_path = /obj/machinery/computer/gulag_teleporter_computer
|
||||
|
||||
/obj/item/weapon/circuitboard/computer/rdconsole
|
||||
name = "RD Console (Computer Board)"
|
||||
name = "R&D Console (Computer Board)"
|
||||
build_path = /obj/machinery/computer/rdconsole/core
|
||||
|
||||
/obj/item/weapon/circuitboard/computer/rdconsole/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I,/obj/item/weapon/screwdriver))
|
||||
if(build_path == /obj/machinery/computer/rdconsole/core)
|
||||
name = "RD Console - Robotics (Computer Board)"
|
||||
name = "R&D Console - Robotics (Computer Board)"
|
||||
build_path = /obj/machinery/computer/rdconsole/robotics
|
||||
to_chat(user, "<span class='notice'>Access protocols successfully updated.</span>")
|
||||
else
|
||||
name = "RD Console (Computer Board)"
|
||||
name = "R&D Console (Computer Board)"
|
||||
build_path = /obj/machinery/computer/rdconsole/core
|
||||
to_chat(user, "<span class='notice'>Defaulting access protocols.</span>")
|
||||
else
|
||||
|
||||
@@ -532,7 +532,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
|
||||
else
|
||||
SSjob.prioritized_jobs += j
|
||||
prioritycount++
|
||||
usr << "<span class='notice'>[j.title] has been successfully [priority ? "prioritized" : "unprioritized"]. Potential employees will notice your request.</span>"
|
||||
to_chat(usr, "<span class='notice'>[j.title] has been successfully [priority ? "prioritized" : "unprioritized"]. Potential employees will notice your request.</span>")
|
||||
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
|
||||
|
||||
if ("print")
|
||||
|
||||
@@ -115,9 +115,9 @@
|
||||
message_admins("[key_name_admin(usr)] has changed the security level to [get_security_level()].")
|
||||
switch(GLOB.security_level)
|
||||
if(SEC_LEVEL_GREEN)
|
||||
feedback_inc("alert_comms_green",1)
|
||||
SSblackbox.inc("alert_comms_green",1)
|
||||
if(SEC_LEVEL_BLUE)
|
||||
feedback_inc("alert_comms_blue",1)
|
||||
SSblackbox.inc("alert_comms_blue",1)
|
||||
tmp_alertlevel = 0
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>You are not authorized to do this!</span>")
|
||||
@@ -176,7 +176,7 @@
|
||||
SSshuttle.points -= S.credit_cost
|
||||
minor_announce("[usr.name] has purchased [S.name] for [S.credit_cost] credits." , "Shuttle Purchase")
|
||||
message_admins("[key_name_admin(usr)] purchased [S.name].")
|
||||
feedback_add_details("shuttle_purchase", S.name)
|
||||
SSblackbox.add_details("shuttle_purchase", S.name)
|
||||
else
|
||||
to_chat(usr, "Something went wrong! The shuttle exchange system seems to be down.")
|
||||
else
|
||||
@@ -368,9 +368,9 @@
|
||||
message_admins("[key_name_admin(usr)] has changed the security level to [get_security_level()].")
|
||||
switch(GLOB.security_level)
|
||||
if(SEC_LEVEL_GREEN)
|
||||
feedback_inc("alert_comms_green",1)
|
||||
SSblackbox.inc("alert_comms_green",1)
|
||||
if(SEC_LEVEL_BLUE)
|
||||
feedback_inc("alert_comms_blue",1)
|
||||
SSblackbox.inc("alert_comms_blue",1)
|
||||
tmp_alertlevel = 0
|
||||
src.aistate = STATE_DEFAULT
|
||||
if("ai-changeseclevel")
|
||||
|
||||
@@ -455,14 +455,16 @@
|
||||
name = "monitor decryption key"
|
||||
var/obj/machinery/message_server/server = null
|
||||
|
||||
/obj/item/weapon/paper/monitorkey/New()
|
||||
/obj/item/weapon/paper/monitorkey/Initialize()
|
||||
..()
|
||||
spawn(10)
|
||||
if(GLOB.message_servers)
|
||||
for(var/obj/machinery/message_server/server in GLOB.message_servers)
|
||||
if(!isnull(server))
|
||||
if(!isnull(server.decryptkey))
|
||||
info = "<center><h2>Daily Key Reset</h2></center><br>The new message monitor key is '[server.decryptkey]'.<br>Please keep this a secret and away from the clown.<br>If necessary, change the password to a more secure one."
|
||||
info_links = info
|
||||
add_overlay("paper_words")
|
||||
break
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/obj/item/weapon/paper/monitorkey/LateInitialize()
|
||||
if(GLOB.message_servers)
|
||||
for(var/obj/machinery/message_server/server in GLOB.message_servers)
|
||||
if(!isnull(server))
|
||||
if(!isnull(server.decryptkey))
|
||||
info = "<center><h2>Daily Key Reset</h2></center><br>The new message monitor key is '[server.decryptkey]'.<br>Please keep this a secret and away from the clown.<br>If necessary, change the password to a more secure one."
|
||||
info_links = info
|
||||
add_overlay("paper_words")
|
||||
break
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
var/list/rangers = list()
|
||||
var/charge = 35
|
||||
var/stop = 0
|
||||
var/list/available = list()
|
||||
var/list/select_name = list()
|
||||
var/list/spotlights = list()
|
||||
var/list/sparkles = list()
|
||||
var/static/list/songs = list(
|
||||
@@ -30,6 +28,7 @@
|
||||
var/song_path = null
|
||||
var/song_length = 0
|
||||
var/song_beat = 0
|
||||
var/GBP_required = 0
|
||||
|
||||
/datum/track/New(name, path, length, beat)
|
||||
song_name = name
|
||||
@@ -37,6 +36,19 @@
|
||||
song_length = length
|
||||
song_beat = beat
|
||||
|
||||
/obj/machinery/disco/proc/add_track(file, name, length, beat)
|
||||
var/sound/S = file
|
||||
if(!istype(S))
|
||||
return
|
||||
if(!name)
|
||||
name = "[file]"
|
||||
if(!beat)
|
||||
beat = 5
|
||||
if(!length)
|
||||
length = 2400 //Unless there's a way to discern via BYOND.
|
||||
var/datum/track/T = new /datum/track(name, file, length, beat)
|
||||
songs += T
|
||||
|
||||
/obj/machinery/disco/Initialize()
|
||||
..()
|
||||
selection = songs[1]
|
||||
@@ -126,14 +138,14 @@
|
||||
if(active)
|
||||
to_chat(usr, "<span class='warning'>Error: You cannot change the song until the current one is over.</span>")
|
||||
return
|
||||
check_GBP()
|
||||
select_name = input(usr, "Choose your song", "Track:") as null|anything in available
|
||||
if (QDELETED(src))
|
||||
return
|
||||
|
||||
var/list/available = list()
|
||||
for(var/datum/track/S in songs)
|
||||
if(select_name == S.song_name)
|
||||
selection = S
|
||||
break
|
||||
available[S.song_name] = S
|
||||
var/selected = input(usr, "Choose your song", "Track:") as null|anything in available
|
||||
if(QDELETED(src) || !selected || !istype(available[selected], /datum/track))
|
||||
return
|
||||
selection = available[selected]
|
||||
updateUsrDialog()
|
||||
if("horn")
|
||||
deejay('sound/items/AirHorn2.ogg')
|
||||
@@ -159,13 +171,6 @@
|
||||
charge -= 5
|
||||
playsound(src, S,300,1)
|
||||
|
||||
/obj/machinery/disco/proc/check_GBP()
|
||||
available |= "Engineering's Basic Beat"
|
||||
available |= "Engineering's Domination Dance"
|
||||
available |= "Engineering's Superiority Shimmy"
|
||||
available |= "Engineering's Ultimate High-Energy Hustle"
|
||||
|
||||
|
||||
/obj/machinery/disco/proc/dance_setup()
|
||||
stop = world.time + selection.song_length
|
||||
var/turf/cen = get_turf(src)
|
||||
|
||||
@@ -19,12 +19,12 @@
|
||||
/obj/machinery/doorButtons/proc/findObjsByTag()
|
||||
return
|
||||
|
||||
/obj/machinery/doorButtons/Initialize(mapload)
|
||||
if(mapload)
|
||||
..()
|
||||
return TRUE
|
||||
else
|
||||
findObjsByTag()
|
||||
/obj/machinery/doorButtons/Initialize()
|
||||
..()
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/obj/machinery/doorButtons/LateInitialize()
|
||||
findObjsByTag()
|
||||
|
||||
/obj/machinery/doorButtons/emag_act(mob/user)
|
||||
if(!emagged)
|
||||
|
||||
@@ -200,7 +200,7 @@
|
||||
if(beaker.reagents && beaker.reagents.reagent_list.len)
|
||||
to_chat(usr, "<span class='notice'>Attached is \a [beaker] with [beaker.reagents.total_volume] units of liquid.</span>")
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>Attached is an empty [beaker].</span>")
|
||||
to_chat(usr, "<span class='notice'>Attached is an empty [beaker.name].</span>")
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>No chemicals are attached.</span>")
|
||||
|
||||
|
||||
@@ -535,7 +535,7 @@ GLOBAL_LIST_EMPTY(allCasters)
|
||||
if(choice=="Confirm")
|
||||
scan_user(usr)
|
||||
GLOB.news_network.CreateFeedChannel(channel_name, scanned_user, c_locked)
|
||||
feedback_inc("newscaster_channels",1)
|
||||
SSblackbox.inc("newscaster_channels",1)
|
||||
screen=5
|
||||
updateUsrDialog()
|
||||
else if(href_list["set_channel_receiving"])
|
||||
@@ -558,7 +558,7 @@ GLOBAL_LIST_EMPTY(allCasters)
|
||||
screen=6
|
||||
else
|
||||
GLOB.news_network.SubmitArticle("<font face=\"[PEN_FONT]\">[parsepencode(msg, usr, SIGNFONT)]</font>", scanned_user, channel_name, photo, 0, allow_comments)
|
||||
feedback_inc("newscaster_stories",1)
|
||||
SSblackbox.inc("newscaster_stories",1)
|
||||
screen=4
|
||||
msg = ""
|
||||
updateUsrDialog()
|
||||
@@ -850,7 +850,7 @@ GLOBAL_LIST_EMPTY(allCasters)
|
||||
return
|
||||
|
||||
/obj/machinery/newscaster/proc/print_paper()
|
||||
feedback_inc("newscaster_newspapers_printed",1)
|
||||
SSblackbox.inc("newscaster_newspapers_printed",1)
|
||||
var/obj/item/weapon/newspaper/NEWSPAPER = new /obj/item/weapon/newspaper
|
||||
for(var/datum/newscaster/feed_channel/FC in GLOB.news_network.network_channels)
|
||||
NEWSPAPER.news_content += FC
|
||||
|
||||
Regular → Executable
+5
-2
@@ -61,7 +61,7 @@
|
||||
G.loc = src
|
||||
charging = G
|
||||
use_power = 2
|
||||
update_icon()
|
||||
update_icon(scan = TRUE)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>[src] isn't connected to anything!</span>")
|
||||
return 1
|
||||
@@ -162,10 +162,13 @@
|
||||
..()
|
||||
|
||||
|
||||
/obj/machinery/recharger/update_icon(using_power = 0) //we have an update_icon() in addition to the stuff in process to make it feel a tiny bit snappier.
|
||||
/obj/machinery/recharger/update_icon(using_power = 0, scan) //we have an update_icon() in addition to the stuff in process to make it feel a tiny bit snappier.
|
||||
if(stat & (NOPOWER|BROKEN) || !anchored)
|
||||
icon_state = "rechargeroff"
|
||||
return
|
||||
if(scan)
|
||||
icon_state = "rechargeroff"
|
||||
return
|
||||
if(panel_open)
|
||||
icon_state = "rechargeropen"
|
||||
return
|
||||
|
||||
@@ -439,12 +439,12 @@ GLOBAL_LIST_EMPTY(allConsoles)
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
/obj/machinery/requests_console/say_quote(input, list/spans, message_mode)
|
||||
/obj/machinery/requests_console/say_mod(input, message_mode)
|
||||
var/ending = copytext(input, length(input) - 2)
|
||||
if (ending == "!!!")
|
||||
return "blares, \"[attach_spans(input, spans)]\""
|
||||
|
||||
return ..()
|
||||
. = "blares"
|
||||
else
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/requests_console/proc/clear_emergency()
|
||||
emergency = null
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user