Merge remote-tracking branch 'refs/remotes/Citadel-Station-13/master' into donoritemmodularization

# Conflicts:
#	code/citadel/custom_loadout/custom_items.dm
#	code/datums/components/riding.dm
#	code/game/objects/items/implants/implantuplink.dm
#	icons/mob/neck.dmi
#	icons/obj/clothing/cloaks.dmi
This commit is contained in:
deathride58
2017-12-08 19:58:41 -05:00
182 changed files with 2740 additions and 736 deletions
+1 -1
View File
@@ -1,3 +1,3 @@
[Directions]: # (Include the Round ID from the Status panel or retrieve it from https://atlantaned.space/newSS13tools/round.php ! If you believe the issue to be caused by a testmerge [OOC tab -> Show Server Revision], report it in the pull request's comment section instead. Explain your issue in detail, including the steps to reproduce it.)
[Directions]: # (INCLUDE THE ROUND ID from the Status panel or retrieve it from https://atlantaned.space/newSS13tools/round.php ! If you believe the issue to be caused by a test merge [OOC tab -> Show Server Revision], report it in the pull request's comment section instead. Explain your issue in detail, including the steps to reproduce it.)
[For Admins]: # (Oddities induced by var-edits and other admin tools are not necessarily bugs. Verify that your issues occur under regular circumstances before reporting them.)
+1
View File
@@ -192,6 +192,7 @@ Temporary Items
#Visual studio stuff
*.vscode/*
tools/MapAtmosFixer/MapAtmosFixer/obj/x86/Debug/MapAtmosFixer.csproj.CoreCompileInputs.cache
#GitHub Atom
.atom-build.json
+3
View File
@@ -1,5 +1,8 @@
language: generic
sudo: false
branches:
except:
- ___TGS3TempBranch
env:
global:
- BYOND_MAJOR="511"
+1 -1
View File
@@ -163,7 +163,7 @@
death = 0;
desc = "Looks secure.";
flavour_text = "You are a bartender for the beach!";
icon = 'icons/obj/cryogenic2.dmi';
icon = 'icons/obj/machines/sleeper.dmi';
icon_state = "sleeper";
mob_name = "Jerry Thomas";
name = "bartenders cryosleeper";
+4 -2
View File
@@ -32247,10 +32247,12 @@
/obj/machinery/light_switch{
pixel_x = 27
},
/obj/machinery/photocopier,
/obj/machinery/light/small{
dir = 4
},
/obj/structure/easel,
/obj/item/canvas/twentythreeXtwentythree,
/obj/item/canvas/twentythreeXtwentythree,
/turf/open/floor/plasteel,
/area/storage/art)
"boP" = (
@@ -101206,7 +101208,7 @@ bzE
bLk
bML
bue
bMQ
bzE
bRj
bSB
bPR
File diff suppressed because it is too large Load Diff
+497
View File
@@ -0,0 +1,497 @@
//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
"a" = (
/turf/template_noop,
/area/template_noop)
"b" = (
/turf/closed/wall/mineral/plastitanium,
/area/shuttle/escape)
"c" = (
/obj/effect/spawner/structure/window/plasma/reinforced,
/turf/open/floor/plasteel/elevatorshaft,
/area/shuttle/escape)
"d" = (
/obj/structure/table/wood,
/obj/item/device/flashlight/lamp/green,
/turf/open/floor/mineral/gold,
/area/shuttle/escape)
"e" = (
/obj/structure/chair/comfy/brown{
dir = 1
},
/turf/open/floor/mineral/gold,
/area/shuttle/escape)
"f" = (
/obj/machinery/computer/emergency_shuttle,
/turf/open/floor/mineral/gold,
/area/shuttle/escape)
"g" = (
/obj/structure/table/wood,
/obj/item/storage/fancy/cigarettes/cigars/havana,
/obj/item/lighter{
pixel_x = -4;
pixel_y = 6
},
/turf/open/floor/mineral/gold,
/area/shuttle/escape)
"h" = (
/obj/machinery/computer/atmos_alert{
dir = 4
},
/turf/open/floor/mineral/gold,
/area/shuttle/escape)
"i" = (
/obj/structure/chair/comfy/brown{
dir = 8
},
/turf/open/floor/mineral/gold,
/area/shuttle/escape)
"j" = (
/turf/open/floor/mineral/gold,
/area/shuttle/escape)
"k" = (
/obj/structure/chair/comfy/brown{
dir = 4
},
/turf/open/floor/mineral/gold,
/area/shuttle/escape)
"l" = (
/obj/machinery/computer/security{
dir = 8
},
/turf/open/floor/mineral/gold,
/area/shuttle/escape)
"m" = (
/obj/machinery/computer/crew{
dir = 4
},
/turf/open/floor/mineral/gold,
/area/shuttle/escape)
"n" = (
/obj/structure/table/wood/poker,
/obj/item/storage/box/drinkingglasses,
/obj/item/reagent_containers/food/drinks/bottle/whiskey,
/obj/machinery/light,
/turf/open/floor/mineral/gold,
/area/shuttle/escape)
"o" = (
/obj/machinery/computer/communications{
dir = 8
},
/turf/open/floor/mineral/gold,
/area/shuttle/escape)
"p" = (
/obj/machinery/door/airlock/gold{
req_access_txt = "19"
},
/turf/open/floor/mineral/gold,
/area/shuttle/escape)
"q" = (
/obj/structure/statue/plasma/scientist{
anchored = 1;
oreAmount = 50
},
/turf/open/floor/light/colour_cycle,
/area/shuttle/escape)
"r" = (
/turf/open/floor/mineral/plasma,
/area/shuttle/escape)
"s" = (
/turf/open/floor/mineral/silver,
/area/shuttle/escape)
"t" = (
/turf/open/floor/light/colour_cycle,
/area/shuttle/escape)
"u" = (
/obj/docking_port/mobile/emergency{
name = "Disco Inferno";
timid = 1
},
/obj/machinery/door/airlock/gold{
armor = list("melee" = 30, "bullet" = 30, "laser" = 20, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100);
heat_proof = 1;
resistance_flags = 2
},
/turf/open/floor/mineral/plasma,
/area/shuttle/escape)
"v" = (
/obj/machinery/disco{
anchored = 1;
req_access = null
},
/turf/open/floor/light/colour_cycle,
/area/shuttle/escape)
"w" = (
/obj/machinery/door/airlock/gold,
/turf/open/floor/wood,
/area/shuttle/escape)
"x" = (
/turf/open/floor/wood,
/area/shuttle/escape)
"y" = (
/turf/open/floor/carpet,
/area/shuttle/escape)
"z" = (
/obj/structure/chair/comfy/brown{
dir = 2
},
/turf/open/floor/carpet,
/area/shuttle/escape)
"A" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/drinks/bottle/cognac,
/turf/open/floor/wood,
/area/shuttle/escape)
"B" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/drinks/bottle/vodka/badminka,
/turf/open/floor/wood,
/area/shuttle/escape)
"C" = (
/obj/machinery/computer/slot_machine,
/obj/machinery/light{
dir = 8
},
/turf/open/floor/wood,
/area/shuttle/escape)
"D" = (
/obj/structure/chair/comfy/brown{
dir = 8
},
/turf/open/floor/wood,
/area/shuttle/escape)
"E" = (
/obj/structure/chair/comfy/brown{
dir = 4
},
/turf/open/floor/carpet,
/area/shuttle/escape)
"F" = (
/obj/structure/table/wood/poker,
/obj/item/toy/cards/deck,
/turf/open/floor/carpet,
/area/shuttle/escape)
"G" = (
/obj/structure/chair/comfy/brown{
dir = 8
},
/turf/open/floor/carpet,
/area/shuttle/escape)
"H" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass,
/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass,
/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass,
/obj/machinery/light{
dir = 4
},
/obj/item/coin/plasma,
/obj/item/coin/plasma,
/turf/open/floor/wood,
/area/shuttle/escape)
"I" = (
/obj/machinery/computer/slot_machine{
dir = 3
},
/turf/open/floor/wood,
/area/shuttle/escape)
"J" = (
/obj/structure/chair/comfy/brown{
dir = 1
},
/turf/open/floor/carpet,
/area/shuttle/escape)
"K" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/drinks/bottle/absinthe,
/turf/open/floor/wood,
/area/shuttle/escape)
"L" = (
/obj/structure/table/wood/fancy,
/obj/item/reagent_containers/food/drinks/bottle/lizardwine,
/turf/open/floor/wood,
/area/shuttle/escape)
"M" = (
/obj/structure/shuttle/engine/heater,
/obj/structure/window/plasma/reinforced{
dir = 1
},
/turf/open/floor/plating/airless,
/area/shuttle/escape)
"N" = (
/obj/structure/shuttle/engine/propulsion,
/turf/open/floor/plating/airless,
/area/shuttle/escape)
"O" = (
/turf/closed/wall/mineral/plastitanium/nodiagonal,
/area/shuttle/escape)
"P" = (
/turf/closed/wall/mineral/plastitanium/nodiagonal,
/area/shuttle/escape)
"Q" = (
/turf/closed/wall/mineral/plastitanium/nodiagonal,
/area/shuttle/escape)
(1,1,1) = {"
a
a
a
a
b
b
b
c
b
u
b
c
c
c
b
O
b
w
b
c
b
a
"}
(2,1,1) = {"
a
b
b
b
O
q
r
r
r
r
j
r
r
r
r
q
c
x
C
I
b
b
"}
(3,1,1) = {"
b
b
h
m
c
r
r
r
r
s
j
s
r
r
r
r
c
x
D
D
M
N
"}
(4,1,1) = {"
c
d
i
i
c
r
r
r
j
j
t
j
j
r
r
r
c
x
x
x
M
N
"}
(5,1,1) = {"
c
e
j
j
c
r
r
s
j
t
t
t
j
s
r
r
c
y
E
y
M
N
"}
(6,1,1) = {"
c
f
j
n
c
r
j
j
t
t
v
t
t
j
j
r
c
z
F
J
M
N
"}
(7,1,1) = {"
c
e
j
j
p
r
r
s
j
t
t
t
j
s
r
r
c
y
G
y
M
N
"}
(8,1,1) = {"
c
g
k
k
c
r
r
r
j
j
t
j
j
r
r
r
c
x
x
x
M
N
"}
(9,1,1) = {"
b
b
l
o
c
r
r
r
r
s
j
s
r
r
r
r
c
A
x
K
M
N
"}
(10,1,1) = {"
a
b
b
b
O
q
r
r
r
r
j
r
r
r
r
q
c
B
H
L
b
b
"}
(11,1,1) = {"
a
a
a
a
b
b
b
c
b
b
b
c
c
c
b
b
b
c
b
c
b
a
"}
+1 -6
View File
@@ -10,11 +10,6 @@
#define COMPONENT_DUPE_ALLOWED 1 //duplicates allowed
#define COMPONENT_DUPE_UNIQUE 2 //new component is deleted
// Signal return value flags
// The other defines are under the signal they're used in
#define COMPONENT_ACTIVATED 1 // call parent.ComponentActivated(comp) and component.AfterComponentActivated()
// All signals. Format:
// When the signal is called: (signal arguments)
@@ -28,7 +23,7 @@
// /atom signals
#define COMSIG_PARENT_ATTACKBY "atom_attackby" //from base of atom/attackby(): (/obj/item, /mob/living, params)
#define COMPONENT_NO_AFTERATTACK 2 //Return this in response if you don't want afterattack to be called
#define COMPONENT_NO_AFTERATTACK 1 //Return this in response if you don't want afterattack to be called
#define COMSIG_ATOM_HULK_ATTACK "hulk_attack" //from base of atom/attack_hulk(): (/mob/living/carbon/human)
#define COMSIG_PARENT_EXAMINE "atom_examine" //from base of atom/examine(): (/mob)
#define COMSIG_ATOM_ENTERED "atom_entered" //from base of atom/Entered(): (/atom/movable, /atom)
+4
View File
@@ -490,3 +490,7 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
#define FRIENDLY_SPAWN 2
#define RIDING_OFFSET_ALL "ALL"
//Fullscreen overlay resolution in tiles.
#define FULLSCREEN_OVERLAY_RESOLUTION_X 15
#define FULLSCREEN_OVERLAY_RESOLUTION_Y 15
+1 -1
View File
@@ -20,7 +20,7 @@
#define SOUND_MINIMUM_PRESSURE 10
#define FALLOFF_SOUNDS 0.5
#define FALLOFF_SOUNDS 1
//Ambience types
+2 -2
View File
@@ -22,6 +22,6 @@ When using time2text(), please use "DDD" to find the weekday. Refrain from using
#define TICKS *world.tick_lag
#define DS2TICKS(DS) (DS/world.tick_lag)
#define DS2TICKS(DS) ((DS)/world.tick_lag)
#define TICKS2DS(T) (T TICKS)
#define TICKS2DS(T) ((T) TICKS)
+16 -16
View File
@@ -9,6 +9,16 @@
* Misc
*/
#define LAZYINITLIST(L) if (!L) L = list()
#define UNSETEMPTY(L) if (L && !L.len) L = null
#define LAZYREMOVE(L, I) if(L) { L -= I; if(!L.len) { L = null; } }
#define LAZYADD(L, I) if(!L) { L = list(); } L += I;
#define LAZYACCESS(L, I) (L ? (isnum(I) ? (I > 0 && I <= L.len ? L[I] : null) : L[I]) : null)
#define LAZYSET(L, K, V) if(!L) { L = list(); } L[K] = V;
#define LAZYLEN(L) length(L)
#define LAZYCLEARLIST(L) if(L) L.Cut()
#define SANITIZE_LIST(L) ( islist(L) ? L : list() )
//Returns a list in plain english as a string
/proc/english_list(list/input, nothing_text = "nothing", and_text = " and ", comma_text = ", ", final_comma_text = "" )
var/total = input.len
@@ -32,7 +42,7 @@
//Returns list element or null. Should prevent "index out of bounds" error.
/proc/listgetindex(list/L, index)
if(istype(L))
if(LAZYLEN(L))
if(isnum(index) && IsInteger(index))
if(IsInRange(index,1,L.len))
return L[index]
@@ -42,7 +52,7 @@
//Return either pick(list) or null if list is not of type /list or is empty
/proc/safepick(list/L)
if(istype(L) && L.len)
if(LAZYLEN(L))
return pick(L)
//Checks if the list is empty
@@ -53,7 +63,7 @@
//Checks for specific types in a list
/proc/is_type_in_list(atom/A, list/L)
if(!L || !L.len || !A)
if(!LAZYLEN(L) || !A)
return FALSE
for(var/type in L)
if(istype(A, type))
@@ -62,7 +72,7 @@
//Checks for specific types in specifically structured (Assoc "type" = TRUE) lists ('typecaches')
/proc/is_type_in_typecache(atom/A, list/L)
if(!L || !L.len || !A)
if(!LAZYLEN(L) || !A)
return FALSE
if(ispath(A))
@@ -72,7 +82,7 @@
//Checks for a string in a list
/proc/is_string_in_list(string, list/L)
if(!L || !L.len || !string)
if(!LAZYLEN(L) || !string)
return
for(var/V in L)
if(string == V)
@@ -81,7 +91,7 @@
//Removes a string from a list
/proc/remove_strings_from_list(string, list/L)
if(!L || !L.len || !string)
if(!LAZYLEN(L) || !string)
return
for(var/V in L)
if(V == string)
@@ -486,16 +496,6 @@
//Picks from the list, with some safeties, and returns the "default" arg if it fails
#define DEFAULTPICK(L, default) ((islist(L) && length(L)) ? pick(L) : default)
#define LAZYINITLIST(L) if (!L) L = list()
#define UNSETEMPTY(L) if (L && !L.len) L = null
#define LAZYREMOVE(L, I) if(L) { L -= I; if(!L.len) { L = null; } }
#define LAZYADD(L, I) if(!L) { L = list(); } L += I;
#define LAZYACCESS(L, I) (L ? (isnum(I) ? (I > 0 && I <= L.len ? L[I] : null) : L[I]) : null)
#define LAZYSET(L, K, V) if(!L) { L = list(); } L[K] = V;
#define LAZYLEN(L) length(L)
#define LAZYCLEARLIST(L) if(L) L.Cut()
#define SANITIZE_LIST(L) ( islist(L) ? L : list() )
/* Definining a counter as a series of key -> numeric value entries
* All these procs modify in place.
-19
View File
@@ -326,25 +326,6 @@
return M
return null
// Will return a list of active candidates. It increases the buffer 5 times until it finds a candidate which is active within the buffer.
/proc/get_candidates(be_special_type, afk_bracket = CONFIG_GET(number/inactivity_period), jobbanType)
var/list/candidates = list()
// Keep looping until we find a non-afk candidate within the time bracket (we limit the bracket to 10 minutes (6000))
var/afk_period = CONFIG_GET(number/afk_period)
while(!candidates.len && afk_bracket < afk_period)
for(var/mob/dead/observer/G in GLOB.player_list)
if(G.client != null)
if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
if(!G.client.is_afk(afk_bracket) && (be_special_type in G.client.prefs.be_special))
if (jobbanType)
if(!(jobban_isbanned(G, jobbanType) || jobban_isbanned(G, "Syndicate")))
candidates += G.client
else
candidates += G.client
afk_bracket += 600 // Add a minute to the bracket, for every attempt
return candidates
/proc/considered_alive(datum/mind/M, enforce_human = TRUE)
if(M && M.current)
if(enforce_human)
+6 -4
View File
@@ -192,15 +192,17 @@ GLOBAL_LIST_INIT(sqrtTable, list(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4,
/proc/mouse_angle_from_client(client/client)
var/list/mouse_control = params2list(client.mouseParams)
if(mouse_control["screen-loc"])
if(mouse_control["screen-loc"] && client)
var/list/screen_loc_params = splittext(mouse_control["screen-loc"], ",")
var/list/screen_loc_X = splittext(screen_loc_params[1],":")
var/list/screen_loc_Y = splittext(screen_loc_params[2],":")
var/x = (text2num(screen_loc_X[1]) * 32 + text2num(screen_loc_X[2]) - 32)
var/y = (text2num(screen_loc_Y[1]) * 32 + text2num(screen_loc_Y[2]) - 32)
var/screenview = (client.view * 2 + 1) * world.icon_size //Refer to http://www.byond.com/docs/ref/info.html#/client/var/view for mad maths
var/ox = round(screenview/2) - client.pixel_x //"origin" x
var/oy = round(screenview/2) - client.pixel_y //"origin" y
var/list/screenview = getviewsize(client)
var/screenviewX = screenview[1] * world.icon_size
var/screenviewY = screenview[2] * world.icon_size
var/ox = round(screenviewX/2) - client.pixel_x //"origin" x
var/oy = round(screenviewY/2) - client.pixel_y //"origin" y
var/angle = NORM_ROT(Atan2(y - oy, x - ox))
return angle
+17 -3
View File
@@ -353,9 +353,8 @@ Turf and target are separate in case you want to teleport some distance from a t
var/M = E/(SPEED_OF_LIGHT_SQ)
return M
//Takes the value of energy used/produced/ect.
//Returns a text value of that number in W, kW, MW, or GW.
/proc/DisplayPower(var/powerused)
// Format a power value in W, kW, MW, or GW.
/proc/DisplayPower(powerused)
if(powerused < 1000) //Less than a kW
return "[powerused] W"
else if(powerused < 1000000) //Less than a MW
@@ -364,6 +363,21 @@ Turf and target are separate in case you want to teleport some distance from a t
return "[round((powerused * 0.000001),0.001)] MW"
return "[round((powerused * 0.000000001),0.0001)] GW"
// Format an energy value in J, kJ, MJ, or GJ. 1W = 1J/s.
/proc/DisplayEnergy(units)
// APCs process every (SSmachines.wait * 0.1) seconds, and turn 1 W of
// excess power into GLOB.CELLRATE energy units when charging cells.
// With the current configuration of wait=20 and CELLRATE=0.002, this
// means that one unit is 1 kJ.
units *= SSmachines.wait * 0.1 / GLOB.CELLRATE
if (units < 1000) // Less than a kJ
return "[round(units, 0.1)] J"
else if (units < 1000000) // Less than a MJ
return "[round(units * 0.001, 0.01)] kJ"
else if (units < 1000000000) // Less than a GJ
return "[round(units * 0.000001, 0.001)] MJ"
return "[round(units * 0.000000001, 0.0001)] GJ"
/proc/key_name(whom, include_link = null, include_name = 1)
var/mob/M
var/client/C
+12
View File
@@ -0,0 +1,12 @@
/proc/getviewsize(view)
var/viewX
var/viewY
if(isnum(view))
var/totalviewrange = 1 + 2 * view
viewX = totalviewrange
viewY = totalviewrange
else
var/list/viewrangelist = splittext(view,"x")
viewX = text2num(viewrangelist[1])
viewY = text2num(viewrangelist[2])
return list(viewX, viewY)
-1
View File
@@ -35,4 +35,3 @@ GLOBAL_PROTECT(MAX_EX_FLASH_RANGE)
GLOBAL_VAR_INIT(MAX_EX_FLAME_RANGE, 14)
GLOBAL_PROTECT(MAX_EX_FLAME_RANGE)
GLOBAL_VAR_INIT(DYN_EX_SCALE, 0.5)
+7 -7
View File
@@ -440,20 +440,20 @@
mouse_opacity = MOUSE_OPACITY_OPAQUE
screen_loc = "CENTER"
/obj/screen/click_catcher/proc/UpdateGreed(view_size_x = 7, view_size_y = 7)
/obj/screen/click_catcher/proc/UpdateGreed(view_size_x = 15, view_size_y = 15)
var/icon/newicon = icon('icons/mob/screen_gen.dmi', "flash")
if(view_size_x > 16 || view_size_y > 16)
newicon.Scale((16 * 2 + 1) * world.icon_size,(16 * 2 + 1) * world.icon_size)
if(view_size_x > 32 || view_size_y > 32)
newicon.Scale(16 * world.icon_size,16 * world.icon_size)
icon = newicon
var/tx = view_size_x/16
var/ty = view_size_y/16
var/tx = ((view_size_x - 1)*0.5)/16
var/ty = ((view_size_y - 1)*0.5)/16
var/matrix/M = new
M.Scale(tx, ty)
transform = M
screen_loc = "CENTER-16,CENTER-16"
else
screen_loc = "CENTER-[view_size_x],CENTER-[view_size_y]"
newicon.Scale((view_size_x * 2 + 1) * world.icon_size,(view_size_y * 2 + 1) * world.icon_size)
screen_loc = "CENTER-[(view_size_x-1)*0.5],CENTER-[(view_size_y-1)*0.5]"
newicon.Scale(view_size_x * world.icon_size,view_size_y * world.icon_size)
icon = newicon
/obj/screen/click_catcher/Click(location, control, params)
+2 -2
View File
@@ -16,9 +16,9 @@
if (client && screen.should_show_to(src))
client.screen += screen
if (screen.screen_loc == "CENTER-7,CENTER-7" && screen.view != client.view)
var/scale = (1 + 2 * client.view) / 15
var/list/actualview = getviewsize(client.view)
screen.view = client.view
screen.transform = matrix(scale, 0, 0, 0, scale, 0)
screen.transform = matrix(actualview[1]/FULLSCREEN_OVERLAY_RESOLUTION_X, 0, 0, 0, actualview[2]/FULLSCREEN_OVERLAY_RESOLUTION_Y, 0)
return screen
+6 -4
View File
@@ -255,11 +255,13 @@
/obj/screen/parallax_layer/proc/update_o(view)
if (!view)
view = world.view
var/count = Ceiling(view/(480/world.icon_size))+1
var/list/viewscales = getviewsize(view)
var/countx = Ceiling((viewscales[1]/2)/(480/world.icon_size))+1
var/county = Ceiling((viewscales[2]/2)/(480/world.icon_size))+1
var/list/new_overlays = new
for(var/x in -count to count)
for(var/y in -count to count)
for(var/x in -countx to countx)
for(var/y in -county to county)
if(x == 0 && y == 0)
continue
var/mutable_appearance/texture_overlay = mutable_appearance(icon, icon_state)
+49 -28
View File
@@ -11,7 +11,7 @@
attack_verb = list("poked", "jabbed", "hit")
light_color = "#37FFF7"
var/light_brightness = 3
actions_types = list(/datum/action/item_action/pick_color)
actions_types = list()
/obj/item/toy/sword/cx/attack_self(mob/user)
active = !( active )
@@ -57,18 +57,21 @@
var/mob/M = loc
M.update_inv_hands()
/obj/item/toy/sword/cx/ui_action_click(mob/user, var/datum/action/A)
if(istype(A, /datum/action/item_action/pick_color))
if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes")
var/energy_color_input = input(usr,"Choose Energy Color") as color|null
if(energy_color_input)
light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
update_icon()
update_light()
A.UpdateButtonIcon()
/obj/item/toy/sword/cx/AltClick(mob/living/user)
if(user.incapacitated() || !istype(user))
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
return
if(!in_range(src, user))
return
if(user.incapacitated() || !istype(user) || !in_range(src, user))
return
else
..()
if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes")
var/energy_color_input = input(usr,"Choose Energy Color") as color|null
if(energy_color_input)
light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
update_icon()
update_light()
/obj/item/toy/sword/cx/worn_overlays(isinhands, icon_file)
. = ..()
@@ -79,7 +82,21 @@
. += blade_inhand
/obj/item/toy/sword/cx/attackby(obj/item/W, mob/living/user, params)
return //NO MORE MAKING DUAL ESWORDS
if(istype(W, /obj/item/toy/sword/cx))
if((W.flags_1 & NODROP_1) || (flags_1 & NODROP_1))
to_chat(user, "<span class='warning'>\the [flags_1 & NODROP_1 ? src : W] is stuck to your hand, you can't attach it to \the [flags_1 & NODROP_1 ? W : src]!</span>")
return
else
to_chat(user, "<span class='notice'>You combine the two plastic swords, making a single supermassive toy! You're fake-cool.</span>")
new /obj/item/twohanded/hypereutactic/toy(user.loc)
qdel(W)
qdel(src)
else
return ..()
/obj/item/toy/sword/cx/examine(mob/user)
..()
to_chat(user, "<span class='notice'>Alt-click to recolor it.</span>")
/*///autolathe memes/// I really need to stop doing this and find a proper way of adding in my toys
@@ -124,7 +141,7 @@
origin_tech = "combat=3;magnets=4"
block_chance = 60
light_color = "#37FFF7"
actions_types = list(/datum/action/item_action/pick_color)
actions_types = list()
/obj/item/melee/transforming/energy/sword/cx/transform_weapon(mob/living/user, supress_message_text)
active = !active //I'd use a ..() here but it'd inherit from the regular esword's proc instead, so SPAGHETTI CODE
@@ -152,9 +169,6 @@
update_icon()
transform_messages(user, supress_message_text)
add_fingerprint(user)
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
return TRUE
/obj/item/melee/transforming/energy/sword/cx/transform_messages(mob/living/user, supress_message_text)
@@ -181,18 +195,25 @@
var/mob/M = loc
M.update_inv_hands()
/obj/item/melee/transforming/energy/sword/cx/ui_action_click(mob/user, var/datum/action/A)
if(istype(A, /datum/action/item_action/pick_color))
if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes")
var/energy_color_input = input(usr,"Choose Energy Color") as color|null
if(energy_color_input)
light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
update_icon()
update_light()
A.UpdateButtonIcon()
/obj/item/melee/transforming/energy/sword/cx/AltClick(mob/living/user)
if(user.incapacitated() || !istype(user))
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
return
if(!in_range(src, user))
return
if(user.incapacitated() || !istype(user) || !in_range(src, user))
return
else
..()
if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes")
var/energy_color_input = input(usr,"Choose Energy Color") as color|null
if(energy_color_input)
light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
update_icon()
update_light()
/obj/item/melee/transforming/energy/sword/cx/examine(mob/user)
..()
to_chat(user, "<span class='notice'>Alt-click to recolor it.</span>")
/obj/item/melee/transforming/energy/sword/cx/worn_overlays(isinhands, icon_file)
. = ..()
+1 -3
View File
@@ -231,7 +231,5 @@
icon_state = "vermillion-i"
item_state = "vermillion-w"
body_parts_covered = CHEST|GROIN|LEGS|ARMS|HANDS
icon = 'icons/obj/custom.dmi'
icon_override = 'icons/obj/custom.dmi'
@@ -208,9 +208,9 @@ CONFIG_DEF(string/panic_server_name)
/datum/config_entry/string/panic_server_name/ValidateAndSet(str_val)
return str_val != "\[Put the name here\]" && ..()
CONFIG_DEF(string/panic_address) //Reconnect a player this linked server if this server isn't accepting new players
CONFIG_DEF(string/panic_server_address) //Reconnect a player this linked server if this server isn't accepting new players
/datum/config_entry/string/panic_address/ValidateAndSet(str_val)
/datum/config_entry/string/panic_server_address/ValidateAndSet(str_val)
return str_val != "byond://address:port" && ..()
CONFIG_DEF(string/invoke_youtubedl)
@@ -377,7 +377,7 @@ CONFIG_TWEAK(number/mc_tick_rate/ValidateAndSet(str_val))
CONFIG_DEF(flag/resume_after_initializations)
CONFIG_TWEAK(flag/ValidateAndSet(str_val))
CONFIG_TWEAK(flag/resume_after_initializations/ValidateAndSet(str_val))
. = ..()
if(. && Master.current_runlevel)
world.sleep_offline = !value
@@ -385,3 +385,6 @@ CONFIG_TWEAK(flag/ValidateAndSet(str_val))
CONFIG_DEF(number/rounds_until_hard_restart)
value = -1
min_val = 0
CONFIG_DEF(string/default_view)
value = "15x15"
@@ -263,4 +263,4 @@ CONFIG_DEF(number/emergency_shuttle_autocall_threshold)
max_val = 1
integer = FALSE
CONFIG_DEF(flag/ic_printing)
CONFIG_DEF(flag/ic_printing)
+4 -2
View File
@@ -39,9 +39,9 @@ SUBSYSTEM_DEF(blackbox)
sealed = SSblackbox.sealed
//no touchie
/datum/controller/subsystem/blackbox/can_vv_get(var_name)
/datum/controller/subsystem/blackbox/vv_get_var(var_name)
if(var_name == "feedback")
return FALSE
return debug_variable(var_name, deepCopyList(feedback), 0, src)
return ..()
/datum/controller/subsystem/blackbox/vv_edit_var(var_name, var_value)
@@ -218,6 +218,8 @@ Versioning
FV.json["data"]["[pos]"] = list() //in 512 "pos" can be replaced with "[FV.json["data"].len+1]"
for(var/i in data)
FV.json["data"]["[pos]"]["[i]"] = "[data[i]]" //and here with "[FV.json["data"].len]"
else
CRASH("Invalid feedback key_type: [key_type]")
/datum/controller/subsystem/blackbox/proc/record_feedback_recurse_list(list/L, list/key_list, increment, depth = 1)
if(depth == key_list.len)
@@ -55,5 +55,8 @@ SUBSYSTEM_DEF(server_maint)
co.ehjax_send(data = "roundrestart")
if(server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite
C << link("byond://[server]")
if(SERVER_TOOLS_PRESENT)
SSblackbox.record_feedback("text", "server_tools", 1, SERVER_TOOLS_VERSION)
SSblackbox.record_feedback("text", "server_tools_api", 1, SERVER_TOOLS_API_VERSION)
#undef PING_BUFFER_TIME
+200 -101
View File
@@ -1,5 +1,6 @@
#define BUCKET_LEN (world.fps*1*60) //how many ticks should we keep in the bucket. (1 minutes worth)
#define BUCKET_POS(timer) (round((timer.timeToRun - SStimer.head_offset) / world.tick_lag) + 1)
#define BUCKET_POS(timer) ((round((timer.timeToRun - SStimer.head_offset) / world.tick_lag) % BUCKET_LEN) + 1)
#define TIMER_MAX (world.time + TICKS2DS(min(BUCKET_LEN-(SStimer.practical_offset-DS2TICKS(world.time - SStimer.head_offset))-1, BUCKET_LEN-1)))
#define TIMER_ID_MAX (2**24) //max float with integer precision
SUBSYSTEM_DEF(timer)
@@ -9,11 +10,11 @@ SUBSYSTEM_DEF(timer)
flags = SS_TICKER|SS_NO_INIT
var/list/datum/timedevent/processing = list()
var/list/datum/timedevent/second_queue = list() //awe, yes, you've had first queue, but what about second queue?
var/list/hashes = list()
var/head_offset = 0 //world.time of the first entry in the the bucket.
var/practical_offset = 0 //index of the first non-empty item in the bucket.
var/practical_offset = 1 //index of the first non-empty item in the bucket.
var/bucket_resolution = 0 //world.tick_lag the bucket was designed for
var/bucket_count = 0 //how many timers are in the buckets
@@ -27,13 +28,19 @@ SUBSYSTEM_DEF(timer)
var/static/last_invoke_warning = 0
var/static/bucket_auto_reset = TRUE
/datum/controller/subsystem/timer/PreInit()
bucket_list.len = BUCKET_LEN
head_offset = world.time
bucket_resolution = world.tick_lag
/datum/controller/subsystem/timer/stat_entry(msg)
..("B:[bucket_count] P:[length(processing)] H:[length(hashes)] C:[length(clienttime_timers)]")
..("B:[bucket_count] P:[length(second_queue)] H:[length(hashes)] C:[length(clienttime_timers)] S:[length(timer_id_dict)]")
/datum/controller/subsystem/timer/fire(resumed = FALSE)
var/lit = last_invoke_tick
var/last_check = world.time - TIMER_NO_INVOKE_WARNING
var/list/bucket_list = src.bucket_list
if(!bucket_count)
last_invoke_tick = world.time
@@ -60,50 +67,62 @@ SUBSYSTEM_DEF(timer)
bucket_node = bucket_node.next
anti_loop_check--
while(bucket_node && bucket_node != bucket_head && anti_loop_check)
log_world("Active timers in the processing queue:")
for(var/I in processing)
log_world("Active timers in the second_queue queue:")
for(var/I in second_queue)
log_world(get_timer_debug_string(I))
while(length(clienttime_timers))
var/datum/timedevent/ctime_timer = clienttime_timers[clienttime_timers.len]
if (ctime_timer.timeToRun <= REALTIMEOFDAY)
--clienttime_timers.len
var/datum/callback/callBack = ctime_timer.callBack
ctime_timer.spent = REALTIMEOFDAY
callBack.InvokeAsync()
qdel(ctime_timer)
else
break //None of the rest are ready to run
var/next_clienttime_timer_index = 0
var/len = length(clienttime_timers)
for (next_clienttime_timer_index in 1 to len)
if (MC_TICK_CHECK)
return
next_clienttime_timer_index--
break
var/datum/timedevent/ctime_timer = clienttime_timers[next_clienttime_timer_index]
if (ctime_timer.timeToRun > REALTIMEOFDAY)
next_clienttime_timer_index--
break
var/datum/callback/callBack = ctime_timer.callBack
if (!callBack)
clienttime_timers.Cut(next_clienttime_timer_index,next_clienttime_timer_index+1)
CRASH("Invalid timer: [get_timer_debug_string(ctime_timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset], REALTIMEOFDAY: [REALTIMEOFDAY]")
ctime_timer.spent = REALTIMEOFDAY
callBack.InvokeAsync()
qdel(ctime_timer)
if (next_clienttime_timer_index)
clienttime_timers.Cut(1,next_clienttime_timer_index+1)
if (MC_TICK_CHECK)
return
var/static/list/spent = list()
var/static/datum/timedevent/timer
var/static/datum/timedevent/head
if (practical_offset > BUCKET_LEN)
head_offset += TICKS2DS(BUCKET_LEN)
practical_offset = 1
resumed = FALSE
if (practical_offset > BUCKET_LEN || (!resumed && length(bucket_list) != BUCKET_LEN || world.tick_lag != bucket_resolution))
shift_buckets()
if ((length(bucket_list) != BUCKET_LEN) || (world.tick_lag != bucket_resolution))
reset_buckets()
bucket_list = src.bucket_list
resumed = FALSE
if (!resumed)
timer = null
head = null
while (practical_offset <= BUCKET_LEN && head_offset + (practical_offset*world.tick_lag) <= world.time && !MC_TICK_CHECK)
while (practical_offset <= BUCKET_LEN && head_offset + (practical_offset*world.tick_lag) <= world.time)
var/datum/timedevent/head = bucket_list[practical_offset]
if (!timer || !head || timer == head)
head = bucket_list[practical_offset]
if (!head)
practical_offset++
if (MC_TICK_CHECK)
break
continue
timer = head
do
while (timer)
var/datum/callback/callBack = timer.callBack
if (!callBack)
qdel(timer)
bucket_resolution = null //force bucket recreation
CRASH("Invalid timer: [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
@@ -113,15 +132,68 @@ SUBSYSTEM_DEF(timer)
callBack.InvokeAsync()
last_invoke_tick = world.time
timer = timer.next
if (MC_TICK_CHECK)
return
while (timer && timer != head)
timer = null
timer = timer.next
if (timer == head)
break
bucket_list[practical_offset++] = null
if (MC_TICK_CHECK)
return
//we freed up a bucket, lets see if anything in second_queue needs to be shifted to that bucket.
var/i = 0
var/L = length(second_queue)
for (i in 1 to L)
timer = second_queue[i]
if (timer.timeToRun >= TIMER_MAX)
i--
break
if (timer.timeToRun < head_offset)
bucket_resolution = null //force bucket recreation
CRASH("[i] Invalid timer state: Timer in long run queue with a time to run less then head_offset. [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
if (timer.callBack && !timer.spent)
timer.callBack.InvokeAsync()
spent += timer
bucket_count++
else if(!QDELETED(timer))
qdel(timer)
continue
if (timer.timeToRun < head_offset + TICKS2DS(practical_offset))
bucket_resolution = null //force bucket recreation
CRASH("[i] Invalid timer state: Timer in long run queue that would require a backtrack to transfer to short run queue. [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
if (timer.callBack && !timer.spent)
timer.callBack.InvokeAsync()
spent += timer
bucket_count++
else if(!QDELETED(timer))
qdel(timer)
continue
bucket_count++
var/bucket_pos = max(1, BUCKET_POS(timer))
var/datum/timedevent/bucket_head = bucket_list[bucket_pos]
if (!bucket_head)
bucket_list[bucket_pos] = timer
timer.next = null
timer.prev = null
continue
if (!bucket_head.prev)
bucket_head.prev = bucket_head
timer.next = bucket_head
timer.prev = bucket_head.prev
timer.next.prev = timer
timer.prev.next = timer
if (i)
second_queue.Cut(1, i+1)
timer = null
bucket_count -= length(spent)
@@ -141,7 +213,7 @@ SUBSYSTEM_DEF(timer)
if(!TE.callBack)
. += ", NO CALLBACK"
/datum/controller/subsystem/timer/proc/shift_buckets()
/datum/controller/subsystem/timer/proc/reset_buckets()
var/list/bucket_list = src.bucket_list
var/list/alltimers = list()
//collect the timers currently in the bucket
@@ -162,7 +234,7 @@ SUBSYSTEM_DEF(timer)
head_offset = world.time
bucket_resolution = world.tick_lag
alltimers += processing
alltimers += second_queue
if (!length(alltimers))
return
@@ -173,22 +245,26 @@ SUBSYSTEM_DEF(timer)
if (head.timeToRun < head_offset)
head_offset = head.timeToRun
var/list/timers_to_remove = list()
for (var/thing in alltimers)
var/datum/timedevent/timer = thing
var/new_bucket_count
var/i = 1
for (i in 1 to length(alltimers))
var/datum/timedevent/timer = alltimers[1]
if (!timer)
timers_to_remove += timer
continue
var/bucket_pos = BUCKET_POS(timer)
if (bucket_pos > BUCKET_LEN)
if (timer.timeToRun >= TIMER_MAX)
i--
break
timers_to_remove += timer //remove it from the big list once we are done
if (!timer.callBack || timer.spent)
WARNING("Invalid timer: [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
if (timer.callBack)
qdel(timer)
continue
bucket_count++
new_bucket_count++
var/datum/timedevent/bucket_head = bucket_list[bucket_pos]
if (!bucket_head)
bucket_list[bucket_pos] = timer
@@ -202,12 +278,14 @@ SUBSYSTEM_DEF(timer)
timer.prev = bucket_head.prev
timer.next.prev = timer
timer.prev.next = timer
processing = (alltimers - timers_to_remove)
if (i)
alltimers.Cut(1, i+1)
second_queue = alltimers
bucket_count = new_bucket_count
/datum/controller/subsystem/timer/Recover()
processing |= SStimer.processing
second_queue |= SStimer.second_queue
hashes |= SStimer.hashes
timer_id_dict |= SStimer.timer_id_dict
bucket_list |= SStimer.bucket_list
@@ -224,8 +302,6 @@ SUBSYSTEM_DEF(timer)
var/datum/timedevent/next
var/datum/timedevent/prev
var/static/nextid = 1
/datum/timedevent/New(datum/callback/callBack, timeToRun, flags, hash)
id = TIMER_ID_NULL
src.callBack = callBack
@@ -235,56 +311,65 @@ SUBSYSTEM_DEF(timer)
if (flags & TIMER_UNIQUE)
SStimer.hashes[hash] = src
if (flags & TIMER_STOPPABLE)
do
if (nextid >= TIMER_ID_MAX)
nextid = 1
id = nextid++
while(SStimer.timer_id_dict["timerid" + num2text(id, 8)])
SStimer.timer_id_dict["timerid" + num2text(id, 8)] = src
id = GUID()
SStimer.timer_id_dict[id] = src
name = "Timer: " + num2text(id, 8) + ", TTR: [timeToRun], Flags: [jointext(bitfield2list(flags, list("TIMER_UNIQUE", "TIMER_OVERRIDE", "TIMER_CLIENT_TIME", "TIMER_STOPPABLE", "TIMER_NO_HASH_WAIT")), ", ")], callBack: [REF(callBack)], callBack.object: [callBack.object][REF(callBack.object)]([getcallingtype()]), callBack.delegate:[callBack.delegate]([callBack.arguments ? callBack.arguments.Join(", ") : ""])"
name = "Timer: [id] (\ref[src]), TTR: [timeToRun], Flags: [jointext(bitfield2list(flags, list("TIMER_UNIQUE", "TIMER_OVERRIDE", "TIMER_CLIENT_TIME", "TIMER_STOPPABLE", "TIMER_NO_HASH_WAIT")), ", ")], callBack: \ref[callBack], callBack.object: [callBack.object]\ref[callBack.object]([getcallingtype()]), callBack.delegate:[callBack.delegate]([callBack.arguments ? callBack.arguments.Join(", ") : ""])"
if (spent)
CRASH("HOLY JESUS. WHAT IS THAT? WHAT THE FUCK IS THAT?")
if ((timeToRun < world.time || timeToRun < SStimer.head_offset) && !(flags & TIMER_CLIENT_TIME))
CRASH("Invalid timer state: Timer created that would require a backtrack to run (addtimer would never let this happen): [SStimer.get_timer_debug_string(src)]")
if (callBack.object != GLOBAL_PROC)
LAZYADD(callBack.object.active_timers, src)
var/list/L
if (flags & TIMER_CLIENT_TIME)
//sorted insert
var/list/ctts = SStimer.clienttime_timers
var/cttl = length(ctts)
L = SStimer.clienttime_timers
else if (timeToRun >= TIMER_MAX)
L = SStimer.second_queue
if (L)
//binary search sorted insert
var/cttl = length(L)
if(cttl)
var/datum/timedevent/Last = ctts[cttl]
if(Last.timeToRun >= timeToRun)
ctts += src
else
for(var/i in cttl to 1 step -1)
var/datum/timedevent/E = ctts[i]
if(E.timeToRun <= timeToRun)
ctts.Insert(i, src)
break
var/left = 1
var/right = cttl
var/mid = (left+right) >> 1 //rounded divide by two for hedgehogs
var/datum/timedevent/item
while (left < right)
item = L[mid]
if (item.timeToRun <= timeToRun)
left = mid+1
else
right = mid
mid = (left+right) >> 1
item = L[mid]
mid = item.timeToRun > timeToRun ? mid : mid+1
L.Insert(mid, src)
else
ctts += src
L += src
return
//get the list of buckets
var/list/bucket_list = SStimer.bucket_list
//calculate our place in the bucket list
var/bucket_pos = BUCKET_POS(src)
//we are too far aways from needing to run to be in the bucket list, shift_buckets() will handle us.
if (bucket_pos > length(bucket_list))
SStimer.processing += src
return
//get the bucket for our tick
var/datum/timedevent/bucket_head = bucket_list[bucket_pos]
SStimer.bucket_count++
//empty bucket, we will just add ourselves
if (!bucket_head)
bucket_list[bucket_pos] = src
if (bucket_pos < SStimer.practical_offset)
SStimer.practical_offset = bucket_pos
return
//other wise, lets do a simplified linked list add.
if (!bucket_head.prev)
@@ -296,10 +381,9 @@ SUBSYSTEM_DEF(timer)
/datum/timedevent/Destroy()
..()
if (flags & TIMER_UNIQUE)
if (flags & TIMER_UNIQUE && hash)
SStimer.hashes -= hash
if (callBack && callBack.object && callBack.object != GLOBAL_PROC && callBack.object.active_timers)
callBack.object.active_timers -= src
UNSETEMPTY(callBack.object.active_timers)
@@ -307,13 +391,33 @@ SUBSYSTEM_DEF(timer)
callBack = null
if (flags & TIMER_STOPPABLE)
SStimer.timer_id_dict -= "timerid" + num2text(id, 8)
SStimer.timer_id_dict -= id
if (flags & TIMER_CLIENT_TIME)
SStimer.clienttime_timers -= src
if (!spent)
spent = world.time
SStimer.clienttime_timers -= src
return QDEL_HINT_IWILLGC
if (!spent)
spent = world.time
var/bucketpos = BUCKET_POS(src)
var/datum/timedevent/buckethead
var/list/bucket_list = SStimer.bucket_list
if (bucketpos > 0)
buckethead = bucket_list[bucketpos]
if (buckethead == src)
bucket_list[bucketpos] = next
SStimer.bucket_count--
else if (timeToRun < TIMER_MAX || next || prev)
SStimer.bucket_count--
else
var/l = length(SStimer.second_queue)
SStimer.second_queue -= src
if (l == length(SStimer.second_queue))
SStimer.bucket_count--
if (prev == next && next)
next.prev = null
prev.next = null
@@ -322,19 +426,6 @@ SUBSYSTEM_DEF(timer)
prev.next = next
if (next)
next.prev = prev
var/bucketpos = BUCKET_POS(src)
var/datum/timedevent/buckethead
var/list/bucket_list = SStimer.bucket_list
if (bucketpos > 0 && bucketpos <= length(bucket_list))
buckethead = bucket_list[bucketpos]
SStimer.bucket_count--
else
SStimer.processing -= src
if (buckethead == src)
bucket_list[bucketpos] = next
else
if (prev && prev.next == src)
prev.next = next
@@ -351,9 +442,16 @@ SUBSYSTEM_DEF(timer)
else
. = "[callBack.object.type]"
/proc/addtimer(datum/callback/callback, wait, flags)
/proc/addtimer(datum/callback/callback, wait = 0, flags = 0)
if (!callback)
return
CRASH("addtimer called without a callback")
if (wait < 0)
stack_trace("Addtimer called with a negitive wait. Converting to 0")
//alot of things add short timers on themselves in their destroy, we ignore those cases
if (wait >= 1 && callback && callback.object && callback.object != GLOBAL_PROC && QDELETED(callback.object))
stack_trace("Add timer called with a callback assigned to a qdeleted object")
wait = max(wait, 0)
@@ -374,11 +472,10 @@ SUBSYSTEM_DEF(timer)
var/datum/timedevent/hash_timer = SStimer.hashes[hash]
if(hash_timer)
if (hash_timer.spent) //it's pending deletion, pretend it doesn't exist.
hash_timer.hash = null
SStimer.hashes -= hash
hash_timer.hash = null //but keep it from accidentally deleting us
else
if (flags & TIMER_OVERRIDE)
hash_timer.hash = null //no need having it delete it's hash if we are going to replace it
qdel(hash_timer)
else
if (hash_timer.flags & TIMER_STOPPABLE)
@@ -403,7 +500,7 @@ SUBSYSTEM_DEF(timer)
qdel(id)
return TRUE
//id is string
var/datum/timedevent/timer = SStimer.timer_id_dict["timerid[id]"]
var/datum/timedevent/timer = SStimer.timer_id_dict[id]
if (timer && !timer.spent)
qdel(timer)
return TRUE
@@ -412,3 +509,5 @@ SUBSYSTEM_DEF(timer)
#undef BUCKET_LEN
#undef BUCKET_POS
#undef TIMER_MAX
#undef TIMER_ID_MAX
+9 -8
View File
@@ -71,7 +71,7 @@
var/datum/objective/escape/escape_objective = new
escape_objective.owner = owner
objectives += escape_objective
if(31 to 60)
var/datum/objective/steal/steal_objective = new
steal_objective.owner = owner
@@ -103,8 +103,8 @@
if (!(locate(/datum/objective/hijack) in owner.objectives))
var/datum/objective/hijack/hijack_objective = new
hijack_objective.owner = owner
objectives += hijack_objective
objectives += hijack_objective
for(var/datum/objective/O in objectives)
owner.objectives += O
@@ -128,7 +128,7 @@
if(H.age < wiz_age)
H.age = wiz_age
H.equipOutfit(outfit_type)
/datum/antagonist/wizard/greet()
to_chat(owner, "<span class='boldannounce'>You are the Space Wizard!</span>")
to_chat(owner, "<B>The Space Wizards Federation has given you the following tasks:</B>")
@@ -204,11 +204,11 @@
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/forcewall(null))
H.put_in_hands(new /obj/item/gun/magic/staff/healing(H))
to_chat(owner, "<B>Your service has not gone unrewarded, however. Studying under [master.current.real_name], you have learned livesaving survival spells. You are able to cast charge and forcewall.")
if(APPRENTICE_HEALING)
if(APPRENTICE_ROBELESS)
owner.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/knock(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/mind_transfer(null))
to_chat(owner, "<B>Your service has not gone unrewarded, however. Studying under [master.current.real_name], you have learned stealthy, robeless spells. You are able to cast knock and mindswap.")
/datum/antagonist/wizard/apprentice/create_objectives()
var/datum/objective/protect/new_objective = new /datum/objective/protect
new_objective.owner = owner
@@ -221,6 +221,7 @@
/datum/antagonist/wizard/apprentice/imposter
name = "Wizard Imposter"
allow_rename = FALSE
move_to_lair = FALSE
/datum/antagonist/wizard/apprentice/imposter/greet()
to_chat(owner, "<B>You are an imposter! Trick and confuse the crew to misdirect malice from your handsome original!</B>")
@@ -266,7 +267,7 @@
/datum/antagonist/wizard/academy/equip_wizard()
. = ..()
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt)
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile)
owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball)
@@ -274,7 +275,7 @@
var/mob/living/M = owner.current
if(!istype(M))
return
var/obj/item/implant/exile/Implant = new/obj/item/implant/exile(M)
Implant.implant(M)
+14 -31
View File
@@ -14,13 +14,13 @@
if(!isnum(dupe_mode))
qdel(src)
CRASH("[type]: Invalid dupe_mode!")
if(dupe_type && !ispath(dupe_type))
var/dt = dupe_type
if(dt && !ispath(dt))
qdel(src)
CRASH("[type]: Invalid dupe_type!")
parent = P
var/list/arguments = args.Copy()
arguments.Cut(1, 2)
var/list/arguments = args.Copy(2)
if(Initialize(arglist(arguments)) == COMPONENT_INCOMPATIBLE)
qdel(src, TRUE, TRUE)
return
@@ -142,10 +142,6 @@
/datum/component/proc/OnTransfer(datum/new_parent)
return
/datum/component/proc/AfterComponentActivated()
set waitfor = FALSE
return
/datum/component/proc/_GetInverseTypeList(our_type = type)
#if DM_VERSION >= 513
#warning 512 is definitely stable now, remove the old code
@@ -167,8 +163,7 @@
var/list/comps = datum_components
if(!comps)
return NONE
var/list/arguments = args.Copy()
arguments.Cut(1, 2)
var/list/arguments = args.Copy(2)
var/target = comps[/datum/component]
if(!length(target))
var/datum/component/C = target
@@ -177,28 +172,16 @@
var/datum/callback/CB = C.signal_procs[sigtype]
if(!CB)
return NONE
. = CB.InvokeAsync(arglist(arguments))
if(. & COMPONENT_ACTIVATED)
ComponentActivated(C)
C.AfterComponentActivated()
else
. = NONE
for(var/I in target)
var/datum/component/C = I
if(!C.enabled)
continue
var/datum/callback/CB = C.signal_procs[sigtype]
if(!CB)
continue
var/retval = CB.InvokeAsync(arglist(arguments))
. |= retval
if(retval & COMPONENT_ACTIVATED)
ComponentActivated(C)
C.AfterComponentActivated()
/datum/proc/ComponentActivated(datum/component/C)
set waitfor = FALSE
return
return CB.InvokeAsync(arglist(arguments))
. = NONE
for(var/I in target)
var/datum/component/C = I
if(!C.enabled)
continue
var/datum/callback/CB = C.signal_procs[sigtype]
if(!CB)
continue
. |= CB.InvokeAsync(arglist(arguments))
/datum/proc/GetComponent(c_type)
var/list/dc = datum_components
+5 -1
View File
@@ -3,10 +3,12 @@
var/list/archdrops
var/prob2drop
var/dug
var/datum/callback/callback
/datum/component/archaeology/Initialize(_prob2drop, list/_archdrops = list())
/datum/component/archaeology/Initialize(_prob2drop, list/_archdrops = list(), datum/callback/_callback)
prob2drop = Clamp(_prob2drop, 0, 100)
archdrops = _archdrops
callback = _callback
RegisterSignal(COMSIG_PARENT_ATTACKBY,.proc/Dig)
RegisterSignal(COMSIG_ATOM_EX_ACT, .proc/BombDig)
RegisterSignal(COMSIG_ATOM_SING_PULL, .proc/SingDig)
@@ -67,6 +69,8 @@
if(OT.slowdown) //Things like snow slow you down until you dig them.
OT.slowdown = 0
dug = TRUE
if(callback)
callback.Invoke()
/datum/component/archaeology/proc/SingDig(S, current_size)
switch(current_size)
+1 -2
View File
@@ -9,5 +9,4 @@
var/mob/living/carbon/victim = AM
if(istype(victim))
for(var/datum/disease/D in diseases)
victim.ContactContractDisease(D, "feet")
return COMPONENT_ACTIVATED
victim.ContactContractDisease(D, "feet")
+10 -14
View File
@@ -16,20 +16,19 @@
var/list/materials
var/show_on_examine
var/list/allowed_typecache
var/last_inserted_type
var/last_inserted_id
var/last_amount_inserted
var/last_insert_success
var/precise_insertion = FALSE
var/datum/callback/precondition
var/datum/callback/after_insert
/datum/component/material_container/Initialize(list/mat_list, max_amt = 0, _show_on_examine = FALSE, list/allowed_types, datum/callback/_precondition)
/datum/component/material_container/Initialize(list/mat_list, max_amt = 0, _show_on_examine = FALSE, list/allowed_types, datum/callback/_precondition, datum/callback/_after_insert)
materials = list()
max_amount = max(0, max_amt)
show_on_examine = _show_on_examine
if(allowed_types)
allowed_typecache = typecacheof(allowed_types)
precondition = _precondition
after_insert = _after_insert
RegisterSignal(COMSIG_PARENT_ATTACKBY, .proc/OnAttackBy)
RegisterSignal(COMSIG_PARENT_EXAMINE, .proc/OnExamine)
@@ -57,10 +56,9 @@
if((I.flags_2 & (HOLOGRAM_2 | NO_MAT_REDEMPTION_2)) || (tc && !is_type_in_typecache(I, tc)))
to_chat(user, "<span class='warning'>[parent] won't accept [I]!</span>")
return
. = COMPONENT_ACTIVATED | COMPONENT_NO_AFTERATTACK
last_insert_success = FALSE
. = COMPONENT_NO_AFTERATTACK
var/datum/callback/pc = precondition
if(pc && !pc.Invoke())
if(pc && !pc.Invoke(user))
return
var/material_amount = get_item_material_amount(I)
if(!material_amount)
@@ -69,11 +67,12 @@
if(!has_space(material_amount))
to_chat(user, "<span class='warning'>[parent] is full. Please remove metal or glass from [parent] in order to insert more.</span>")
return
INVOKE_ASYNC(src, .proc/user_insert, I, user)
user_insert(I, user)
/datum/component/material_container/proc/user_insert(obj/item/I, mob/living/user)
var/requested_amount
if(istype(I, /obj/item/stack) && precise_insertion)
var/Itype = I.type
if(ispath(Itype, /obj/item/stack) && precise_insertion)
var/atom/current_parent = parent
requested_amount = input(user, "How much do you want to insert?", "Inserting sheets") as num|null
if(isnull(requested_amount) || (requested_amount <= 0))
@@ -85,7 +84,6 @@
return
var/inserted = insert_item(I, stack_amt = requested_amount)
if(inserted)
last_insert_success = TRUE
if(istype(I, /obj/item/stack))
to_chat(user, "<span class='notice'>You insert [inserted] sheet[inserted>1 ? "s" : ""] into [parent].</span>")
if(!QDELETED(I))
@@ -93,6 +91,8 @@
else
to_chat(user, "<span class='notice'>You insert a material total of [inserted] into [parent].</span>")
qdel(I)
if(after_insert)
after_insert.Invoke(Itype, last_inserted_id, inserted)
else
user.put_in_active_hand(I)
@@ -132,9 +132,7 @@
return FALSE
last_inserted_id = insert_materials(S,amt)
last_inserted_type = S.type
S.use(amt)
last_amount_inserted = amt
return amt
/datum/component/material_container/proc/insert_item(obj/item/I, multiplier = 1, stack_amt)
@@ -148,8 +146,6 @@
return FALSE
last_inserted_id = insert_materials(I, multiplier)
last_inserted_type = I.type
last_amount_inserted = material_amount
return material_amount
/datum/component/material_container/proc/insert_materials(obj/item/I, multiplier = 1) //for internal usage only
+1 -1
View File
@@ -131,7 +131,7 @@
buckled_mob.pixel_x = 0
buckled_mob.pixel_y = 0
if(buckled_mob.client)
buckled_mob.client.change_view(world.view)
buckled_mob.client.change_view(CONFIG_GET(string/default_view))
//MOVEMENT
/datum/component/riding/proc/turf_check(turf/next, turf/current)
+5 -8
View File
@@ -1,18 +1,15 @@
/datum/component/slippery
var/intensity
var/lube_flags
var/mob/slip_victim
var/datum/callback/callback
/datum/component/slippery/Initialize(_intensity, _lube_flags = NONE)
/datum/component/slippery/Initialize(_intensity, _lube_flags = NONE, datum/callback/_callback)
intensity = max(_intensity, 0)
lube_flags = _lube_flags
callback = _callback
RegisterSignal(list(COMSIG_MOVABLE_CROSSED, COMSIG_ATOM_ENTERED), .proc/Slip)
/datum/component/slippery/proc/Slip(atom/movable/AM)
var/mob/victim = AM
if(istype(victim) && !victim.is_flying() && victim.slip(intensity, parent, lube_flags))
slip_victim = victim
return COMPONENT_ACTIVATED
/datum/component/slippery/AfterComponentActivated()
slip_victim = null
if(istype(victim) && !victim.is_flying() && victim.slip(intensity, parent, lube_flags) && callback)
callback.Invoke(victim)
@@ -4,7 +4,7 @@
mid_sounds = list('sound/machines/shower/shower_mid1.ogg'=1,'sound/machines/shower/shower_mid2.ogg'=1,'sound/machines/shower/shower_mid3.ogg'=1)
mid_length = 10
end_sound = 'sound/machines/shower/shower_end.ogg'
volume = 25
volume = 20
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+1 -1
View File
@@ -109,4 +109,4 @@
var/mob/living/silicon/ai/AI = user
AI.holopad_talk(message, language)
return FALSE
return FALSE
return TRUE
+7 -1
View File
@@ -94,7 +94,13 @@
admin_notes = "Due to the limited space for non paying crew, this shuttle may cause a riot."
credit_cost = 10000
/datum/map_template/shuttle/emergency/discoinferno
suffix = "discoinferno"
name = "Disco Inferno"
description = "The glorious results of centuries of plasma research done by Nanotrasen employees. This is the reason why you are here. Get on and dance like you're on fire, burn baby burn!"
admin_notes = "Flaming hot."
credit_cost = 10000
/datum/map_template/shuttle/emergency/arena
suffix = "arena"
name = "The Arena"
+1
View File
@@ -171,6 +171,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/maintenance/department/science/xenobiology
name = "Xenobiology Maintenance"
icon_state = "xenomaint"
xenobiology_compatible = TRUE
//Maintenance - Generic
+1
View File
@@ -61,6 +61,7 @@
var/list/cameras
var/list/firealarms
var/firedoors_last_closed_on = 0
var/xenobiology_compatible = FALSE //Can the Xenobio management console transverse this area by default?
/*Adding a wizard area teleport list because motherfucking lag -- Urist*/
/*I am far too lazy to make it a proper list of areas so I'll just make it run the usual telepot routine at the start of the game*/
+1 -3
View File
@@ -37,7 +37,7 @@
GLOB._preloader.load(src)
var/do_initialize = SSatoms.initialized
if(do_initialize > INITIALIZATION_INSSATOMS)
if(do_initialize != INITIALIZATION_INSSATOMS)
args[1] = do_initialize == INITIALIZATION_INNEW_MAPLOAD
if(SSatoms.InitAtom(src, args))
//we were deleted
@@ -57,9 +57,7 @@
//Note: the following functions don't call the base for optimization and must copypasta:
// /turf/Initialize
// /turf/open/space/Initialize
// /mob/dead/new_player/Initialize
//Do also note that this proc always runs in New for /mob/dead
/atom/proc/Initialize(mapload, ...)
if(initialized)
stack_trace("Warning: [src]([type]) initialized multiple times!")
@@ -1,8 +1,8 @@
/datum/round_event_control/borer
name = "Borer"
typepath = /datum/round_event/borer
weight = 10 //Default weight
max_occurrences = 1
weight = 0
max_occurrences = 0
min_players = 20 //10 is MINIMUM needed, but this is not a gamemode that does well in lowpop
earliest_start = 24000 //40 min, double default timer
@@ -254,6 +254,9 @@
if(T.type == /turf/closed/wall/r_wall && prob(10))
new /obj/effect/temp_visual/revenant(T)
T.ChangeTurf(/turf/closed/wall/r_wall/rust)
for(var/obj/effect/decal/cleanable/salt/salt in T)
new /obj/effect/temp_visual/revenant(T)
qdel(salt)
for(var/obj/structure/closet/closet in T.contents)
closet.open()
for(var/obj/structure/bodycontainer/corpseholder in T)
+2 -2
View File
@@ -1,6 +1,6 @@
/obj/machinery/sleep_console
name = "sleeper console"
icon = 'icons/obj/Cryogenic2.dmi'
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "console"
density = FALSE
anchored = TRUE
@@ -8,7 +8,7 @@
/obj/machinery/sleeper
name = "sleeper"
desc = "An enclosed machine used to stabilize and heal patients."
icon = 'icons/obj/Cryogenic2.dmi'
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
density = FALSE
anchored = TRUE
+12 -18
View File
@@ -46,7 +46,7 @@
)
/obj/machinery/autolathe/Initialize()
AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS))
AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS), 0, FALSE, null, null, CALLBACK(src, .proc/AfterMaterialInsert))
. = ..()
wires = new /datum/wires/autolathe(src)
@@ -124,23 +124,17 @@
return ..()
/obj/machinery/mecha_part_fabricator/ComponentActivated(datum/component/C)
..()
if(istype(C, /datum/component/material_container))
var/datum/component/material_container/M = C
if(!M.last_insert_success)
return
var/lit = M.last_inserted_type
if(ispath(lit, /obj/item/ore/bluespace_crystal))
use_power(max(500,M.last_amount_inserted/10))
else
switch(M.last_inserted_id)
if (MAT_METAL)
flick("autolathe_o",src)//plays metal insertion animation
if (MAT_GLASS)
flick("autolathe_r",src)//plays glass insertion animation
use_power(M.last_amount_inserted*100)
updateUsrDialog()
/obj/machinery/autolathe/proc/AfterMaterialInsert(type_inserted, id_inserted, amount_inserted)
if(ispath(type_inserted, /obj/item/ore/bluespace_crystal))
use_power(max(500, amount_inserted / 10))
else
switch(id_inserted)
if (MAT_METAL)
flick("autolathe_o",src)//plays metal insertion animation
if (MAT_GLASS)
flick("autolathe_r",src)//plays glass insertion animation
use_power(amount_inserted * 100)
updateUsrDialog()
/obj/machinery/autolathe/Topic(href, href_list)
if(..())
+1 -1
View File
@@ -5,7 +5,7 @@
/obj/machinery/camera
name = "security camera"
desc = "It's used to monitor rooms."
icon = 'icons/obj/monitors.dmi'
icon = 'icons/obj/machines/camera.dmi'
icon_state = "camera"
use_power = ACTIVE_POWER_USE
idle_power_usage = 5
@@ -1,7 +1,7 @@
/obj/item/wallframe/camera
name = "camera assembly"
desc = "The basic construction for Nanotrasen-Always-Watching-You cameras."
icon = 'icons/obj/monitors.dmi'
icon = 'icons/obj/machines/camera.dmi'
icon_state = "cameracase"
materials = list(MAT_METAL=400, MAT_GLASS=250)
result_path = /obj/structure/camera_assembly
@@ -10,7 +10,7 @@
/obj/structure/camera_assembly
name = "camera assembly"
desc = "The basic construction for Nanotrasen-Always-Watching-You cameras."
icon = 'icons/obj/monitors.dmi'
icon = 'icons/obj/machines/camera.dmi'
icon_state = "camera1"
max_integrity = 150
// Motion, EMP-Proof, X-Ray
+1 -1
View File
@@ -13,7 +13,7 @@
name = "cloning pod"
desc = "An electronically-lockable pod for growing organic tissue."
density = TRUE
icon = 'icons/obj/cloning.dmi'
icon = 'icons/obj/machines/cloning.dmi'
icon_state = "pod_0"
req_access = list(ACCESS_CLONING) //FOR PREMATURE UNLOCKING.
verb_say = "states"
+1 -1
View File
@@ -66,7 +66,7 @@
if(result_filters["Responsive"] && !APC.aidisabled)
continue
dat += "<a href='?src=[REF(src)];access_apc=[REF(APC)]'>[A]</a><br>\
<b>Charge:</b> [DisplayPower(APC.cell.charge)] / [DisplayPower(APC.cell.maxcharge)] ([round((APC.cell.charge / APC.cell.maxcharge) * 100)]%)<br>\
<b>Charge:</b> [DisplayEnergy(APC.cell.charge)] / [DisplayEnergy(APC.cell.maxcharge)] ([round((APC.cell.charge / APC.cell.maxcharge) * 100)]%)<br>\
<b>Area:</b> [APC.area]<br>\
[APC.aidisabled || APC.panel_open ? "<font color='#FF0000'>APC does not respond to interface query.</font>" : "<font color='#00FF00'>APC responds to interface query.</font>"]<br><br>"
dat += "<a href='?src=[REF(src)];check_logs=1'>Check Logs</a><br>"
+1 -1
View File
@@ -1,7 +1,7 @@
/obj/machinery/dna_scannernew
name = "\improper DNA scanner"
desc = "It scans DNA structures."
icon = 'icons/obj/Cryogenic2.dmi'
icon = 'icons/obj/machines/cloning.dmi'
icon_state = "scanner"
density = TRUE
anchored = TRUE
+1 -1
View File
@@ -22,7 +22,7 @@
layer = BELOW_OPEN_DOOR_LAYER
closingLayer = CLOSED_FIREDOOR_LAYER
assemblytype = /obj/structure/firelock_frame
armor = list(melee = 30, bullet = 30, laser = 20, energy = 20, bomb = 10, bio = 100, rad = 100, fire = 95, acid = 70)
armor = list("melee" = 30, "bullet" = 30, "laser" = 20, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 95, "acid" = 70)
var/boltslocked = TRUE
var/list/affecting_areas
+2 -2
View File
@@ -2,7 +2,7 @@
/obj/machinery/suit_storage_unit
name = "suit storage unit"
desc = "An industrial unit made to hold space suits. It comes with a built-in UV cauterization mechanism. A small warning label advises that organic matter should not be placed into the unit."
icon = 'icons/obj/suitstorage.dmi'
icon = 'icons/obj/machines/suit_storage.dmi'
icon_state = "close"
anchored = TRUE
density = TRUE
@@ -210,7 +210,7 @@
mob_occupant.adjustFireLoss(rand(20, 36))
else
mob_occupant.adjustFireLoss(rand(10, 16))
mob_occupant.emote("scream")
mob_occupant.emote("scream")
addtimer(CALLBACK(src, .proc/cook), 50)
else
uv_cycles = initial(uv_cycles)
+1 -1
View File
@@ -138,7 +138,7 @@
if(isnull(amount))
amount = 0
var/atom/temp = new typepath(null)
var/atom/temp = typepath
var/datum/data/vending_product/R = new /datum/data/vending_product()
R.product_name = initial(temp.name)
R.product_path = typepath
@@ -32,7 +32,7 @@
/obj/item/mecha_parts/mecha_equipment/medical/sleeper
name = "mounted sleeper"
desc = "Equipment for medical exosuits. A mounted sleeper that stabilizes patients and can inject reagents in the exosuit's reserves."
icon = 'icons/obj/Cryogenic2.dmi'
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
origin_tech = "engineering=3;biotech=3;plasmatech=2"
energy_drain = 20
+12 -16
View File
@@ -34,13 +34,14 @@
"Misc"
)
var/datum/component/material_container/materials
/obj/machinery/mecha_part_fabricator/Initialize()
var/datum/component/material_container/materials = AddComponent(/datum/component/material_container,
list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE),
FALSE, list(/obj/item/stack, /obj/item/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready))
materials.precise_insertion = TRUE
. = ..()
files = new /datum/research(src) //Setup the research data holder.
materials = AddComponent(/datum/component/material_container,
list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE), 0,
FALSE, list(/obj/item/stack, /obj/item/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready), CALLBACK(src, .proc/AfterMaterialInsert))
materials.precise_insertion = TRUE
return ..()
/obj/machinery/mecha_part_fabricator/RefreshParts()
var/T = 0
@@ -415,16 +416,11 @@
materials.retrieve_all()
..()
/obj/machinery/mecha_part_fabricator/ComponentActivated(datum/component/C)
..()
if(istype(C, /datum/component/material_container))
var/datum/component/material_container/M = C
if(!M.last_insert_success)
return
var/stack_name = material2name(M.last_inserted_id)
add_overlay("fab-load-[stack_name]")
addtimer(CALLBACK(src, /atom/proc/cut_overlay, "fab-load-[stack_name]"), 10)
updateUsrDialog()
/obj/machinery/mecha_part_fabricator/proc/AfterMaterialInsert(type_inserted, id_inserted, amount_inserted)
var/stack_name = material2name(id_inserted)
add_overlay("fab-load-[stack_name]")
addtimer(CALLBACK(src, /atom/proc/cut_overlay, "fab-load-[stack_name]"), 10)
updateUsrDialog()
/obj/machinery/mecha_part_fabricator/attackby(obj/item/W, mob/user, params)
if(default_deconstruction_screwdriver(user, "fab-o", "fab-idle", W))
+2 -2
View File
@@ -970,7 +970,7 @@
setDir(dir_in)
if(L && L.client)
L.client.change_view(world.view)
L.client.change_view(CONFIG_GET(string/default_view))
zoom_mode = 0
/////////////////////////
@@ -1042,4 +1042,4 @@ GLOBAL_VAR_INIT(year_integer, text2num(year)) // = 2013???
/obj/mecha/update_remote_sight(mob/living/user)
if(occupant_sight_flags)
if(user == occupant)
user.sight |= occupant_sight_flags
user.sight |= occupant_sight_flags
+1 -1
View File
@@ -244,7 +244,7 @@
owner.client.change_view(12)
SEND_SOUND(owner, sound('sound/mecha/imag_enh.ogg',volume=50))
else
owner.client.change_view(world.view) //world.view - default mob view size
owner.client.change_view(CONFIG_GET(string/default_view)) //world.view - default mob view size
UpdateButtonIcon()
/datum/action/innate/mecha/mech_switch_damtype
@@ -10,16 +10,11 @@
/obj/item/device/pda/clown/Initialize()
. = ..()
AddComponent(/datum/component/slippery, 120, NO_SLIP_WHEN_WALKING)
AddComponent(/datum/component/slippery, 120, NO_SLIP_WHEN_WALKING, CALLBACK(src, .proc/AfterSlip))
/obj/item/device/pda/clown/ComponentActivated(datum/component/C)
..()
var/datum/component/slippery/S = C
if(!istype(S))
return
var/mob/living/carbon/human/M = S.slip_victim
if (istype(M) && (M.real_name != src.owner))
slipvictims |= M
/obj/item/device/pda/clown/proc/AfterSlip(mob/living/carbon/human/M)
if (istype(M) && (M.real_name != owner))
slipvictims |=M
var/obj/item/cartridge/virus/clown/cart = cartridge
if(istype(cart) && cart.charges < 5)
cart.charges++
@@ -30,7 +30,7 @@
to_chat(R, "<span class='warning'>You need a power cell installed for that.</span>")
return
if(!R.cell.use(circuit_cost))
to_chat(R, "<span class='warning'>You don't have the power for that (you need [DisplayPower(circuit_cost)].)</span>")
to_chat(R, "<span class='warning'>You don't have the energy for that (you need [DisplayEnergy(circuit_cost)].)</span>")
return
if(recharging)
to_chat(R, "<span class='warning'>[src] needs some time to recharge first.</span>")
@@ -34,6 +34,7 @@
/obj/item/implant/uplink/activate()
GET_COMPONENT(hidden_uplink, /datum/component/uplink)
if(hidden_uplink)
hidden_uplink.locked = FALSE
hidden_uplink.interact(usr)
/obj/item/implanter/uplink
+1 -1
View File
@@ -162,7 +162,7 @@
/obj/item/inducer/examine(mob/living/M)
..()
if(cell)
to_chat(M, "<span class='notice'>Its display shows: [DisplayPower(cell.charge)].</span>")
to_chat(M, "<span class='notice'>Its display shows: [DisplayEnergy(cell.charge)].</span>")
else
to_chat(M,"<span class='notice'>Its display is dark.</span>")
if(opened)
+194
View File
@@ -0,0 +1,194 @@
#define pet_carrier_full(carrier) carrier.occupants.len >= carrier.max_occupants || carrier.occupant_weight >= carrier.max_occupant_weight
//Used to transport little animals without having to drag them across the station.
//Comes with a handy lock to prevent them from running off.
/obj/item/pet_carrier
name = "pet carrier"
desc = "A big white-and-blue pet carrier. Good for carrying <s>meat to the chef</s> cute animals around."
icon = 'icons/obj/pet_carrier.dmi'
icon_state = "pet_carrier_open"
item_state = "pet_carrier"
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
force = 5
attack_verb = list("bashed", "carried")
w_class = WEIGHT_CLASS_BULKY
throw_speed = 2
throw_range = 3
materials = list(MAT_METAL = 7500, MAT_GLASS = 100)
var/open = TRUE
var/locked = FALSE
var/list/occupants = list()
var/occupant_weight = 0
var/max_occupants = 3 //Hard-cap so you can't have infinite mice or something in one carrier
var/max_occupant_weight = MOB_SIZE_SMALL //This is calculated from the mob sizes of occupants
/obj/item/pet_carrier/Destroy()
if(occupants.len)
for(var/V in occupants)
remove_occupant(V)
return ..()
/obj/item/pet_carrier/Exited(atom/movable/occupant)
if(occupant in occupants && isliving(occupant))
var/mob/living/L = occupant
occupants -= occupant
occupant_weight -= L.mob_size
/obj/item/pet_carrier/handle_atom_del(atom/A)
if(A in occupants && isliving(A))
var/mob/living/L = A
occupants -= L
occupant_weight -= L.mob_size
..()
/obj/item/pet_carrier/examine(mob/user)
..()
if(occupants.len)
for(var/V in occupants)
var/mob/living/L = V
to_chat(user, "<span class='notice'>It has [L] inside.</span>")
else
to_chat(user, "<span class='notice'>It has nothing inside.</span>")
if(user.canUseTopic(src))
to_chat(user, "<span class='notice'>Activate it in your hand to [open ? "close" : "open"] its door.</span>")
if(!open)
to_chat(user, "<span class='notice'>Alt-click to [locked ? "unlock" : "lock"] its door.</span>")
/obj/item/pet_carrier/attack_self(mob/living/user)
if(open)
to_chat(user, "<span class='notice'>You close [src]'s door.</span>")
playsound(user, 'sound/effects/bin_close.ogg', 50, TRUE)
open = FALSE
else
if(locked)
to_chat(user, "<span class='warning'>[src] is locked!</span>")
return
to_chat(user, "<span class='notice'>You open [src]'s door.</span>")
playsound(user, 'sound/effects/bin_open.ogg', 50, TRUE)
open = TRUE
update_icon()
/obj/item/pet_carrier/AltClick(mob/living/user)
if(open)
return
locked = !locked
to_chat(user, "<span class='notice'>You flip the lock switch [locked ? "down" : "up"].</span>")
if(locked)
playsound(user, 'sound/machines/boltsdown.ogg', 30, TRUE)
else
playsound(user, 'sound/machines/boltsup.ogg', 30, TRUE)
update_icon()
/obj/item/pet_carrier/attack(mob/living/target, mob/living/user)
if(user.a_intent == INTENT_HARM)
return ..()
if(!open)
to_chat(user, "<span class='warning'>You need to open [src]'s door!</span>")
return
if(target.mob_size > max_occupant_weight)
if(ishuman(target))
var/mob/living/carbon/human/H = target
if(iscatperson(H))
to_chat(user, "<span class='warning'>You'd need a lot of catnip and treats, plus maybe a laser pointer, for that to work.</span>")
else
to_chat(user, "<span class='warning'>Humans, generally, do not fit into pet carriers.</span>")
else
to_chat(user, "<span class='warning'>You get the feeling [target] isn't meant for a [name].</span>")
return
if(user == target)
to_chat(user, "<span class='warning'>Why would you ever do that?</span>")
return
load_occupant(user, target)
/obj/item/pet_carrier/relaymove(mob/living/user, direction)
if(open)
loc.visible_message("<span class='notice'>[user] climbs out of [src]!</span>", \
"<span class='warning'>[user] jumps out of [src]!</span>")
remove_occupant(user)
return
else if(!locked)
loc.visible_message("<span class='notice'>[user] pushes open the door to [src]!</span>", \
"<span class='warning'>[user] pushes open the door of [src]!</span>")
open = TRUE
update_icon()
return
else if(user.client)
container_resist(user)
/obj/item/pet_carrier/container_resist(mob/living/user)
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
if(user.mob_size <= MOB_SIZE_SMALL)
to_chat(user, "<span class='notice'>You poke a limb through [src]'s bars and start fumbling for the lock switch... (This will take some time.)</span>")
to_chat(loc, "<span class='warning'>You see [user] reach through the bars and fumble for the lock switch!</span>")
if(!do_after(user, rand(300, 400), target = user) || open || !locked || !user in occupants)
return
loc.visible_message("<span class='warning'>[user] flips the lock switch on [src] by reaching through!</span>", ignored_mob = user)
to_chat(user, "<span class='boldannounce'>Bingo! The lock pops open!</span>")
locked = FALSE
playsound(src, 'sound/machines/boltsup.ogg', 30, TRUE)
update_icon()
else
loc.visible_message("<span class='warning'>[src] starts rattling as something pushes against the door!</span>", ignored_mob = user)
to_chat(user, "<span class='notice'>You start pushing out of [src]... (This will take about 20 seconds.)</span>")
if(!do_after(user, 200, target = user) || open || !locked || !user in occupants)
return
loc.visible_message("<span class='warning'>[user] shoves out of [src]!</span>", ignored_mob = user)
to_chat(user, "<span class='notice'>You shove open [src]'s door against the lock's resistance and fall out!</span>")
locked = FALSE
open = TRUE
update_icon()
remove_occupant(user)
/obj/item/pet_carrier/update_icon()
cut_overlay("unlocked")
cut_overlay("locked")
if(open)
icon_state = initial(icon_state)
else
icon_state = "pet_carrier_[!occupants.len ? "closed" : "occupied"]"
add_overlay("[locked ? "" : "un"]locked")
/obj/item/pet_carrier/MouseDrop(atom/over_atom)
if(isopenturf(over_atom) && usr.Adjacent(over_atom) && open && occupants.len)
usr.visible_message("<span class='notice'>[usr] unloads [src].</span>", \
"<span class='notice'>You unload [src] onto [over_atom].</span>")
for(var/V in occupants)
remove_occupant(V, over_atom)
/obj/item/pet_carrier/proc/load_occupant(mob/living/user, mob/living/target)
if(pet_carrier_full(src))
to_chat(user, "<span class='warning'>[src] is already carrying too much!</span>")
return
user.visible_message("<span class='notice'>[user] starts loading [target] into [src].</span>", \
"<span class='notice'>You start loading [target] into [src]...</span>", ignored_mob = target)
to_chat(target, "<span class='userdanger'>[user] starts loading you into their [name]!</span>")
if(!do_mob(user, target, 30))
return
if(target in occupants)
return
if(pet_carrier_full(src)) //Run the checks again, just in case
to_chat(user, "<span class='warning'>[src] is already carrying too much!</span>")
return
user.visible_message("<span class='notice'>[user] loads [target] into [src]!</span>", \
"<span class='notice'>You load [target] into [src].</span>", ignored_mob = target)
to_chat(target, "<span class='userdanger'>[user] loads you into their [name]!</span>")
add_occupant(target)
/obj/item/pet_carrier/proc/add_occupant(mob/living/occupant)
if(occupant in occupants || !istype(occupant))
return
occupant.forceMove(src)
occupants += occupant
occupant_weight += occupant.mob_size
/obj/item/pet_carrier/proc/remove_occupant(mob/living/occupant, turf/new_turf)
if(!occupant in occupants || !istype(occupant))
return
occupant.forceMove(new_turf ? new_turf : drop_location())
occupants -= occupant
occupant_weight -= occupant.mob_size
occupant.setDir(SOUTH)
#undef pet_carrier_full
@@ -73,6 +73,7 @@
new /obj/item/device/autosurgeon/cmo(src)
new /obj/item/door_remote/chief_medical_officer(src)
new /obj/item/clothing/neck/petcollar(src)
new /obj/item/pet_carrier(src)
/obj/structure/closet/secure_closet/animal
name = "animal control"
@@ -12,6 +12,7 @@
new /obj/item/storage/backpack/satchel/cap(src)
new /obj/item/clothing/neck/cloak/cap(src)
new /obj/item/clothing/neck/petcollar(src)
new /obj/item/pet_carrier(src)
new /obj/item/storage/backpack/duffelbag/captain(src)
new /obj/item/clothing/head/crown/fancy(src)
new /obj/item/clothing/suit/captunic(src)
@@ -53,6 +54,7 @@
new /obj/item/restraints/handcuffs/cable/zipties(src)
new /obj/item/gun/energy/e_gun/cx(src)
new /obj/item/clothing/neck/petcollar(src)
new /obj/item/pet_carrier(src)
new /obj/item/door_remote/civillian(src)
/obj/structure/closet/secure_closet/hos
+1 -1
View File
@@ -33,7 +33,7 @@
/obj/structure/fluff/empty_sleeper //Empty sleepers are created by a good few ghost roles in lavaland.
name = "empty sleeper"
desc = "An open sleeper. It looks as though it would be awaiting another patient, were it not broken."
icon = 'icons/obj/Cryogenic2.dmi'
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper-open"
/obj/structure/fluff/empty_sleeper/nanotrasen
@@ -76,7 +76,7 @@
name = "timeless prison"
desc = "Although this stasis pod looks medicinal, it seems as though it's meant to preserve something for a very long time."
mob_name = "a penitent exile"
icon = 'icons/obj/Cryogenic2.dmi'
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
roundstart = FALSE
death = FALSE
@@ -259,7 +259,7 @@
name = "prisoner containment sleeper"
desc = "A sleeper designed to put its occupant into a deep coma, unbreakable until the sleeper turns off. This one's glass is cracked and you can see a pale, sleeping face staring out."
mob_name = "an escaped prisoner"
icon = 'icons/obj/Cryogenic2.dmi'
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper_s"
outfit = /datum/outfit/lavalandprisoner
roundstart = FALSE
@@ -296,7 +296,7 @@
name = "staff sleeper"
desc = "A sleeper designed for long-term stasis between guest visits."
mob_name = "hotel staff member"
icon = 'icons/obj/Cryogenic2.dmi'
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper_s"
objectives = "Cater to visiting guests with your fellow staff. Do not leave your assigned hotel and always remember: The customer is always right!"
death = FALSE
@@ -393,7 +393,7 @@
name = "Syndicate Operative"
roundstart = FALSE
death = FALSE
icon = 'icons/obj/Cryogenic2.dmi'
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper_s"
id_access_list = list(ACCESS_SYNDICATE)
outfit = /datum/outfit/syndicate_empty
@@ -461,7 +461,7 @@
name = "old cryogenics pod"
desc = "A humming cryo pod. You can barely recognise a security uniform underneath the built up ice. The machine is attempting to wake up its occupant."
mob_name = "a security officer"
icon = 'icons/obj/cryogenic2.dmi'
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
roundstart = FALSE
death = FALSE
@@ -485,7 +485,7 @@
name = "old cryogenics pod"
desc = "A humming cryo pod. You can barely recognise an engineering uniform underneath the built up ice. The machine is attempting to wake up its occupant."
mob_name = "an engineer"
icon = 'icons/obj/cryogenic2.dmi'
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
roundstart = FALSE
death = FALSE
@@ -509,7 +509,7 @@
name = "old cryogenics pod"
desc = "A humming cryo pod. You can barely recognise a science uniform underneath the built up ice. The machine is attempting to wake up its occupant."
mob_name = "a scientist"
icon = 'icons/obj/cryogenic2.dmi'
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
roundstart = FALSE
death = FALSE
@@ -535,7 +535,7 @@
name = "space pirate sleeper"
desc = "A cryo sleeper smelling faintly of rum."
random = TRUE
icon = 'icons/obj/cryogenic2.dmi'
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
mob_name = "a space pirate"
mob_species = /datum/species/human
@@ -561,7 +561,7 @@
/obj/effect/mob_spawn/human/pirate/Destroy()
new/obj/structure/showcase/machinery/oldpod/used(drop_location())
return ..()
/obj/effect/mob_spawn/human/pirate/captain
rank = "Captain"
outfit = /datum/outfit/pirate/space/captain
+1 -1
View File
@@ -26,7 +26,7 @@
update_icon()
/obj/structure/grille/update_icon()
if(QDELETED(src))
if(QDELETED(src) || broken)
return
var/ratio = obj_integrity / max_integrity
@@ -37,7 +37,7 @@
buckled_mob.pixel_x = 0
buckled_mob.pixel_y = 0
if(buckled_mob.client)
buckled_mob.client.change_view(world.view)
buckled_mob.client.change_view(CONFIG_GET(string/default_view))
anchored = FALSE
. = ..()
STOP_PROCESSING(SSfastprocess, src)
+3 -3
View File
@@ -36,13 +36,13 @@
/obj/structure/showcase/horrific_experiment
name = "horrific experiment"
desc = "Some sort of pod filled with blood and viscera. You swear you can see it moving..."
icon = 'icons/obj/cloning.dmi'
icon = 'icons/obj/machines/cloning.dmi'
icon_state = "pod_g"
/obj/structure/showcase/machinery/oldpod
name = "damaged cryogenic pod"
desc = "A damaged cryogenic pod long since lost to time, including its former occupant..."
icon = 'icons/obj/cryogenic2.dmi'
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper-open"
/obj/structure/showcase/machinery/oldpod/used
@@ -83,7 +83,7 @@
/obj/structure/showcase/machinery/cloning_pod
name = "cloning pod exhibit"
desc = "Signs describe how cloning pods like these ensure that every Nanotrasen employee can carry out their contracts in full, even in the unlikely event of their catastrophic death. Hopefully they aren't all made of cardboard, like this one."
icon = 'icons/obj/cloning.dmi'
icon = 'icons/obj/machines/cloning.dmi'
icon_state = "pod_0"
/obj/structure/showcase/perfect_employee
+1 -1
View File
@@ -10,7 +10,7 @@
// Looping through the player list has the added bonus of working for mobs inside containers
var/sound/S = sound(get_sfx(soundin))
var/maxdistance = (world.view + extrarange) * 3
var/maxdistance = (world.view + extrarange)
var/list/listeners = GLOB.player_list
if(!ignore_walls) //these sounds don't carry through walls
listeners = listeners & hearers(maxdistance,turf_source)
+2 -7
View File
@@ -275,17 +275,12 @@
else
qdel(GetComponent(/datum/component/slippery))
return
var/datum/component/slippery/S = LoadComponent(/datum/component/slippery)
var/datum/component/slippery/S = LoadComponent(/datum/component/slippery, NONE, CALLBACK(src, .proc/AfterSlip))
S.intensity = intensity
S.lube_flags = lube_flags
/turf/open/ComponentActivated(datum/component/C)
..()
var/datum/component/slippery/S = C
if(!istype(S))
return
/turf/open/proc/AfterSlip(mob/living/L)
if(wet == TURF_WET_LUBE)
var/mob/living/L = S.slip_victim
L.confused = max(L.confused, 8)
/turf/open/proc/MakeDry(wet_setting = TURF_WET_WATER)
@@ -87,6 +87,9 @@
/turf/open/floor/plating/asteroid/basalt/Initialize()
. = ..()
set_basalt_light(src)
GET_COMPONENT(arch, /datum/component/archaeology)
ASSERT(isnull(arch.callback))
arch.callback = CALLBACK(src, /atom/proc/set_light, 0)
/proc/set_basalt_light(turf/open/floor/B)
switch(B.icon_state)
@@ -95,12 +98,6 @@
if("basalt5", "basalt9")
B.set_light(1.4, 0.6, LIGHT_COLOR_LAVA) //barely anything!
/turf/open/floor/plating/asteroid/basalt/ComponentActivated(datum/component/C)
..()
if(istype(C, /datum/component/archaeology))
set_light(0)
///////Surface. The surface is warm, but survivable without a suit. Internals are required. The floors break to chasms, which drop you into the underground.
/turf/open/floor/plating/asteroid/basalt/lava_land_surface
+7
View File
@@ -1,3 +1,5 @@
#define MAX_DENT_DECALS 15
/turf/closed/wall
name = "wall"
desc = "A huge chunk of metal used to separate rooms."
@@ -297,6 +299,9 @@
return FALSE
/turf/closed/wall/proc/add_dent(denttype, x=rand(-8, 8), y=rand(-8, 8))
if(LAZYLEN(dent_decals) >= MAX_DENT_DECALS)
return
var/mutable_appearance/decal = pick(dent_decal_list[denttype])
decal.pixel_x = x
decal.pixel_y = y
@@ -304,3 +309,5 @@
cut_overlay(dent_decals)
LAZYADD(dent_decals, decal)
add_overlay(dent_decals)
#undef MAX_DENT_DECALS
+1 -1
View File
@@ -5,7 +5,7 @@
/obj/machinery/vr_sleeper
name = "virtual reality sleeper"
desc = "A sleeper modified to alter the subconscious state of the user, allowing them to visit virtual worlds."
icon = 'icons/obj/Cryogenic2.dmi'
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
state_open = TRUE
anchored = TRUE
+1 -1
View File
@@ -111,7 +111,7 @@
//get message text, limit it's length.and clean/escape html
if(!msg)
msg = input(src,"Message:", "Private message to [key_name(recipient, 0, 0)]") as text|null
msg = trim(msg)
if(!msg)
return
+2 -2
View File
@@ -651,10 +651,10 @@ Traitors and the like can also be revived with the previous role mostly intact.
set name = "Change View Range"
set desc = "switches between 1x and custom views"
if(view == world.view)
if(view == CONFIG_GET(string/default_view))
change_view(input("Select view range:", "FUCK YE", 7) in list(1,2,3,4,5,6,7,8,9,10,11,12,13,14,128))
else
change_view(world.view)
change_view(CONFIG_GET(string/default_view))
log_admin("[key_name(usr)] changed their view range to [view].")
//message_admins("\blue [key_name_admin(usr)] changed their view range to [view].") //why? removed by order of XSI
@@ -7,7 +7,7 @@
//list of open turfs adjacent to us
var/list/atmos_adjacent_turfs
//bitfield of dirs in which we are superconducitng
var/atmos_supeconductivity = 0
var/atmos_supeconductivity = NONE
//used to determine whether we should archive
var/archived_cycle = 0
@@ -25,8 +25,7 @@
var/pressure_direction = 0
var/datum/excited_group/excited_group
var/excited = 0
var/recently_active = 0
var/excited = FALSE
var/datum/gas_mixture/turf/air
var/obj/effect/hotspot/active_hotspot
@@ -54,10 +53,10 @@
/turf/open/assume_air(datum/gas_mixture/giver) //use this for machines to adjust air
if(!giver)
return 0
return FALSE
air.merge(giver)
update_visuals()
return 1
return TRUE
/turf/open/remove_air(amount)
var/datum/gas_mixture/ours = return_air()
@@ -83,7 +82,7 @@
/turf/temperature_expose()
if(temperature > heat_capacity)
to_be_destroyed = 1
to_be_destroyed = TRUE
/turf/proc/archive()
temperature_archived = temperature
@@ -102,7 +101,7 @@
#if DM_VERSION >= 513
#warning 512 is stable now for sure, remove the old code
#endif
#if DM_VERSION >= 512
if (atmos_overlay_types)
for(var/overlay in atmos_overlay_types-new_overlay_types) //doesn't remove overlays that would only be added
@@ -175,64 +174,48 @@
for(var/t in adjacent_turfs)
var/turf/open/enemy_tile = t
if(fire_count > enemy_tile.current_cycle)
enemy_tile.archive()
if(fire_count <= enemy_tile.current_cycle)
continue
enemy_tile.archive()
/******************* GROUP HANDLING START *****************************************************************/
/******************* GROUP HANDLING START *****************************************************************/
var/should_share_air = FALSE
var/datum/gas_mixture/enemy_air = enemy_tile.air
if(enemy_tile.excited)
//cache for sanic speed
var/datum/excited_group/enemy_excited_group = enemy_tile.excited_group
if(our_excited_group)
if(enemy_excited_group)
if(our_excited_group != enemy_excited_group)
//combine groups (this also handles updating the excited_group var of all involved turfs)
our_excited_group.merge_groups(enemy_excited_group)
our_excited_group = excited_group //update our cache
should_share_air = TRUE
else
if((recently_active == 1 && enemy_tile.recently_active == 1) || our_air.compare(enemy_air))
our_excited_group.add_turf(enemy_tile) //add enemy to our group
should_share_air = TRUE
var/should_share_air = FALSE
var/datum/gas_mixture/enemy_air = enemy_tile.air
//cache for sanic speed
var/datum/excited_group/enemy_excited_group = enemy_tile.excited_group
if(our_excited_group && enemy_excited_group)
if(our_excited_group != enemy_excited_group)
//combine groups (this also handles updating the excited_group var of all involved turfs)
our_excited_group.merge_groups(enemy_excited_group)
our_excited_group = excited_group //update our cache
should_share_air = TRUE
else if(our_air.compare(enemy_air))
if(!enemy_tile.excited)
SSair.add_to_active(enemy_tile)
var/datum/excited_group/EG = our_excited_group || enemy_excited_group || new
if(!our_excited_group)
EG.add_turf(src)
if(!enemy_excited_group)
EG.add_turf(enemy_tile)
our_excited_group = excited_group
should_share_air = TRUE
//air sharing
if(should_share_air)
var/difference = our_air.share(enemy_air, adjacent_turfs_length)
if(difference)
if(difference > 0)
consider_pressure_difference(enemy_tile, difference)
else
if(enemy_excited_group)
if((recently_active == 1 && enemy_tile.recently_active == 1) || our_air.compare(enemy_air))
enemy_excited_group.add_turf(src) //join self to enemy group
our_excited_group = excited_group //update our cache
should_share_air = TRUE
else
if((recently_active == 1 && enemy_tile.recently_active == 1) || our_air.compare(enemy_air))
var/datum/excited_group/EG = new //generate new group
EG.add_turf(src)
EG.add_turf(enemy_tile)
our_excited_group = excited_group //update our cache
should_share_air = TRUE
else
if(our_air.compare(enemy_air)) //compare if
SSair.add_to_active(enemy_tile) //excite enemy
if(our_excited_group)
our_excited_group.add_turf(enemy_tile) //add enemy to group
else
var/datum/excited_group/EG = new //generate new group
EG.add_turf(src)
EG.add_turf(enemy_tile)
our_excited_group = excited_group //update our cache
should_share_air = TRUE
//air sharing
if(should_share_air)
var/difference = our_air.share(enemy_air, adjacent_turfs_length)
if(difference)
if(difference > 0)
consider_pressure_difference(enemy_tile, difference)
else
enemy_tile.consider_pressure_difference(src, -difference)
LAST_SHARE_CHECK
enemy_tile.consider_pressure_difference(src, -difference)
LAST_SHARE_CHECK
/******************* GROUP HANDLING FINISH *********************************************************************/
/******************* GROUP HANDLING FINISH *********************************************************************/
if (planet_atmos) //share our air with the "atmosphere" "above" the turf
var/datum/gas_mixture/G = new
@@ -250,12 +233,8 @@
update_visuals()
var/remove = TRUE
if(our_air.temperature > MINIMUM_TEMPERATURE_START_SUPERCONDUCTION)
if(consider_superconductivity(starting = 1))
remove = FALSE
if ((!our_excited_group && remove) || (cached_atmos_cooldown > (EXCITED_GROUP_DISMANTLE_CYCLES * 2)))
if((!our_excited_group && !(our_air.temperature > MINIMUM_TEMPERATURE_START_SUPERCONDUCTION && consider_superconductivity(starting = TRUE))) \
|| (cached_atmos_cooldown > (EXCITED_GROUP_DISMANTLE_CYCLES * 2)))
SSair.remove_from_active(src)
atmos_cooldown = cached_atmos_cooldown
@@ -279,9 +258,9 @@
var/const/PROBABILITY_OFFSET = 25
var/const/PROBABILITY_BASE_PRECENT = 75
set waitfor = 0
. = 0
. = FALSE
if (!anchored && !pulledby)
. = 1
. = TRUE
if (last_high_pressure_movement_air_cycle < SSair.times_fired)
var/move_prob = 100
if (pressure_resistance > 0)
@@ -304,7 +283,6 @@
/datum/excited_group/proc/add_turf(turf/open/T)
turf_list += T
T.excited_group = src
T.recently_active = 1
reset_cooldowns()
/datum/excited_group/proc/merge_groups(datum/excited_group/E)
@@ -328,25 +306,27 @@
dismantle_cooldown = 0
//argument is so world start can clear out any turf differences quickly.
/datum/excited_group/proc/self_breakdown(space_is_all_consuming = 0)
/datum/excited_group/proc/self_breakdown(space_is_all_consuming = FALSE)
var/datum/gas_mixture/A = new
//make local for sanic speed
var/list/A_gases = A.gases
var/list/turf_list = src.turf_list
var/turflen = turf_list.len
var/space_in_group = 0
var/space_in_group = FALSE
for(var/t in turf_list)
var/turf/open/T = t
if (space_is_all_consuming && !space_in_group && istype(T.air, /datum/gas_mixture/immutable/space))
space_in_group = 1
space_in_group = TRUE
qdel(A)
A = new/datum/gas_mixture/immutable/space()
A = new /datum/gas_mixture/immutable/space()
A_gases = A.gases //update the cache
break
A.merge(T.air)
for(var/id in A_gases)
A_gases[id][MOLES] = A_gases[id][MOLES]/turflen
A_gases[id][MOLES] /= turflen
for(var/t in turf_list)
var/turf/open/T = t
@@ -359,8 +339,7 @@
/datum/excited_group/proc/dismantle()
for(var/t in turf_list)
var/turf/open/T = t
T.excited = 0
T.recently_active = 0
T.excited = FALSE
T.excited_group = null
SSair.active_turfs -= T
garbage_collect()
@@ -432,7 +411,7 @@
//Make sure still hot enough to continue conducting heat
if(temp < MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION)
SSair.active_super_conductivity -= src
return 0
return FALSE
/turf/open/finish_superconduction()
//Conduct with air on my tile if I have it
@@ -442,21 +421,21 @@
/turf/proc/consider_superconductivity()
if(!thermal_conductivity)
return 0
return FALSE
SSair.active_super_conductivity |= src
return 1
return TRUE
/turf/open/consider_superconductivity(starting)
if(air.temperature < (starting?MINIMUM_TEMPERATURE_START_SUPERCONDUCTION:MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION))
return 0
return FALSE
if(air.heat_capacity() < M_CELL_WITH_RATIO) // Was: MOLES_CELLSTANDARD*0.1*0.05 Since there are no variables here we can make this a constant.
return 0
return FALSE
return ..()
/turf/closed/consider_superconductivity(starting)
if(temperature < (starting?MINIMUM_TEMPERATURE_START_SUPERCONDUCTION:MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION))
return 0
return FALSE
return ..()
/turf/proc/radiate_to_spess() //Radiate excess tile heat to space
@@ -465,7 +444,7 @@
if((heat_capacity > 0) && (abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER))
var/heat = thermal_conductivity*delta_temperature* \
(heat_capacity*700000/(heat_capacity+700000)) //700000 is the heat_capacity from a space turf, hardcoded here
(heat_capacity*HEAT_CAPACITY_VACUUM/(heat_capacity+HEAT_CAPACITY_VACUUM))
temperature -= heat/heat_capacity
/turf/open/proc/temperature_share_open_to_solid(turf/sharer)
@@ -356,6 +356,9 @@
. = TRUE
if("threshold")
var/env = params["env"]
if(text2path(env))
env = text2path(env)
var/name = params["var"]
var/datum/tlv/tlv = TLV[env]
if(isnull(tlv))
@@ -1,7 +1,7 @@
/obj/machinery/atmospherics/components/unary/thermomachine
name = "thermomachine"
desc = "Heats or cools gas in connected pipes."
icon = 'icons/obj/Cryogenic2.dmi'
icon = 'icons/obj/atmospherics/components/thermomachine.dmi'
icon_state = "freezer"
var/icon_state_on = "cold_on"
var/icon_state_open = "cold_off"
@@ -160,7 +160,6 @@
/obj/machinery/atmospherics/components/unary/thermomachine/freezer
name = "freezer"
icon = 'icons/obj/Cryogenic2.dmi'
icon_state = "freezer"
icon_state_on = "freezer_1"
icon_state_open = "freezer-o"
@@ -177,7 +176,6 @@
/obj/machinery/atmospherics/components/unary/thermomachine/heater
name = "heater"
icon = 'icons/obj/Cryogenic2.dmi'
icon_state = "heater"
icon_state_on = "heater_1"
icon_state_open = "heater-o"
+8 -8
View File
@@ -204,7 +204,7 @@
brute_damage = 1000
/obj/effect/mob_spawn/human/alive
icon = 'icons/obj/Cryogenic2.dmi'
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
death = FALSE
roundstart = FALSE //you could use these for alive fake humans on roundstart but this is more common scenario
@@ -243,7 +243,7 @@
mob_type = /mob/living/simple_animal/mouse
death = FALSE
roundstart = FALSE
icon = 'icons/obj/Cryogenic2.dmi'
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
/obj/effect/mob_spawn/cow
@@ -252,7 +252,7 @@
death = FALSE
roundstart = FALSE
mob_gender = FEMALE
icon = 'icons/obj/Cryogenic2.dmi'
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
// I'll work on making a list of corpses people request for maps, or that I think will be commonly used. Syndicate operatives for example.
@@ -274,7 +274,7 @@
roundstart = FALSE
random = TRUE
name = "sleeper"
icon = 'icons/obj/Cryogenic2.dmi'
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
flavour_text = "You are a space doctor!"
assignedrole = "Space Doctor"
@@ -329,7 +329,7 @@
roundstart = FALSE
random = TRUE
name = "bartender sleeper"
icon = 'icons/obj/Cryogenic2.dmi'
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
flavour_text = "You are a space bartender!"
assignedrole = "Space Bartender"
@@ -353,7 +353,7 @@
random = TRUE
mob_name = "Beach Bum"
name = "beach bum sleeper"
icon = 'icons/obj/Cryogenic2.dmi'
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
flavour_text = "You are a beach bum!"
assignedrole = "Beach Bum"
@@ -431,7 +431,7 @@
roundstart = FALSE
mob_name = "Nanotrasen Commander"
name = "sleeper"
icon = 'icons/obj/Cryogenic2.dmi'
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
flavour_text = "You are a Nanotrasen Commander!"
@@ -440,7 +440,7 @@
roundstart = FALSE
mob_name = "Private Security Officer"
name = "sleeper"
icon = 'icons/obj/Cryogenic2.dmi'
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
faction = "nanotrasenprivate"
flavour_text = "You are a Nanotrasen Private Security Officer!"
@@ -229,7 +229,7 @@
/obj/effect/mob_spawn/human/syndicatesoldier/coldres/alive
name = "sleeper"
mob_name = "Syndicate Snow Operative"
icon = 'icons/obj/Cryogenic2.dmi'
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
roundstart = FALSE
death = FALSE
@@ -17,6 +17,8 @@
var/list/json = json_decode(file2text(json_file))
shenanigans = json["phrases"]
#define TIMEWASTE_MEDAL "Overextended The Joke"
/obj/structure/speaking_tile/interact(mob/user)
if(!isliving(user) || speaking)
return
@@ -45,11 +47,11 @@
SpeakPeace(list("Alright maybe that's <b>too</b> boring.", "I can't keep manually typing these lines out though.", "It's hard to explain but the code structure I'm using is kind of terrible."))
if(10)
SpeakPeace(list("Oh I have an idea!", "Lets outsource this endless banter to Poly!", "Then you'll be able to keep listening to this without getting bored!"))
if(isnull(shenanigans))
if(isnull(shenanigans) || !shenanigans.len)
shenanigans = list("Except the poly file is missing...")
if(11 to 14, 16 to 50, 52 to 99, 103 to 107, 109 to 203, 205 to 249, 252 to 665, 667 to 999, 1001 to 5642)
SpeakPeace(list(pick(shenanigans),pick(shenanigans),pick(shenanigans)))
if(times_spoken_to * 0.1 == round(times_spoken_to * 0.1))
if(times_spoken_to % 10 == 0)
SpeakPeace(list("That's [times_spoken_to] times you've spoken to me by the way."))
if(15)
SpeakPeace(list("See? Isn't this fun?","Now you can mash this for hours without getting bored.","Anyway I'll leave you it."))
@@ -79,6 +81,7 @@
if(1000)
SpeakPeace(list("The ends exists somewhere beyond meaningful milestones.", "There will be no more messages until then.", "You disgust me."))
if(5643)
UnlockMedal(TIMEWASTE_MEDAL,user.client)
var/obj/item/reagent_containers/food/drinks/trophy/gold_cup/never_ends = new(get_turf(user))
never_ends.name = "Overextending The Joke: First Place"
never_ends.desc = "And so we are left alone with our regrets."
@@ -87,7 +90,7 @@
speaking = FALSE
times_spoken_to++
#undef TIMEWASTE_MEDAL
/obj/structure/speaking_tile/proc/SpeakPeace(list/statements)
for(var/i in 1 to statements.len)
say("<span class='deadsay'>[statements[i]]</span>")
+6 -2
View File
@@ -442,7 +442,7 @@ GLOBAL_LIST(external_rsc_urls)
message_admins("<span class='adminnotice'>Failed Login: [key] - New account attempting to connect during panic bunker</span>")
to_chat(src, "Sorry but the server is currently not accepting connections from never before seen players.")
var/list/connectiontopic_a = params2list(connectiontopic)
var/list/panic_addr = CONFIG_GET(string/panic_address)
var/list/panic_addr = CONFIG_GET(string/panic_server_address)
if(panic_addr && !connectiontopic_a["redirect"])
var/panic_name = CONFIG_GET(string/panic_server_name)
to_chat(src, "<span class='notice'>Sending you to [panic_name ? panic_name : panic_addr].</span>")
@@ -663,6 +663,9 @@ GLOBAL_LIST(external_rsc_urls)
return FALSE
if ("key")
return FALSE
if("view")
change_view(var_value)
return TRUE
. = ..()
@@ -683,7 +686,8 @@ GLOBAL_LIST(external_rsc_urls)
/client/proc/apply_clickcatcher()
generate_clickcatcher()
void.UpdateGreed(view,view)
var/list/actualview = getviewsize(view)
void.UpdateGreed(actualview[1],actualview[2])
/client/proc/AnnouncePR(announcement)
if(prefs && prefs.chat_toggles & CHAT_PULLR)
+3
View File
@@ -72,6 +72,9 @@
if(!(M.failed_last_breath || M.losebreath))
lung_strength = "healthy"
if(M.stat == DEAD && heart && world.time - M.timeofdeath < DEFIB_TIME_LIMIT * 10)
heart_strength = "<span class='boldannounce'>a faint, fluttery</span>"
var/diagnosis = (body_part == "chest" ? "You hear [heart_strength] pulse and [lung_strength] respiration." : "You faintly hear [heart_strength] pulse.")
user.visible_message("[user] places [src] against [M]'s [body_part] and listens attentively.", "<span class='notice'>You place [src] against [M]'s [body_part]. [diagnosis]</span>")
return
@@ -1100,7 +1100,7 @@
/obj/item/clothing/head/helmet/space/hardsuit/flightsuit/proc/toggle_zoom(mob/living/user, force_off = FALSE)
if(zoom || force_off)
user.client.change_view(world.view)
user.client.change_view(CONFIG_GET(string/default_view))
to_chat(user, "<span class='boldnotice'>Disabling smart zooming image enhancement...</span>")
zoom = FALSE
return FALSE
+1 -3
View File
@@ -6,11 +6,9 @@
alertadmins = 0
/datum/round_event/camera_failure
startWhen = 1
endWhen = 2
fakeable = FALSE
/datum/round_event/camera_failure/tick()
/datum/round_event/camera_failure/start()
var/iterations = 1
var/obj/machinery/camera/C = pick(GLOB.cameranet.cameras)
while(prob(round(100/iterations)))
+13 -14
View File
@@ -11,29 +11,29 @@
/datum/round_event/wizard/cursed_items/start()
var/item_set = pick("wizardmimic", "swords", "bigfatdoobie", "boxing", "voicemodulators", "catgirls2015")
var/list/wearslots = list(slot_wear_suit, slot_shoes, slot_head, slot_wear_mask, slot_gloves, slot_ears)
var/list/loadout = list()
var/list/loadout[slots_amt]
var/ruins_spaceworthiness
var/ruins_wizard_loadout
loadout.len = 7
switch(item_set)
if("wizardmimic")
loadout = list(/obj/item/clothing/suit/wizrobe, /obj/item/clothing/shoes/sandal/magic, /obj/item/clothing/head/wizard)
loadout[slot_wear_suit] = /obj/item/clothing/suit/wizrobe
loadout[slot_shoes] = /obj/item/clothing/shoes/sandal/magic
loadout[slot_head] = /obj/item/clothing/head/wizard
ruins_spaceworthiness = 1
if("swords")
loadout[5] = /obj/item/katana/cursed
loadout[slot_hands] = /obj/item/katana/cursed
if("bigfatdoobie")
loadout[4] = /obj/item/clothing/mask/cigarette/rollie/trippy
loadout[slot_wear_mask] = /obj/item/clothing/mask/cigarette/rollie/trippy
ruins_spaceworthiness = 1
if("boxing")
loadout[4] = /obj/item/clothing/mask/luchador
loadout[6] = /obj/item/clothing/gloves/boxing
loadout[slot_wear_mask] = /obj/item/clothing/mask/luchador
loadout[slot_gloves] = /obj/item/clothing/gloves/boxing
ruins_spaceworthiness = 1
if("voicemodulators")
loadout[4] = /obj/item/clothing/mask/chameleon
loadout[slot_wear_mask] = /obj/item/clothing/mask/chameleon
if("catgirls2015")
loadout[3] = /obj/item/clothing/head/kitty
loadout[slot_head] = /obj/item/clothing/head/kitty
ruins_spaceworthiness = 1
ruins_wizard_loadout = 1
@@ -44,14 +44,13 @@
continue
if(item_set == "catgirls2015") //Wizard code means never having to say you're sorry
H.gender = FEMALE
var/list/slots = list(H.wear_suit, H.shoes, H.head, H.wear_mask, H.gloves, H.ears) //add new slots as needed to back
for(var/i in 1 to loadout.len)
if(loadout[i])
var/obj/item/J = loadout[i]
var/obj/item/I = new J //dumb but required because of byond throwing a fit anytime new gets too close to a list
H.temporarilyRemoveItemFromInventory(slots[i], TRUE)
H.equip_to_slot_or_del(I, wearslots[i])
I.flags_1 |= NODROP_1
H.dropItemToGround(H.get_item_by_slot(i), TRUE)
H.equip_to_slot_or_del(I, i)
I.flags_1 |= NODROP_1 | DROPDEL_1
I.name = "cursed " + I.name
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
+3 -4
View File
@@ -6,12 +6,11 @@
earliest_start = 0
/datum/round_event/wizard/imposter/start()
for(var/datum/mind/M in SSticker.mode.wizards)
if(!ishuman(M.current))
continue
var/mob/living/carbon/human/W = M.current
var/list/candidates = get_candidates(ROLE_WIZARD)
var/list/candidates = pollGhostCandidates("Would you like to be an imposter wizard?", ROLE_WIZARD)
if(!candidates)
return //Sad Trombone
var/client/C = pick(candidates)
@@ -28,10 +27,10 @@
var/datum/antagonist/wizard/master = M.has_antag_datum(/datum/antagonist/wizard)
if(!master.wiz_team)
master.create_wiz_team()
var/datum/antagonist/wizard/apprentice/imposter = new(I.mind)
var/datum/antagonist/wizard/apprentice/imposter/imposter = new(I.mind)
imposter.master = M
imposter.wiz_team = master.wiz_team
master.wiz_team += imposter
master.wiz_team.add_member(imposter)
I.mind.add_antag_datum(imposter)
//Remove if possible
SSticker.mode.apprentices += I.mind
+1 -1
View File
@@ -22,7 +22,7 @@
for(var/mob/living/carbon/human/H in GLOB.carbon_list) //yes, even the dead
H.set_species(new_species)
H.real_name = new_species.random_name(H.gender,1)
H.real_name = H.dna.species.random_name(H.gender,1)
H.dna.unique_enzymes = H.dna.generate_unique_enzymes()
to_chat(H, "<span class='notice'>You feel somehow... different?</span>")
if(!all_the_same)
+16 -15
View File
@@ -115,6 +115,7 @@
I.Blend(B.broken_outline, ICON_OVERLAY, rand(5), 1)
I.SwapColor(rgb(255, 0, 220, 255), rgb(0, 0, 0, 0))
B.icon = I
B.name = "broken [name]"
if(prob(33))
new/obj/item/shard(drop_location())
playsound(src, "shatter", 70, 1)
@@ -186,7 +187,7 @@
// Formatting is the same as food.
/obj/item/reagent_containers/food/drinks/coffee
name = "Robust Coffee"
name = "robust coffee"
desc = "Careful, the beverage you're about to enjoy is extremely hot."
icon_state = "coffee"
list_reagents = list("coffee" = 30)
@@ -195,7 +196,7 @@
isGlass = FALSE
/obj/item/reagent_containers/food/drinks/ice
name = "Ice Cup"
name = "ice cup"
desc = "Careful, cold ice, do not chew."
icon_state = "coffee"
list_reagents = list("ice" = 30)
@@ -216,12 +217,12 @@
icon_state = "tea_empty"
/obj/item/reagent_containers/food/drinks/mug/tea
name = "Duke Purple Tea"
name = "Duke Purple tea"
desc = "An insult to Duke Purple is an insult to the Space Queen! Any proper gentleman will fight you, if you sully this tea."
list_reagents = list("tea" = 30)
/obj/item/reagent_containers/food/drinks/mug/coco
name = "Dutch Hot Coco"
name = "Dutch hot coco"
desc = "Made in Space South America."
list_reagents = list("hot_coco" = 30, "sugar" = 5)
foodtype = SUGAR
@@ -230,7 +231,7 @@
/obj/item/reagent_containers/food/drinks/dry_ramen
name = "Cup Ramen"
name = "cup ramen"
desc = "Just add 10ml of water, self heats! A taste that reminds you of your school years."
icon_state = "ramen"
list_reagents = list("dry_ramen" = 30)
@@ -238,7 +239,7 @@
isGlass = FALSE
/obj/item/reagent_containers/food/drinks/beer
name = "Space Beer"
name = "space beer"
desc = "Beer. In space."
icon_state = "beer"
list_reagents = list("beer" = 30)
@@ -282,7 +283,7 @@
I.Blend(B.broken_outline, ICON_OVERLAY, rand(5), 1)
I.SwapColor(rgb(255, 0, 220, 255), rgb(0, 0, 0, 0))
B.icon = I
B.name = "broken carton"
B.name = "broken [name]"
B.force = 0
B.throwforce = 0
B.desc = "A carton with the bottom half burst open. Might give you a papercut."
@@ -420,28 +421,28 @@
foodtype = SUGAR
/obj/item/reagent_containers/food/drinks/soda_cans/tonic
name = "T-Borg's Tonic Water"
name = "T-Borg's tonic water"
desc = "Quinine tastes funny, but at least it'll keep that Space Malaria away."
icon_state = "tonic"
list_reagents = list("tonic" = 50)
foodtype = ALCOHOL
/obj/item/reagent_containers/food/drinks/soda_cans/sodawater
name = "Soda Water"
name = "soda water"
desc = "A can of soda water. Why not make a scotch and soda?"
icon_state = "sodawater"
list_reagents = list("sodawater" = 50)
/obj/item/reagent_containers/food/drinks/soda_cans/lemon_lime
name = "Orange Soda"
name = "orange soda"
desc = "You wanted ORANGE. It gave you Lemon Lime."
icon_state = "lemon-lime"
list_reagents = list("lemon_lime" = 30)
foodtype = FRUIT
/obj/item/reagent_containers/food/drinks/soda_cans/lemon_lime/New()
..()
name = "Lemon-Lime Soda"
/obj/item/reagent_containers/food/drinks/soda_cans/lemon_lime/Initialize()
. = ..()
name = "lemon-lime soda"
/obj/item/reagent_containers/food/drinks/soda_cans/space_up
name = "Space-Up!"
@@ -485,14 +486,14 @@
list_reagents = list("pwr_game" = 30)
/obj/item/reagent_containers/food/drinks/soda_cans/shamblers
name = "Shambler's Juice"
name = "Shambler's juice"
desc = "~Shake me up some of that Shambler's Juice!~"
icon_state = "shamblers"
list_reagents = list("shamblers" = 30)
foodtype = SUGAR | JUNKFOOD
/obj/item/reagent_containers/food/drinks/soda_cans/air
name = "Canned Air"
name = "canned air"
desc = "There is no air shortage. Do not drink."
icon_state = "air"
list_reagents = list("nitrogen" = 24, "oxygen" = 6)
@@ -35,10 +35,10 @@
new/obj/item/shard(drop_location())
playsound(src, "shatter", 70, 1)
else
B.name = "broken carton"
B.force = 0
B.throwforce = 0
B.desc = "A carton with the bottom half burst open. Might give you a papercut."
B.name = "broken [name]"
transfer_fingerprints_to(B)
qdel(src)
@@ -119,7 +119,7 @@
//Keeping this here for now, I'll ask if I should keep it here.
/obj/item/broken_bottle
name = "Broken Bottle"
name = "broken bottle"
desc = "A bottle with a sharp broken bottom."
icon = 'icons/obj/drinks.dmi'
icon_state = "broken_bottle"
@@ -135,37 +135,37 @@
sharpness = IS_SHARP
/obj/item/reagent_containers/food/drinks/bottle/gin
name = "Griffeater Gin"
name = "Griffeater gin"
desc = "A bottle of high quality gin, produced in the New London Space Station."
icon_state = "ginbottle"
list_reagents = list("gin" = 100)
/obj/item/reagent_containers/food/drinks/bottle/whiskey
name = "Uncle Git's Special Reserve"
name = "Uncle Git's special reserve"
desc = "A premium single-malt whiskey, gently matured inside the tunnels of a nuclear shelter. TUNNEL WHISKEY RULES."
icon_state = "whiskeybottle"
list_reagents = list("whiskey" = 100)
/obj/item/reagent_containers/food/drinks/bottle/vodka
name = "Tunguska Triple Distilled"
name = "Tunguska triple distilled"
desc = "Aah, vodka. Prime choice of drink AND fuel by Russians worldwide."
icon_state = "vodkabottle"
list_reagents = list("vodka" = 100)
/obj/item/reagent_containers/food/drinks/bottle/vodka/badminka
name = "Badminka Vodka"
name = "Badminka vodka"
desc = "The label's written in Cyrillic. All you can make out is the name and a word that looks vaguely like 'Vodka'."
icon_state = "badminka"
list_reagents = list("vodka" = 100)
/obj/item/reagent_containers/food/drinks/bottle/tequila
name = "Caccavo Guaranteed Quality Tequila"
name = "Caccavo guaranteed quality tequila"
desc = "Made from premium petroleum distillates, pure thalidomide and other fine quality ingredients!"
icon_state = "tequilabottle"
list_reagents = list("tequila" = 100)
/obj/item/reagent_containers/food/drinks/bottle/bottleofnothing
name = "Bottle of Nothing"
name = "bottle of nothing"
desc = "A bottle filled with nothing."
icon_state = "bottleofnothing"
list_reagents = list("nothing" = 100)
@@ -178,13 +178,13 @@
list_reagents = list("patron" = 100)
/obj/item/reagent_containers/food/drinks/bottle/rum
name = "Captain Pete's Cuban Spiced Rum"
name = "Captain Pete's Cuban spiced rum"
desc = "This isn't just rum, oh no. It's practically GRIFF in a bottle."
icon_state = "rumbottle"
list_reagents = list("rum" = 100)
/obj/item/reagent_containers/food/drinks/bottle/holywater
name = "Flask of Holy Water"
name = "flask of holy water"
desc = "A flask of the chaplain's holy water."
icon_state = "holyflask"
list_reagents = list("holywater" = 100)
@@ -195,39 +195,39 @@
list_reagents = list("hell_water" = 100)
/obj/item/reagent_containers/food/drinks/bottle/vermouth
name = "Goldeneye Vermouth"
name = "Goldeneye vermouth"
desc = "Sweet, sweet dryness~"
icon_state = "vermouthbottle"
list_reagents = list("vermouth" = 100)
/obj/item/reagent_containers/food/drinks/bottle/kahlua
name = "Robert Robust's Coffee Liqueur"
name = "Robert Robust's coffee liqueur"
desc = "A widely known, Mexican coffee-flavoured liqueur. In production since 1936, HONK."
icon_state = "kahluabottle"
list_reagents = list("kahlua" = 100)
foodtype = VEGETABLES
/obj/item/reagent_containers/food/drinks/bottle/goldschlager
name = "College Girl Goldschlager"
name = "College Girl goldschlager"
desc = "Because they are the only ones who will drink 100 proof cinnamon schnapps."
icon_state = "goldschlagerbottle"
list_reagents = list("goldschlager" = 100)
/obj/item/reagent_containers/food/drinks/bottle/cognac
name = "Chateau De Baton Premium Cognac"
name = "Chateau de Baton premium cognac"
desc = "A sweet and strongly alchoholic drink, made after numerous distillations and years of maturing. You might as well not scream 'SHITCURITY' this time."
icon_state = "cognacbottle"
list_reagents = list("cognac" = 100)
/obj/item/reagent_containers/food/drinks/bottle/wine
name = "Doublebeard Bearded Special Wine"
name = "Doublebeard's bearded special wine"
desc = "A faint aura of unease and asspainery surrounds the bottle."
icon_state = "winebottle"
list_reagents = list("wine" = 100)
foodtype = FRUIT | ALCOHOL
/obj/item/reagent_containers/food/drinks/bottle/absinthe
name = "Extra-Strong Absinthe"
name = "extra-strong absinthe"
desc = "An strong alcoholic drink brewed and distributed by"
icon_state = "absinthebottle"
list_reagents = list("absinthe" = 100)
@@ -272,7 +272,7 @@
/obj/item/reagent_containers/food/drinks/bottle/absinthe/premium
name = "Gwyn's Premium Absinthe"
name = "Gwyn's premium absinthe"
desc = "A potent alcoholic beverage, almost makes you forget the ash in your lungs."
icon_state = "absinthepremium"
@@ -280,7 +280,7 @@
return
/obj/item/reagent_containers/food/drinks/bottle/lizardwine
name = "Bottle of lizard wine"
name = "bottle of lizard wine"
desc = "An alcoholic beverage from Space China, made by infusing lizard tails in ethanol. Inexplicably popular among command staff."
icon_state = "lizardwine"
list_reagents = list("lizardwine" = 100)
@@ -302,7 +302,7 @@
//////////////////////////JUICES AND STUFF ///////////////////////
/obj/item/reagent_containers/food/drinks/bottle/orangejuice
name = "Orange Juice"
name = "orange juice"
desc = "Full of vitamins and deliciousness!"
icon_state = "orangejuice"
item_state = "carton"
@@ -313,7 +313,7 @@
foodtype = FRUIT
/obj/item/reagent_containers/food/drinks/bottle/cream
name = "Milk Cream"
name = "milk cream"
desc = "It's cream. Made from milk. What else did you think you'd find in there?"
icon_state = "cream"
item_state = "carton"
@@ -324,7 +324,7 @@
foodtype = DAIRY
/obj/item/reagent_containers/food/drinks/bottle/tomatojuice
name = "Tomato Juice"
name = "tomato juice"
desc = "Well, at least it LOOKS like tomato juice. You can't tell with all that redness."
icon_state = "tomatojuice"
item_state = "carton"
@@ -335,7 +335,7 @@
foodtype = VEGETABLES
/obj/item/reagent_containers/food/drinks/bottle/limejuice
name = "Lime Juice"
name = "lime juice"
desc = "Sweet-sour goodness."
icon_state = "limejuice"
item_state = "carton"
@@ -380,7 +380,7 @@
foodtype = VEGETABLES | FRIED | DAIRY
/obj/item/reagent_containers/food/snacks/cubannachos
name = "cuban nachos"
name = "Cuban nachos"
desc = "That's some dangerously spicy nachos."
icon_state = "cubannachos"
bonus_reagents = list("nutriment" = 2, "vitamin" = 3)
@@ -4,7 +4,7 @@
/obj/item/reagent_containers/food/snacks/donut
name = "donut"
desc = "Goes great with Robust Coffee."
desc = "Goes great with robust coffee."
icon_state = "donut1"
bitesize = 5
bonus_reagents = list("sugar" = 1)
@@ -253,6 +253,9 @@ em {font-style: normal; font-weight: bold;}
.say {}
.deadsay {color: #5c00e6;}
.binarysay {color: #20c20e; background-color: #000000; display: block;}
.binarysay a {color: #00ff00;}
.binarysay a:active, .binarysay a:visited {color: #88ff88;}
.radio {color: #008000;}
.sciradio {color: #993399;}
.comradio {color: #948f02;}
+1 -1
View File
@@ -1,7 +1,7 @@
/obj/machinery/biogenerator
name = "biogenerator"
desc = "Converts plants into biomass, which can be used to construct useful items."
icon = 'icons/obj/biogenerator.dmi'
icon = 'icons/obj/machines/biogenerator.dmi'
icon_state = "biogen-empty"
density = TRUE
anchored = TRUE
+2 -2
View File
@@ -16,9 +16,9 @@
randomize_stats()
..()
if(prob(60))
add_random_reagents()
add_random_reagents(1, 3)
if(prob(50))
add_random_traits()
add_random_traits(1, 2)
add_random_plant_type(35)
/obj/item/reagent_containers/food/snacks/grown/random
+1 -1
View File
@@ -375,7 +375,7 @@
pocell.maxcharge *= CG.rate*1000
pocell.charge = pocell.maxcharge
pocell.name = "[G.name] battery"
pocell.desc = "A rechargeable plant based power cell. This one has a power rating of [DisplayPower(pocell.maxcharge)], and you should not swallow it."
pocell.desc = "A rechargeable plant-based power cell. This one has a rating of [DisplayEnergy(pocell.maxcharge)], and you should not swallow it."
if(G.reagents.has_reagent("plasma", 2))
pocell.rigged = 1
@@ -13,7 +13,7 @@
/obj/item/integrated_circuit/passive/power/solar_cell
name = "tiny photovoltaic cell"
desc = "It's a very tiny solar cell, generally used in calculators."
extended_desc = "The cell generates 1W of power per second in optimal lighting conditions. Less light will result in less power being generated."
extended_desc = "The cell generates 1 W of power in optimal lighting conditions. Less light will result in less power being generated."
icon_state = "solar_cell"
complexity = 8
origin_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 3, TECH_DATA = 2)
+3 -3
View File
@@ -320,7 +320,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(mind.current.key && copytext(mind.current.key,1,2)!="@") //makes sure we don't accidentally kick any clients
to_chat(usr, "<span class='warning'>Another consciousness is in your body...It is resisting you.</span>")
return
client.change_view(world.view)
client.change_view(CONFIG_GET(string/default_view))
SStgui.on_transfer(src, mind.current) // Transfer NanoUIs.
mind.current.key = key
return 1
@@ -456,7 +456,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set desc = "Change your view range."
var/max_view = client.prefs.unlock_content ? GHOST_MAX_VIEW_RANGE_MEMBER : GHOST_MAX_VIEW_RANGE_DEFAULT
if(client.view == world.view)
if(client.view == CONFIG_GET(string/default_view))
var/list/views = list()
for(var/i in 7 to max_view)
views |= i
@@ -464,7 +464,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(new_view)
client.change_view(Clamp(new_view, 7, max_view))
else
client.change_view(world.view)
client.change_view(CONFIG_GET(string/default_view))
/mob/dead/observer/verb/add_view_range(input as num)
set name = "Add View Range"
+21 -21
View File
@@ -37,36 +37,36 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
//kinda localization -- rastaf0
//same keys as above, but on russian keyboard layout. This file uses cp1251 as encoding.
// Location
"ê" = "right hand",
"ä" = "left hand",
"ø" = "intercom",
"ê" = "right hand",
"ä" = "left hand",
"ø" = "intercom",
// Department
"ð" = "department",
"ñ" = "Command",
"ò" = "Science",
"ü" = "Medical",
"ó" = "Engineering",
"û" = "Security",
"ã" = "Supply",
"ì" = "Service",
"ð" = "department",
"ñ" = "Command",
"ò" = "Science",
"ü" = "Medical",
"ó" = "Engineering",
"û" = "Security",
"ã" = "Supply",
"ì" = "Service",
// Faction
"å" = "Syndicate",
"í" = "CentCom",
"å" = "Syndicate",
"í" = "CentCom",
// Species
"è" = "binary",
"ï" = "changeling",
"ô" = "alientalk",
"è" = "binary",
"ï" = "changeling",
"ô" = "alientalk",
// Admin
"ç" = "admin",
"â" = "deadmin",
"ç" = "admin",
"â" = "deadmin",
// Misc
"ù" = "AI Private",
"÷" = "cords"
"ù" = "AI Private",
"÷" = "cords"
))
/mob/living/say(message, bubble_type,var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE)
@@ -137,7 +137,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
var/datum/saymode/SM = SSradio.saymodes[key]
if(key && SM)
if(!SM.handle_message(src, message, language))
if(!SM.handle_message(src, message, language) && !message_mode)
return
+2 -1
View File
@@ -817,7 +817,8 @@
return (GLOB.cameranet && GLOB.cameranet.checkTurfVis(get_turf_pixel(A))) || apc_override
//AI is carded/shunted
//view(src) returns nothing for carded/shunted AIs and they have x-ray vision so just use get_dist
return get_dist(src, A) <= client.view
var/list/viewscale = getviewsize(client.view)
return get_dist(src, A) <= max(viewscale[1]*0.5,viewscale[2]*0.5)
/mob/living/silicon/ai/proc/relay_speech(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode)
raw_message = lang_treat(speaker, message_language, raw_message, spans, message_mode)

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