Merge branch 'master' into upstream-merge-26129

This commit is contained in:
LetterJay
2017-04-29 11:45:37 -05:00
committed by GitHub
131 changed files with 1020 additions and 743 deletions
+2 -1
View File
@@ -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)
+18
View File
@@ -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.
+18
View File
@@ -0,0 +1,18 @@
diff a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm (rejected hunks)
@@ -26,4 +26,13 @@
#define INITIALIZE_HINT_NORMAL 0 //Nothing happens
#define INITIALIZE_HINT_LATELOAD 1 //Call LateInitialize
-#define INITIALIZE_HINT_QDEL 2 //Call qdel on the atom
\ No newline at end of file
+#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);\
+ }\
+}
\ No newline at end of file
+1 -1
View File
@@ -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)
+1 -1
View File
@@ -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)
+1 -1
View File
@@ -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)
+1
View File
@@ -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"
+1
View File
@@ -76,6 +76,7 @@
refill_canister = /obj/item/weapon/vending_refill/soviet
#undef STANDARD_CHARGE
#undef CONTRABAND_CHARGE
#undef COIN_CHARGE
+3 -1
View File
@@ -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
+4 -6
View File
@@ -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
View File
@@ -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
+9
View File
@@ -0,0 +1,9 @@
diff a/code/controllers/subsystem/atoms.dm b/code/controllers/subsystem/atoms.dm (rejected hunks)
@@ -12,6 +12,7 @@ SUBSYSTEM_DEF(atoms)
var/old_initialized
var/list/late_loaders
+ var/list/created_atoms
var/list/BadInitializeCalls = list()
+26 -18
View File
@@ -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
+31 -24
View File
@@ -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()
..()
@@ -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]
+1 -1
View File
@@ -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
+4 -6
View File
@@ -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.")
+12 -1
View File
@@ -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()
@@ -446,7 +447,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 +527,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
-4
View File
@@ -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())
+2 -2
View File
@@ -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]
+1 -1
View File
@@ -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()
+1 -1
View File
@@ -1143,7 +1143,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"
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -4,6 +4,7 @@
name = "\improper Unexplored Location"
icon_state = "away"
has_gravity = 1
hidden = TRUE
/area/ruin/unpowered
+20 -10
View File
@@ -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)
+3 -3
View File
@@ -45,7 +45,7 @@
return ..()
/atom/movable/Initialize(mapload)
..()
. = ..()
for(var/L in initial_languages)
grant_language(L)
@@ -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)
+2 -2
View File
@@ -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))
@@ -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)
@@ -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)
@@ -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>")
@@ -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>", \
+5 -8
View File
@@ -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()
+1 -1
View File
@@ -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"])
@@ -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
+1 -1
View File
@@ -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")
@@ -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)
+1 -1
View File
@@ -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>")
+10
View File
@@ -0,0 +1,10 @@
diff a/code/game/objects/items.dm b/code/game/objects/items.dm (rejected hunks)
@@ -102,7 +102,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s
/obj/item/Initialize()
if (!materials)
materials = list()
- ..()
+ . = ..()
for(var/path in actions_types)
new path(src)
actions_types = null
+2
View File
@@ -465,11 +465,13 @@
icon_state = "crayonblack"
paint_color = "#1C1C1C" //Not completely black because total black looks bad. So Mostly Black.
item_color = "black"
reagent_contents = list("nutriment" = 1, "blackcrayonpowder" = 1)
/obj/item/toy/crayon/white
icon_state = "crayonwhite"
paint_color = "#FFFFFF"
item_color = "white"
reagent_contents = list("nutriment" = 1, "whitecrayonpowder" = 1)
/obj/item/toy/crayon/mime
icon_state = "crayonmime"
@@ -87,7 +87,7 @@
var/mob/living/silicon/robot/R = user
if(shock)
user <<"<span class='notice'>You clear all active holograms, and reset your projector to normal.</span>"
to_chat(user, "<span class='notice'>You clear all active holograms, and reset your projector to normal.</span>")
holosign_type = /obj/structure/holosign/barrier/cyborg
creation_time = 5
if(signs.len)
@@ -96,7 +96,7 @@
shock = 0
return
else if(R.emagged&&!shock)
user <<"<span class='warning'>You clear all active holograms, and overload your energy projector!</span>"
to_chat(user, "<span class='warning'>You clear all active holograms, and overload your energy projector!</span>")
holosign_type = /obj/structure/holosign/barrier/cyborg/hacked
creation_time = 30
if(signs.len)
+2 -2
View File
@@ -60,9 +60,9 @@
/obj/item/weapon/melee/baton/examine(mob/user)
..()
if(bcell)
user <<"<span class='notice'>The baton is [round(bcell.percent())]% charged.</span>"
to_chat(user, "<span class='notice'>The baton is [round(bcell.percent())]% charged.</span>")
else
user <<"<span class='warning'>The baton does not have a power source installed.</span>"
to_chat(user, "<span class='warning'>The baton does not have a power source installed.</span>")
/obj/item/weapon/melee/baton/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/weapon/stock_parts/cell))
+1 -1
View File
@@ -37,7 +37,7 @@
..()
/obj/Initialize()
..()
. = ..()
if (!armor)
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0)
if(on_blueprints && isturf(loc))
+3 -3
View File
@@ -115,7 +115,7 @@
update_icon()
return
if(locked)
user <<"<span class='warning'> The [name] won't budge!</span>"
to_chat(user, "<span class='warning'>The [name] won't budge!</span>")
return
else
open = !open
@@ -131,7 +131,7 @@
/obj/structure/fireaxecabinet/attack_tk(mob/user)
if(locked)
user <<"<span class='warning'> The [name] won't budge!</span>"
to_chat(user, "<span class='warning'>The [name] won't budge!</span>")
return
else
open = !open
@@ -177,7 +177,7 @@
set src in oview(1)
if(locked)
usr <<"<span class='warning'> The [name] won't budge!</span>"
to_chat(usr, "<span class='warning'>The [name] won't budge!</span>")
return
else
open = !open
+4 -7
View File
@@ -14,18 +14,15 @@
/obj/structure/ladder/Initialize(mapload)
if(!initialized)
GLOB.ladders += src
..()
if(mapload)
return TRUE
update_link()
GLOB.ladders += src
..()
return INITIALIZE_HINT_LATELOAD
/obj/structure/ladder/Destroy()
GLOB.ladders -= src
. = ..()
/obj/structure/ladder/proc/update_link()
/obj/structure/ladder/LateInitialize()
for(var/obj/structure/ladder/L in GLOB.ladders)
if(L.id == id)
if(L.height == (height - 1))
+2
View File
@@ -42,6 +42,8 @@
if (opacity)
has_opaque_atom = TRUE
return INITIALIZE_HINT_NORMAL
/turf/open/space/attack_ghost(mob/dead/observer/user)
if(destination_z)
+1
View File
@@ -56,6 +56,7 @@
if (opacity)
has_opaque_atom = TRUE
return INITIALIZE_HINT_NORMAL
/turf/proc/Initalize_Atmos(times_fired)
CalculateAdjacentTurfs()
+3 -1
View File
@@ -166,8 +166,10 @@ GLOBAL_LIST_INIT(admin_verbs_debug, AVerbsDebug())
//citadel code
/client/proc/give_humans_genitals,
/client/proc/test_mammal_overlays,
/client/proc/pump_random_event
/client/proc/pump_random_event,
/client/proc/cmd_display_init_log
)
GLOBAL_PROTECT(admin_verbs_possess)
GLOBAL_LIST_INIT(admin_verbs_possess, list(/proc/possess,/proc/release))
GLOBAL_PROTECT(admin_verbs_permissions)
+11
View File
@@ -0,0 +1,11 @@
diff a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm (rejected hunks)
@@ -153,7 +153,8 @@ var/list/admin_verbs_debug = list(
/client/proc/clear_dynamic_transit,
/client/proc/toggle_medal_disable,
/client/proc/view_runtimes,
- /client/proc/pump_random_event
+ /client/proc/pump_random_event,
+ /client/proc/cmd_display_init_log
)
var/list/admin_verbs_possess = list(
/proc/possess,
+1 -1
View File
@@ -477,7 +477,7 @@
var/list/new_args = list()
for(var/arg in arguments)
new_args += SDQL_expression(source, arg)
if(object == world) // Global proc.
if(object == GLOB) // Global proc.
procname = "/proc/[procname]"
return WrapAdminProcCall(GLOBAL_PROC, procname, new_args)
return WrapAdminProcCall(object, procname, new_args)
+1 -1
View File
@@ -591,7 +591,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
admin_keys += "[C][C.holder.fakekey ? "(Stealth)" : ""][C.is_afk() ? "(AFK)" : ""]"
for(var/admin in admin_keys)
if(LAZYLEN(admin_keys) > 1)
if(LAZYLEN(message) > 1)
message += ", [admin]"
else
message += "[admin]"
+7
View File
@@ -721,6 +721,13 @@ GLOBAL_PROTECT(AdminProcCall)
usr << browse(dat, "window=dellog")
/client/proc/cmd_display_init_log()
set category = "Debug"
set name = "Display Initialzie() Log"
set desc = "Displays a list of things that didn't handle Initialize() properly"
usr << browse(replacetext(SSatoms.InitLog(), "\n", "<br>"), "window=initlog")
/client/proc/debug_huds(i as num)
set category = "Debug"
set name = "Debug HUDs"
+5 -1
View File
@@ -505,7 +505,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
message_admins("[key_name_admin(src)] has changed Central Command's name to [input]")
log_admin("[key_name(src)] has changed the Central Command name to: [input]")
/client/proc/cmd_admin_delete(atom/O as obj|mob|turf in world)
/client/proc/cmd_admin_delete(atom/A as obj|mob|turf in world)
set category = "Admin"
set name = "Delete"
@@ -523,6 +523,10 @@ Traitors and the like can also be revived with the previous role mostly intact.
else
qdel(O)
T.ChangeTurf(T.baseturf)
else
qdel(D)
/client/proc/cmd_admin_list_open_jobs()
set category = "Admin"
set name = "Manage Job Slots"
@@ -662,7 +662,7 @@
playsound(src.loc, W.usesound, 50, 1)
if (do_after(user, 20*W.toolspeed, target = src))
if (buildstage == 1)
user <<"<span class='notice'>You remove the air alarm electronics.</span>"
to_chat(user, "<span class='notice'>You remove the air alarm electronics.</span>")
new /obj/item/weapon/electronics/airalarm( src.loc )
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
buildstage = 0
+20 -8
View File
@@ -172,7 +172,6 @@ GLOBAL_LIST_EMPTY(asset_datums)
//DEFINITIONS FOR ASSET DATUMS START HERE.
/datum/asset/simple/tgui
assets = list(
"tgui.css" = 'tgui/assets/tgui.css',
@@ -208,13 +207,6 @@ GLOBAL_LIST_EMPTY(asset_datums)
"sig_none.gif" = 'icons/program_icons/sig_none.gif',
)
/datum/asset/simple/pda
assets = list(
"pda_atmos.png" = 'icons/pda_icons/pda_atmos.png',
@@ -267,6 +259,26 @@ GLOBAL_LIST_EMPTY(asset_datums)
"jquery-1.10.2.min.js" = 'html/IRV/jquery-1.10.2.min.js'
)
/datum/asset/simple/changelog
assets = list(
"88x31.png" = 'html/88x31.png',
"bug-minus.png" = 'html/bug-minus.png',
"cross-circle.png" = 'html/cross-circle.png',
"hard-hat-exclamation.png" = 'html/hard-hat-exclamation.png',
"image-minus.png" = 'html/image-minus.png',
"image-plus.png" = 'html/image-plus.png',
"music-minus.png" = 'html/music-minus.png',
"music-plus.png" = 'html/music-plus.png',
"tick-circle.png" = 'html/tick-circle.png',
"wrench-screwdriver.png" = 'html/wrench-screwdriver.png',
"spell-check.png" = 'html/spell-check.png',
"burn-exclamation.png" = 'html/burn-exclamation.png',
"chevron.png" = 'html/chevron.png',
"chevron-expand.png" = 'html/chevron-expand.png',
"scales.png" = 'html/scales.png',
"changelog.css" = 'html/changelog.css'
)
//Registers HTML Interface assets.
/datum/asset/HTML_interface/register()
for(var/path in typesof(/datum/html_interface))
+1 -2
View File
@@ -455,8 +455,7 @@
if(v in blacklisted_vars)
continue
vars[v] = initial(vars[v])
if(chambered.BB)
qdel(chambered.BB)
QDEL_NULL(chambered.BB)
chambered.newshot()
/obj/item/weapon/gun/energy/laser/chameleon/proc/set_chameleon_ammo(obj/item/ammo_casing/AC, passthrough = TRUE, reset = FALSE)
+1 -1
View File
@@ -224,5 +224,5 @@
to_chat(user, "<span class='warning'>The rune can only be used on battlemage armour!</span>")
return
W.current_charges += 8
user <<"<span class='notice'>You charge \the [W]. It can now absorb [W.current_charges] hits.</span>"
to_chat(user, "<span class='notice'>You charge \the [W]. It can now absorb [W.current_charges] hits.</span>")
qdel(src)
@@ -416,8 +416,8 @@
/datum/chemical_reaction/bananahonk
name = "Banana Honk"
id = "bananahonk"
results = list("bananahonk" = 3)
required_reagents = list("banana" = 1, "cream" = 1, "sugar" = 1)
results = list("bananahonk" = 2)
required_reagents = list("laughter" = 1, "cream" = 1)
/datum/chemical_reaction/silencer
name = "Silencer"
@@ -542,9 +542,9 @@
results = list("chocolate_milk" = 2)
required_reagents = list("milk" = 1, "cocoa" = 1)
mix_message = "The color changes as the mixture blends smoothly."
/datum/chemical_reaction/eggnog
name = "eggnog"
id = "eggnog"
results = list("eggnog" = 15)
required_reagents = list("rum" = 5, "cream" = 5, "eggyolk" = 5)
required_reagents = list("rum" = 5, "cream" = 5, "eggyolk" = 5)
+42 -42
View File
@@ -45,52 +45,52 @@
var/list/effects = list()
var/last_change = 0
/obj/machinery/computer/holodeck/Initialize(mapload)
. = mapload //late-initialize, area_copy need turfs to have air
if(!mapload)
..()
..()
return INITIALIZE_HINT_LATELOAD
if(ispath(holodeck_type,/area))
var/list/possible = get_areas(holodeck_type,subtypes = FALSE)
linked = pop(possible)
if(ispath(offline_program,/area))
var/list/possible = get_areas(offline_program,subtypes = FALSE)
offline_program = pop(possible)
// the following is necessary for power reasons
if(!linked || !offline_program)
log_world("No matching holodeck area found")
qdel(src)
return
var/area/AS = get_area(src)
if(istype(AS,/area/holodeck))
log_world("### MAPPING ERROR")
log_world("Holodeck computer cannot be in a holodeck.")
log_world("This would cause circular power dependency.")
qdel(src) // todo handle constructed computers
return //l-lewd...
else
linked.linked = src // todo detect multiple/constructed computers
/obj/machinery/computer/holodeck/LateInitialize()
if(ispath(holodeck_type,/area))
var/list/possible = get_areas(holodeck_type,subtypes = FALSE)
linked = pop(possible)
if(ispath(offline_program,/area))
var/list/possible = get_areas(offline_program,subtypes = FALSE)
offline_program = pop(possible)
// the following is necessary for power reasons
if(!linked || !offline_program)
log_world("No matching holodeck area found")
qdel(src)
return
var/area/AS = get_area(src)
if(istype(AS,/area/holodeck))
log_world("### MAPPING ERROR")
log_world("Holodeck computer cannot be in a holodeck.")
log_world("This would cause circular power dependency.")
qdel(src) // todo handle constructed computers
return //l-lewd...
else
linked.linked = src // todo detect multiple/constructed computers
program_cache = list()
emag_programs = list()
for(var/typekey in subtypesof(program_type))
var/area/holodeck/A = locate(typekey)
if(!A || A == offline_program)
continue
if(A.contents.len == 0)
continue // not loaded
if(A.restricted)
emag_programs += A
else
program_cache += A
if(typekey == init_program)
load_program(A,force=1)
if(random_program && program_cache.len && init_program == null)
load_program(pick(program_cache),force=1)
else if(!program)
load_program(offline_program)
program_cache = list()
emag_programs = list()
for(var/typekey in subtypesof(program_type))
var/area/holodeck/A = locate(typekey)
if(!A || A == offline_program)
continue
if(A.contents.len == 0)
continue // not loaded
if(A.restricted)
emag_programs += A
else
program_cache += A
if(typekey == init_program)
load_program(A,force=1)
if(random_program && program_cache.len && init_program == null)
load_program(pick(program_cache),force=1)
else if(!program)
load_program(offline_program)
/obj/machinery/computer/holodeck/power_change()
..()
+47
View File
@@ -0,0 +1,47 @@
diff a/code/modules/holodeck/computer.dm b/code/modules/holodeck/computer.dm (rejected hunks)
@@ -64,25 +64,26 @@
..()
/obj/machinery/computer/holodeck/Initialize(mapload)
- . = mapload //late-initialize, area_copy need turfs to have air
- if(!mapload)
- ..()
- program_cache = list()
- emag_programs = list()
- for(var/typekey in subtypesof(program_type))
- var/area/holodeck/A = locate(typekey)
- if(!A || A == offline_program) continue
- if(A.contents.len == 0) continue // not loaded
- if(A.restricted)
- emag_programs += A
- else
- program_cache += A
- if(typekey == init_program)
- load_program(A,force=1)
- if(random_program && program_cache.len && init_program == null)
- load_program(pick(program_cache),force=1)
- else if(!program)
- load_program(offline_program)
+ ..()
+ return INITIALIZE_HINT_LATELOAD
+
+/obj/machinery/computer/holodeck/LateInitialize()
+ program_cache = list()
+ emag_programs = list()
+ for(var/typekey in subtypesof(program_type))
+ var/area/holodeck/A = locate(typekey)
+ if(!A || A == offline_program) continue
+ if(A.contents.len == 0) continue // not loaded
+ if(A.restricted)
+ emag_programs += A
+ else
+ program_cache += A
+ if(typekey == init_program)
+ load_program(A,force=1)
+ if(random_program && program_cache.len && init_program == null)
+ load_program(pick(program_cache),force=1)
+ else if(!program)
+ load_program(offline_program)
/obj/machinery/computer/holodeck/power_change()
..()
+4 -1
View File
@@ -51,7 +51,7 @@
return FALSE
smooth_zlevel(world.maxz)
SortAreas()
repopulate_sorted_areas()
//initialize things that are normally initialized after map load
initTemplateBounds(bounds)
@@ -74,6 +74,9 @@
//initialize things that are normally initialized after map load
initTemplateBounds(bounds)
if(!SSmapping.loading_ruins) //Will be done manually during mapping ss init
repopulate_sorted_areas()
log_game("[name] loaded at at [T.x],[T.y],[T.z]")
return TRUE
+2 -5
View File
@@ -1,9 +1,6 @@
//Dead mobs can exist whenever. This is needful
/mob/dead/New(loc)
..()
if(!initialized)
args[1] = FALSE
Initialize(arglist(args)) //EXIST DAMN YOU!!!
INITIALIZE_IMMEDIATE(/mob/dead)
/mob/dead/dust() //ghosts can't be vaporised.
return
@@ -30,6 +30,7 @@
loc = pick(GLOB.newplayer_start)
else
loc = locate(1,1,1)
return INITIALIZE_HINT_NORMAL
/mob/dead/new_player/proc/new_player_panel()
@@ -48,11 +49,11 @@
output += "<p><a href='byond://?src=\ref[src];observe=1'>Observe</A></p>"
if(!IsGuestKey(src.key))
if (SSdbcore.Connect())
if (SSdbcore.Connect())
var/isadmin = 0
if(src.client && src.client.holder)
isadmin = 1
var/datum/DBQuery/query_get_new_polls = SSdbcore.NewQuery("SELECT id FROM [format_table_name("poll_question")] WHERE [(isadmin ? "" : "adminonly = false AND")] Now() BETWEEN starttime AND endtime AND id NOT IN (SELECT pollid FROM [format_table_name("poll_vote")] WHERE ckey = \"[ckey]\") AND id NOT IN (SELECT pollid FROM [format_table_name("poll_textreply")] WHERE ckey = \"[ckey]\")")
var/datum/DBQuery/query_get_new_polls = SSdbcore.NewQuery("SELECT id FROM [format_table_name("poll_question")] WHERE [(isadmin ? "" : "adminonly = false AND")] Now() BETWEEN starttime AND endtime AND id NOT IN (SELECT pollid FROM [format_table_name("poll_vote")] WHERE ckey = \"[ckey]\") AND id NOT IN (SELECT pollid FROM [format_table_name("poll_textreply")] WHERE ckey = \"[ckey]\")")
if(!query_get_new_polls.Execute())
return
var/newpoll = 0
@@ -302,7 +303,7 @@
if(!IsJobAvailable(rank))
alert(src, "[rank] is not available. Please try another.")
return 0
if(SSticker.late_join_disabled)
alert(src, "An administrator has disabled late join spawning.")
return FALSE
@@ -0,0 +1,9 @@
diff a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm (rejected hunks)
@@ -30,6 +30,7 @@
loc = pick(newplayer_start)
else
loc = locate(1,1,1)
+ return INITIALIZE_HINT_NORMAL
/mob/dead/new_player/proc/new_player_panel()
+7 -3
View File
@@ -355,9 +355,13 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(!isobserver(usr))
to_chat(usr, "Not when you're not dead!")
return
var/A
A = input("Area to jump to", "BOOYEA", A) as null|anything in GLOB.sortedAreas
var/area/thearea = A
var/list/filtered = list()
for(var/V in GLOB.sortedAreas)
var/area/A = V
if(!A.hidden)
filtered += A
var/area/thearea = input("Area to jump to", "BOOYEA") as null|anything in filtered
if(!thearea)
return
+70 -72
View File
@@ -67,7 +67,7 @@
//Eyes
var/obj/item/organ/eyes/mutanteyes = /obj/item/organ/eyes
//Ears
var/obj/item/organ/ears/mutantears = /obj/item/organ/ears
@@ -497,6 +497,8 @@
var/g = (H.gender == FEMALE) ? "f" : "m"
var/image/I
for(var/layer in relevant_layers)
var/layertext = mutant_bodyparts_layertext(layer)
@@ -561,9 +563,9 @@
S = /datum/sprite_accessory/slimecoon_snout*/
if(!S || S.icon_state == "none")
continue
var/mutable_appearance/accessory_overlay = mutable_appearance(S.icon, layer = -layer)
//A little rename so we don't have to use tail_lizard or tail_human when naming the sprites.
if(bodypart == "tail_lizard" || bodypart == "tail_human" || bodypart == "mam_tail" || bodypart == "slimecoontail" || bodypart == "xenotail")
bodypart = "tail"
@@ -574,11 +576,15 @@
if(bodypart == "xenohead")
bodypart = "xhead"
var/icon_string
if(S.gender_specific)
accessory_overlay.icon_state = "[g]_[bodypart]_[S.icon_state]_[layertext]"
else
accessory_overlay.icon_state = "m_[bodypart]_[S.icon_state]_[layertext]"
I = image("icon" = S.icon, "icon_state" = icon_string, "layer" =- layer)
if(S.center)
accessory_overlay = center_image(accessory_overlay, S.dimension_x, S.dimension_y)
@@ -624,86 +630,78 @@
inner_accessory_overlay = center_image(inner_accessory_overlay, S.dimension_x, S.dimension_y)
standing += inner_accessory_overlay
if(S.extra) //apply the extra overlay, if there is one
var/mutable_appearance/extra_accessory_overlay = mutable_appearance(S.icon, layer = -layer)
if(S.gender_specific)
extra_accessory_overlay.icon_state = "[g]_[bodypart]_extra_[S.icon_state]_[layertext]"
icon_string = "[g]_[bodypart]_extra_[S.icon_state]_[layertext]"
else
extra_accessory_overlay.icon_state = "m_[bodypart]_extra_[S.icon_state]_[layertext]"
icon_string = "m_[bodypart]_extra_[S.icon_state]_[layertext]"
I = image("icon" = S.icon, "icon_state" = icon_string, "layer" =- layer)
if(S.center)
extra_accessory_overlay.icon_state = center_image(extra_accessory_overlay, S.dimension_x, S.dimension_y)
if(!forced_colour)
switch(S.extra_color_src) //change the color of the extra overlay
if(MUTCOLORS)
if(fixed_mut_color)
extra_accessory_overlay.color = "#[fixed_mut_color]"
else
extra_accessory_overlay.color = "#[H.dna.features["mcolor"]]"
if(MUTCOLORS2)
if(fixed_mut_color2)
extra_accessory_overlay.color = "#[fixed_mut_color2]"
else
extra_accessory_overlay.color = "#[H.dna.features["mcolor2"]]"
if(MUTCOLORS3)
if(fixed_mut_color3)
extra_accessory_overlay.color = "#[fixed_mut_color3]"
else
extra_accessory_overlay.color = "#[H.dna.features["mcolor3"]]"
if(HAIR)
if(hair_color == "mutcolor")
extra_accessory_overlay.color = "#[H.dna.features["mcolor"]]"
else
extra_accessory_overlay.color = "#[H.hair_color]"
if(FACEHAIR)
extra_accessory_overlay.color = "#[H.facial_hair_color]"
if(EYECOLOR)
extra_accessory_overlay.color = "#[H.eye_color]"
else
extra_accessory_overlay.color = forced_colour
standing += extra_accessory_overlay
I = center_image(I,S.dimension_x,S.dimension_y)
switch(S.extra_color_src) //change the color of the extra overlay
if(MUTCOLORS)
if(fixed_mut_color)
I.color = "#[fixed_mut_color]"
else
I.color = "#[H.dna.features["mcolor"]]"
if(MUTCOLORS2)
if(fixed_mut_color2)
I.color = "#[fixed_mut_color2]"
else
I.color = "#[H.dna.features["mcolor2"]]"
if(MUTCOLORS3)
if(fixed_mut_color3)
I.color = "#[fixed_mut_color3]"
else
I.color = "#[H.dna.features["mcolor3"]]"
if(HAIR)
if(hair_color == "mutcolor")
I.color = "#[H.dna.features["mcolor"]]"
else
I.color = "#[H.hair_color]"
if(FACEHAIR)
I.color = "#[H.facial_hair_color]"
if(EYECOLOR)
I.color = "#[H.eye_color]"
standing += I
if(S.extra2) //apply the extra overlay, if there is one
var/mutable_appearance/extra2_accessory_overlay = mutable_appearance(S.icon, layer = -layer)
if(S.gender_specific)
extra2_accessory_overlay.icon_state = "[g]_[bodypart]_extra2_[S.icon_state]_[layertext]"
icon_string = "[g]_[bodypart]_extra2_[S.icon_state]_[layertext]"
else
extra2_accessory_overlay.icon_state = "m_[bodypart]_extra2_[S.icon_state]_[layertext]"
icon_string = "m_[bodypart]_extra2_[S.icon_state]_[layertext]"
I = image("icon" = S.icon, "icon_state" = icon_string, "layer" =- layer)
if(S.center)
extra2_accessory_overlay.icon_state = center_image(extra2_accessory_overlay, S.dimension_x, S.dimension_y)
if(!forced_colour)
switch(S.extra_color_src) //change the color of the extra overlay
if(MUTCOLORS)
if(fixed_mut_color)
extra2_accessory_overlay.color = "#[fixed_mut_color]"
else
extra2_accessory_overlay.color = "#[H.dna.features["mcolor"]]"
if(MUTCOLORS2)
if(fixed_mut_color2)
extra2_accessory_overlay.color = "#[fixed_mut_color2]"
else
extra2_accessory_overlay.color = "#[H.dna.features["mcolor2"]]"
if(MUTCOLORS3)
if(fixed_mut_color3)
extra2_accessory_overlay.color = "#[fixed_mut_color3]"
else
extra2_accessory_overlay.color = "#[H.dna.features["mcolor3"]]"
if(HAIR)
if(hair_color == "mutcolor")
extra2_accessory_overlay.color = "#[H.dna.features["mcolor"]]"
else
extra2_accessory_overlay.color = "#[H.hair_color]"
if(FACEHAIR)
extra2_accessory_overlay.color = "#[H.facial_hair_color]"
if(EYECOLOR)
extra2_accessory_overlay.color = "#[H.eye_color]"
else
extra2_accessory_overlay.color = forced_colour
standing += extra2_accessory_overlay
I = center_image(I,S.dimension_x,S.dimension_y)
switch(S.extra2_color_src) //change the color of the extra overlay
if(MUTCOLORS)
if(fixed_mut_color)
I.color = "#[fixed_mut_color]"
else
I.color = "#[H.dna.features["mcolor"]]"
if(MUTCOLORS2)
if(fixed_mut_color2)
I.color = "#[fixed_mut_color2]"
else
I.color = "#[H.dna.features["mcolor2"]]"
if(MUTCOLORS3)
if(fixed_mut_color3)
I.color = "#[fixed_mut_color3]"
else
I.color = "#[H.dna.features["mcolor3"]]"
if(HAIR)
if(hair_color == "mutcolor")
I.color = "#[H.dna.features["mcolor"]]"
else
I.color = "#[H.hair_color]"
standing += I
H.overlays_standing[layer] = standing.Copy()
standing = list()
+2 -2
View File
@@ -238,7 +238,7 @@
else if(icontype == "Angel")
icon_state = "ai-angel"
//else
//usr <<"You can only change your display once!"
//to_chat(usr, "You can only change your display once!")
//return
/mob/living/silicon/ai/Stat()
@@ -351,7 +351,7 @@
if(isAI(usr))
var/mob/living/silicon/ai/AI = src
if(AI.control_disabled)
src << "Wireless control is disabled!"
to_chat(src, "Wireless control is disabled!")
return
SSshuttle.cancelEvac(src)
return
@@ -22,7 +22,7 @@
ventcrawler = VENTCRAWLER_ALWAYS
var/datum/mind/origin
var/egg_lain = 0
gold_core_spawnable = 1 //are you sure about this??
// gold_core_spawnable = 1 //are you sure about this??
/mob/living/simple_animal/hostile/headcrab/proc/Infect(mob/living/carbon/victim)
var/obj/item/organ/body_egg/changeling_egg/egg = new(victim)
@@ -46,7 +46,7 @@ Difficulty: Very Hard
del_on_death = 1
medal_type = MEDAL_PREFIX
score_type = COLOSSUS_SCORE
loot = list(/obj/machinery/anomalous_crystal/random, /obj/item/organ/vocal_cords/colossus)
loot = list(/obj/effect/spawner/lootdrop/anomalous_crystal, /obj/item/organ/vocal_cords/colossus)
butcher_results = list(/obj/item/weapon/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/animalhide/ashdrake = 10, /obj/item/stack/sheet/bone = 30)
deathmessage = "disintegrates, leaving a glowing core in its wake."
death_sound = 'sound/magic/demon_dies.ogg'
@@ -360,9 +360,20 @@ Difficulty: Very Hard
///Anomolous Crystal///
#define ACTIVATE_TOUCH "touch"
#define ACTIVATE_SPEECH "speech"
#define ACTIVATE_HEAT "heat"
#define ACTIVATE_BULLET "bullet"
#define ACTIVATE_ENERGY "energy"
#define ACTIVATE_BOMB "bomb"
#define ACTIVATE_MOB_BUMP "bumping"
#define ACTIVATE_WEAPON "weapon"
#define ACTIVATE_MAGIC "magic"
/obj/machinery/anomalous_crystal
name = "anomalous crystal"
desc = "A strange chunk of crystal, being in the presence of it fills you with equal parts excitement and dread."
var/observer_desc = "Anomalous crystals have descriptions that only observers can see. But this one hasn't been changed from the default."
icon = 'icons/obj/lavaland/artefacts.dmi'
icon_state = "anomaly_crystal"
light_range = 8
@@ -370,66 +381,78 @@ Difficulty: Very Hard
use_power = 0
density = 1
flags = HEAR
var/activation_method = "touch"
var/activation_method
var/list/possible_methods = list(ACTIVATE_TOUCH, ACTIVATE_SPEECH, ACTIVATE_HEAT, ACTIVATE_BULLET, ACTIVATE_ENERGY, ACTIVATE_BOMB, ACTIVATE_MOB_BUMP, ACTIVATE_WEAPON, ACTIVATE_MAGIC)
var/activation_damage_type = null
var/last_use_timer = 0
var/cooldown_add = 30
var/list/affected_targets = list()
var/activation_sound = 'sound/effects/break_stone.ogg'
/obj/machinery/anomalous_crystal/New()
activation_method = pick("touch","laser","bullet","energy","bomb","mob_bump","heat","weapon","speech")
..()
/obj/machinery/anomalous_crystal/Initialize(mapload)
. = ..()
if(!activation_method)
activation_method = pick(possible_methods)
/obj/machinery/anomalous_crystal/examine(mob/user)
. = ..()
if(isobserver(user))
to_chat(user, observer_desc)
to_chat(user, "It is activated by [activation_method].")
/obj/machinery/anomalous_crystal/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans)
..()
if(isliving(speaker))
ActivationReaction(speaker,"speech")
ActivationReaction(speaker, ACTIVATE_SPEECH)
/obj/machinery/anomalous_crystal/attack_hand(mob/user)
..()
ActivationReaction(user,"touch")
ActivationReaction(user, ACTIVATE_TOUCH)
/obj/machinery/anomalous_crystal/attackby(obj/item/I, mob/user, params)
if(I.is_hot())
ActivationReaction(user,"heat")
ActivationReaction(user, ACTIVATE_HEAT)
else
ActivationReaction(user,"weapon")
ActivationReaction(user, ACTIVATE_WEAPON)
..()
/obj/machinery/anomalous_crystal/bullet_act(obj/item/projectile/P, def_zone)
..()
if(istype(P, /obj/item/projectile/magic))
ActivationReaction(P.firer, "magic", P.damage_type)
ActivationReaction(P.firer, ACTIVATE_MAGIC, P.damage_type)
return
ActivationReaction(P.firer, P.flag, P.damage_type)
/obj/machinery/anomalous_crystal/proc/ActivationReaction(mob/user, method, damtype)
if(world.time < last_use_timer)
return 0
return FALSE
if(activation_damage_type && activation_damage_type != damtype)
return 0
return FALSE
if(method != activation_method)
return 0
return FALSE
last_use_timer = (world.time + cooldown_add)
playsound(user, activation_sound, 100, 1)
return 1
return TRUE
/obj/machinery/anomalous_crystal/Bumped(atom/AM as mob|obj)
..()
if(ismob(AM))
ActivationReaction(AM,"mob_bump")
ActivationReaction(AM, ACTIVATE_MOB_BUMP)
/obj/machinery/anomalous_crystal/ex_act()
ActivationReaction(null,"bomb")
ActivationReaction(null, ACTIVATE_BOMB)
/obj/machinery/anomalous_crystal/random/New()//Just a random crysal spawner for loot
var/random_crystal = pick(typesof(/obj/machinery/anomalous_crystal) - /obj/machinery/anomalous_crystal/random - /obj/machinery/anomalous_crystal)
new random_crystal(loc)
qdel(src)
/obj/effect/spawner/lootdrop/anomalous_crystal
name = "anomalous crystal spawner"
/obj/effect/spawner/lootdrop/anomalous_crystal/Initialize()
loot = subtypesof(/obj/machinery/anomalous_crystal)
. = ..()
/obj/machinery/anomalous_crystal/honk //Strips and equips you as a clown. I apologize for nothing
activation_method = "mob_bump"
observer_desc = "This crystal strips and equips its targets as clowns."
possible_methods = list(ACTIVATE_MOB_BUMP, ACTIVATE_SPEECH)
activation_sound = 'sound/items/bikehorn.ogg'
/obj/machinery/anomalous_crystal/honk/ActivationReaction(mob/user)
@@ -442,12 +465,9 @@ Difficulty: Very Hard
qdel(C)
affected_targets.Add(H)
/obj/machinery/anomalous_crystal/honk/New()
..()
activation_method = pick("mob_bump","speech")
/obj/machinery/anomalous_crystal/theme_warp //Warps the area you're in to look like a new one
activation_method = "touch"
observer_desc = "This crystal warps the area around it to a theme."
activation_method = ACTIVATE_TOUCH
cooldown_add = 200
var/terrain_theme = "winter"
var/NewTerrainFloors
@@ -457,9 +477,11 @@ Difficulty: Very Hard
var/list/NewFlora = list()
var/florachance = 8
/obj/machinery/anomalous_crystal/theme_warp/New()
..()
/obj/machinery/anomalous_crystal/theme_warp/Initialize()
. = ..()
terrain_theme = pick("lavaland","winter","jungle","ayy lmao")
observer_desc = "This crystal changes the area around it to match the theme of \"[terrain_theme]\"."
switch(terrain_theme)
if("lavaland")//Depressurizes the place... and free cult metal, I guess.
NewTerrainFloors = /turf/open/floor/grass/snow/basalt
@@ -518,15 +540,19 @@ Difficulty: Very Hard
affected_targets += A
/obj/machinery/anomalous_crystal/emitter //Generates a projectile when interacted with
activation_method = "touch"
observer_desc = "This crystal generates a projectile when activated."
activation_method = ACTIVATE_TOUCH
cooldown_add = 50
var/generated_projectile = /obj/item/projectile/beam/emitter
var/obj/item/projectile/generated_projectile = /obj/item/projectile/beam/emitter
/obj/machinery/anomalous_crystal/emitter/New()
..()
/obj/machinery/anomalous_crystal/emitter/Initialize()
. = ..()
generated_projectile = pick(/obj/item/projectile/magic/aoe/fireball/infernal,/obj/item/projectile/magic/aoe/lightning,/obj/item/projectile/magic/spellblade,
/obj/item/projectile/bullet/meteorshot, /obj/item/projectile/beam/xray, /obj/item/projectile/colossus)
var/proj_name = initial(generated_projectile.name)
observer_desc = "This crystal generates \a [proj_name] when activated."
/obj/machinery/anomalous_crystal/emitter/ActivationReaction(mob/user, method)
if(..())
var/obj/item/projectile/P = new generated_projectile(get_turf(src))
@@ -547,7 +573,8 @@ Difficulty: Very Hard
P.fire()
/obj/machinery/anomalous_crystal/dark_reprise //Revives anyone nearby, but turns them into shadowpeople and renders them uncloneable, so the crystal is your only hope of getting up again if you go down.
activation_method = "touch"
observer_desc = "When activated, this crystal revives anyone nearby, but turns them into Shadowpeople and makes them unclonable, making the crystal their only hope of getting up again."
activation_method = ACTIVATE_TOUCH
activation_sound = 'sound/hallucinations/growl1.ogg'
/obj/machinery/anomalous_crystal/dark_reprise/ActivationReaction(mob/user, method)
@@ -565,13 +592,20 @@ Difficulty: Very Hard
H.grab_ghost(force = TRUE)
/obj/machinery/anomalous_crystal/helpers //Lets ghost spawn as helpful creatures that can only heal people slightly. Incredibly fragile and they can't converse with humans
activation_method = "touch"
var/ready_to_deploy = 0
observer_desc = "This crystal allows ghosts to turn into a fragile creature that can heal people."
activation_method = ACTIVATE_TOUCH
activation_sound = 'sound/effects/ghost2.ogg'
var/ready_to_deploy = FALSE
/obj/machinery/anomalous_crystal/helpers/Destroy()
GLOB.poi_list -= src
. = ..()
/obj/machinery/anomalous_crystal/helpers/ActivationReaction(mob/user, method)
if(..() && !ready_to_deploy)
ready_to_deploy = 1
notify_ghosts("An anomalous crystal has been activated in [get_area(src)]! This crystal can always be used by ghosts hereafter.", enter_link = "<a href=?src=\ref[src];ghostjoin=1>(Click to enter)</a>", source = src, action = NOTIFY_ATTACK)
GLOB.poi_list |= src
ready_to_deploy = TRUE
notify_ghosts("An anomalous crystal has been activated in [get_area(src)]! This crystal can always be used by ghosts hereafter.", enter_link = "<a href=?src=\ref[src];ghostjoin=1>(Click to enter)</a>", ghost_sound = 'sound/effects/ghost2.ogg', source = src, action = NOTIFY_ATTACK)
/obj/machinery/anomalous_crystal/helpers/attack_ghost(mob/dead/observer/user)
..()
@@ -613,10 +647,12 @@ Difficulty: Very Hard
verb_ask = "floats inquisitively"
verb_exclaim = "zaps"
verb_yell = "bangs"
initial_languages = list(/datum/language/common, /datum/language/slime)
only_speaks_language = /datum/language/slime
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
light_range = 4
faction = list("neutral")
del_on_death = 1
del_on_death = TRUE
unsuitable_atmos_damage = 0
movement_type = FLYING
minbodytemp = 0
@@ -638,7 +674,7 @@ Difficulty: Very Hard
. = ..()
if(isliving(target) && target != src)
var/mob/living/L = target
if(L.stat < DEAD)
if(L.stat != DEAD)
L.heal_overall_damage(heal_power, heal_power)
new /obj/effect/overlay/temp/heal(get_turf(target), "#80F5FF")
@@ -649,13 +685,14 @@ Difficulty: Very Hard
/obj/machinery/anomalous_crystal/refresher //Deletes and recreates a copy of the item, "refreshing" it.
activation_method = "touch"
observer_desc = "This crystal \"refreshes\" items that it affects, rendering them as new."
activation_method = ACTIVATE_TOUCH
cooldown_add = 50
activation_sound = 'sound/magic/TIMEPARADOX2.ogg'
var/list/banned_items_typecache = list(/obj/item/weapon/storage, /obj/item/weapon/implant, /obj/item/weapon/implanter, /obj/item/weapon/disk/nuclear, /obj/item/projectile, /obj/item/weapon/spellbook)
/obj/machinery/anomalous_crystal/refresher/New()
..()
/obj/machinery/anomalous_crystal/refresher/Initialize()
. = ..()
banned_items_typecache = typecacheof(banned_items_typecache)
@@ -675,7 +712,8 @@ Difficulty: Very Hard
qdel(CHOSEN)
/obj/machinery/anomalous_crystal/possessor //Allows you to bodyjack small animals, then exit them at your leisure, but you can only do this once per activation. Because they blow up. Also, if the bodyjacked animal dies, SO DO YOU.
activation_method = "touch"
observer_desc = "When activated, this crystal allows you to take over small animals, and then exit them at the possessors leisure. Exiting the animal kills it, and if you die while possessing the animal, you die as well."
activation_method = ACTIVATE_TOUCH
/obj/machinery/anomalous_crystal/possessor/ActivationReaction(mob/user, method)
if(..())
@@ -770,4 +808,14 @@ Difficulty: Very Hard
target_mind.RemoveSpell(/obj/effect/proc_holder/spell/targeted/exit_possession)
#undef ACTIVATE_TOUCH
#undef ACTIVATE_SPEECH
#undef ACTIVATE_HEAT
#undef ACTIVATE_BULLET
#undef ACTIVATE_ENERGY
#undef ACTIVATE_BOMB
#undef ACTIVATE_MOB_BUMP
#undef ACTIVATE_WEAPON
#undef ACTIVATE_MAGIC
#undef MEDAL_PREFIX
@@ -127,9 +127,11 @@
stuttering = 0
/mob/living/simple_animal/proc/handle_automated_action()
set waitfor = FALSE
return
/mob/living/simple_animal/proc/handle_automated_movement()
set waitfor = FALSE
if(!stop_automated_movement && wander)
if((isturf(src.loc) || allow_movement_on_non_turfs) && !resting && !buckled && canmove) //This is so it only moves if it's not inside a closet, gentics machine, etc.
turns_since_move++
@@ -142,6 +144,7 @@
return 1
/mob/living/simple_animal/proc/handle_automated_speech(var/override)
set waitfor = FALSE
if(speak_chance)
if(prob(speak_chance) || override)
if(speak && speak.len)
+1 -1
View File
@@ -396,7 +396,7 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
A.action = action
A.target = source
if(!alert_overlay)
alert_overlay = new(src)
alert_overlay = new(source)
alert_overlay.layer = FLOAT_LAYER
alert_overlay.plane = FLOAT_PLANE
A.add_overlay(alert_overlay)
@@ -3,7 +3,7 @@
filedesc = "ID card modification program"
program_icon_state = "id"
extended_desc = "Program for programming employee ID cards to access parts of the station."
transfer_access = GLOB.access_change_ids
transfer_access = GLOB.access_heads
requires_ntnet = 0
size = 8
var/mod_mode = 1
@@ -452,7 +452,7 @@
var/obj/item/weapon/card/id/auth_card = card_slot.stored_card2
if(auth_card)
region_access = list()
if(transfer_access in auth_card.GetAccess())
if(GLOB.access_change_ids in auth_card.GetAccess())
minor = 0
authenticated = 1
return 1
+1 -1
View File
@@ -39,7 +39,7 @@
narsie_spawn_animation()
sleep(70)
SSshuttle.emergency.request(null, 0.1) // Cannot recall
SSshuttle.emergency.request(null, set_coefficient = 0.1) // Cannot recall
/obj/singularity/narsie/large/attack_ghost(mob/dead/observer/user as mob)
@@ -135,27 +135,27 @@
/// SAW ROUNDS
/obj/item/ammo_casing/mm556x45
desc = "A 556x45mm bullet casing."
/obj/item/ammo_casing/mm195x129
desc = "A 1.95x129mm bullet casing."
icon_state = "762-casing"
caliber = "mm55645"
caliber = "mm195129"
projectile_type = /obj/item/projectile/bullet/saw
/obj/item/ammo_casing/mm556x45/bleeding
desc = "A 556x45mm bullet casing with specialized inner-casing, that when it makes contact with a target, release tiny shrapnel to induce internal bleeding."
/obj/item/ammo_casing/mm195x129/bleeding
desc = "A 1.95x129mm bullet casing with specialized inner-casing, that when it makes contact with a target, release tiny shrapnel to induce internal bleeding."
icon_state = "762-casing"
projectile_type = /obj/item/projectile/bullet/saw/bleeding
/obj/item/ammo_casing/mm556x45/hollow
desc = "A 556x45mm bullet casing designed to cause more damage to unarmored targets."
/obj/item/ammo_casing/mm195x129/hollow
desc = "A 1.95x129mm bullet casing designed to cause more damage to unarmored targets."
projectile_type = /obj/item/projectile/bullet/saw/hollow
/obj/item/ammo_casing/mm556x45/ap
desc = "A 556x45mm bullet casing designed with a hardened-tipped core to help penetrate armored targets."
/obj/item/ammo_casing/mm195x129/ap
desc = "A 1.95x129mm bullet casing designed with a hardened-tipped core to help penetrate armored targets."
projectile_type = /obj/item/projectile/bullet/saw/ap
/obj/item/ammo_casing/mm556x45/incen
desc = "A 556x45mm bullet casing designed with a chemical-filled capsule on the tip that when bursted, reacts with the atmosphere to produce a fireball, engulfing the target in flames. "
/obj/item/ammo_casing/mm195x129/incen
desc = "A 1.95x129mm bullet casing designed with a chemical-filled capsule on the tip that when bursted, reacts with the atmosphere to produce a fireball, engulfing the target in flames. "
projectile_type = /obj/item/projectile/bullet/saw/incen
@@ -234,35 +234,35 @@
//// SAW MAGAZINES
/obj/item/ammo_box/magazine/mm556x45
name = "box magazine (5.56x45mm)"
/obj/item/ammo_box/magazine/mm195x129
name = "box magazine (1.95x129mm)"
icon_state = "a762-50"
origin_tech = "combat=2"
ammo_type = /obj/item/ammo_casing/mm556x45
caliber = "mm55645"
ammo_type = /obj/item/ammo_casing/mm195x129
caliber = "mm195129"
max_ammo = 50
/obj/item/ammo_box/magazine/mm556x45/bleeding
name = "box magazine (Bleeding 5.56x45mm)"
/obj/item/ammo_box/magazine/mm195x129/bleeding
name = "box magazine (Bleeding 1.95x129mm)"
origin_tech = "combat=3"
ammo_type = /obj/item/ammo_casing/mm556x45/bleeding
ammo_type = /obj/item/ammo_casing/mm195x129/bleeding
/obj/item/ammo_box/magazine/mm556x45/hollow
name = "box magazine (Hollow-Point 5.56x45mm)"
/obj/item/ammo_box/magazine/mm195x129/hollow
name = "box magazine (Hollow-Point 1.95x129mm)"
origin_tech = "combat=3"
ammo_type = /obj/item/ammo_casing/mm556x45/hollow
ammo_type = /obj/item/ammo_casing/mm195x129/hollow
/obj/item/ammo_box/magazine/mm556x45/ap
name = "box magazine (Armor Penetrating 5.56x45mm)"
/obj/item/ammo_box/magazine/mm195x129/ap
name = "box magazine (Armor Penetrating 1.95x129mm)"
origin_tech = "combat=4"
ammo_type = /obj/item/ammo_casing/mm556x45/ap
ammo_type = /obj/item/ammo_casing/mm195x129/ap
/obj/item/ammo_box/magazine/mm556x45/incen
name = "box magazine (Incendiary 5.56x45mm)"
/obj/item/ammo_box/magazine/mm195x129/incen
name = "box magazine (Incendiary 1.95x129mm)"
origin_tech = "combat=4"
ammo_type = /obj/item/ammo_casing/mm556x45/incen
ammo_type = /obj/item/ammo_casing/mm195x129/incen
/obj/item/ammo_box/magazine/mm556x45/update_icon()
/obj/item/ammo_box/magazine/mm195x129/update_icon()
..()
icon_state = "a762-[round(ammo_count(),10)]"
@@ -278,13 +278,13 @@
/obj/item/weapon/gun/ballistic/automatic/l6_saw
name = "\improper L6 SAW"
desc = "A heavily modified 5.56x45mm light machine gun, designated 'L6 SAW'. Has 'Aussec Armoury - 2531' engraved on the receiver below the designation."
desc = "A heavily modified 1.95x129mm light machine gun, designated 'L6 SAW'. Has 'Aussec Armoury - 2531' engraved on the receiver below the designation."
icon_state = "l6closed100"
item_state = "l6closedmag"
w_class = WEIGHT_CLASS_HUGE
slot_flags = 0
origin_tech = "combat=6;engineering=3;syndicate=6"
mag_type = /obj/item/ammo_box/magazine/mm556x45
mag_type = /obj/item/ammo_box/magazine/mm195x129
weapon_weight = WEAPON_HEAVY
fire_sound = 'sound/weapons/Gunshot_smg.ogg'
var/cover_open = 0
@@ -138,7 +138,7 @@
/obj/item/weapon/gun/energy/plasmacutter/examine(mob/user)
..()
if(power_supply)
user <<"<span class='notice'>[src] is [round(power_supply.percent())]% charged.</span>"
to_chat(user, "<span class='notice'>[src] is [round(power_supply.percent())]% charged.</span>")
/obj/item/weapon/gun/energy/plasmacutter/attackby(obj/item/A, mob/user)
if(istype(A, /obj/item/stack/sheet/mineral/plasma))
@@ -54,7 +54,9 @@
/obj/item/slime_extract = list(),
/obj/item/weapon/reagent_containers/pill = list(),
/obj/item/weapon/reagent_containers/food = list(),
/obj/item/weapon/reagent_containers/honeycomb = list()
/obj/item/weapon/reagent_containers/honeycomb = list(),
/obj/item/toy/crayon = list()
)
var/list/juice_items = list (
@@ -456,3 +458,13 @@
O.reagents.trans_to(beaker, amount)
if(!O.reagents.total_volume)
remove_object(O)
for (var/obj/item/toy/crayon/O in holdingitems)
if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
break
for (var/r_id in O.reagent_contents)
var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume
if (space == 0)
break
beaker.reagents.add_reagent(r_id, min(O.reagent_contents[r_id], space))
remove_object(O)
@@ -1128,7 +1128,7 @@
//For colouring in /proc/mix_color_from_reagents
/datum/reagent/crayonpowder
/datum/reagent/colorful_reagent/crayonpowder
name = "Crayon Powder"
id = "crayon powder"
var/colorname = "none"
@@ -1137,50 +1137,72 @@
color = "#FFFFFF" // rgb: 207, 54, 0
taste_description = "the back of class"
/datum/reagent/crayonpowder/New()
/datum/reagent/colorful_reagent/crayonpowder/New()
description = "\an [colorname] powder made by grinding down crayons, good for colouring chemical reagents."
/datum/reagent/crayonpowder/red
/datum/reagent/colorful_reagent/crayonpowder/red
name = "Red Crayon Powder"
id = "redcrayonpowder"
colorname = "red"
color = "#DA0000" // red
random_color_list = list("#DA0000")
/datum/reagent/crayonpowder/orange
/datum/reagent/colorful_reagent/crayonpowder/orange
name = "Orange Crayon Powder"
id = "orangecrayonpowder"
colorname = "orange"
color = "#FF9300" // orange
random_color_list = list("#FF9300")
/datum/reagent/crayonpowder/yellow
/datum/reagent/colorful_reagent/crayonpowder/yellow
name = "Yellow Crayon Powder"
id = "yellowcrayonpowder"
colorname = "yellow"
color = "#FFF200" // yellow
random_color_list = list("#FFF200")
/datum/reagent/crayonpowder/green
/datum/reagent/colorful_reagent/crayonpowder/green
name = "Green Crayon Powder"
id = "greencrayonpowder"
colorname = "green"
color = "#A8E61D" // green
random_color_list = list("#A8E61D")
/datum/reagent/crayonpowder/blue
/datum/reagent/colorful_reagent/crayonpowder/blue
name = "Blue Crayon Powder"
id = "bluecrayonpowder"
colorname = "blue"
color = "#00B7EF" // blue
random_color_list = list("#00B7EF")
/datum/reagent/crayonpowder/purple
/datum/reagent/colorful_reagent/crayonpowder/purple
name = "Purple Crayon Powder"
id = "purplecrayonpowder"
colorname = "purple"
color = "#DA00FF" // purple
random_color_list = list("#DA00FF")
/datum/reagent/crayonpowder/invisible
/datum/reagent/colorful_reagent/crayonpowder/invisible
name = "Invisible Crayon Powder"
id = "invisiblecrayonpowder"
colorname = "invisible"
color = "#FFFFFF00" // white + no alpha
random_color_list = list(null) //because using the powder color turns things invisible
/datum/reagent/colorful_reagent/crayonpowder/black
name = "Black Crayon Powder"
id = "blackcrayonpowder"
colorname = "black"
color = "#1C1C1C" // not quite black
random_color_list = list("#404040")
/datum/reagent/colorful_reagent/crayonpowder/white
name = "White Crayon Powder"
id = "whitecrayonpowder"
colorname = "white"
color = "#FFFFFF" // white
random_color_list = list("#FFFFFF") //doesn't actually change appearance at all
@@ -25,13 +25,10 @@
/obj/item/weapon/reagent_containers/blood/proc/update_pack_name()
if(!labelled)
if(volume)
if(blood_type)
name = "blood pack [blood_type]"
else
name = "blood pack"
if(blood_type)
name = "blood pack - [blood_type]"
else
name = "empty blood pack"
name = "blood pack"
/obj/item/weapon/reagent_containers/blood/update_icon()
var/percent = round((reagents.total_volume / volume) * 100)
@@ -69,7 +66,7 @@
blood_type = "L"
/obj/item/weapon/reagent_containers/blood/empty
name = "empty blood pack"
name = "blood pack"
icon_state = "empty"
/obj/item/weapon/reagent_containers/blood/attackby(obj/item/I, mob/user, params)
+4 -3
View File
@@ -212,13 +212,14 @@
/obj/machinery/conveyor_switch/Initialize(mapload, newid)
if(mapload)
return TRUE //need machines list
. = ..()
..()
if(!id)
id = newid
update()
return INITIALIZE_HINT_LATELOAD //for machines list
/obj/machinery/conveyor_switch/LateInitialize()
conveyors = list()
for(var/obj/machinery/conveyor/C in GLOB.machines)
if(C.id == id)
+10
View File
@@ -0,0 +1,10 @@
diff a/code/modules/recycling/conveyor2.dm b/code/modules/recycling/conveyor2.dm (rejected hunks)
@@ -220,7 +220,7 @@
id = newid
update()
- return INITIALIZE_HINT_LATELOAD
+ return INITIALIZE_HINT_LATELOAD //for machines list
/obj/machinery/conveyor_switch/LateInitialize()
conveyors = list()
+11 -11
View File
@@ -64,17 +64,17 @@
deconstruct()
/obj/machinery/disposal/Initialize(mapload)
. = mapload //late-initialize, we need turfs to have air
if(initialized) //will only be run on late mapload initialization
//this will get a copy of the air turf and take a SEND PRESSURE amount of air from it
var/atom/L = loc
var/datum/gas_mixture/env = new
env.copy_from(L.return_air())
var/datum/gas_mixture/removed = env.remove(SEND_PRESSURE + 1)
air_contents.merge(removed)
trunk_check()
else
..()
..()
return INITIALIZE_HINT_LATELOAD //we need turfs to have air
/obj/machinery/disposal/LateInitialize()
//this will get a copy of the air turf and take a SEND PRESSURE amount of air from it
var/atom/L = loc
var/datum/gas_mixture/env = new
env.copy_from(L.return_air())
var/datum/gas_mixture/removed = env.remove(SEND_PRESSURE + 1)
air_contents.merge(removed)
trunk_check()
/obj/machinery/disposal/attackby(obj/item/I, mob/user, params)
add_fingerprint(user)
+1 -1
View File
@@ -1068,7 +1068,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
/obj/machinery/computer/rdconsole/robotics/New()
..()
if(circuit)
circuit.name = "RD Console - Robotics (Computer Board)"
circuit.name = "R&D Console - Robotics (Computer Board)"
circuit.build_path = /obj/machinery/computer/rdconsole/robotics
/obj/machinery/computer/rdconsole/core
@@ -20,7 +20,7 @@
if(Uses >= 5)
to_chat(user, "<span class='warning'>You cannot enhance this extract further!</span>")
return ..()
user <<"<span class='notice'>You apply the enhancer to the slime extract. It may now be reused one more time.</span>"
to_chat(user, "<span class='notice'>You apply the enhancer to the slime extract. It may now be reused one more time.</span>")
Uses++
qdel(O)
..()
@@ -146,8 +146,8 @@
M.docile = 1
M.nutrition = 700
M <<"<span class='warning'>You absorb the potion and feel your intense desire to feed melt away.</span>"
user <<"<span class='notice'>You feed the slime the potion, removing its hunger and calming it.</span>"
to_chat(M, "<span class='warning'>You absorb the potion and feel your intense desire to feed melt away.</span>")
to_chat(user, "<span class='notice'>You feed the slime the potion, removing its hunger and calming it.</span>")
var/newname = copytext(sanitize(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text),1,MAX_NAME_LEN)
if (!newname)
@@ -261,10 +261,10 @@
to_chat(user, "<span class='warning'>The slime is dead!</span>")
return ..()
if(M.cores >= 5)
user <<"<span class='warning'>The slime already has the maximum amount of extract!</span>"
to_chat(user, "<span class='warning'>The slime already has the maximum amount of extract!</span>")
return ..()
user <<"<span class='notice'>You feed the slime the steroid. It will now produce one more extract.</span>"
to_chat(user, "<span class='notice'>You feed the slime the steroid. It will now produce one more extract.</span>")
M.cores++
qdel(src)
@@ -288,10 +288,10 @@
to_chat(user, "<span class='warning'>The slime is dead!</span>")
return ..()
if(M.mutation_chance == 0)
user <<"<span class='warning'>The slime already has no chance of mutating!</span>"
to_chat(user, "<span class='warning'>The slime already has no chance of mutating!</span>")
return ..()
user <<"<span class='notice'>You feed the slime the stabilizer. It is now less likely to mutate.</span>"
to_chat(user, "<span class='notice'>You feed the slime the stabilizer. It is now less likely to mutate.</span>")
M.mutation_chance = Clamp(M.mutation_chance-15,0,100)
qdel(src)
@@ -312,10 +312,10 @@
to_chat(user, "<span class='warning'>This slime has already consumed a mutator, any more would be far too unstable!</span>")
return ..()
if(M.mutation_chance == 100)
user <<"<span class='warning'>The slime is already guaranteed to mutate!</span>"
to_chat(user, "<span class='warning'>The slime is already guaranteed to mutate!</span>")
return ..()
user <<"<span class='notice'>You feed the slime the mutator. It is now more likely to mutate.</span>"
to_chat(user, "<span class='notice'>You feed the slime the mutator. It is now more likely to mutate.</span>")
M.mutation_chance = Clamp(M.mutation_chance+12,0,100)
M.mutator_used = TRUE
qdel(src)
@@ -348,7 +348,7 @@
return ..()
R.vehicle_move_delay = 0
user <<"<span class='notice'>You slather the red gunk over the [C], making it faster.</span>"
to_chat(user, "<span class='notice'>You slather the red gunk over the [C], making it faster.</span>")
C.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
C.add_atom_colour("#FF0000", FIXED_COLOUR_PRIORITY)
qdel(src)
@@ -373,7 +373,7 @@
if(C.max_heat_protection_temperature == FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT)
to_chat(user, "<span class='warning'>The [C] is already fireproof!</span>")
return ..()
user <<"<span class='notice'>You slather the blue gunk over the [C], fireproofing it.</span>"
to_chat(user, "<span class='notice'>You slather the blue gunk over the [C], fireproofing it.</span>")
C.name = "fireproofed [C.name]"
C.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
C.add_atom_colour("#000080", FIXED_COLOUR_PRIORITY)
+9 -7
View File
@@ -22,20 +22,22 @@
var/perma_docked = FALSE //highlander with RESPAWN??? OH GOD!!!
/obj/docking_port/mobile/arrivals/Initialize(mapload)
if(mapload)
return TRUE //late initialize to make sure the latejoin list is populated
preferred_direction = dir
if(SSshuttle.arrivals)
WARNING("More than one arrivals docking_port placed on map!")
qdel(src)
return
return INITIALIZE_HINT_QDEL
SSshuttle.arrivals = src
. = ..()
. = ..()
preferred_direction = dir
return INITIALIZE_HINT_LATELOAD //for latejoin list
/obj/docking_port/mobile/arrivals/LateInitialize()
areas = list()
var/list/new_latejoin = list()
@@ -177,7 +179,7 @@
Launch(TRUE)
user << "<span class='notice'>Calling your shuttle. One moment...</span>"
to_chat(user, "<span class='notice'>Calling your shuttle. One moment...</span>")
while(mode != SHUTTLE_CALL && !damaged)
stoplag()
+11
View File
@@ -0,0 +1,11 @@
diff a/code/modules/shuttle/arrivals.dm b/code/modules/shuttle/arrivals.dm (rejected hunks)
@@ -30,6 +30,9 @@
..()
preferred_direction = dir
+ return INITIALIZE_HINT_LATELOAD //for latejoin list
+
+/obj/docking_port/mobile/arrivals/LateInitialize()
areas = list()
var/list/new_latejoin = list()
+11 -2
View File
@@ -207,8 +207,17 @@
. = ..()
/obj/docking_port/mobile/emergency/request(obj/docking_port/stationary/S, coefficient=1, area/signalOrigin, reason, redAlert)
var/call_time = SSshuttle.emergencyCallTime * coefficient
/obj/docking_port/mobile/emergency/request(obj/docking_port/stationary/S, area/signalOrigin, reason, redAlert, set_coefficient=null)
if(!isnum(set_coefficient))
var/security_num = seclevel2num(get_security_level())
switch(security_num)
if(SEC_LEVEL_GREEN)
set_coefficient = 2
if(SEC_LEVEL_BLUE)
set_coefficient = 1
else
set_coefficient = 0.5
var/call_time = SSshuttle.emergencyCallTime * set_coefficient
switch(mode)
// The shuttle can not normally be called while "recalling", so
// if this proc is called, it's via admin fiat
@@ -47,7 +47,7 @@
L+=T
if(!L.len)
usr <<"The spell matrix was unable to locate a suitable teleport destination for an unknown reason. Sorry."
to_chat(usr, "The spell matrix was unable to locate a suitable teleport destination for an unknown reason. Sorry.")
return
if(target && target.buckled)
+2 -2
View File
@@ -26,9 +26,9 @@
if(M.mind)
for(var/obj/effect/proc_holder/spell/S in M.mind.spell_list)
S.charge_counter = S.charge_max
M <<"<span class='notice'>You feel raw magic flowing through you. It feels good!</span>"
to_chat(M, "<span class='notice'>You feel raw magic flowing through you. It feels good!</span>")
else
M <<"<span class='notice'>you feel very strange for a moment, but then it passes.</span>"
to_chat(M, "<span class='notice'>You feel very strange for a moment, but then it passes.</span>")
burnt_out = 1
charged_item = M
break
+1 -1
View File
@@ -234,7 +234,7 @@
else
var/list/funky_turfs = RANGE_TURFS(1, user)
for(var/turf/closed/solid in funky_turfs)
user << "<span class='warning'>You're too close to a wall.</span>"
to_chat(user, "<span class='warning'>You're too close to a wall.</span>")
return
dancefloor_exists = TRUE
var/i = 1
+1 -1
View File
@@ -22,7 +22,7 @@
if(C.disabilities & DEAF)
deaf = max(deaf, 1)
else
if(HAS_SECONDARY_FLAG(C.ears, HEALS_EARS))
if(C.ears && HAS_SECONDARY_FLAG(C.ears, HEALS_EARS))
deaf = max(deaf - 1, 1)
ear_damage = max(ear_damage - 0.10, 0)
// if higher than UNHEALING_EAR_DAMAGE, no natural healing occurs.
+10
View File
@@ -0,0 +1,10 @@
diff a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm (rejected hunks)
@@ -54,7 +54,7 @@
return new step_type
/datum/surgery/proc/complete()
- feedback_add_details("surgeries_completed", type)
+ feedback_add_details("surgeries_completed", "[type]")
qdel(src)
+16 -16
View File
@@ -222,7 +222,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
/datum/uplink_item/dangerous/machinegun
name = "L6 Squad Automatic Weapon"
desc = "A fully-loaded Aussec Armoury belt-fed machine gun. \
This deadly weapon has a massive 50-round magazine of devastating 5.56x45mm ammunition."
This deadly weapon has a massive 50-round magazine of devastating 1.95x129mm ammunition."
item = /obj/item/weapon/gun/ballistic/automatic/l6_saw
cost = 18
surplus = 0
@@ -469,34 +469,34 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
include_modes = list(/datum/game_mode/nuclear)
/datum/uplink_item/ammo/machinegun/basic
name = "5.56x45mm Box Magazine"
desc = "A 50-round magazine of 5.56x45mm ammunition for use with the L6 SAW. \
name = "1.95x129mm Box Magazine"
desc = "A 50-round magazine of 1.95x129mm ammunition for use with the L6 SAW. \
By the time you need to use this, you'll already be on a pile of corpses."
item = /obj/item/ammo_box/magazine/mm556x45
item = /obj/item/ammo_box/magazine/mm195x129
/datum/uplink_item/ammo/machinegun/bleeding
name = "5.56x45mm (Bleeding) Box Magazine"
desc = "A 50-round magazine of 5.56x45mm ammunition for use in the L6 SAW; equipped with special properties \
name = "1.95x129mm (Bleeding) Box Magazine"
desc = "A 50-round magazine of 1.95x129mm ammunition for use in the L6 SAW; equipped with special properties \
to induce internal bleeding on targets."
item = /obj/item/ammo_box/magazine/mm556x45/bleeding
item = /obj/item/ammo_box/magazine/mm195x129/bleeding
/datum/uplink_item/ammo/machinegun/hollow
name = "5.56x45mm (Hollow-Point) Box Magazine"
desc = "A 50-round magazine of 5.56x45mm ammunition for use in the L6 SAW; equipped with hollow-point tips to help \
name = "1.95x129mm (Hollow-Point) Box Magazine"
desc = "A 50-round magazine of 1.95x129mm ammunition for use in the L6 SAW; equipped with hollow-point tips to help \
with the unarmored masses of crew."
item = /obj/item/ammo_box/magazine/mm556x45/hollow
item = /obj/item/ammo_box/magazine/mm195x129/hollow
/datum/uplink_item/ammo/machinegun/ap
name = "5.56x45mm (Armor Penetrating) Box Magazine"
desc = "A 50-round magazine of 5.56x45mm ammunition for use in the L6 SAW; equipped with special properties \
name = "1.95x129mm (Armor Penetrating) Box Magazine"
desc = "A 50-round magazine of 1.95x129mm ammunition for use in the L6 SAW; equipped with special properties \
to puncture even the most durable armor."
item = /obj/item/ammo_box/magazine/mm556x45/ap
item = /obj/item/ammo_box/magazine/mm195x129/ap
/datum/uplink_item/ammo/machinegun/incen
name = "5.56x45mm (Incendiary) Box Magazine"
desc = "A 50-round magazine of 5.56x45mm ammunition for use in the L6 SAW; tipped with a special flammable \
name = "1.95x129mm (Incendiary) Box Magazine"
desc = "A 50-round magazine of 1.95x129mm ammunition for use in the L6 SAW; tipped with a special flammable \
mixture that'll ignite anyone struck by the bullet. Some men just want to watch the world burn."
item = /obj/item/ammo_box/magazine/mm556x45/incen
item = /obj/item/ammo_box/magazine/mm195x129/incen
/datum/uplink_item/ammo/sniper
cost = 4
-4
View File
@@ -1,4 +0,0 @@
author: "Poojawa"
delete-after: True
changes:
- soundadd: "all new, improved vore sound effects!"
-4
View File
@@ -1,4 +0,0 @@
author: "Poojawa"
delete-after: True
changes:
- rscadd: "Admins now have the ticket system returned to us. Should make life easier. A bit WIP still because Cyberboss memes"
-4
View File
@@ -1,4 +0,0 @@
author: "CitadelStationBot"
delete-after: True
changes:
- bugfix: "Fixed mining closets having extra, unrelated items"

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