Merge branch 'master' into AllMapChangesInOne
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
#define WACKY "Wacky"
|
||||
#define MUT_MUTE "Mute"
|
||||
#define SMILE "Smile"
|
||||
#define STONER "Stoner"
|
||||
#define UNINTELLIGABLE "Unintelligable"
|
||||
#define SWEDISH "Swedish"
|
||||
#define CHAV "Chav"
|
||||
|
||||
@@ -14,6 +14,7 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
|
||||
#define NOBLUDGEON 4 // when an item has this it produces no "X has been hit by Y with Z" message in the default attackby()
|
||||
#define MASKINTERNALS 8 // mask allows internals
|
||||
#define HEAR 16 // This flag is what recursive_hear_check() uses to determine wether to add an item to the hearer list or not.
|
||||
#define CHECK_RICOCHET 32 // Projectiels will check ricochet on things impacted that have this.
|
||||
#define CONDUCT 64 // conducts electricity (metal etc.)
|
||||
#define ABSTRACT 128 // for all things that are technically items but used for various different stuff, made it 128 because it could conflict with other flags other way
|
||||
#define NODECONSTRUCT 128 // For machines and structures that should not break into parts, eg, holodeck stuff
|
||||
@@ -57,6 +58,7 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
|
||||
#define UNUSED_TRANSIT_TURF 2
|
||||
#define CAN_BE_DIRTY 4 //If a turf can be made dirty at roundstart. This is also used in areas.
|
||||
#define NO_DEATHRATTLE 16 // Do not notify deadchat about any deaths that occur on this turf.
|
||||
//#define CHECK_RICOCHET 32 //Same thing as atom flag.
|
||||
|
||||
/*
|
||||
These defines are used specifically with the atom/pass_flags bitmask
|
||||
|
||||
@@ -51,8 +51,10 @@
|
||||
#define LIGHT_COLOR_GREEN "#64C864" //Bright but quickly dissipating neon green. rgb(100, 200, 100)
|
||||
#define LIGHT_COLOR_BLUE "#6496FA" //Cold, diluted blue. rgb(100, 150, 250)
|
||||
|
||||
#define LIGHT_COLOR_BLUEGREEN "#7DE1AF" //Light blueish green. rgb(125, 225, 175)
|
||||
#define LIGHT_COLOR_CYAN "#7DE1E1" //Diluted cyan. rgb(125, 225, 225)
|
||||
#define LIGHT_COLOR_LIGHT_CYAN "#40CEFF" //More-saturated cyan. rgb(64, 206, 255)
|
||||
#define LIGHT_COLOR_DARK_BLUE "#6496FA" //Saturated blue. rgb(51, 117, 248)
|
||||
#define LIGHT_COLOR_PINK "#E17DE1" //Diluted, mid-warmth pink. rgb(225, 125, 225)
|
||||
#define LIGHT_COLOR_YELLOW "#E1E17D" //Dimmed yellow, leaning kaki. rgb(225, 225, 125)
|
||||
#define LIGHT_COLOR_BROWN "#966432" //Clear brown, mostly dim. rgb(150, 100, 50)
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
//Investigate logging defines
|
||||
#define INVESTIGATE_ATMOS "atmos"
|
||||
#define INVESTIGATE_BOTANY "botany"
|
||||
#define INVESTIGATE_CARGO "cargo"
|
||||
#define INVESTIGATE_EXPERIMENTOR "experimentor"
|
||||
#define INVESTIGATE_GRAVITY "gravity"
|
||||
#define INVESTIGATE_RECORDS "records"
|
||||
#define INVESTIGATE_SINGULO "singulo"
|
||||
#define INVESTIGATE_SUPERMATTER "supermatter"
|
||||
#define INVESTIGATE_TELESCI "telesci"
|
||||
#define INVESTIGATE_WIRES "wires"
|
||||
|
||||
//Individual logging defines
|
||||
#define INDIVIDUAL_ATTACK_LOG "Attack log"
|
||||
#define INDIVIDUAL_SAY_LOG "Say log"
|
||||
#define INDIVIDUAL_EMOTE_LOG "Emote log"
|
||||
#define INDIVIDUAL_OOC_LOG "OOC log"
|
||||
#define INDIVIDUAL_SHOW_ALL_LOG "All logs"
|
||||
@@ -34,8 +34,8 @@ Last space-z level = empty
|
||||
#define MAP_REMOVE_JOB(jobpath) /datum/job/##jobpath/map_check() { return (SSmapping.config.map_name != JOB_MODIFICATION_MAP_NAME) && ..() }
|
||||
|
||||
//zlevel defines, can be overridden for different maps in the appropriate _maps file.
|
||||
#define ZLEVEL_STATION 1
|
||||
#define ZLEVEL_CENTCOM 2
|
||||
#define ZLEVEL_CENTCOM 1
|
||||
#define ZLEVEL_STATION 2
|
||||
#define ZLEVEL_MINING 5
|
||||
#define ZLEVEL_LAVALAND 5
|
||||
#define ZLEVEL_EMPTY_SPACE 11
|
||||
|
||||
@@ -4,6 +4,19 @@
|
||||
// #define EAST 4
|
||||
// #define WEST 8
|
||||
|
||||
//These get to go at the top, because they're special
|
||||
//You can use these defines to get the typepath of the currently running proc/verb (yes procs + verbs are objects)
|
||||
/* eg:
|
||||
/mob/living/carbon/human/death()
|
||||
world << THIS_PROC_TYPE_STR //You can only output the string versions
|
||||
Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a string with () (eg: the _WITH_ARGS defines) to make it look nicer)
|
||||
*/
|
||||
#define THIS_PROC_TYPE .....
|
||||
#define THIS_PROC_TYPE_STR "[THIS_PROC_TYPE]" //Because you can only obtain a string of THIS_PROC_TYPE using "[]", and it's nice to just +/+= strings
|
||||
#define THIS_PROC_TYPE_STR_WITH_ARGS "[THIS_PROC_TYPE]([args.Join(",")])"
|
||||
#define THIS_PROC_TYPE_WEIRD ...... //This one is WEIRD, in some cases (When used in certain defines? (eg: ASSERT)) THIS_PROC_TYPE will fail to work, but THIS_PROC_TYPE_WEIRD will work instead
|
||||
#define THIS_PROC_TYPE_WEIRD_STR "[THIS_PROC_TYPE_WEIRD]" //Included for completeness
|
||||
#define THIS_PROC_TYPE_WEIRD_STR_WITH_ARGS "[THIS_PROC_TYPE_WEIRD]([args.Join(",")])" //Ditto
|
||||
|
||||
#define MIDNIGHT_ROLLOVER 864000 //number of deciseconds in a day
|
||||
|
||||
@@ -411,3 +424,9 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
|
||||
#define NO_FIELD 0
|
||||
#define FIELD_TURF 1
|
||||
#define FIELD_EDGE 2
|
||||
|
||||
//gibtonite state defines
|
||||
#define GIBTONITE_UNSTRUCK 0
|
||||
#define GIBTONITE_ACTIVE 1
|
||||
#define GIBTONITE_STABLE 2
|
||||
#define GIBTONITE_DETONATE 3
|
||||
@@ -114,13 +114,6 @@
|
||||
#define SNPC_MARTYR 3
|
||||
#define SNPC_PSYCHO 4
|
||||
|
||||
//Individual logging defines
|
||||
#define INDIVIDUAL_ATTACK_LOG "Attack log"
|
||||
#define INDIVIDUAL_SAY_LOG "Say log"
|
||||
#define INDIVIDUAL_EMOTE_LOG "Emote log"
|
||||
#define INDIVIDUAL_OOC_LOG "OOC log"
|
||||
#define INDIVIDUAL_SHOW_ALL_LOG "All logs"
|
||||
|
||||
#define TK_MAXRANGE 15
|
||||
|
||||
#define NO_SLIP_WHEN_WALKING 1
|
||||
@@ -131,3 +124,8 @@
|
||||
#define MAX_CHICKENS 50
|
||||
|
||||
#define UNHEALING_EAR_DAMAGE 100
|
||||
|
||||
|
||||
#define INCORPOREAL_MOVE_BASIC 1
|
||||
#define INCORPOREAL_MOVE_SHADOW 2 // leaves a trail of shadows
|
||||
#define INCORPOREAL_MOVE_JAUNT 3 // is blocked by holy water/salt
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
|
||||
// Subsystem init_order, from highest priority to lowest priority
|
||||
// Subsystems shutdown in the reverse of the order they initialize in
|
||||
// The numbers just define the ordering, they are meaningless otherwise.
|
||||
|
||||
#define INIT_ORDER_SERVER_MAINT 16
|
||||
@@ -71,4 +72,4 @@
|
||||
#define RUNLEVEL_GAME 4
|
||||
#define RUNLEVEL_POSTGAME 8
|
||||
|
||||
#define RUNLEVELS_DEFAULT (RUNLEVEL_SETUP | RUNLEVEL_GAME | RUNLEVEL_POSTGAME)
|
||||
#define RUNLEVELS_DEFAULT (RUNLEVEL_SETUP | RUNLEVEL_GAME | RUNLEVEL_POSTGAME)
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
#define WIRE_AI "AI Connection"
|
||||
#define WIRE_ALARM "Alarm"
|
||||
#define WIRE_AVOIDANCE "Avoidance"
|
||||
#define WIRE_BACKUP1 "Auxillary Power 1"
|
||||
#define WIRE_BACKUP2 "Auxillary Power 2"
|
||||
#define WIRE_BACKUP1 "Auxiliary Power 1"
|
||||
#define WIRE_BACKUP2 "Auxiliary Power 2"
|
||||
#define WIRE_BEACON "Beacon"
|
||||
#define WIRE_BOLTS "Bolts"
|
||||
#define WIRE_BOOM "Boom"
|
||||
|
||||
@@ -167,23 +167,14 @@
|
||||
underlay_appearance.icon = fixed_underlay["icon"]
|
||||
underlay_appearance.icon_state = fixed_underlay["icon_state"]
|
||||
else
|
||||
var/turf/T = get_step(src, turn(adjacencies, 180))
|
||||
if(T && (T.density || T.smooth))
|
||||
var/turned_adjacency = turn(adjacencies, 180)
|
||||
var/turf/T = get_step(src, turned_adjacency)
|
||||
if(!T.get_smooth_underlay_icon(underlay_appearance, src, turned_adjacency))
|
||||
T = get_step(src, turn(adjacencies, 135))
|
||||
if(T && (T.density || T.smooth))
|
||||
if(!T.get_smooth_underlay_icon(underlay_appearance, src, turned_adjacency))
|
||||
T = get_step(src, turn(adjacencies, 225))
|
||||
|
||||
if(isspaceturf(T) && !istype(T, /turf/open/space/transit))
|
||||
underlay_appearance.icon = 'icons/turf/space.dmi'
|
||||
underlay_appearance.icon_state = SPACE_ICON_STATE
|
||||
underlay_appearance.plane = PLANE_SPACE
|
||||
else if(T && !T.density && !T.smooth)
|
||||
underlay_appearance.icon = T.icon
|
||||
underlay_appearance.icon_state = T.icon_state
|
||||
else if(baseturf && !initial(baseturf.density) && !initial(baseturf.smooth))
|
||||
underlay_appearance.icon = initial(baseturf.icon)
|
||||
underlay_appearance.icon_state = initial(baseturf.icon_state)
|
||||
else
|
||||
//if all else fails, ask our own turf
|
||||
if(!T.get_smooth_underlay_icon(underlay_appearance, src, turned_adjacency) && !get_smooth_underlay_icon(underlay_appearance, src, turned_adjacency))
|
||||
underlay_appearance.icon = DEFAULT_UNDERLAY_ICON
|
||||
underlay_appearance.icon_state = DEFAULT_UNDERLAY_ICON_STATE
|
||||
underlays = U
|
||||
|
||||
+16
-2
@@ -130,6 +130,22 @@ GLOBAL_LIST_INIT(sqrtTable, list(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4,
|
||||
var/t = round((val - min) / d)
|
||||
return val - (t * d)
|
||||
|
||||
#define NORM_ROT(rot) ((((rot % 360) + (rot - round(rot, 1))) > 0) ? ((rot % 360) + (rot - round(rot, 1))) : (((rot % 360) + (rot - round(rot, 1))) + 360))
|
||||
|
||||
/proc/get_angle_of_incidence(face_angle, angle_in, auto_normalize = TRUE)
|
||||
|
||||
var/angle_in_s = NORM_ROT(angle_in)
|
||||
var/face_angle_s = NORM_ROT(face_angle)
|
||||
var/incidence = face_angle_s - angle_in_s
|
||||
var/incidence_s = incidence
|
||||
while(incidence_s < -90)
|
||||
incidence_s += 180
|
||||
while(incidence_s > 90)
|
||||
incidence_s -= 180
|
||||
if(auto_normalize)
|
||||
return incidence_s
|
||||
else
|
||||
return incidence
|
||||
|
||||
//A logarithm that converts an integer to a number scaled between 0 and 1 (can be tweaked to be higher).
|
||||
//Currently, this is used for hydroponics-produce sprite transforming, but could be useful for other transform functions.
|
||||
@@ -141,8 +157,6 @@ GLOBAL_LIST_INIT(sqrtTable, list(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4,
|
||||
return size_factor + scaling_modifier //scale mod of 0 results in a number from 0 to 1. A scale modifier of +0.5 returns 0.5 to 1.5
|
||||
//to_chat(world, "Transform multiplier of [src] is [size_factor + scaling_modifer]")
|
||||
|
||||
|
||||
|
||||
//converts a uniform distributed random number into a normal distributed one
|
||||
//since this method produces two random numbers, one is saved for subsequent calls
|
||||
//(making the cost negligble for every second call)
|
||||
|
||||
@@ -1079,18 +1079,17 @@ B --><-- A
|
||||
return L
|
||||
|
||||
//similar function to RANGE_TURFS(), but will search spiralling outwards from the center (like the above, but only turfs)
|
||||
/proc/spiral_range_turfs(dist=0, center=usr, orange=0)
|
||||
/proc/spiral_range_turfs(dist=0, center=usr, orange=0, list/outlist = list(), tick_checked)
|
||||
outlist.Cut()
|
||||
if(!dist)
|
||||
if(!orange)
|
||||
return list(center)
|
||||
else
|
||||
return list()
|
||||
outlist += center
|
||||
return outlist
|
||||
|
||||
var/turf/t_center = get_turf(center)
|
||||
if(!t_center)
|
||||
return list()
|
||||
return outlist
|
||||
|
||||
var/list/L = list()
|
||||
var/list/L = outlist
|
||||
var/turf/T
|
||||
var/y
|
||||
var/x
|
||||
@@ -1128,6 +1127,8 @@ B --><-- A
|
||||
if(T)
|
||||
L += T
|
||||
c_dist++
|
||||
if(tick_checked)
|
||||
CHECK_TICK
|
||||
|
||||
return L
|
||||
|
||||
|
||||
@@ -22,12 +22,12 @@ GLOBAL_VAR_INIT(tinted_weldhelh, TRUE)
|
||||
// Debug2 is used in conjunction with a lot of admin verbs and therefore is actually legit.
|
||||
GLOBAL_VAR_INIT(Debug, FALSE) // global debug switch
|
||||
GLOBAL_VAR_INIT(Debug2, FALSE)
|
||||
|
||||
//This was a define, but I changed it to a variable so it can be changed in-game.(kept the all-caps definition because... code...) -Errorage
|
||||
GLOBAL_VAR_INIT(MAX_EX_DEVESTATION_RANGE, 3)
|
||||
GLOBAL_VAR_INIT(MAX_EX_HEAVY_RANGE, 7)
|
||||
GLOBAL_VAR_INIT(MAX_EX_LIGHT_RANGE, 14)
|
||||
GLOBAL_VAR_INIT(MAX_EX_FLASH_RANGE, 14)
|
||||
GLOBAL_VAR_INIT(MAX_EX_FLAME_RANGE, 14)
|
||||
GLOBAL_VAR_INIT(DYN_EX_SCALE, 0.5)
|
||||
|
||||
|
||||
//This was a define, but I changed it to a variable so it can be changed in-game.(kept the all-caps definition because... code...) -Errorage
|
||||
GLOBAL_VAR_INIT(MAX_EX_DEVESTATION_RANGE, 3)
|
||||
GLOBAL_VAR_INIT(MAX_EX_HEAVY_RANGE, 7)
|
||||
GLOBAL_VAR_INIT(MAX_EX_LIGHT_RANGE, 14)
|
||||
GLOBAL_VAR_INIT(MAX_EX_FLASH_RANGE, 14)
|
||||
GLOBAL_VAR_INIT(MAX_EX_FLAME_RANGE, 14)
|
||||
GLOBAL_VAR_INIT(DYN_EX_SCALE, 0.5)
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
if(next_move > world.time) // in the year 2000...
|
||||
return
|
||||
|
||||
if(A.IsObscured())
|
||||
if(!modifiers["catcher"] && A.IsObscured())
|
||||
return
|
||||
|
||||
if(istype(loc,/obj/mecha))
|
||||
@@ -119,7 +119,7 @@
|
||||
//User itself, current loc, and user inventory
|
||||
if(DirectAccess(A))
|
||||
if(W)
|
||||
melee_item_attack_chain(src,W,A,params)
|
||||
W.melee_attack_chain(src, A, params)
|
||||
else
|
||||
if(ismob(A))
|
||||
changeNext_move(CLICK_CD_MELEE)
|
||||
@@ -133,7 +133,7 @@
|
||||
//Standard reach turf to turf or reaching inside storage
|
||||
if(CanReach(A,W))
|
||||
if(W)
|
||||
melee_item_attack_chain(src,W,A,params)
|
||||
W.melee_attack_chain(src, A, params)
|
||||
else
|
||||
if(ismob(A))
|
||||
changeNext_move(CLICK_CD_MELEE)
|
||||
@@ -325,8 +325,6 @@
|
||||
|
||||
/mob/living/carbon/human/CtrlClick(mob/user)
|
||||
if(ishuman(user) && Adjacent(user))
|
||||
if(world.time < user.next_move)
|
||||
return FALSE
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.dna.species.grab(H, src, H.mind.martial_art)
|
||||
H.changeNext_move(CLICK_CD_MELEE)
|
||||
@@ -448,6 +446,7 @@
|
||||
C.swap_hand()
|
||||
else
|
||||
var/turf/T = params2turf(modifiers["screen-loc"], get_turf(usr))
|
||||
params += "&catcher=1"
|
||||
if(T)
|
||||
T.Click(location, control, params)
|
||||
. = 1
|
||||
@@ -466,4 +465,4 @@
|
||||
view = -1
|
||||
else
|
||||
view = 1
|
||||
add_view_range(view)
|
||||
add_view_range(view)
|
||||
@@ -71,7 +71,7 @@
|
||||
|
||||
// cyborgs are prohibited from using storage items so we can I think safely remove (A.loc in contents)
|
||||
if(A == loc || (A in loc) || (A in contents))
|
||||
melee_item_attack_chain(src, W, A, params)
|
||||
W.melee_attack_chain(src, A, params)
|
||||
return
|
||||
|
||||
if(!isturf(loc))
|
||||
@@ -80,7 +80,7 @@
|
||||
// cyborgs are prohibited from using storage items so we can I think safely remove (A.loc && isturf(A.loc.loc))
|
||||
if(isturf(A) || isturf(A.loc))
|
||||
if(A.Adjacent(src)) // see adjacent.dm
|
||||
melee_item_attack_chain(src, W, A, params)
|
||||
W.melee_attack_chain(src, A, params)
|
||||
return
|
||||
else
|
||||
W.afterattack(A, src, 0, params)
|
||||
|
||||
@@ -271,8 +271,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
|
||||
|
||||
/obj/screen/alert/bloodsense/Initialize()
|
||||
. = ..()
|
||||
if(!narnar)
|
||||
narnar = new('icons/mob/screen_alert.dmi', "mini_nar")
|
||||
narnar = new('icons/mob/screen_alert.dmi', "mini_nar")
|
||||
START_PROCESSING(SSprocessing, src)
|
||||
|
||||
/obj/screen/alert/bloodsense/Destroy()
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
|
||||
/proc/melee_item_attack_chain(mob/user, obj/item/I, atom/target, params)
|
||||
if(I.pre_attackby(target, user, params))
|
||||
/obj/item/proc/melee_attack_chain(mob/user, atom/target, params)
|
||||
if(pre_attackby(target, user, params))
|
||||
// Return 1 in attackby() to prevent afterattack() effects (when safely moving items for example)
|
||||
var/resolved = target.attackby(I,user,params)
|
||||
if(!resolved && target && I)
|
||||
I.afterattack(target, user, 1, params) // 1: clicking something Adjacent
|
||||
var/resolved = target.attackby(src, user, params)
|
||||
if(!resolved && target && !QDELETED(src))
|
||||
afterattack(target, user, 1, params) // 1: clicking something Adjacent
|
||||
|
||||
|
||||
// Called when the item is in the active hand, and clicked; alternately, there is an 'activate held object' verb or you can hit pagedown.
|
||||
|
||||
@@ -124,7 +124,8 @@
|
||||
|
||||
if(!isturf(target) && istype(focus,/obj/item) && target.Adjacent(focus))
|
||||
apply_focus_overlay()
|
||||
melee_item_attack_chain(tk_user, focus, target, params) //isn't copying the attack chain fun. we should do it more often.
|
||||
var/obj/item/I = focus
|
||||
I.melee_attack_chain(tk_user, target, params) //isn't copying the attack chain fun. we should do it more often.
|
||||
if(check_if_focusable(focus))
|
||||
focus.do_attack_animation(target, null, focus)
|
||||
else
|
||||
|
||||
@@ -177,7 +177,8 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
to_chat(world, "<span class='boldannounce'>[msg]</span>")
|
||||
log_world(msg)
|
||||
|
||||
SetRunLevel(1)
|
||||
if (!current_runlevel)
|
||||
SetRunLevel(1)
|
||||
|
||||
// Sort subsystems by display setting for easy access.
|
||||
sortTim(subsystems, /proc/cmp_subsystem_display)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
SUBSYSTEM_DEF(blackbox)
|
||||
name = "Blackbox"
|
||||
wait = 6000
|
||||
flags = SS_NO_TICK_CHECK | SS_NO_INIT
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
flags = SS_NO_TICK_CHECK | SS_NO_INIT
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
|
||||
var/list/msg_common = list()
|
||||
var/list/msg_science = list()
|
||||
@@ -86,12 +86,11 @@ SUBSYSTEM_DEF(blackbox)
|
||||
|
||||
if (!SSdbcore.Connect())
|
||||
return
|
||||
|
||||
|
||||
var/list/sqlrowlist = list()
|
||||
|
||||
for (var/datum/feedback_variable/FV in feedback)
|
||||
sqlrowlist += list("time" = "Now()", "round_id" = GLOB.round_id, "var_name" = "'[sanitizeSQL(FV.get_variable())]'", "var_value" = FV.get_value(), "details" = "'[sanitizeSQL(FV.get_details())]'")
|
||||
|
||||
sqlrowlist += list(list("time" = "Now()", "round_id" = GLOB.round_id, "var_name" = "'[sanitizeSQL(FV.get_variable())]'", "var_value" = FV.get_value(), "details" = "'[sanitizeSQL(FV.get_details())]'"))
|
||||
if (!length(sqlrowlist))
|
||||
return
|
||||
|
||||
|
||||
@@ -23,7 +23,8 @@ SUBSYSTEM_DEF(dbcore)
|
||||
var/failed_connections = 0
|
||||
|
||||
/datum/controller/subsystem/dbcore/PreInit()
|
||||
_db_con = _dm_db_new_con()
|
||||
if(!_db_con)
|
||||
_db_con = _dm_db_new_con()
|
||||
|
||||
/datum/controller/subsystem/dbcore/Recover()
|
||||
_db_con = SSdbcore._db_con
|
||||
|
||||
@@ -0,0 +1,510 @@
|
||||
SUBSYSTEM_DEF(explosion)
|
||||
priority = 99
|
||||
wait = 1
|
||||
flags = SS_TICKER|SS_NO_INIT
|
||||
|
||||
var/list/explosions
|
||||
|
||||
var/rebuild_tick_split_count = FALSE
|
||||
var/tick_portions_required = 0
|
||||
|
||||
var/list/logs
|
||||
|
||||
var/list/zlevels_that_ignore_bombcap
|
||||
var/list/doppler_arrays
|
||||
|
||||
//legacy caps, set by config
|
||||
var/devastation_cap = 3
|
||||
var/heavy_cap = 7
|
||||
var/light_cap = 14
|
||||
var/flash_cap = 14
|
||||
var/flame_cap = 14
|
||||
var/dyn_ex_scale = 0.5
|
||||
|
||||
var/id_counter = 0
|
||||
|
||||
/datum/controller/subsystem/explosion/PreInit()
|
||||
doppler_arrays = list()
|
||||
logs = list()
|
||||
explosions = list()
|
||||
zlevels_that_ignore_bombcap = list("[ZLEVEL_MINING]")
|
||||
|
||||
/datum/controller/subsystem/explosion/Shutdown()
|
||||
QDEL_LIST(explosions)
|
||||
QDEL_LIST(logs)
|
||||
zlevels_that_ignore_bombcap.Cut()
|
||||
|
||||
/datum/controller/subsystem/explosion/Recover()
|
||||
explosions = SSexplosion.explosions
|
||||
logs = SSexplosion.logs
|
||||
id_counter = SSexplosion.id_counter
|
||||
rebuild_tick_split_count = TRUE
|
||||
zlevels_that_ignore_bombcap = SSexplosion.zlevels_that_ignore_bombcap
|
||||
doppler_arrays = SSexplosion.doppler_arrays
|
||||
|
||||
devastation_cap = SSexplosion.devastation_cap
|
||||
heavy_cap = SSexplosion.heavy_cap
|
||||
light_cap = SSexplosion.light_cap
|
||||
flash_cap = SSexplosion.flash_cap
|
||||
flame_cap = SSexplosion.flame_cap
|
||||
dyn_ex_scale = SSexplosion.dyn_ex_scale
|
||||
|
||||
/datum/controller/subsystem/explosion/fire()
|
||||
var/list/cached_explosions = explosions
|
||||
var/num_explosions = cached_explosions.len
|
||||
if(!num_explosions)
|
||||
return
|
||||
|
||||
//figure exactly how many tick splits are required
|
||||
var/num_splits
|
||||
if(rebuild_tick_split_count)
|
||||
var/reactionary = config.reactionary_explosions
|
||||
num_splits = num_explosions
|
||||
for(var/I in cached_explosions)
|
||||
var/datum/explosion/E = I
|
||||
if(!E.turfs_processed)
|
||||
++num_splits
|
||||
if(reactionary && !E.densities_processed)
|
||||
++num_splits
|
||||
tick_portions_required = num_splits
|
||||
else
|
||||
num_splits = tick_portions_required
|
||||
|
||||
MC_SPLIT_TICK_INIT(num_splits)
|
||||
|
||||
for(var/I in cached_explosions)
|
||||
var/datum/explosion/E = I
|
||||
|
||||
var/etp = E.turfs_processed
|
||||
if(!etp)
|
||||
if(GatherTurfs(E))
|
||||
--tick_portions_required
|
||||
etp = TRUE
|
||||
MC_SPLIT_TICK
|
||||
|
||||
var/edp = E.densities_processed
|
||||
if(!edp)
|
||||
if(DensityCalculate(E, etp))
|
||||
--tick_portions_required
|
||||
edp = TRUE
|
||||
MC_SPLIT_TICK
|
||||
|
||||
if(ProcessExplosion(E, edp)) //splits the tick
|
||||
--tick_portions_required
|
||||
explosions -= E
|
||||
logs += E
|
||||
NotifyDopplers(E)
|
||||
MC_SPLIT_TICK
|
||||
|
||||
/datum/controller/subsystem/explosion/proc/NotifyDopplers(datum/explosion/E)
|
||||
for(var/array in doppler_arrays)
|
||||
var/obj/machinery/doppler_array/A = array
|
||||
A.sense_explosion(E.epicenter, E.devastation, E.heavy, E.light, E.finished_at - E.started_at, E.orig_dev_range, E.orig_heavy_range, E.orig_light_range)
|
||||
|
||||
/datum/controller/subsystem/explosion/proc/Create(atom/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = TRUE, ignorecap = FALSE, flame_range = 0 , silent = FALSE, smoke = FALSE)
|
||||
epicenter = get_turf(epicenter)
|
||||
if(!epicenter)
|
||||
return
|
||||
|
||||
if(adminlog)
|
||||
message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area: [get_area(epicenter)] [ADMIN_COORDJMP(epicenter)]")
|
||||
log_game("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z])")
|
||||
|
||||
var/datum/explosion/E = new(++id_counter, epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, flame_range, silent, smoke, ignorecap)
|
||||
|
||||
if(heavy_impact_range > 1)
|
||||
var/datum/effect_system/explosion/Eff
|
||||
if(smoke)
|
||||
Eff = new /datum/effect_system/explosion/smoke
|
||||
else
|
||||
Eff = new
|
||||
Eff.set_up(epicenter)
|
||||
Eff.start()
|
||||
|
||||
//flash mobs
|
||||
if(flash_range)
|
||||
for(var/mob/living/L in viewers(flash_range, epicenter))
|
||||
L.flash_act()
|
||||
|
||||
if(!silent)
|
||||
ExplosionSound(epicenter, devastation_range, heavy_impact_range, E.extent)
|
||||
|
||||
//add to SS
|
||||
if(E.extent)
|
||||
tick_portions_required += 2 + (config.reactionary_explosions ? 1 : 0)
|
||||
explosions += E
|
||||
else
|
||||
logs += E //Already done processing
|
||||
|
||||
/datum/controller/subsystem/explosion/proc/CreateDynamic(atom/epicenter, power, flash_range, adminlog = TRUE, ignorecap = TRUE, flame_range = 0 , silent = FALSE, smoke = TRUE)
|
||||
if(!power)
|
||||
return
|
||||
var/range = round((2 * power) ** dyn_ex_scale)
|
||||
Create(epicenter, round(range * 0.25), round(range * 0.5), round(range), flash_range*range, adminlog, ignorecap, flame_range*range, silent, smoke)
|
||||
|
||||
// Using default dyn_ex scale:
|
||||
// 100 explosion power is a (5, 10, 20) explosion.
|
||||
// 75 explosion power is a (4, 8, 17) explosion.
|
||||
// 50 explosion power is a (3, 7, 14) explosion.
|
||||
// 25 explosion power is a (2, 5, 10) explosion.
|
||||
// 10 explosion power is a (1, 3, 6) explosion.
|
||||
// 5 explosion power is a (0, 1, 3) explosion.
|
||||
// 1 explosion power is a (0, 0, 1) explosion.
|
||||
|
||||
/datum/explosion
|
||||
var/explosion_id
|
||||
var/turf/epicenter
|
||||
|
||||
var/started_at
|
||||
var/finished_at
|
||||
var/tick_started
|
||||
var/tick_finished
|
||||
|
||||
var/turfs_processed = FALSE
|
||||
var/densities_processed = FALSE
|
||||
|
||||
var/orig_dev_range
|
||||
var/orig_heavy_range
|
||||
var/orig_light_range
|
||||
var/orig_flash_range
|
||||
var/orig_flame_range
|
||||
|
||||
var/devastation
|
||||
var/heavy
|
||||
var/light
|
||||
var/extent
|
||||
|
||||
var/flash
|
||||
var/flame
|
||||
|
||||
var/gather_dist = 0
|
||||
|
||||
var/list/gathered_turfs
|
||||
var/list/calculated_turfs
|
||||
|
||||
var/list/unsafe_turfs
|
||||
|
||||
/datum/explosion/New(id, turf/epi, devastation_range, heavy_impact_range, light_impact_range, flash_range, flame_range, silent, smoke, ignorecap)
|
||||
explosion_id = id
|
||||
epicenter = epi
|
||||
|
||||
densities_processed = !config.reactionary_explosions
|
||||
|
||||
orig_dev_range = devastation_range
|
||||
orig_heavy_range = heavy_impact_range
|
||||
orig_light_range = light_impact_range
|
||||
orig_flash_range = flash_range
|
||||
orig_flame_range = flame_range
|
||||
|
||||
if(!ignorecap && !("[epicenter.z]" in SSexplosion.zlevels_that_ignore_bombcap))
|
||||
//Clamp all values
|
||||
devastation_range = min(SSexplosion.devastation_cap, devastation_range)
|
||||
heavy_impact_range = min(SSexplosion.heavy_cap, heavy_impact_range)
|
||||
light_impact_range = min(SSexplosion.light_cap, light_impact_range)
|
||||
flash_range = min(SSexplosion.flash_cap, flash_range)
|
||||
flame_range = min(SSexplosion.flame_cap, flame_range)
|
||||
|
||||
//store this
|
||||
devastation = devastation_range
|
||||
heavy = heavy_impact_range
|
||||
light = light_impact_range
|
||||
|
||||
extent = max(devastation_range, heavy_impact_range, light_impact_range, flame_range)
|
||||
|
||||
flash = flash_range
|
||||
flame = flame_range
|
||||
|
||||
started_at = REALTIMEOFDAY
|
||||
tick_started = world.time
|
||||
|
||||
gathered_turfs = list()
|
||||
calculated_turfs = list()
|
||||
unsafe_turfs = list()
|
||||
|
||||
// Play sounds; we want sounds to be different depending on distance so we will manually do it ourselves.
|
||||
// Stereo users will also hear the direction of the explosion!
|
||||
|
||||
// Calculate far explosion sound range. Only allow the sound effect for heavy/devastating explosions.
|
||||
// 3/7/14 will calculate to 80 + 35
|
||||
/proc/ExplosionSound(turf/epicenter, devastation_range, heavy_impact_range, extent)
|
||||
var/far_dist = 0
|
||||
far_dist += heavy_impact_range * 5
|
||||
far_dist += devastation_range * 20
|
||||
|
||||
var/z0 = epicenter.z
|
||||
|
||||
var/frequency = get_rand_frequency()
|
||||
var/ex_sound = get_sfx("explosion")
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
// Double check for client
|
||||
var/turf/M_turf = get_turf(M)
|
||||
if(M_turf && M_turf.z == z0)
|
||||
var/dist = get_dist(M_turf, epicenter)
|
||||
// If inside the blast radius + world.view - 2
|
||||
if(dist <= round(extent + world.view - 2, 1))
|
||||
M.playsound_local(epicenter, ex_sound, 100, 1, frequency, falloff = 5)
|
||||
// You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station.
|
||||
else if(dist <= far_dist)
|
||||
var/far_volume = Clamp(far_dist, 30, 50) // Volume is based on explosion size and dist
|
||||
far_volume += (dist <= far_dist * 0.5 ? 50 : 0) // add 50 volume if the mob is pretty close to the explosion
|
||||
M.playsound_local(epicenter, 'sound/effects/explosionfar.ogg', far_volume, 1, frequency, falloff = 5)
|
||||
|
||||
/datum/explosion/Destroy()
|
||||
SSexplosion.explosions -= src
|
||||
SSexplosion.logs -= src
|
||||
LAZYCLEARLIST(gathered_turfs)
|
||||
LAZYCLEARLIST(calculated_turfs)
|
||||
LAZYCLEARLIST(unsafe_turfs)
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/explosion/proc/GatherTurfs(datum/explosion/E)
|
||||
var/turf/epicenter = E.epicenter
|
||||
|
||||
var/x0 = epicenter.x
|
||||
var/y0 = epicenter.y
|
||||
var/z0 = epicenter.z
|
||||
|
||||
var/c_dist = E.gather_dist
|
||||
var/dist = E.extent
|
||||
|
||||
var/list/L = E.gathered_turfs
|
||||
|
||||
if(!c_dist)
|
||||
L += epicenter
|
||||
++c_dist
|
||||
|
||||
while( c_dist <= dist )
|
||||
var/y = y0 + c_dist
|
||||
var/x = x0 - c_dist + 1
|
||||
for(x in x to x0 + c_dist)
|
||||
var/turf/T = locate(x, y, z0)
|
||||
if(T)
|
||||
L += T
|
||||
|
||||
y = y0 + c_dist - 1
|
||||
x = x0 + c_dist
|
||||
for(y in y0 - c_dist to y)
|
||||
var/turf/T = locate(x, y, z0)
|
||||
if(T)
|
||||
L += T
|
||||
|
||||
y = y0 - c_dist
|
||||
x = x0 + c_dist - 1
|
||||
for(x in x0 - c_dist to x)
|
||||
var/turf/T = locate(x, y, z0)
|
||||
if(T)
|
||||
L += T
|
||||
|
||||
y = y0 - c_dist + 1
|
||||
x = x0 - c_dist
|
||||
for(y in y to y0 + c_dist)
|
||||
var/turf/T = locate(x, y, z0)
|
||||
if(T)
|
||||
L += T
|
||||
++c_dist
|
||||
|
||||
if(MC_TICK_CHECK)
|
||||
break
|
||||
|
||||
if(c_dist > dist)
|
||||
E.turfs_processed = TRUE
|
||||
return TRUE
|
||||
else
|
||||
E.gather_dist = c_dist
|
||||
return FALSE
|
||||
|
||||
/datum/controller/subsystem/explosion/proc/DensityCalculate(datum/explosion/E, done_gathering_turfs)
|
||||
var/list/L = E.calculated_turfs
|
||||
var/cut_to = 1
|
||||
for(var/I in E.gathered_turfs) // we cache the explosion block rating of every turf in the explosion area
|
||||
var/turf/T = I
|
||||
++cut_to
|
||||
|
||||
var/current_exp_block = T.density ? T.explosion_block : 0
|
||||
|
||||
for(var/obj/machinery/door/D in T)
|
||||
if(D.density)
|
||||
current_exp_block += D.explosion_block
|
||||
|
||||
for(var/obj/structure/window/W in T)
|
||||
if(W.reinf && W.fulltile)
|
||||
current_exp_block += W.explosion_block
|
||||
|
||||
for(var/obj/structure/blob/B in T)
|
||||
current_exp_block += B.explosion_block
|
||||
|
||||
L[T] = current_exp_block
|
||||
|
||||
if(MC_TICK_CHECK)
|
||||
E.gathered_turfs.Cut(1, cut_to)
|
||||
return FALSE
|
||||
|
||||
E.gathered_turfs.Cut()
|
||||
return done_gathering_turfs
|
||||
|
||||
/datum/controller/subsystem/explosion/proc/ProcessExplosion(datum/explosion/E, done_calculating_turfs)
|
||||
//cache shit for speed
|
||||
var/id = E.explosion_id
|
||||
|
||||
var/list/cached_unsafe = E.unsafe_turfs
|
||||
var/list/cached_exp_block = E.calculated_turfs
|
||||
var/list/affected_turfs = cached_exp_block ? cached_exp_block : E.gathered_turfs
|
||||
|
||||
var/devastation_range = E.devastation
|
||||
var/heavy_impact_range = E.heavy
|
||||
var/light_impact_range = E.light
|
||||
|
||||
var/flame_range = E.flame
|
||||
var/throw_range_max = E.extent
|
||||
|
||||
var/turf/epi = E.epicenter
|
||||
|
||||
var/x0 = epi.x
|
||||
var/y0 = epi.y
|
||||
|
||||
var/cut_to = 1
|
||||
for(var/TI in affected_turfs)
|
||||
var/turf/T = TI
|
||||
++cut_to
|
||||
|
||||
var/init_dist = cheap_hypotenuse(T.x, T.y, x0, y0)
|
||||
var/dist = init_dist
|
||||
|
||||
if(cached_exp_block)
|
||||
var/turf/Trajectory = T
|
||||
while(Trajectory != epi)
|
||||
Trajectory = get_step_towards(Trajectory, epi)
|
||||
dist += cached_exp_block[Trajectory]
|
||||
|
||||
var/flame_dist = dist < flame_range
|
||||
var/throw_dist = dist
|
||||
|
||||
if(dist < devastation_range)
|
||||
dist = 1
|
||||
else if(dist < heavy_impact_range)
|
||||
dist = 2
|
||||
else if(dist < light_impact_range)
|
||||
dist = 3
|
||||
else
|
||||
dist = 0
|
||||
|
||||
//------- EX_ACT AND TURF FIRES -------
|
||||
|
||||
if(flame_dist && prob(40) && !isspaceturf(T) && !T.density)
|
||||
new /obj/effect/hotspot(T) //Mostly for ambience!
|
||||
|
||||
if(dist > 0)
|
||||
T.explosion_level = max(T.explosion_level, dist) //let the bigger one have it
|
||||
T.explosion_id = id
|
||||
T.ex_act(dist)
|
||||
cached_unsafe += T
|
||||
|
||||
//--- THROW ITEMS AROUND ---
|
||||
|
||||
var/throw_dir = get_dir(epi, T)
|
||||
for(var/obj/item/I in T)
|
||||
if(!I.anchored)
|
||||
var/throw_range = rand(throw_dist, throw_range_max)
|
||||
var/turf/throw_at = get_ranged_target_turf(I, throw_dir, throw_range)
|
||||
I.throw_speed = 4 //Temporarily change their throw_speed for embedding purposes (Resets when it finishes throwing, regardless of hitting anything)
|
||||
I.throw_at(throw_at, throw_range, 4)
|
||||
|
||||
if(MC_TICK_CHECK)
|
||||
var/circumference = (PI * (init_dist + 4) * 2) //+4 to radius to prevent shit gaps
|
||||
if(cached_unsafe.len > circumference) //only do this every revolution
|
||||
for(var/Unexplode in cached_unsafe)
|
||||
var/turf/UnexplodeT = Unexplode
|
||||
UnexplodeT.explosion_level = 0
|
||||
cached_unsafe.Cut()
|
||||
done_calculating_turfs = FALSE
|
||||
break
|
||||
|
||||
affected_turfs.Cut(1, cut_to)
|
||||
|
||||
if(!done_calculating_turfs)
|
||||
return FALSE
|
||||
|
||||
//unfuck the shit
|
||||
for(var/Unexplode in cached_unsafe)
|
||||
var/turf/UnexplodeT = Unexplode
|
||||
UnexplodeT.explosion_level = 0
|
||||
cached_unsafe.Cut()
|
||||
|
||||
E.finished_at = REALTIMEOFDAY
|
||||
E.tick_finished = world.time
|
||||
|
||||
return TRUE
|
||||
|
||||
/client/proc/check_bomb_impacts()
|
||||
set name = "Check Bomb Impact"
|
||||
set category = "Debug"
|
||||
|
||||
var/newmode = alert("Use reactionary explosions?","Check Bomb Impact", "Yes", "No")
|
||||
var/turf/epicenter = get_turf(mob)
|
||||
if(!epicenter)
|
||||
return
|
||||
|
||||
var/x0 = epicenter.x
|
||||
var/y0 = epicenter.y
|
||||
|
||||
var/dev = 0
|
||||
var/heavy = 0
|
||||
var/light = 0
|
||||
var/list/choices = list("Small Bomb","Medium Bomb","Big Bomb","Custom Bomb")
|
||||
var/choice = input("Bomb Size?") in choices
|
||||
switch(choice)
|
||||
if(null)
|
||||
return 0
|
||||
if("Small Bomb")
|
||||
dev = 1
|
||||
heavy = 2
|
||||
light = 3
|
||||
if("Medium Bomb")
|
||||
dev = 2
|
||||
heavy = 3
|
||||
light = 4
|
||||
if("Big Bomb")
|
||||
dev = 3
|
||||
heavy = 5
|
||||
light = 7
|
||||
if("Custom Bomb")
|
||||
dev = input("Devestation range (Tiles):") as num
|
||||
heavy = input("Heavy impact range (Tiles):") as num
|
||||
light = input("Light impact range (Tiles):") as num
|
||||
else
|
||||
return
|
||||
|
||||
var/datum/explosion/E = new(null, epicenter, dev, heavy, light, ignorecap = TRUE)
|
||||
|
||||
while(!SSexplosion.GatherTurfs(E))
|
||||
stoplag()
|
||||
var/list/turfs
|
||||
if(newmode)
|
||||
while(!SSexplosion.DensityCalculate(E, TRUE))
|
||||
stoplag()
|
||||
turfs = E.calculated_turfs.Copy()
|
||||
else
|
||||
turfs = E.gathered_turfs.Copy()
|
||||
|
||||
qdel(E)
|
||||
|
||||
for(var/I in turfs)
|
||||
var/turf/T = I
|
||||
var/dist = cheap_hypotenuse(T.x, T.y, x0, y0) + turfs[T]
|
||||
|
||||
if(dist < dev)
|
||||
T.color = "red"
|
||||
T.maptext = "Dev"
|
||||
else if (dist < heavy)
|
||||
T.color = "yellow"
|
||||
T.maptext = "Heavy"
|
||||
else if (dist < light)
|
||||
T.color = "blue"
|
||||
T.maptext = "Light"
|
||||
CHECK_TICK
|
||||
|
||||
sleep(100)
|
||||
for(var/I in turfs)
|
||||
var/turf/T = I
|
||||
T.color = null
|
||||
T.maptext = null
|
||||
@@ -164,8 +164,8 @@ SUBSYSTEM_DEF(garbage)
|
||||
if (time > highest_del_time)
|
||||
highest_del_time = time
|
||||
if (time > 10)
|
||||
log_game("Error: [type]([refID]) took longer then 1 second to delete (took [time/10] seconds to delete)")
|
||||
message_admins("Error: [type]([refID]) took longer then 1 second to delete (took [time/10] seconds to delete).")
|
||||
log_game("Error: [type]([refID]) took longer than 1 second to delete (took [time/10] seconds to delete)")
|
||||
message_admins("Error: [type]([refID]) took longer than 1 second to delete (took [time/10] seconds to delete).")
|
||||
postpone(time/5)
|
||||
|
||||
/datum/controller/subsystem/garbage/proc/HardQueue(datum/A)
|
||||
|
||||
@@ -15,14 +15,15 @@ SUBSYSTEM_DEF(lighting)
|
||||
|
||||
|
||||
/datum/controller/subsystem/lighting/Initialize(timeofday)
|
||||
if (config.starlight)
|
||||
for(var/I in GLOB.sortedAreas)
|
||||
var/area/A = I
|
||||
if (A.dynamic_lighting == DYNAMIC_LIGHTING_IFSTARLIGHT)
|
||||
A.luminosity = 0
|
||||
if(!initialized)
|
||||
if (config.starlight)
|
||||
for(var/I in GLOB.sortedAreas)
|
||||
var/area/A = I
|
||||
if (A.dynamic_lighting == DYNAMIC_LIGHTING_IFSTARLIGHT)
|
||||
A.luminosity = 0
|
||||
|
||||
create_all_lighting_objects()
|
||||
initialized = TRUE
|
||||
create_all_lighting_objects()
|
||||
initialized = TRUE
|
||||
|
||||
fire(FALSE, TRUE)
|
||||
|
||||
|
||||
@@ -37,11 +37,11 @@ SUBSYSTEM_DEF(machines)
|
||||
|
||||
var/seconds = wait * 0.1
|
||||
while(currentrun.len)
|
||||
var/datum/thing = currentrun[currentrun.len]
|
||||
var/obj/machinery/thing = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
if(thing && thing.process(seconds) != PROCESS_KILL)
|
||||
if(thing:use_power)
|
||||
thing:auto_use_power() //add back the power state
|
||||
if(thing.use_power)
|
||||
thing.auto_use_power() //add back the power state
|
||||
else
|
||||
processing -= thing
|
||||
if (thing)
|
||||
|
||||
@@ -119,7 +119,9 @@ SUBSYSTEM_DEF(mapping)
|
||||
INIT_ANNOUNCE("Loading [config.map_name]...")
|
||||
TryLoadZ(config.GetFullMapPath(), FailedZs, ZLEVEL_STATION)
|
||||
INIT_ANNOUNCE("Loaded station in [(REALTIMEOFDAY - start_time)/10]s!")
|
||||
SSblackbox.add_details("map_name", config.map_name)
|
||||
if(SSdbcore.Connect())
|
||||
var/datum/DBQuery/query_round_map_name = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET map_name = '[config.map_name]' WHERE id = [GLOB.round_id]")
|
||||
query_round_map_name.Execute()
|
||||
|
||||
if(config.minetype != "lavaland")
|
||||
INIT_ANNOUNCE("WARNING: A map without lavaland set as it's minetype was loaded! This is being ignored! Update the maploader code!")
|
||||
|
||||
@@ -25,6 +25,7 @@ SUBSYSTEM_DEF(shuttle)
|
||||
var/area/emergencyLastCallLoc
|
||||
var/emergencyCallAmount = 0 //how many times the escape shuttle was called
|
||||
var/emergencyNoEscape
|
||||
var/emergencyNoRecall = FALSE
|
||||
var/list/hostileEnvironments = list()
|
||||
|
||||
//supply shuttle stuff
|
||||
|
||||
@@ -744,6 +744,15 @@ SUBSYSTEM_DEF(ticker)
|
||||
cinematic = SSticker.cinematic
|
||||
maprotatechecked = SSticker.maprotatechecked
|
||||
|
||||
switch (current_state)
|
||||
if(GAME_STATE_SETTING_UP)
|
||||
Master.SetRunLevel(RUNLEVEL_SETUP)
|
||||
if(GAME_STATE_PLAYING)
|
||||
Master.SetRunLevel(RUNLEVEL_GAME)
|
||||
if(GAME_STATE_FINISHED)
|
||||
Master.SetRunLevel(RUNLEVEL_POSTGAME)
|
||||
|
||||
|
||||
modevoted = SSticker.modevoted
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/send_news_report()
|
||||
@@ -844,17 +853,17 @@ SUBSYSTEM_DEF(ticker)
|
||||
if(delay_end)
|
||||
to_chat(world, "<span class='boldannounce'>An admin has delayed the round end.</span>")
|
||||
return
|
||||
|
||||
|
||||
to_chat(world, "<span class='boldannounce'>Rebooting World in [delay/10] [(delay >= 10 && delay < 20) ? "second" : "seconds"]. [reason]</span>")
|
||||
|
||||
var/start_wait = world.time
|
||||
UNTIL(round_end_sound_sent && (world.time - start_wait) > (delay * 2)) //don't wait forever
|
||||
UNTIL(round_end_sound_sent || (world.time - start_wait) > (delay * 2)) //don't wait forever
|
||||
sleep(delay - (world.time - start_wait))
|
||||
|
||||
if(delay_end)
|
||||
to_chat(world, "<span class='boldannounce'>Reboot was cancelled by an admin.</span>")
|
||||
return
|
||||
|
||||
|
||||
SSblackbox.set_details("[feedback_c]","[feedback_r]")
|
||||
|
||||
log_game("<span class='boldannounce'>Rebooting World. [reason]</span>")
|
||||
|
||||
@@ -55,9 +55,8 @@
|
||||
else if(isbrain(current) || isclockmob(current))
|
||||
to_chat(current, "<span class='nezbere'>You can communicate with other servants by using the Hierophant Network action button in the upper left.</span>")
|
||||
..()
|
||||
if(istype(SSticker.mode, /datum/game_mode/clockwork_cult))
|
||||
var/datum/game_mode/clockwork_cult/C = SSticker.mode
|
||||
C.present_tasks(owner) //Memorize the objectives
|
||||
to_chat(current, "<b>This is Ratvar's will:</b> [CLOCKCULT_OBJECTIVE]")
|
||||
owner.memory += "<b>Ratvar's will:</b> [CLOCKCULT_OBJECTIVE]<br>" //Memorize the objectives
|
||||
|
||||
/datum/antagonist/clockcult/apply_innate_effects(mob/living/mob_override)
|
||||
. = ..()
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
var/list/symptoms = list() // The symptoms of the disease.
|
||||
var/id = ""
|
||||
var/processing = 0
|
||||
|
||||
|
||||
// The order goes from easy to cure to hard to cure.
|
||||
var/static/list/advance_cures = list(
|
||||
"sodiumchloride", "sugar", "orangejuice",
|
||||
@@ -399,7 +399,7 @@
|
||||
AD.Refresh()
|
||||
|
||||
for(var/mob/living/carbon/human/H in shuffle(GLOB.living_mob_list))
|
||||
if(H.z != 1)
|
||||
if(H.z != ZLEVEL_STATION)
|
||||
continue
|
||||
if(!H.HasDisease(D))
|
||||
H.ForceContractDisease(D)
|
||||
|
||||
@@ -1,10 +1,48 @@
|
||||
/proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1, ignorecap = 0, flame_range, silent = 0, smoke = 1)
|
||||
set waitfor = 0
|
||||
src = null //so we don't abort once src is deleted
|
||||
#define EXPLOSION_THROW_SPEED 4
|
||||
|
||||
GLOBAL_LIST_EMPTY(explosions)
|
||||
//Against my better judgement, I will return the explosion datum
|
||||
//If I see any GC errors for it I will find you
|
||||
//and I will gib you
|
||||
/proc/explosion(atom/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = TRUE, ignorecap = FALSE, flame_range = 0 , silent = FALSE, smoke = FALSE)
|
||||
return new /datum/explosion(epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog, ignorecap, flame_range, silent, smoke)
|
||||
|
||||
//This datum creates 3 async tasks
|
||||
//1 GatherSpiralTurfsProc runs spiral_range_turfs(tick_checked = TRUE) to populate the affected_turfs list
|
||||
//2 CaculateExplosionBlock adds the blockings to the cached_exp_block list
|
||||
//3 The main thread explodes the prepared turfs
|
||||
|
||||
/datum/explosion
|
||||
var/explosion_id
|
||||
var/started_at
|
||||
var/running = TRUE
|
||||
var/stopped = 0 //This is the number of threads stopped !DOESN'T COUNT THREAD 2!
|
||||
var/static/id_counter = 0
|
||||
|
||||
#define EX_PREPROCESS_EXIT_CHECK \
|
||||
if(!running) {\
|
||||
stopped = 2;\
|
||||
qdel(src);\
|
||||
return;\
|
||||
}
|
||||
|
||||
#define EX_PREPROCESS_CHECK_TICK \
|
||||
if(TICK_CHECK) {\
|
||||
stoplag();\
|
||||
EX_PREPROCESS_EXIT_CHECK\
|
||||
}
|
||||
|
||||
/datum/explosion/New(atom/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog, ignorecap, flame_range, silent, smoke)
|
||||
set waitfor = FALSE
|
||||
|
||||
var/id = ++id_counter
|
||||
explosion_id = id
|
||||
|
||||
epicenter = get_turf(epicenter)
|
||||
if(!epicenter)
|
||||
return
|
||||
|
||||
GLOB.explosions += src
|
||||
if(isnull(flame_range))
|
||||
flame_range = light_impact_range
|
||||
if(isnull(flash_range))
|
||||
@@ -30,14 +68,13 @@
|
||||
//I would make this not ex_act the thing that triggered the explosion,
|
||||
//but everything that explodes gives us their loc or a get_turf()
|
||||
//and somethings expect us to ex_act them so they can qdel()
|
||||
sleep(1) //tldr, let the calling proc call qdel(src) before we explode
|
||||
stoplag() //tldr, let the calling proc call qdel(src) before we explode
|
||||
|
||||
var/static/explosionid = 1
|
||||
var/id = explosionid++
|
||||
var/start = world.timeofday
|
||||
EX_PREPROCESS_EXIT_CHECK
|
||||
|
||||
started_at = REALTIMEOFDAY
|
||||
|
||||
var/max_range = max(devastation_range, heavy_impact_range, light_impact_range, flame_range)
|
||||
var/list/cached_exp_block = list()
|
||||
|
||||
if(adminlog)
|
||||
message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area: [get_area(epicenter)] [ADMIN_COORDJMP(epicenter)]")
|
||||
@@ -53,23 +90,27 @@
|
||||
far_dist += heavy_impact_range * 5
|
||||
far_dist += devastation_range * 20
|
||||
|
||||
var/x0 = epicenter.x
|
||||
var/y0 = epicenter.y
|
||||
var/z0 = epicenter.z
|
||||
|
||||
if(!silent)
|
||||
var/frequency = get_rand_frequency()
|
||||
var/ex_sound = get_sfx("explosion")
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
// Double check for client
|
||||
if(M && M.client)
|
||||
var/turf/M_turf = get_turf(M)
|
||||
if(M_turf && M_turf.z == epicenter.z)
|
||||
var/dist = get_dist(M_turf, epicenter)
|
||||
// If inside the blast radius + world.view - 2
|
||||
if(dist <= round(max_range + world.view - 2, 1))
|
||||
M.playsound_local(epicenter, ex_sound, 100, 1, frequency, falloff = 5)
|
||||
// You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station.
|
||||
else if(dist <= far_dist)
|
||||
var/far_volume = Clamp(far_dist, 30, 50) // Volume is based on explosion size and dist
|
||||
far_volume += (dist <= far_dist * 0.5 ? 50 : 0) // add 50 volume if the mob is pretty close to the explosion
|
||||
M.playsound_local(epicenter, 'sound/effects/explosionfar.ogg', far_volume, 1, frequency, falloff = 5)
|
||||
var/turf/M_turf = get_turf(M)
|
||||
if(M_turf && M_turf.z == z0)
|
||||
var/dist = get_dist(M_turf, epicenter)
|
||||
// If inside the blast radius + world.view - 2
|
||||
if(dist <= round(max_range + world.view - 2, 1))
|
||||
M.playsound_local(epicenter, ex_sound, 100, 1, frequency, falloff = 5)
|
||||
// You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station.
|
||||
else if(dist <= far_dist)
|
||||
var/far_volume = Clamp(far_dist, 30, 50) // Volume is based on explosion size and dist
|
||||
far_volume += (dist <= far_dist * 0.5 ? 50 : 0) // add 50 volume if the mob is pretty close to the explosion
|
||||
M.playsound_local(epicenter, 'sound/effects/explosionfar.ogg', far_volume, 1, frequency, falloff = 5)
|
||||
EX_PREPROCESS_CHECK_TICK
|
||||
|
||||
//postpone processing for a bit
|
||||
var/postponeCycles = max(round(devastation_range/8),1)
|
||||
@@ -77,66 +118,52 @@
|
||||
SSmachines.postpone(postponeCycles)
|
||||
|
||||
if(heavy_impact_range > 1)
|
||||
var/datum/effect_system/explosion/E
|
||||
if(smoke)
|
||||
var/datum/effect_system/explosion/smoke/E = new/datum/effect_system/explosion/smoke()
|
||||
E.set_up(epicenter)
|
||||
E.start()
|
||||
E = new /datum/effect_system/explosion/smoke
|
||||
else
|
||||
var/datum/effect_system/explosion/E = new/datum/effect_system/explosion()
|
||||
E.set_up(epicenter)
|
||||
E.start()
|
||||
E = new
|
||||
E.set_up(epicenter)
|
||||
E.start()
|
||||
|
||||
var/x0 = epicenter.x
|
||||
var/y0 = epicenter.y
|
||||
var/z0 = epicenter.z
|
||||
|
||||
var/list/affected_turfs = spiral_range_turfs(max_range, epicenter)
|
||||
|
||||
if(config.reactionary_explosions)
|
||||
for(var/turf/T in affected_turfs) // we cache the explosion block rating of every turf in the explosion area
|
||||
cached_exp_block[T] = 0
|
||||
if(T.density && T.explosion_block)
|
||||
cached_exp_block[T] += T.explosion_block
|
||||
|
||||
for(var/obj/machinery/door/D in T)
|
||||
if(D.density && D.explosion_block)
|
||||
cached_exp_block[T] += D.explosion_block
|
||||
|
||||
for(var/obj/structure/window/W in T)
|
||||
if(W.reinf && W.fulltile)
|
||||
cached_exp_block[T] += W.explosion_block
|
||||
|
||||
for(var/obj/structure/blob/B in T)
|
||||
cached_exp_block[T] += B.explosion_block
|
||||
CHECK_TICK
|
||||
EX_PREPROCESS_CHECK_TICK
|
||||
|
||||
//flash mobs
|
||||
if(flash_range)
|
||||
for(var/mob/living/L in viewers(flash_range, epicenter))
|
||||
L.flash_act()
|
||||
|
||||
CHECK_TICK
|
||||
EX_PREPROCESS_CHECK_TICK
|
||||
|
||||
var/list/exploded_this_tick = list() //open turfs that need to be blocked off while we sleep
|
||||
for(var/turf/T in affected_turfs)
|
||||
var/list/affected_turfs = GatherSpiralTurfs(max_range, epicenter)
|
||||
|
||||
if (!T)
|
||||
continue
|
||||
var/reactionary = config.reactionary_explosions
|
||||
var/list/cached_exp_block
|
||||
|
||||
if(reactionary)
|
||||
cached_exp_block = CaculateExplosionBlock(affected_turfs)
|
||||
|
||||
//lists are guaranteed to contain at least 1 turf at this point
|
||||
|
||||
var/iteration = 0
|
||||
var/affTurfLen = affected_turfs.len
|
||||
var/expBlockLen = cached_exp_block.len
|
||||
for(var/TI in affected_turfs)
|
||||
var/turf/T = TI
|
||||
++iteration
|
||||
var/init_dist = cheap_hypotenuse(T.x, T.y, x0, y0)
|
||||
var/dist = init_dist
|
||||
|
||||
if(config.reactionary_explosions)
|
||||
if(reactionary)
|
||||
var/turf/Trajectory = T
|
||||
while(Trajectory != epicenter)
|
||||
Trajectory = get_step_towards(Trajectory, epicenter)
|
||||
dist += cached_exp_block[Trajectory]
|
||||
|
||||
var/flame_dist = 0
|
||||
var/flame_dist = dist < flame_range
|
||||
var/throw_dist = dist
|
||||
|
||||
if(dist < flame_range)
|
||||
flame_dist = 1
|
||||
|
||||
if(dist < devastation_range)
|
||||
dist = 1
|
||||
else if(dist < heavy_impact_range)
|
||||
@@ -148,27 +175,61 @@
|
||||
|
||||
//------- EX_ACT AND TURF FIRES -------
|
||||
|
||||
if(T)
|
||||
if(flame_dist && prob(40) && !isspaceturf(T) && !T.density)
|
||||
new /obj/effect/hotspot(T) //Mostly for ambience!
|
||||
if(dist > 0)
|
||||
T.explosion_level = max(T.explosion_level, dist) //let the bigger one have it
|
||||
T.explosion_id = id
|
||||
T.ex_act(dist)
|
||||
exploded_this_tick += T
|
||||
if(flame_dist && prob(40) && !isspaceturf(T) && !T.density)
|
||||
new /obj/effect/hotspot(T) //Mostly for ambience!
|
||||
|
||||
if(dist > 0)
|
||||
T.explosion_level = max(T.explosion_level, dist) //let the bigger one have it
|
||||
T.explosion_id = id
|
||||
T.ex_act(dist)
|
||||
exploded_this_tick += T
|
||||
|
||||
//--- THROW ITEMS AROUND ---
|
||||
|
||||
var/throw_dir = get_dir(epicenter,T)
|
||||
for(var/obj/item/I in T)
|
||||
if(I && !I.anchored)
|
||||
if(!I.anchored)
|
||||
var/throw_range = rand(throw_dist, max_range)
|
||||
var/turf/throw_at = get_ranged_target_turf(I, throw_dir, throw_range)
|
||||
I.throw_speed = 4 //Temporarily change their throw_speed for embedding purposes (Reset when it finishes throwing, regardless of hitting anything)
|
||||
I.throw_at(throw_at, throw_range, I.throw_speed)
|
||||
I.throw_speed = EXPLOSION_THROW_SPEED //Temporarily change their throw_speed for embedding purposes (Reset when it finishes throwing, regardless of hitting anything)
|
||||
I.throw_at(throw_at, throw_range, EXPLOSION_THROW_SPEED)
|
||||
|
||||
if(TICK_CHECK)
|
||||
//wait for the lists to repop
|
||||
var/break_condition
|
||||
if(reactionary)
|
||||
//If we've caught up to the density checker thread and there are no more turfs to process
|
||||
break_condition = iteration == expBlockLen && iteration < affTurfLen
|
||||
else
|
||||
//If we've caught up to the turf gathering thread and it's still running
|
||||
break_condition = iteration == affTurfLen && !stopped
|
||||
|
||||
if(break_condition || TICK_CHECK)
|
||||
stoplag()
|
||||
|
||||
if(!running)
|
||||
break
|
||||
|
||||
//update the trackers
|
||||
affTurfLen = affected_turfs.len
|
||||
expBlockLen = cached_exp_block.len
|
||||
|
||||
if(break_condition)
|
||||
if(reactionary)
|
||||
//until there are more block checked turfs than what we are currently at
|
||||
//or the explosion has stopped
|
||||
UNTIL(iteration < affTurfLen || !running)
|
||||
else
|
||||
//until there are more gathered turfs than what we are currently at
|
||||
//or there are no more turfs to gather/the explosion has stopped
|
||||
UNTIL(iteration < expBlockLen || stopped)
|
||||
|
||||
if(!running)
|
||||
break
|
||||
|
||||
//update the trackers
|
||||
affTurfLen = affected_turfs.len
|
||||
expBlockLen = cached_exp_block.len
|
||||
|
||||
var/circumference = (PI * (init_dist + 4) * 2) //+4 to radius to prevent shit gaps
|
||||
if(exploded_this_tick.len > circumference) //only do this every revolution
|
||||
for(var/Unexplode in exploded_this_tick)
|
||||
@@ -182,24 +243,67 @@
|
||||
UnexplodeT.explosion_level = 0
|
||||
exploded_this_tick.Cut()
|
||||
|
||||
var/took = (world.timeofday-start)/10
|
||||
//You need to press the DebugGame verb to see these now....they were getting annoying and we've collected a fair bit of data. Just -test- changes to explosion code using this please so we can compare
|
||||
var/took = (REALTIMEOFDAY - started_at) / 10
|
||||
|
||||
//You need to press the DebugGame verb to see these now....they were getting annoying and we've collected a fair bit of data. Just -test- changes to explosion code using this please so we can compare
|
||||
if(GLOB.Debug2)
|
||||
log_world("## DEBUG: Explosion([x0],[y0],[z0])(d[devastation_range],h[heavy_impact_range],l[light_impact_range]): Took [took] seconds.")
|
||||
|
||||
//Machines which report explosions.
|
||||
for(var/array in GLOB.doppler_arrays)
|
||||
var/obj/machinery/doppler_array/A = array
|
||||
A.sense_explosion(epicenter,devastation_range,heavy_impact_range,light_impact_range,took,orig_dev_range,orig_heavy_range,orig_light_range)
|
||||
if(!stopped) //if we aren't in a hurry
|
||||
//Machines which report explosions.
|
||||
for(var/array in GLOB.doppler_arrays)
|
||||
var/obj/machinery/doppler_array/A = array
|
||||
A.sense_explosion(epicenter, devastation_range, heavy_impact_range, light_impact_range, took,orig_dev_range, orig_heavy_range, orig_light_range)
|
||||
|
||||
return 1
|
||||
++stopped
|
||||
qdel(src)
|
||||
|
||||
#undef EX_PREPROCESS_EXIT_CHECK
|
||||
#undef EX_PREPROCESS_CHECK_TICK
|
||||
|
||||
//asyncly populate the affected_turfs list
|
||||
/datum/explosion/proc/GatherSpiralTurfs(range, turf/epicenter)
|
||||
set waitfor = FALSE
|
||||
. = list()
|
||||
spiral_range_turfs(range, epicenter, outlist = ., tick_checked = TRUE)
|
||||
++stopped
|
||||
|
||||
/proc/secondaryexplosion(turf/epicenter, range)
|
||||
for(var/turf/tile in spiral_range_turfs(range, epicenter))
|
||||
tile.ex_act(2)
|
||||
/datum/explosion/proc/CaculateExplosionBlock(list/affected_turfs)
|
||||
set waitfor = FALSE
|
||||
|
||||
. = list()
|
||||
var/processed = 0
|
||||
while(!stopped && running)
|
||||
var/I
|
||||
for(I in (processed + 1) to affected_turfs.len) // we cache the explosion block rating of every turf in the explosion area
|
||||
var/turf/T = affected_turfs[I]
|
||||
var/current_exp_block = T.density ? T.explosion_block : 0
|
||||
|
||||
for(var/obj/machinery/door/D in T)
|
||||
if(D.density)
|
||||
current_exp_block += D.explosion_block
|
||||
|
||||
for(var/obj/structure/window/W in T)
|
||||
if(W.reinf && W.fulltile)
|
||||
current_exp_block += W.explosion_block
|
||||
|
||||
for(var/obj/structure/blob/B in T)
|
||||
current_exp_block += B.explosion_block
|
||||
|
||||
.[T] = current_exp_block
|
||||
|
||||
if(TICK_CHECK)
|
||||
break
|
||||
|
||||
processed = I
|
||||
stoplag()
|
||||
|
||||
/datum/explosion/Destroy()
|
||||
running = FALSE
|
||||
if(stopped < 2) //wait for main thread and spiral_range thread
|
||||
return QDEL_HINT_IWILLGC
|
||||
GLOB.explosions -= src
|
||||
return ..()
|
||||
|
||||
/client/proc/check_bomb_impacts()
|
||||
set name = "Check Bomb Impact"
|
||||
@@ -1,34 +1,37 @@
|
||||
/datum/getrev
|
||||
var/parentcommit
|
||||
var/originmastercommit
|
||||
var/commit
|
||||
var/list/testmerge = list()
|
||||
var/has_pr_details = FALSE //example data in a testmerge entry when this is true: https://api.github.com/repositories/3234987/pulls/22586
|
||||
var/date
|
||||
|
||||
/datum/getrev/New()
|
||||
var/head_file = file2text(".git/logs/HEAD")
|
||||
if(SERVERTOOLS && fexists("..\\prtestjob.lk"))
|
||||
var/list/tmp = world.file2list("..\\prtestjob.lk")
|
||||
for(var/I in tmp)
|
||||
if(I)
|
||||
testmerge |= I
|
||||
var/testlen = max(testmerge.len - 1, 0)
|
||||
var/regex/head_log = new("(\\w{40}) .+> (\\d{10}).+(?=(\n.*(\\w{40}).*){[testlen]}\n*\\Z)")
|
||||
head_log.Find(head_file)
|
||||
parentcommit = head_log.group[1]
|
||||
date = unix2date(text2num(head_log.group[2]))
|
||||
commit = head_log.group[4]
|
||||
|
||||
log_world("Running /tg/ revision:")
|
||||
log_world("[date]")
|
||||
var/list/logs = world.file2list(".git/logs/HEAD")
|
||||
if(logs)
|
||||
logs = splittext(logs[logs.len - 1], " ")
|
||||
date = unix2date(text2num(logs[5]))
|
||||
commit = logs[2]
|
||||
log_world("[date]")
|
||||
logs = world.file2list(".git/logs/refs/remotes/origin/master")
|
||||
if(logs)
|
||||
originmastercommit = splittext(logs[logs.len - 1], " ")[2]
|
||||
|
||||
if(testmerge.len)
|
||||
log_world(commit)
|
||||
for(var/line in testmerge)
|
||||
if(line)
|
||||
log_world("Test merge active of PR #[line]")
|
||||
SSblackbox.add_details("testmerged_prs","[line]")
|
||||
log_world("Based off master commit [parentcommit]")
|
||||
log_world("Based off origin/master commit [originmastercommit]")
|
||||
else
|
||||
log_world(parentcommit)
|
||||
log_world(originmastercommit)
|
||||
|
||||
/datum/getrev/proc/DownloadPRDetails()
|
||||
if(!config.githubrepoid)
|
||||
@@ -73,13 +76,13 @@
|
||||
set name = "Show Server Revision"
|
||||
set desc = "Check the current server code revision"
|
||||
|
||||
if(GLOB.revdata.parentcommit)
|
||||
if(GLOB.revdata.originmastercommit)
|
||||
to_chat(src, "<b>Server revision compiled on:</b> [GLOB.revdata.date]")
|
||||
var/prefix = ""
|
||||
if(GLOB.revdata.testmerge.len)
|
||||
to_chat(src, GLOB.revdata.GetTestMergeInfo())
|
||||
prefix = "Based off master commit: "
|
||||
var/pc = GLOB.revdata.parentcommit
|
||||
prefix = "Based off origin/master commit: "
|
||||
var/pc = GLOB.revdata.originmastercommit
|
||||
to_chat(src, "[prefix]<a href='[config.githuburl]/commit/[pc]'>[copytext(pc, 1, min(length(pc), 7))]</a>")
|
||||
else
|
||||
to_chat(src, "Revision unknown")
|
||||
|
||||
@@ -44,11 +44,12 @@
|
||||
//cleans up ALL references :)
|
||||
/datum/holocall/Destroy()
|
||||
user.reset_perspective()
|
||||
if(user.client)
|
||||
if(!QDELETED(eye) && user.client)
|
||||
for(var/datum/camerachunk/chunk in eye.visibleCameraChunks)
|
||||
user.client.images -= chunk.obscured
|
||||
chunk.remove(eye)
|
||||
qdel(eye)
|
||||
eye = null
|
||||
user.remote_control = null
|
||||
QDEL_NULL(eye)
|
||||
|
||||
user = null
|
||||
if(hologram)
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
|
||||
var/minetype = "lavaland"
|
||||
|
||||
var/list/transition_config = list(MAIN_STATION = CROSSLINKED,
|
||||
CENTCOMM = SELFLOOPING,
|
||||
var/list/transition_config = list(CENTCOMM = SELFLOOPING,
|
||||
MAIN_STATION = CROSSLINKED,
|
||||
EMPTY_AREA_1 = CROSSLINKED,
|
||||
EMPTY_AREA_2 = CROSSLINKED,
|
||||
MINING = SELFLOOPING,
|
||||
|
||||
@@ -608,6 +608,23 @@ GLOBAL_LIST_EMPTY(mutations_list)
|
||||
message = replacetext(message," muh valids "," getting my kicks ")
|
||||
return trim(message)
|
||||
|
||||
/datum/mutation/human/stoner
|
||||
name = "Stoner"
|
||||
quality = NEGATIVE
|
||||
dna_block = NON_SCANNABLE
|
||||
text_gain_indication = "<span class='notice'>You feel...totally chill, man!</span>"
|
||||
text_lose_indication = "<span class='notice'>You feel like you have a better sense of time.</span>"
|
||||
|
||||
/datum/mutation/human/stoner/on_acquiring(mob/living/carbon/human/owner)
|
||||
..()
|
||||
owner.grant_language(/datum/language/beachbum)
|
||||
owner.remove_language(/datum/language/common)
|
||||
|
||||
/datum/mutation/human/stoner/on_losing(mob/living/carbon/human/owner)
|
||||
..()
|
||||
owner.grant_language(/datum/language/common)
|
||||
owner.remove_language(/datum/language/beachbum)
|
||||
|
||||
/datum/mutation/human/laser_eyes
|
||||
name = "Laser Eyes"
|
||||
quality = POSITIVE
|
||||
|
||||
+11
-6
@@ -20,7 +20,8 @@
|
||||
var/r_hand = null
|
||||
var/l_hand = null
|
||||
var/internals_slot = null //ID of slot containing a gas tank
|
||||
var/list/backpack_contents = list() // In the list(path=count,otherpath=count) format
|
||||
var/list/backpack_contents = null // In the list(path=count,otherpath=count) format
|
||||
var/list/implants = null
|
||||
|
||||
/datum/outfit/proc/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
//to be overriden for customization depending on client prefs,species etc
|
||||
@@ -71,11 +72,11 @@
|
||||
H.equip_to_slot_or_del(new l_pocket(H),slot_l_store)
|
||||
if(r_pocket)
|
||||
H.equip_to_slot_or_del(new r_pocket(H),slot_r_store)
|
||||
|
||||
for(var/path in backpack_contents)
|
||||
var/number = backpack_contents[path]
|
||||
for(var/i=0,i<number,i++)
|
||||
H.equip_to_slot_or_del(new path(H),slot_in_backpack)
|
||||
if(backpack_contents)
|
||||
for(var/path in backpack_contents)
|
||||
var/number = backpack_contents[path]
|
||||
for(var/i=0,i<number,i++)
|
||||
H.equip_to_slot_or_del(new path(H),slot_in_backpack)
|
||||
|
||||
if(!H.head && toggle_helmet && istype(H.wear_suit, /obj/item/clothing/suit/space/hardsuit))
|
||||
var/obj/item/clothing/suit/space/hardsuit/HS = H.wear_suit
|
||||
@@ -88,6 +89,10 @@
|
||||
if(internals_slot)
|
||||
H.internal = H.get_item_by_slot(internals_slot)
|
||||
H.update_action_buttons_icon()
|
||||
if(implants)
|
||||
for(var/implant_type in implants)
|
||||
var/obj/item/weapon/implant/I = new implant_type(H)
|
||||
I.implant(H, null, silent=TRUE)
|
||||
|
||||
H.update_body()
|
||||
return 1
|
||||
|
||||
+59
-116
@@ -1,6 +1,4 @@
|
||||
/datum/riding
|
||||
var/generic_pixel_x = 0 //All dirs show this pixel_x for the driver
|
||||
var/generic_pixel_y = 0 //All dirs show this pixel_y for the driver, use these vars if the pixel shift is stable across all dir, override handle_vehicle_offsets otherwise.
|
||||
var/next_vehicle_move = 0 //used for move delays
|
||||
var/vehicle_move_delay = 2 //tick delay between movements, lower = faster, higher = slower
|
||||
var/keytype = null
|
||||
@@ -34,16 +32,29 @@
|
||||
/datum/riding/proc/force_dismount(mob/living/M)
|
||||
ridden.unbuckle_mob(M)
|
||||
|
||||
//Override this to set your vehicle's various pixel offsets
|
||||
//if they differ between directions, otherwise use the
|
||||
//generic variables
|
||||
/datum/riding/proc/handle_vehicle_offsets()
|
||||
var/ridden_dir = "[ridden.dir]"
|
||||
var/passindex = 0
|
||||
if(ridden.has_buckled_mobs())
|
||||
for(var/m in ridden.buckled_mobs)
|
||||
passindex++
|
||||
var/mob/living/buckled_mob = m
|
||||
buckled_mob.setDir(ridden.dir)
|
||||
buckled_mob.pixel_x = generic_pixel_x
|
||||
buckled_mob.pixel_y = generic_pixel_y
|
||||
var/list/offsets = get_offsets(passindex)
|
||||
dir_loop:
|
||||
for(var/offsetdir in offsets)
|
||||
if(offsetdir == ridden_dir)
|
||||
var/list/diroffsets = offsets[offsetdir]
|
||||
buckled_mob.pixel_x = diroffsets[1]
|
||||
if(diroffsets.len == 2)
|
||||
buckled_mob.pixel_y = diroffsets[2]
|
||||
if(diroffsets.len == 3)
|
||||
buckled_mob.layer = diroffsets[3]
|
||||
break dir_loop
|
||||
|
||||
|
||||
//Override this to set your vehicle's various pixel offsets
|
||||
/datum/riding/proc/get_offsets(pass_index) // list(dir = x, y, layer)
|
||||
return list("[NORTH]" = list(0, 0), "[SOUTH]" = list(0, 0), "[EAST]" = list(0, 0), "[WEST]" = list(0, 0))
|
||||
|
||||
//KEYS
|
||||
/datum/riding/proc/keycheck(mob/user)
|
||||
@@ -100,10 +111,12 @@
|
||||
//atv
|
||||
/datum/riding/atv
|
||||
keytype = /obj/item/key
|
||||
generic_pixel_x = 0
|
||||
generic_pixel_y = 4
|
||||
vehicle_move_delay = 1
|
||||
|
||||
/datum/riding/atv/get_offsets(pass_index) // list(dir = x, y, layer)
|
||||
return list("[NORTH]" = list(0, 4), "[SOUTH]" = list(0, 4), "[EAST]" = list(0, 4), "[WEST]" = list( 0, 4))
|
||||
|
||||
|
||||
/datum/riding/atv/handle_vehicle_layer()
|
||||
if(ridden.dir == SOUTH)
|
||||
ridden.layer = ABOVE_MOB_LAYER
|
||||
@@ -150,24 +163,9 @@
|
||||
keytype = /obj/item/key/janitor
|
||||
|
||||
|
||||
/datum/riding/janicart/handle_vehicle_offsets()
|
||||
..()
|
||||
if(ridden.has_buckled_mobs())
|
||||
for(var/m in ridden.buckled_mobs)
|
||||
var/mob/living/buckled_mob = m
|
||||
switch(buckled_mob.dir)
|
||||
if(NORTH)
|
||||
buckled_mob.pixel_x = 0
|
||||
buckled_mob.pixel_y = 4
|
||||
if(EAST)
|
||||
buckled_mob.pixel_x = -12
|
||||
buckled_mob.pixel_y = 7
|
||||
if(SOUTH)
|
||||
buckled_mob.pixel_x = 0
|
||||
buckled_mob.pixel_y = 7
|
||||
if(WEST)
|
||||
buckled_mob.pixel_x = 12
|
||||
buckled_mob.pixel_y = 7
|
||||
/datum/riding/janicart/get_offsets(pass_index) // list(dir = x, y, layer)
|
||||
return list("[NORTH]" = list(0, 4), "[SOUTH]" = list(-12, 7), "[EAST]" = list(0, 7), "[WEST]" = list( 12, 7))
|
||||
|
||||
//scooter
|
||||
/datum/riding/scooter/handle_vehicle_layer()
|
||||
if(ridden.dir == SOUTH)
|
||||
@@ -175,20 +173,14 @@
|
||||
else
|
||||
ridden.layer = OBJ_LAYER
|
||||
|
||||
/datum/riding/scooter/get_offsets(pass_index) // list(dir = x, y, layer)
|
||||
return list("[NORTH]" = list(0), "[SOUTH]" = list(-2), "[EAST]" = list(0), "[WEST]" = list( 2))
|
||||
|
||||
/datum/riding/scooter/handle_vehicle_offsets()
|
||||
..()
|
||||
if(ridden.has_buckled_mobs())
|
||||
for(var/m in ridden.buckled_mobs)
|
||||
var/mob/living/buckled_mob = m
|
||||
switch(buckled_mob.dir)
|
||||
if(NORTH)
|
||||
buckled_mob.pixel_x = 0
|
||||
if(EAST)
|
||||
buckled_mob.pixel_x = -2
|
||||
if(SOUTH)
|
||||
buckled_mob.pixel_x = 0
|
||||
if(WEST)
|
||||
buckled_mob.pixel_x = 2
|
||||
if(buckled_mob.get_num_legs() > 0)
|
||||
buckled_mob.pixel_y = 5
|
||||
else
|
||||
@@ -209,16 +201,18 @@
|
||||
//secway
|
||||
/datum/riding/secway
|
||||
keytype = /obj/item/key/security
|
||||
generic_pixel_x = 0
|
||||
generic_pixel_y = 4
|
||||
|
||||
/datum/riding/secway/get_offsets(pass_index) // list(dir = x, y, layer)
|
||||
return list("[NORTH]" = list(0, 4), "[SOUTH]" = list(0, 4), "[EAST]" = list(0, 4), "[WEST]" = list( 0, 4))
|
||||
|
||||
//i want to ride my
|
||||
/datum/riding/bicycle
|
||||
keytype = null
|
||||
generic_pixel_x = 0
|
||||
generic_pixel_y = 4
|
||||
vehicle_move_delay = 0
|
||||
|
||||
/datum/riding/bicycle/get_offsets(pass_index) // list(dir = x, y, layer)
|
||||
return list("[NORTH]" = list(0, 4), "[SOUTH]" = list(0, 4), "[EAST]" = list(0, 4), "[WEST]" = list( 0, 4))
|
||||
|
||||
//speedbike
|
||||
/datum/riding/space/speedbike
|
||||
keytype = null
|
||||
@@ -233,54 +227,28 @@
|
||||
ridden.pixel_x = -18
|
||||
ridden.pixel_y = 0
|
||||
|
||||
/datum/riding/space/speedbike/handle_vehicle_offsets()
|
||||
if(ridden.has_buckled_mobs())
|
||||
for(var/m in ridden.buckled_mobs)
|
||||
var/mob/living/buckled_mob = m
|
||||
buckled_mob.setDir(ridden.dir)
|
||||
switch(ridden.dir)
|
||||
if(NORTH)
|
||||
buckled_mob.pixel_x = 0
|
||||
buckled_mob.pixel_y = -8
|
||||
if(SOUTH)
|
||||
buckled_mob.pixel_x = 0
|
||||
buckled_mob.pixel_y = 4
|
||||
if(EAST)
|
||||
buckled_mob.pixel_x = -10
|
||||
buckled_mob.pixel_y = 5
|
||||
if(WEST)
|
||||
buckled_mob.pixel_x = 10
|
||||
buckled_mob.pixel_y = 5
|
||||
/datum/riding/space/speedbike/get_offsets(pass_index) // list(dir = x, y, layer)
|
||||
return list("[NORTH]" = list(0, -8), "[SOUTH]" = list(0, 4), "[EAST]" = list(-10, 5), "[WEST]" = list( 10, 5))
|
||||
|
||||
//SPEEDUWAGON
|
||||
|
||||
/datum/riding/space/speedwagon
|
||||
vehicle_move_delay = 0
|
||||
|
||||
/datum/riding/space/speedwagon/handle_vehicle_offsets()
|
||||
if(ridden.has_buckled_mobs())
|
||||
for(var/m in ridden.buckled_mobs)
|
||||
var/mob/living/buckled_mob = m
|
||||
buckled_mob.setDir(ridden.dir)
|
||||
ridden.pixel_x = -48
|
||||
ridden.pixel_y = -48
|
||||
switch(ridden.dir)
|
||||
if(NORTH)
|
||||
buckled_mob.pixel_x = -10
|
||||
buckled_mob.pixel_y = -3
|
||||
if(SOUTH)
|
||||
buckled_mob.pixel_x = 16
|
||||
buckled_mob.pixel_y = 3
|
||||
if(EAST)
|
||||
buckled_mob.pixel_x = -4
|
||||
buckled_mob.pixel_y = 30
|
||||
if(WEST)
|
||||
buckled_mob.pixel_x = 4
|
||||
buckled_mob.pixel_y = -1
|
||||
|
||||
/datum/riding/space/speedwagon/handle_vehicle_layer()
|
||||
ridden.layer = BELOW_MOB_LAYER
|
||||
|
||||
/datum/riding/space/speedwagon/get_offsets(pass_index) // list(dir = x, y, layer)
|
||||
switch(pass_index)
|
||||
if(1)
|
||||
return list("[NORTH]" = list(-10, -4), "[SOUTH]" = list(16, 3), "[EAST]" = list(-4, 30), "[WEST]" = list(4, -3))
|
||||
if(2)
|
||||
return list("[NORTH]" = list(19, -5, 4), "[SOUTH]" = list(-13, 3, 4), "[EAST]" = list(-4, -3, 4.1), "[WEST]" = list(4, 28, 3.9))
|
||||
if(3)
|
||||
return list("[NORTH]" = list(-10, -18, 4.2), "[SOUTH]" = list(16, 25, 3.9), "[EAST]" = list(-22, 30), "[WEST]" = list(22, -3, 4.1))
|
||||
if(4)
|
||||
return list("[NORTH]" = list(19, -18, 4.2), "[SOUTH]" = list(-13, 25, 3.9), "[EAST]" = list(-22, 3, 3.9), "[WEST]" = list(22, 28))
|
||||
|
||||
///////////////BOATS////////////
|
||||
/datum/riding/boat
|
||||
keytype = /obj/item/weapon/oar
|
||||
@@ -297,17 +265,15 @@
|
||||
|
||||
/datum/riding/boat/dragon
|
||||
keytype = null
|
||||
generic_pixel_y = 2
|
||||
generic_pixel_x = 1
|
||||
vehicle_move_delay = 1
|
||||
|
||||
/datum/riding/boat/dragon/get_offsets(pass_index) // list(dir = x, y, layer)
|
||||
return list("[NORTH]" = list(1, 2), "[SOUTH]" = list(1, 2), "[EAST]" = list(1, 2), "[WEST]" = list( 1, 2))
|
||||
|
||||
///////////////ANIMALS////////////
|
||||
//general animals
|
||||
/datum/riding/animal
|
||||
keytype = null
|
||||
generic_pixel_x = 0
|
||||
generic_pixel_y = 4
|
||||
|
||||
/datum/riding/animal/handle_ride(mob/user, direction)
|
||||
if(user.incapacitated())
|
||||
@@ -335,7 +301,7 @@
|
||||
/datum/riding/human/ride_check(mob/living/M)
|
||||
var/mob/living/carbon/human/H = ridden //IF this runtimes I'm blaming the admins.
|
||||
if(M.incapacitated(FALSE, TRUE) || H.incapacitated(FALSE, TRUE))
|
||||
M.visible_message("<span class='warning'>[M] falls off [ridden]!</span>")
|
||||
M.visible_message("<span class='boldwarning'>[M] falls off of [ridden]!</span>")
|
||||
Unbuckle(M)
|
||||
return FALSE
|
||||
if(M.restrained(TRUE))
|
||||
@@ -345,22 +311,8 @@
|
||||
if(H.pulling == M)
|
||||
H.stop_pulling()
|
||||
|
||||
/datum/riding/human/handle_vehicle_offsets()
|
||||
for(var/mob/living/M in ridden.buckled_mobs)
|
||||
M.setDir(ridden.dir)
|
||||
switch(ridden.dir)
|
||||
if(NORTH)
|
||||
M.pixel_x = 0
|
||||
M.pixel_y = 6
|
||||
if(SOUTH)
|
||||
M.pixel_x = 0
|
||||
M.pixel_y = 6
|
||||
if(EAST)
|
||||
M.pixel_x = -6
|
||||
M.pixel_y = 4
|
||||
if(WEST)
|
||||
M.pixel_x = 6
|
||||
M.pixel_y = 4
|
||||
/datum/riding/human/get_offsets(pass_index) // list(dir = x, y, layer)
|
||||
return list("[NORTH]" = list(0, 6), "[SOUTH]" = list(0, 6), "[EAST]" = list(-6, 4), "[WEST]" = list( 6, 4))
|
||||
|
||||
/datum/riding/human/handle_vehicle_layer()
|
||||
if(ridden.buckled_mobs && ridden.buckled_mobs.len)
|
||||
@@ -375,7 +327,7 @@
|
||||
ridden.unbuckle_mob(user)
|
||||
user.Weaken(3)
|
||||
user.Stun(3)
|
||||
user.visible_message("<span class='warning'>[ridden] pushes [user] off of them!</span>")
|
||||
user.visible_message("<span class='boldwarning'>[ridden] pushes [user] off of them!</span>")
|
||||
|
||||
/datum/riding/cyborg
|
||||
keytype = null
|
||||
@@ -407,6 +359,9 @@
|
||||
else
|
||||
ridden.layer = MOB_LAYER
|
||||
|
||||
/datum/riding/cyborg/get_offsets(pass_index) // list(dir = x, y, layer)
|
||||
return list("[NORTH]" = list(0, 4), "[SOUTH]" = list(0, 4), "[EAST]" = list(-6, 3), "[WEST]" = list( 6, 3))
|
||||
|
||||
/datum/riding/cyborg/handle_vehicle_offsets()
|
||||
if(ridden.has_buckled_mobs())
|
||||
for(var/mob/living/M in ridden.buckled_mobs)
|
||||
@@ -417,26 +372,14 @@
|
||||
M.pixel_x = R.module.ride_offset_x[dir2text(ridden.dir)]
|
||||
M.pixel_y = R.module.ride_offset_y[dir2text(ridden.dir)]
|
||||
else
|
||||
switch(ridden.dir)
|
||||
if(NORTH)
|
||||
M.pixel_x = 0
|
||||
M.pixel_y = 4
|
||||
if(SOUTH)
|
||||
M.pixel_x = 0
|
||||
M.pixel_y = 4
|
||||
if(EAST)
|
||||
M.pixel_x = -6
|
||||
M.pixel_y = 3
|
||||
if(WEST)
|
||||
M.pixel_x = 6
|
||||
M.pixel_y = 3
|
||||
..()
|
||||
|
||||
/datum/riding/cyborg/force_dismount(mob/living/M)
|
||||
ridden.unbuckle_mob(M)
|
||||
var/turf/target = get_edge_target_turf(ridden, ridden.dir)
|
||||
var/turf/targetm = get_step(get_turf(ridden), ridden.dir)
|
||||
M.Move(targetm)
|
||||
M.visible_message("<span class='warning'>[M] is thrown clear of [ridden]!</span>")
|
||||
M.visible_message("<span class='boldwarning'>[M] is thrown clear of [ridden]!</span>")
|
||||
M.throw_at(target, 14, 5, ridden)
|
||||
M.Weaken(3)
|
||||
|
||||
|
||||
@@ -181,6 +181,7 @@
|
||||
marked_underlay.pixel_x = -owner.pixel_x
|
||||
marked_underlay.pixel_y = -owner.pixel_y
|
||||
owner.underlays += marked_underlay
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/status_effect/crusher_mark/Destroy()
|
||||
|
||||
@@ -1557,4 +1557,4 @@ GLOBAL_LIST_INIT(the_station_areas, list (
|
||||
/area/ai_monitored/turret_protected/ai_upload, //do not try to simplify to "/area/ai_monitored/turret_protected" --rastaf0
|
||||
/area/ai_monitored/turret_protected/ai_upload_foyer,
|
||||
/area/ai_monitored/turret_protected/ai,
|
||||
))
|
||||
))
|
||||
@@ -57,13 +57,13 @@
|
||||
name = "Mining Station Communications"
|
||||
|
||||
/area/mine/cafeteria
|
||||
name = "Mining station Cafeteria"
|
||||
name = "Mining Station Cafeteria"
|
||||
|
||||
/area/mine/hydroponics
|
||||
name = "Mining station Hydroponics"
|
||||
name = "Mining Station Hydroponics"
|
||||
|
||||
/area/mine/sleeper
|
||||
name = "Mining station Emergency Sleeper"
|
||||
name = "Mining Station Emergency Sleeper"
|
||||
|
||||
/area/mine/north_outpost
|
||||
name = "North Mining Outpost"
|
||||
@@ -86,6 +86,7 @@
|
||||
/area/lavaland
|
||||
icon_state = "mining"
|
||||
has_gravity = 1
|
||||
flags = NONE
|
||||
|
||||
/area/lavaland/surface
|
||||
name = "Lavaland"
|
||||
@@ -123,4 +124,4 @@
|
||||
icon_state = "danger"
|
||||
|
||||
/area/lavaland/surface/outdoors/explored
|
||||
name = "Lavaland Labor Camp"
|
||||
name = "Lavaland Labor Camp"
|
||||
|
||||
@@ -115,15 +115,26 @@
|
||||
/area/prison/solitary
|
||||
name = "Solitary Confinement"
|
||||
icon_state = "brig"
|
||||
|
||||
/area/prison/execution_room
|
||||
name = "Prisoner Education Chamber"
|
||||
icon_state = "armory"
|
||||
|
||||
/area/prison/cell_block/A
|
||||
/area/prison/execution_room
|
||||
name = "Prisoner Education Chamber"
|
||||
icon_state = "armory"
|
||||
|
||||
/area/prison/cell_block/a
|
||||
// /area/prison/cell_block/A
|
||||
name = "Prison Cell Block A"
|
||||
icon_state = "brig"
|
||||
|
||||
/area/prison/cell_block/B
|
||||
/area/prison/cell_block/b
|
||||
// /area/prison/cell_block/B
|
||||
name = "Prison Cell Block B"
|
||||
icon_state = "brig"
|
||||
|
||||
/area/prison/cell_block/C
|
||||
/area/prison/cell_block/c
|
||||
// /area/prison/cell_block/C
|
||||
name = "Prison Cell Block C"
|
||||
icon_state = "brig"
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
icon_state = "away"
|
||||
has_gravity = 1
|
||||
hidden = TRUE
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
|
||||
|
||||
|
||||
/area/ruin/unpowered
|
||||
@@ -20,20 +21,48 @@
|
||||
|
||||
|
||||
//Areas
|
||||
|
||||
/area/ruin/powered/beach
|
||||
icon_state = "dk_yellow"
|
||||
|
||||
/area/ruin/powered/clownplanet
|
||||
icon_state = "dk_yellow"
|
||||
|
||||
/area/ruin/powered/animal_hospital
|
||||
icon_state = "dk_yellow"
|
||||
|
||||
/area/ruin/powered/snow_biodome
|
||||
icon_state = "dk_yellow"
|
||||
|
||||
/area/ruin/powered/gluttony
|
||||
icon_state = "dk_yellow"
|
||||
|
||||
/area/ruin/powered/golem_ship
|
||||
name = "Free Golem Ship"
|
||||
icon_state = "dk_yellow"
|
||||
|
||||
/area/ruin/powered/greed
|
||||
icon_state = "dk_yellow"
|
||||
|
||||
/area/ruin/unpowered/hierophant
|
||||
name = "Hierophant's Arena"
|
||||
icon_state = "dk_yellow"
|
||||
|
||||
/area/ruin/powered/pride
|
||||
icon_state = "dk_yellow"
|
||||
|
||||
/area/ruin/powered/seedvault
|
||||
icon_state = "dk_yellow"
|
||||
|
||||
/area/ruin/powered/syndicate_lava_base
|
||||
name = "Secret Base"
|
||||
icon_state = "dk_yellow"
|
||||
|
||||
|
||||
/area/ruin/unpowered/no_grav/way_home
|
||||
name = "\improper Salvation"
|
||||
icon_state = "away"
|
||||
|
||||
/area/ruin/powered/snow_biodome
|
||||
|
||||
/area/ruin/powered/golem_ship
|
||||
name = "Free Golem Ship"
|
||||
|
||||
/area/ruin/powered/syndicate_lava_base
|
||||
name = "Secret Base"
|
||||
|
||||
// Ruins of "onehalf" ship
|
||||
|
||||
@@ -199,3 +228,15 @@
|
||||
/area/ruin/abandonedzoo
|
||||
name = "Abandoned Zoo"
|
||||
icon_state = "green"
|
||||
|
||||
|
||||
//Xeno Nest
|
||||
|
||||
/area/ruin/xenonest
|
||||
name = "The Hive"
|
||||
always_unpowered = 1
|
||||
power_environ = 0
|
||||
power_equip = 0
|
||||
power_light = 0
|
||||
poweralm = 0
|
||||
|
||||
+36
-33
@@ -28,8 +28,8 @@
|
||||
var/list/our_overlays //our local copy of (non-priority) overlays without byond magic. Use procs in SSoverlays to manipulate
|
||||
var/list/priority_overlays //overlays that should remain on top and not normally removed when using cut_overlay functions, like c4.
|
||||
|
||||
var/datum/proximity_monitor/proximity_monitor
|
||||
|
||||
var/datum/proximity_monitor/proximity_monitor
|
||||
|
||||
/atom/New(loc, ...)
|
||||
//atom creation method that preloads variables at creation
|
||||
if(GLOB.use_preloader && (src.type == GLOB._preloader.target_path))//in case the instanciated atom is creating other atoms in New()
|
||||
@@ -39,21 +39,21 @@
|
||||
|
||||
var/do_initialize = SSatoms.initialized
|
||||
if(do_initialize > INITIALIZATION_INSSATOMS)
|
||||
args[1] = do_initialize == INITIALIZATION_INNEW_MAPLOAD
|
||||
if(SSatoms.InitAtom(src, args))
|
||||
//we were deleted
|
||||
return
|
||||
|
||||
var/list/created = SSatoms.created_atoms
|
||||
if(created)
|
||||
created += src
|
||||
args[1] = do_initialize == INITIALIZATION_INNEW_MAPLOAD
|
||||
if(SSatoms.InitAtom(src, args))
|
||||
//we were deleted
|
||||
return
|
||||
|
||||
var/list/created = SSatoms.created_atoms
|
||||
if(created)
|
||||
created += src
|
||||
|
||||
//Called after New if the map is being loaded. mapload = TRUE
|
||||
//Called from base of New if the map is being loaded. mapload = FALSE
|
||||
//This base must be called or derivatives must set initialized to TRUE
|
||||
//must not sleep
|
||||
//This base must be called or derivatives must set initialized to TRUE
|
||||
//must not sleep
|
||||
//Other parameters are passed from New (excluding loc), this does not happen if mapload is TRUE
|
||||
//Must return an Initialize hint. Defined in __DEFINES/subsystems.dm
|
||||
//Must return an Initialize hint. Defined in __DEFINES/subsystems.dm
|
||||
|
||||
//Note: the following functions don't call the base for optimization and must copypasta:
|
||||
// /turf/Initialize
|
||||
@@ -76,23 +76,23 @@
|
||||
if (opacity && isturf(loc))
|
||||
var/turf/T = loc
|
||||
T.has_opaque_atom = TRUE // No need to recalculate it in this case, it's guaranteed to be on afterwards anyways.
|
||||
return INITIALIZE_HINT_NORMAL
|
||||
return INITIALIZE_HINT_NORMAL
|
||||
|
||||
//called if Initialize returns INITIALIZE_HINT_LATELOAD
|
||||
//This version shouldn't be called
|
||||
/atom/proc/LateInitialize()
|
||||
var/static/list/warned_types = list()
|
||||
if(!warned_types[type])
|
||||
WARNING("Old style LateInitialize behaviour detected in [type]!")
|
||||
warned_types[type] = TRUE
|
||||
Initialize(FALSE)
|
||||
//called if Initialize returns INITIALIZE_HINT_LATELOAD
|
||||
//This version shouldn't be called
|
||||
/atom/proc/LateInitialize()
|
||||
var/static/list/warned_types = list()
|
||||
if(!warned_types[type])
|
||||
WARNING("Old style LateInitialize behaviour detected in [type]!")
|
||||
warned_types[type] = TRUE
|
||||
Initialize(FALSE)
|
||||
|
||||
/atom/Destroy()
|
||||
if(alternate_appearances)
|
||||
for(var/K in alternate_appearances)
|
||||
var/datum/atom_hud/alternate_appearance/AA = alternate_appearances[K]
|
||||
AA.remove_from_hud(src)
|
||||
|
||||
for(var/K in alternate_appearances)
|
||||
var/datum/atom_hud/alternate_appearance/AA = alternate_appearances[K]
|
||||
AA.remove_from_hud(src)
|
||||
|
||||
if(reagents)
|
||||
qdel(reagents)
|
||||
|
||||
@@ -100,10 +100,13 @@
|
||||
LAZYCLEARLIST(priority_overlays)
|
||||
//SSoverlays.processing -= src //we COULD do this, but it's better to just let it fall out of the processing queue
|
||||
|
||||
QDEL_NULL(light)
|
||||
|
||||
QDEL_NULL(light)
|
||||
|
||||
return ..()
|
||||
|
||||
/atom/proc/handle_ricochet(obj/item/projectile/P)
|
||||
return
|
||||
|
||||
/atom/proc/CanPass(atom/movable/mover, turf/target, height=1.5)
|
||||
return (!density || !height)
|
||||
|
||||
@@ -274,7 +277,7 @@
|
||||
return
|
||||
|
||||
/atom/proc/ex_act(severity, target)
|
||||
set waitfor = FALSE
|
||||
set waitfor = FALSE
|
||||
contents_explosion(severity, target)
|
||||
|
||||
/atom/proc/blob_act(obj/structure/blob/B)
|
||||
@@ -506,10 +509,10 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
|
||||
/atom/proc/mech_melee_attack(obj/mecha/M)
|
||||
return
|
||||
|
||||
//If a mob logouts/logins in side of an object you can use this proc
|
||||
/atom/proc/on_log(login)
|
||||
if(loc)
|
||||
loc.on_log(login)
|
||||
//If a mob logouts/logins in side of an object you can use this proc
|
||||
/atom/proc/on_log(login)
|
||||
if(loc)
|
||||
loc.on_log(login)
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
diff a/code/game/atoms.dm b/code/game/atoms.dm (rejected hunks)
|
||||
@@ -274,6 +274,7 @@
|
||||
return
|
||||
|
||||
/atom/proc/ex_act(severity, target)
|
||||
+ set waitfor = FALSE
|
||||
contents_explosion(severity, target)
|
||||
|
||||
/atom/proc/blob_act(obj/structure/blob/B)
|
||||
@@ -236,7 +236,7 @@
|
||||
|
||||
|
||||
/obj/item/weapon/antag_spawner/slaughter_demon/attack_self(mob/user)
|
||||
if(user.z != 1)
|
||||
if(user.z != ZLEVEL_STATION)
|
||||
to_chat(user, "<span class='notice'>You should probably wait until you reach the station.</span>")
|
||||
return
|
||||
if(used)
|
||||
|
||||
@@ -171,14 +171,6 @@ Credit where due:
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/game_mode/clockwork_cult/proc/present_tasks(mob/living/L) //Memorizes and displays the clockwork cult's objective
|
||||
if(!L || !istype(L) || !L.mind)
|
||||
return 0
|
||||
var/datum/mind/M = L.mind
|
||||
to_chat(M.current, "<b>This is Ratvar's will:</b> [CLOCKCULT_OBJECTIVE]")
|
||||
M.memory += "<b>Ratvar's will:</b> [CLOCKCULT_OBJECTIVE]<br>"
|
||||
return 1
|
||||
|
||||
/datum/game_mode/clockwork_cult/proc/check_clockwork_victory()
|
||||
if(GLOB.clockwork_gateway_activated)
|
||||
SSticker.news_report = CLOCK_PROSELYTIZATION //failure, technically, but we have the station
|
||||
|
||||
@@ -375,8 +375,8 @@
|
||||
desc = "Used by veteran cultists to instantly transport items to their needful bretheren."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
brightness_on = 1
|
||||
icon_state = "torch-on"
|
||||
item_state = "torch-on"
|
||||
icon_state = "torch"
|
||||
item_state = "torch"
|
||||
color = "#ff0000"
|
||||
on_damage = 15
|
||||
slot_flags = null
|
||||
|
||||
@@ -233,11 +233,11 @@
|
||||
if(ishuman(M))
|
||||
if(!M.stat)
|
||||
surviving_humans++
|
||||
if(M.z == 2)
|
||||
if(M.z == ZLEVEL_CENTCOM)
|
||||
escaped_humans++
|
||||
if(!M.stat)
|
||||
surviving_total++
|
||||
if(M.z == 2)
|
||||
if(M.z == ZLEVEL_CENTCOM)
|
||||
escaped_total++
|
||||
|
||||
|
||||
|
||||
@@ -261,6 +261,20 @@ GLOBAL_LIST_INIT(gang_outfit_pool, list(/obj/item/clothing/suit/jacket/leather,/
|
||||
gang_bosses += G.bosses
|
||||
return gang_bosses
|
||||
|
||||
/datum/game_mode/proc/shuttle_check()
|
||||
if(SSshuttle.emergencyNoRecall)
|
||||
return
|
||||
var/alive = 0
|
||||
for(var/mob/living/L in GLOB.player_list)
|
||||
if(L.stat != DEAD)
|
||||
alive++
|
||||
|
||||
if((alive < (GLOB.joined_player_list.len * 0.4)) && ((SSshuttle.emergency.timeLeft(1) > (SSshuttle.emergencyCallTime * 0.4))))
|
||||
|
||||
SSshuttle.emergencyNoRecall = TRUE
|
||||
SSshuttle.emergency.request(null, set_coefficient = 0.4)
|
||||
priority_announce("Catastrophic casualties detected: crisis shuttle protocols activated - jamming recall signals across all frequencies.")
|
||||
|
||||
/proc/determine_domination_time(var/datum/gang/G)
|
||||
return max(180,480 - (round((G.territory.len/GLOB.start_state.num_territories)*100, 1) * 9))
|
||||
|
||||
|
||||
@@ -53,7 +53,6 @@
|
||||
/datum/gang_item/weapon/ammo/uzi_ammo,
|
||||
/datum/gang_item/equipment/sharpener,
|
||||
/datum/gang_item/equipment/spraycan,
|
||||
/datum/gang_item/equipment/sharpener,
|
||||
/datum/gang_item/equipment/emp,
|
||||
/datum/gang_item/equipment/c4,
|
||||
/datum/gang_item/equipment/frag,
|
||||
@@ -91,7 +90,6 @@
|
||||
/datum/gang_item/weapon/ammo/uzi_ammo,
|
||||
/datum/gang_item/equipment/sharpener,
|
||||
/datum/gang_item/equipment/spraycan,
|
||||
/datum/gang_item/equipment/sharpener,
|
||||
/datum/gang_item/equipment/emp,
|
||||
/datum/gang_item/equipment/c4,
|
||||
/datum/gang_item/equipment/frag,
|
||||
@@ -204,7 +202,9 @@
|
||||
return
|
||||
var/added_names = ""
|
||||
var/lost_names = ""
|
||||
|
||||
|
||||
SSticker.mode.shuttle_check() // See if its time to start wrapping things up
|
||||
|
||||
//Re-add territories that were reclaimed, so if they got tagged over, they can still earn income if they tag it back before the next status report
|
||||
var/list/reclaimed_territories = territory_new & territory_lost
|
||||
territory |= reclaimed_territories
|
||||
|
||||
@@ -326,6 +326,7 @@
|
||||
if(spawn_msg)
|
||||
to_chat(user, spawn_msg)
|
||||
|
||||
|
||||
/datum/gang_item/equipment/wetwork_boots
|
||||
name = "Wetwork boots"
|
||||
id = "wetwork"
|
||||
@@ -412,7 +413,7 @@
|
||||
/datum/gang_item/equipment/dominator/purchase(mob/living/carbon/user, datum/gang/gang, obj/item/device/gangtool/gangtool)
|
||||
var/area/usrarea = get_area(user.loc)
|
||||
var/usrturf = get_turf(user.loc)
|
||||
if(initial(usrarea.name) == "Space" || isspaceturf(usrturf) || usr.z != 1)
|
||||
if(initial(usrarea.name) == "Space" || isspaceturf(usrturf) || usr.z != ZLEVEL_STATION)
|
||||
to_chat(user, "<span class='warning'>You can only use this on the station!</span>")
|
||||
return FALSE
|
||||
|
||||
@@ -422,7 +423,7 @@
|
||||
return FALSE
|
||||
|
||||
if(dominator_excessive_walls(user))
|
||||
to_chat(user, "span class='warning'>The <b>dominator</b> will not function here! The <b>dominator</b> requires a sizable open space within three standard units so that walls do not interfere with the signal.</span>")
|
||||
to_chat(user, "<span class='warning'>The <b>dominator</b> will not function here! The <b>dominator</b> requires a sizable open space within three standard units so that walls do not interfere with the signal.</span>")
|
||||
return FALSE
|
||||
|
||||
if(!(usrarea.type in gang.territory|gang.territory_new))
|
||||
|
||||
@@ -167,6 +167,9 @@
|
||||
if(!can_use(user))
|
||||
return 0
|
||||
|
||||
if(SSshuttle.emergencyNoRecall)
|
||||
return 0
|
||||
|
||||
if(recalling)
|
||||
to_chat(usr, "<span class='warning'>Error: Recall already in progress.</span>")
|
||||
return 0
|
||||
@@ -194,7 +197,7 @@
|
||||
return 0
|
||||
|
||||
var/turf/userturf = get_turf(user)
|
||||
if(userturf.z != 1) //Shuttle can only be recalled while on station
|
||||
if(userturf.z != ZLEVEL_STATION) //Shuttle can only be recalled while on station
|
||||
to_chat(user, "<span class='warning'>\icon[src]Error: Device out of range of station communication arrays.</span>")
|
||||
recalling = 0
|
||||
return 0
|
||||
@@ -212,7 +215,7 @@
|
||||
log_game("[key_name(user)] has tried to recall the shuttle with a gangtool.")
|
||||
message_admins("[key_name_admin(user)] has tried to recall the shuttle with a gangtool.", 1)
|
||||
userturf = get_turf(user)
|
||||
if(userturf.z == 1) //Check one more time that they are on station.
|
||||
if(userturf.z == ZLEVEL_STATION) //Check one more time that they are on station.
|
||||
if(SSshuttle.cancelEvac(user))
|
||||
gang.recalls -= 1
|
||||
return 1
|
||||
|
||||
@@ -70,12 +70,12 @@
|
||||
origin.vest_mode_action.Remove(C)
|
||||
origin.vest_disguise_action.Remove(C)
|
||||
origin.set_droppoint_action.Remove(C)
|
||||
remote_eye.eye_user = null
|
||||
C.reset_perspective(null)
|
||||
if(C.client)
|
||||
C.client.images -= remote_eye.user_image
|
||||
for(var/datum/camerachunk/chunk in remote_eye.visibleCameraChunks)
|
||||
C.client.images -= chunk.obscured
|
||||
chunk.remove(remote_eye)
|
||||
remote_eye.eye_user = null
|
||||
C.remote_control = null
|
||||
C.unset_machine()
|
||||
Remove(C)
|
||||
|
||||
@@ -181,6 +181,7 @@
|
||||
to_chat(H, "<span class='warning'>You feel intensely watched.</span>")
|
||||
sleep(5)
|
||||
to_chat(H, "<span class='warning'><b>Your mind snaps!</b></span>")
|
||||
to_chat(H, "<big><span class='warning'><b>You can't remember how you got here...</b></span></big>")
|
||||
var/objtype = pick(subtypesof(/datum/objective/abductee/))
|
||||
var/datum/objective/abductee/O = new objtype()
|
||||
SSticker.mode.abductees += H.mind
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
var/icon_stun = "revenant_stun"
|
||||
var/icon_drain = "revenant_draining"
|
||||
var/stasis = FALSE
|
||||
incorporeal_move = 3
|
||||
incorporeal_move = INCORPOREAL_MOVE_JAUNT
|
||||
invisibility = INVISIBILITY_REVENANT
|
||||
health = INFINITY //Revenants don't use health, they use essence instead
|
||||
maxHealth = INFINITY
|
||||
@@ -102,7 +102,7 @@
|
||||
if(unreveal_time && world.time >= unreveal_time)
|
||||
unreveal_time = 0
|
||||
revealed = FALSE
|
||||
incorporeal_move = 3
|
||||
incorporeal_move = INCORPOREAL_MOVE_JAUNT
|
||||
invisibility = INVISIBILITY_REVENANT
|
||||
to_chat(src, "<span class='revenboldnotice'>You are once more concealed.</span>")
|
||||
if(unstun_time && world.time >= unstun_time)
|
||||
@@ -222,7 +222,7 @@
|
||||
R.essence = max(reforming_essence - 15 * perfectsouls, 75) //minus any perfect souls
|
||||
R.client_to_revive = client //If the essence reforms, the old revenant is put back in the body
|
||||
R.revenant = src
|
||||
invisibility = INVISIBILITY_ABSTRACT
|
||||
invisibility = INVISIBILITY_ABSTRACT
|
||||
revealed = FALSE
|
||||
ghostize(0)//Don't re-enter invisible corpse
|
||||
return
|
||||
@@ -236,7 +236,7 @@
|
||||
return
|
||||
revealed = TRUE
|
||||
invisibility = 0
|
||||
incorporeal_move = 0
|
||||
incorporeal_move = FALSE
|
||||
if(!unreveal_time)
|
||||
to_chat(src, "<span class='revendanger'>You have been revealed!</span>")
|
||||
unreveal_time = world.time + time
|
||||
@@ -309,12 +309,12 @@
|
||||
|
||||
/mob/living/simple_animal/revenant/proc/death_reset()
|
||||
revealed = FALSE
|
||||
unreveal_time = 0
|
||||
unreveal_time = 0
|
||||
notransform = 0
|
||||
unstun_time = 0
|
||||
inhibited = FALSE
|
||||
draining = FALSE
|
||||
incorporeal_move = 3
|
||||
incorporeal_move = INCORPOREAL_MOVE_JAUNT
|
||||
invisibility = INVISIBILITY_REVENANT
|
||||
alpha=255
|
||||
stasis = FALSE
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#define PINPOINTER_MINIMUM_RANGE 15
|
||||
#define PINPOINTER_EXTRA_RANDOM_RANGE 10
|
||||
#define PINPOINTER_PING_TIME 40
|
||||
#define PROB_ACTUAL_TRAITOR 20
|
||||
#define TRAITOR_AGENT_ROLE "Syndicate External Affairs Agent"
|
||||
|
||||
/datum/game_mode/traitor/internal_affairs
|
||||
name = "Internal Affairs"
|
||||
@@ -171,7 +173,10 @@
|
||||
if(!objective.check_completion())
|
||||
traitored = FALSE
|
||||
return
|
||||
to_chat(owner.current,"<span class='userdanger'> All the other agents are dead, and you're the last loose end. Stage a Syndicate terrorist attack to cover up for today's events. You no longer have any limits on collateral damage.</span>")
|
||||
if(owner.special_role == TRAITOR_AGENT_ROLE)
|
||||
to_chat(owner.current,"<span class='userdanger'> All the loyalist agents are dead, and no more is required of you. Die a glorious death, agent. </span>")
|
||||
else
|
||||
to_chat(owner.current,"<span class='userdanger'> All the other agents are dead, and you're the last loose end. Stage a Syndicate terrorist attack to cover up for today's events. You no longer have any limits on collateral damage.</span>")
|
||||
replace_escape_objective(owner)
|
||||
|
||||
|
||||
@@ -194,7 +199,10 @@
|
||||
if(objective.stolen)
|
||||
var/fail_msg = "<span class='userdanger'>Your sensors tell you that [objective.target.current.real_name], one of the targets you were meant to have killed, pulled one over on you, and is still alive - do the job properly this time! </span>"
|
||||
if(traitored)
|
||||
fail_msg += "<span class='userdanger'> The truth could still slip out!</font><B><font size=5 color=red> Cease any terrorist actions as soon as possible, unneeded property damage or loss of employee life will lead to your contract being terminated.</span>"
|
||||
if(owner.special_role == TRAITOR_AGENT_ROLE)
|
||||
fail_msg += "<span class='userdanger'> You no longer have permission to die. </span>"
|
||||
else
|
||||
fail_msg += "<span class='userdanger'> The truth could still slip out!</font><B><font size=5 color=red> Cease any terrorist actions as soon as possible, unneeded property damage or loss of employee life will lead to your contract being terminated.</span>"
|
||||
reinstate_escape_objective(owner)
|
||||
traitored = FALSE
|
||||
to_chat(owner.current, fail_msg)
|
||||
@@ -238,6 +246,10 @@
|
||||
state.add_steal_targets_timer()
|
||||
if(!issilicon(traitor.current))
|
||||
give_pinpointer(traitor)
|
||||
//Optional traitor objective
|
||||
if(prob(PROB_ACTUAL_TRAITOR))
|
||||
traitor.special_role = TRAITOR_AGENT_ROLE
|
||||
forge_single_objective(traitor)
|
||||
|
||||
else
|
||||
..() // Give them standard objectives.
|
||||
@@ -289,11 +301,18 @@
|
||||
|
||||
/datum/game_mode/traitor/internal_affairs/greet_traitor(datum/mind/traitor)
|
||||
var/crime = pick("distribution of contraband" , "unauthorized erotic action on duty", "embezzlement", "piloting under the influence", "dereliction of duty", "syndicate collaboration", "mutiny", "multiple homicides", "corporate espionage", "recieving bribes", "malpractice", "worship of prohbited life forms", "possession of profane texts", "murder", "arson", "insulting their manager", "grand theft", "conspiracy", "attempting to unionize", "vandalism", "gross incompetence")
|
||||
to_chat(traitor.current, "<span class='userdanger'>You are the [traitor_name].</span>")
|
||||
to_chat(traitor.current, "<span class='userdanger'>Your target is suspected of [crime], and you have been tasked with eliminating them by any means necessary to avoid a costly and embarrassing public trial.</span>")
|
||||
to_chat(traitor.current, "<B><font size=5 color=red>While you have a license to kill, unneeded property damage or loss of employee life will lead to your contract being terminated.</font></B>")
|
||||
to_chat(traitor.current, "<span class='userdanger'>For the sake of plausible deniability, you have been equipped with an array of captured Syndicate weaponry available via uplink.</span>")
|
||||
to_chat(traitor.current, "<span class='userdanger'>Finally, watch your back. Your target has friends in high places, and intel suggests someone may have taken out a contract of their own to protect them.</span>")
|
||||
if(traitor.special_role == TRAITOR_AGENT_ROLE)
|
||||
to_chat(traitor.current, "<span class='userdanger'>You are the [TRAITOR_AGENT_ROLE].</span>")
|
||||
to_chat(traitor.current, "<span class='userdanger'>Your target has been framed for [crime], and you have been tasked with eliminating them to prevent them defending themselves in court.</span>")
|
||||
to_chat(traitor.current, "<B><font size=5 color=red>Any damage you cause will be a further embarrassment to Nanotrasen, so you have no limits on collateral damage.</font></B>")
|
||||
to_chat(traitor.current, "<span class='userdanger'> You have been provided with a standard uplink to accomplish your task. </span>")
|
||||
to_chat(traitor.current, "<span class='userdanger'>Finally, watch your back. Your target has friends in high places, and intel suggests someone may have taken out a contract of their own to protect them.</span>")
|
||||
else
|
||||
to_chat(traitor.current, "<span class='userdanger'>You are the [traitor_name].</span>")
|
||||
to_chat(traitor.current, "<span class='userdanger'>Your target is suspected of [crime], and you have been tasked with eliminating them by any means necessary to avoid a costly and embarrassing public trial.</span>")
|
||||
to_chat(traitor.current, "<B><font size=5 color=red>While you have a license to kill, unneeded property damage or loss of employee life will lead to your contract being terminated.</font></B>")
|
||||
to_chat(traitor.current, "<span class='userdanger'>For the sake of plausible deniability, you have been equipped with an array of captured Syndicate weaponry available via uplink.</span>")
|
||||
to_chat(traitor.current, "<span class='userdanger'>Finally, watch your back. Your target has friends in high places, and intel suggests someone may have taken out a contract of their own to protect them.</span>")
|
||||
traitor.announce_objectives()
|
||||
|
||||
|
||||
@@ -301,6 +320,8 @@
|
||||
/datum/game_mode/traitor/internal_affairs/give_codewords(mob/living/traitor_mob)
|
||||
return
|
||||
|
||||
#undef PROB_ACTUAL_TRAITOR
|
||||
#undef PINPOINTER_EXTRA_RANDOM_RANGE
|
||||
#undef PINPOINTER_MINIMUM_RANGE
|
||||
#undef PINPOINTER_PING_TIME
|
||||
|
||||
|
||||
@@ -85,40 +85,65 @@
|
||||
character.make_Traitor()
|
||||
|
||||
|
||||
/datum/game_mode/proc/forge_single_objective(datum/mind/traitor) //Returns how many objectives are added
|
||||
.=1
|
||||
if(issilicon(traitor.current))
|
||||
var/special_pick = rand(1,4)
|
||||
switch(special_pick)
|
||||
if(1)
|
||||
var/datum/objective/block/block_objective = new
|
||||
block_objective.owner = traitor
|
||||
traitor.objectives += block_objective
|
||||
if(2)
|
||||
var/datum/objective/purge/purge_objective = new
|
||||
purge_objective.owner = traitor
|
||||
traitor.objectives += purge_objective
|
||||
if(3)
|
||||
var/datum/objective/robot_army/robot_objective = new
|
||||
robot_objective.owner = traitor
|
||||
traitor.objectives += robot_objective
|
||||
if(4) //Protect and strand a target
|
||||
var/datum/objective/protect/yandere_one = new
|
||||
yandere_one.owner = traitor
|
||||
traitor.objectives += yandere_one
|
||||
yandere_one.find_target()
|
||||
var/datum/objective/maroon/yandere_two = new
|
||||
yandere_two.owner = traitor
|
||||
yandere_two.target = yandere_one.target
|
||||
yandere_two.update_explanation_text() // normally called in find_target()
|
||||
traitor.objectives += yandere_two
|
||||
.=2
|
||||
else
|
||||
if(prob(50))
|
||||
var/list/active_ais = active_ais()
|
||||
if(active_ais.len && prob(100/GLOB.joined_player_list.len))
|
||||
var/datum/objective/destroy/destroy_objective = new
|
||||
destroy_objective.owner = traitor
|
||||
destroy_objective.find_target()
|
||||
traitor.objectives += destroy_objective
|
||||
else if(prob(30))
|
||||
var/datum/objective/maroon/maroon_objective = new
|
||||
maroon_objective.owner = traitor
|
||||
maroon_objective.find_target()
|
||||
traitor.objectives += maroon_objective
|
||||
else
|
||||
var/datum/objective/assassinate/kill_objective = new
|
||||
kill_objective.owner = traitor
|
||||
kill_objective.find_target()
|
||||
traitor.objectives += kill_objective
|
||||
else
|
||||
var/datum/objective/steal/steal_objective = new
|
||||
steal_objective.owner = traitor
|
||||
steal_objective.find_target()
|
||||
traitor.objectives += steal_objective
|
||||
|
||||
|
||||
/datum/game_mode/proc/forge_traitor_objectives(datum/mind/traitor)
|
||||
if(issilicon(traitor.current))
|
||||
var/objective_count = 0
|
||||
|
||||
if(prob(30))
|
||||
var/special_pick = rand(1,4)
|
||||
switch(special_pick)
|
||||
if(1)
|
||||
var/datum/objective/block/block_objective = new
|
||||
block_objective.owner = traitor
|
||||
traitor.objectives += block_objective
|
||||
objective_count++
|
||||
if(2)
|
||||
var/datum/objective/purge/purge_objective = new
|
||||
purge_objective.owner = traitor
|
||||
traitor.objectives += purge_objective
|
||||
objective_count++
|
||||
if(3)
|
||||
var/datum/objective/robot_army/robot_objective = new
|
||||
robot_objective.owner = traitor
|
||||
traitor.objectives += robot_objective
|
||||
objective_count++
|
||||
if(4) //Protect and strand a target
|
||||
var/datum/objective/protect/yandere_one = new
|
||||
yandere_one.owner = traitor
|
||||
traitor.objectives += yandere_one
|
||||
yandere_one.find_target()
|
||||
objective_count++
|
||||
var/datum/objective/maroon/yandere_two = new
|
||||
yandere_two.owner = traitor
|
||||
yandere_two.target = yandere_one.target
|
||||
yandere_two.update_explanation_text() // normally called in find_target()
|
||||
traitor.objectives += yandere_two
|
||||
objective_count++
|
||||
objective_count+=forge_single_objective(traitor)
|
||||
|
||||
for(var/i = objective_count, i < config.traitor_objectives_amount, i++)
|
||||
var/datum/objective/assassinate/kill_objective = new
|
||||
@@ -142,29 +167,8 @@
|
||||
assign_exchange_role(exchange_red)
|
||||
assign_exchange_role(exchange_blue)
|
||||
objective_count += 1 //Exchange counts towards number of objectives
|
||||
var/list/active_ais = active_ais()
|
||||
for(var/i = objective_count, i < config.traitor_objectives_amount, i++)
|
||||
if(prob(50))
|
||||
if(active_ais.len && prob(100/GLOB.joined_player_list.len))
|
||||
var/datum/objective/destroy/destroy_objective = new
|
||||
destroy_objective.owner = traitor
|
||||
destroy_objective.find_target()
|
||||
traitor.objectives += destroy_objective
|
||||
else if(prob(30))
|
||||
var/datum/objective/maroon/maroon_objective = new
|
||||
maroon_objective.owner = traitor
|
||||
maroon_objective.find_target()
|
||||
traitor.objectives += maroon_objective
|
||||
else
|
||||
var/datum/objective/assassinate/kill_objective = new
|
||||
kill_objective.owner = traitor
|
||||
kill_objective.find_target()
|
||||
traitor.objectives += kill_objective
|
||||
else
|
||||
var/datum/objective/steal/steal_objective = new
|
||||
steal_objective.owner = traitor
|
||||
steal_objective.find_target()
|
||||
traitor.objectives += steal_objective
|
||||
forge_single_objective(traitor)
|
||||
|
||||
if(is_hijacker && objective_count <= config.traitor_objectives_amount) //Don't assign hijack if it would exceed the number of objectives set in config.traitor_objectives_amount
|
||||
if (!(locate(/datum/objective/hijack) in traitor.objectives))
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "soulstone"
|
||||
item_state = "electronic"
|
||||
layer = HIGH_OBJ_LAYER
|
||||
desc = "A fragment of the legendary treasure known simply as the 'Soul Stone'. The shard still flickers with a fraction of the full artefact's power."
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
slot_flags = SLOT_BELT
|
||||
@@ -213,12 +214,12 @@
|
||||
var/obj/screen/alert/bloodsense/BS
|
||||
if(newstruct.mind && ((stoner && iscultist(stoner)) || cultoverride) && SSticker && SSticker.mode)
|
||||
SSticker.mode.add_cultist(newstruct.mind, 0)
|
||||
BS = newstruct.alerts.Find("bloodsense")
|
||||
if(iscultist(stoner) || cultoverride)
|
||||
to_chat(newstruct, "<b>You are still bound to serve the cult[stoner ? " and [stoner]":""], follow their orders and help them complete their goals at all costs.</b>")
|
||||
else if(stoner)
|
||||
to_chat(newstruct, "<b>You are still bound to serve your creator, [stoner], follow their orders and help them complete their goals at all costs.</b>")
|
||||
BS = newstruct.throw_alert("bloodsense", /obj/screen/alert/bloodsense)
|
||||
newstruct.clear_alert("bloodsense")
|
||||
BS = newstruct.throw_alert("bloodsense", /obj/screen/alert/bloodsense)
|
||||
if(BS)
|
||||
BS.Cviewer = newstruct
|
||||
newstruct.cancel_camera()
|
||||
|
||||
@@ -44,8 +44,8 @@
|
||||
"corazone", // prevents cardiac arrest damage
|
||||
"mimesbane") // stops them gasping from lack of air.
|
||||
|
||||
/obj/machinery/clonepod/New()
|
||||
..()
|
||||
/obj/machinery/clonepod/Initialize()
|
||||
. = ..()
|
||||
var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/clonepod(null)
|
||||
B.apply_default_parts(src)
|
||||
|
||||
@@ -358,8 +358,12 @@
|
||||
/obj/machinery/clonepod/proc/go_out()
|
||||
countdown.stop()
|
||||
var/mob/living/mob_occupant = occupant
|
||||
var/turf/T = get_turf(src)
|
||||
|
||||
if(mess) //Clean that mess and dump those gibs!
|
||||
for(var/obj/fl in unattached_flesh)
|
||||
fl.forceMove(T)
|
||||
unattached_flesh.Cut()
|
||||
mess = FALSE
|
||||
new /obj/effect/gibspawner/generic(loc)
|
||||
audible_message("<span class='italics'>You hear a splat.</span>")
|
||||
@@ -375,10 +379,12 @@
|
||||
to_chat(occupant, "<span class='notice'><b>There is a bright flash!</b><br><i>You feel like a new being.</i></span>")
|
||||
mob_occupant.flash_act()
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
occupant.forceMove(T)
|
||||
icon_state = "pod_0"
|
||||
mob_occupant.domutcheck(1) //Waiting until they're out before possible monkeyizing. The 1 argument forces powers to manifest.
|
||||
for(var/fl in unattached_flesh)
|
||||
qdel(fl)
|
||||
unattached_flesh.Cut()
|
||||
|
||||
occupant = null
|
||||
|
||||
@@ -389,8 +395,7 @@
|
||||
SPEAK("Critical error! Please contact a Thinktronic Systems \
|
||||
technician, as your warranty may be affected.")
|
||||
mess = TRUE
|
||||
for(var/obj/item/O in unattached_flesh)
|
||||
qdel(O)
|
||||
maim_clone(mob_occupant) //Remove every bit that's grown back so far to drop later, also destroys bits that haven't grown yet
|
||||
icon_state = "pod_g"
|
||||
if(mob_occupant.mind != clonemind)
|
||||
clonemind.transfer_to(mob_occupant)
|
||||
@@ -450,9 +455,10 @@
|
||||
var/static/list/zones = list("r_arm", "l_arm", "r_leg", "l_leg")
|
||||
for(var/zone in zones)
|
||||
var/obj/item/bodypart/BP = H.get_bodypart(zone)
|
||||
BP.drop_limb()
|
||||
BP.forceMove(src)
|
||||
unattached_flesh += BP
|
||||
if(BP)
|
||||
BP.drop_limb()
|
||||
BP.forceMove(src)
|
||||
unattached_flesh += BP
|
||||
|
||||
for(var/o in H.internal_organs)
|
||||
var/obj/item/organ/organ = o
|
||||
|
||||
@@ -1056,17 +1056,21 @@
|
||||
|
||||
/obj/effect/mob_spawn/human/corpse/orionsecurity
|
||||
name = "Spaceport Security"
|
||||
id_job = "Officer"
|
||||
id_access_list = list(GLOB.access_syndicate)
|
||||
outfit = /datum/outfit/orionsecurity
|
||||
|
||||
/datum/outfit/orionsecurity
|
||||
name = "Orion Spaceport Security"
|
||||
uniform = /obj/item/clothing/under/syndicate
|
||||
suit = /obj/item/clothing/suit/armor/vest
|
||||
shoes = /obj/item/clothing/shoes/combat
|
||||
gloves = /obj/item/clothing/gloves/combat
|
||||
radio = /obj/item/device/radio/headset
|
||||
ears = /obj/item/device/radio/headset
|
||||
mask = /obj/item/clothing/mask/gas
|
||||
helmet = /obj/item/clothing/head/helmet/swat
|
||||
head = /obj/item/clothing/head/helmet/swat
|
||||
back = /obj/item/weapon/storage/backpack
|
||||
has_id = 1
|
||||
id_job = "Officer"
|
||||
id_access_list = list(GLOB.access_syndicate)
|
||||
id = /obj/item/weapon/card/id
|
||||
|
||||
/obj/item/weapon/orion_ship
|
||||
name = "model settler ship"
|
||||
|
||||
@@ -178,7 +178,7 @@
|
||||
/obj/item/weapon/circuitboard/computer/xenobiology
|
||||
name = "circuit board (Xenobiology Console)"
|
||||
build_path = /obj/machinery/computer/camera_advanced/xenobio
|
||||
origin_tech = "programming=3;bio=3"
|
||||
origin_tech = "programming=3;biotech=3"
|
||||
/obj/item/weapon/circuitboard/computer/base_construction
|
||||
name = "circuit board (Aux Mining Base Construction Console)"
|
||||
build_path = /obj/machinery/computer/camera_advanced/base_construction
|
||||
|
||||
@@ -151,13 +151,13 @@ obj/machinery/computer/camera_advanced/attack_ai(mob/user)
|
||||
var/mob/camera/aiEye/remote/remote_eye = C.remote_control
|
||||
remote_eye.origin.current_user = null
|
||||
remote_eye.origin.jump_action.Remove(C)
|
||||
remote_eye.eye_user = null
|
||||
if(C.client)
|
||||
C.reset_perspective(null)
|
||||
if(remote_eye.visible_icon)
|
||||
C.client.images -= remote_eye.user_image
|
||||
for(var/datum/camerachunk/chunk in remote_eye.visibleCameraChunks)
|
||||
C.client.images -= chunk.obscured
|
||||
chunk.remove(remote_eye)
|
||||
remote_eye.eye_user = null
|
||||
C.remote_control = null
|
||||
C.unset_machine()
|
||||
Remove(C)
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
/obj/machinery/computer/communications/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
if (src.z > ZLEVEL_CENTCOM) //Can only use on centcom and SS13
|
||||
if (z != ZLEVEL_STATION && z != ZLEVEL_CENTCOM) //Can only use on centcom and SS13
|
||||
to_chat(usr, "<span class='boldannounce'>Unable to establish a connection</span>: \black You're too far away from the station!")
|
||||
return
|
||||
usr.set_machine(src)
|
||||
|
||||
@@ -292,7 +292,7 @@
|
||||
src.temp = text("Are you sure you wish to delete all records?<br>\n\t<A href='?src=\ref[];temp=1;del_all2=1'>Yes</A><br>\n\t<A href='?src=\ref[];temp=1'>No</A><br>", src, src)
|
||||
|
||||
else if(href_list["del_all2"])
|
||||
investigate_log("[usr.name] ([usr.key]) has deleted all medical records.", "records")
|
||||
investigate_log("[usr.name] ([usr.key]) has deleted all medical records.", INVESTIGATE_RECORDS)
|
||||
GLOB.data_core.medical.Cut()
|
||||
src.temp = "All records deleted."
|
||||
|
||||
@@ -458,7 +458,7 @@
|
||||
src.temp = text("Are you sure you wish to delete the record (Medical Portion Only)?<br>\n\t<A href='?src=\ref[];temp=1;del_r2=1'>Yes</A><br>\n\t<A href='?src=\ref[];temp=1'>No</A><br>", src, src)
|
||||
|
||||
else if(href_list["del_r2"])
|
||||
investigate_log("[usr.name] ([usr.key]) has deleted the medical records for [active1.fields["name"]].", "records")
|
||||
investigate_log("[usr.name] ([usr.key]) has deleted the medical records for [active1.fields["name"]].", INVESTIGATE_RECORDS)
|
||||
if(active2)
|
||||
qdel(active2)
|
||||
active2 = null
|
||||
|
||||
@@ -452,7 +452,7 @@ What a mess.*/
|
||||
temp += "<a href='?src=\ref[src];choice=Clear Screen'>No</a>"
|
||||
|
||||
if("Purge All Records")
|
||||
investigate_log("[usr.name] ([usr.key]) has purged all the security records.", "records")
|
||||
investigate_log("[usr.name] ([usr.key]) has purged all the security records.", INVESTIGATE_RECORDS)
|
||||
for(var/datum/data/record/R in GLOB.data_core.security)
|
||||
qdel(R)
|
||||
GLOB.data_core.security.Cut()
|
||||
@@ -696,18 +696,18 @@ What a mess.*/
|
||||
active2.fields["criminal"] = "Parolled"
|
||||
if("released")
|
||||
active2.fields["criminal"] = "Discharged"
|
||||
investigate_log("[active1.fields["name"]] has been set from [old_field] to [active2.fields["criminal"]] by [usr.name] ([usr.key]).", "records")
|
||||
investigate_log("[active1.fields["name"]] has been set from [old_field] to [active2.fields["criminal"]] by [usr.name] ([usr.key]).", INVESTIGATE_RECORDS)
|
||||
for(var/mob/living/carbon/human/H in GLOB.mob_list) //thanks for forcing me to do this, whoever wrote this shitty records system
|
||||
H.sec_hud_set_security_status()
|
||||
if("Delete Record (Security) Execute")
|
||||
investigate_log("[usr.name] ([usr.key]) has deleted the security records for [active1.fields["name"]].", "records")
|
||||
investigate_log("[usr.name] ([usr.key]) has deleted the security records for [active1.fields["name"]].", INVESTIGATE_RECORDS)
|
||||
if(active2)
|
||||
qdel(active2)
|
||||
active2 = null
|
||||
|
||||
if("Delete Record (ALL) Execute")
|
||||
if(active1)
|
||||
investigate_log("[usr.name] ([usr.key]) has deleted all records for [active1.fields["name"]].", "records")
|
||||
investigate_log("[usr.name] ([usr.key]) has deleted all records for [active1.fields["name"]].", INVESTIGATE_RECORDS)
|
||||
for(var/datum/data/record/R in GLOB.data_core.medical)
|
||||
if((R.fields["name"] == active1.fields["name"] || R.fields["id"] == active1.fields["id"]))
|
||||
qdel(R)
|
||||
|
||||
@@ -317,7 +317,7 @@
|
||||
|
||||
|
||||
/obj/machinery/disco/proc/dance(var/mob/living/M) //Show your moves
|
||||
|
||||
set waitfor = FALSE
|
||||
switch(rand(0,9))
|
||||
if(0 to 1)
|
||||
dance2(M)
|
||||
|
||||
@@ -97,7 +97,14 @@
|
||||
var/static/list/airlock_overlays = list()
|
||||
|
||||
/obj/machinery/door/airlock/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
if (cyclelinkeddir)
|
||||
cyclelinkairlock()
|
||||
if(frequency)
|
||||
set_frequency(frequency)
|
||||
update_icon()
|
||||
|
||||
wires = new /datum/wires/airlock(src)
|
||||
if(src.closeOtherId != null)
|
||||
spawn (5)
|
||||
@@ -120,14 +127,6 @@
|
||||
diag_hud.add_to_hud(src)
|
||||
diag_hud_set_electrified()
|
||||
|
||||
/obj/machinery/door/airlock/Initialize()
|
||||
..()
|
||||
if (cyclelinkeddir)
|
||||
cyclelinkairlock()
|
||||
if(frequency)
|
||||
set_frequency(frequency)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/door/airlock/proc/cyclelinkairlock()
|
||||
if (cyclelinkedairlock)
|
||||
cyclelinkedairlock.cyclelinkedairlock = null
|
||||
@@ -199,14 +198,11 @@
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/door/airlock/Destroy()
|
||||
qdel(wires)
|
||||
wires = null
|
||||
QDEL_NULL(wires)
|
||||
if(charge)
|
||||
qdel(charge)
|
||||
charge = null
|
||||
if(electronics)
|
||||
qdel(electronics)
|
||||
electronics = null
|
||||
QDEL_NULL(electronics)
|
||||
if (cyclelinkedairlock)
|
||||
if (cyclelinkedairlock.cyclelinkedairlock == src)
|
||||
cyclelinkedairlock.cyclelinkedairlock = null
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
GLOBAL_LIST_EMPTY(doppler_arrays)
|
||||
|
||||
GLOBAL_LIST_EMPTY(doppler_arrays)
|
||||
|
||||
/obj/machinery/doppler_array
|
||||
name = "tachyon-doppler array"
|
||||
desc = "A highly precise directional sensor array which measures the release of quants from decaying tachyons. The doppler shifting of the mirror-image formed by these quants can reveal the size, location and temporal affects of energetic disturbances within a large radius ahead of the array.\n<span class='notice'>Alt-click to rotate it clockwise.</span>"
|
||||
@@ -13,10 +13,10 @@ GLOBAL_LIST_EMPTY(doppler_arrays)
|
||||
|
||||
/obj/machinery/doppler_array/New()
|
||||
..()
|
||||
GLOB.doppler_arrays += src
|
||||
GLOB.doppler_arrays += src
|
||||
|
||||
/obj/machinery/doppler_array/Destroy()
|
||||
GLOB.doppler_arrays -= src
|
||||
GLOB.doppler_arrays -= src
|
||||
return ..()
|
||||
|
||||
/obj/machinery/doppler_array/process()
|
||||
|
||||
@@ -51,7 +51,7 @@ Possible to do for anyone motivated enough:
|
||||
var/static/list/holopads = list()
|
||||
|
||||
/obj/machinery/holopad/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/holopad(null)
|
||||
B.apply_default_parts(src)
|
||||
holopads += src
|
||||
@@ -112,6 +112,10 @@ Possible to do for anyone motivated enough:
|
||||
return ..()
|
||||
|
||||
/obj/machinery/holopad/AltClick(mob/living/carbon/human/user)
|
||||
if(isAI(user))
|
||||
hangup_all_calls()
|
||||
return
|
||||
|
||||
if(!CheckCallClose())
|
||||
interact(user)
|
||||
|
||||
@@ -157,6 +161,12 @@ Possible to do for anyone motivated enough:
|
||||
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
|
||||
popup.open()
|
||||
|
||||
//Stop ringing the AI!!
|
||||
/obj/machinery/holopad/proc/hangup_all_calls()
|
||||
for(var/I in holo_calls)
|
||||
var/datum/holocall/HC = I
|
||||
HC.Disconnect(src)
|
||||
|
||||
/obj/machinery/holopad/Topic(href, href_list)
|
||||
if(..() || isAI(usr))
|
||||
return
|
||||
|
||||
@@ -143,7 +143,7 @@
|
||||
else
|
||||
log_msg += "nothing"
|
||||
log_msg += " [sending ? "to" : "from"] [target_x], [target_y], [z] ([A ? A.name : "null area"])"
|
||||
investigate_log(log_msg.Join(), "telesci")
|
||||
investigate_log(log_msg.Join(), INVESTIGATE_TELESCI)
|
||||
updateDialog()
|
||||
|
||||
//Starts in the briefcase. Don't spawn this directly, or it will runtime when closing.
|
||||
|
||||
@@ -87,7 +87,9 @@
|
||||
if(has_cover)
|
||||
cover = new /obj/machinery/porta_turret_cover(loc)
|
||||
cover.parent_turret = src
|
||||
underlays += image('icons/obj/turrets.dmi',icon_state = "basedark")
|
||||
var/mutable_appearance/base = mutable_appearance('icons/obj/turrets.dmi', "basedark")
|
||||
base.layer = NOT_HIGH_OBJ_LAYER
|
||||
underlays += base
|
||||
if(!has_cover)
|
||||
INVOKE_ASYNC(src, .proc/popUp)
|
||||
|
||||
@@ -227,7 +229,6 @@
|
||||
update_icon()
|
||||
|
||||
|
||||
|
||||
/obj/machinery/porta_turret/attackby(obj/item/I, mob/user, params)
|
||||
if(stat & BROKEN)
|
||||
if(istype(I, /obj/item/weapon/crowbar))
|
||||
@@ -553,6 +554,7 @@
|
||||
use_power = 0
|
||||
has_cover = 0
|
||||
scan_range = 9
|
||||
req_access = list(GLOB.access_syndicate)
|
||||
stun_projectile = /obj/item/projectile/bullet
|
||||
lethal_projectile = /obj/item/projectile/bullet
|
||||
lethal_projectile_sound = 'sound/weapons/Gunshot.ogg'
|
||||
@@ -569,6 +571,8 @@
|
||||
return 10 //Syndicate turrets shoot everything not in their faction
|
||||
|
||||
/obj/machinery/porta_turret/syndicate/pod
|
||||
max_integrity = 40
|
||||
integrity_failure = 20
|
||||
obj_integrity = 40
|
||||
stun_projectile = /obj/item/projectile/bullet/weakbullet3
|
||||
lethal_projectile = /obj/item/projectile/bullet/weakbullet3
|
||||
@@ -944,6 +948,7 @@
|
||||
var/atom/target
|
||||
var/turf/target_turf
|
||||
var/warned = FALSE
|
||||
var/mouseparams
|
||||
|
||||
//BUCKLE HOOKS
|
||||
|
||||
@@ -987,8 +992,8 @@
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon_state = "offhand"
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
flags = ABSTRACT | NODROP
|
||||
resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF | NOBLUDGEON
|
||||
flags = ABSTRACT | NODROP | NOBLUDGEON
|
||||
resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
var/obj/machinery/manned_turret/turret
|
||||
|
||||
/obj/item/gun_control/New(obj/machinery/manned_turret/MT)
|
||||
@@ -1000,11 +1005,22 @@
|
||||
/obj/item/gun_control/CanItemAutoclick()
|
||||
return 1
|
||||
|
||||
/obj/item/gun_control/afterattack(atom/targeted_atom, mob/user)
|
||||
/obj/item/gun_control/attack_obj(obj/O, mob/living/user)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
O.attacked_by(src, user)
|
||||
|
||||
/obj/item/gun_control/attack(mob/living/M, mob/living/user)
|
||||
user.lastattacked = M
|
||||
M.lastattacker = user
|
||||
M.attacked_by(src, user)
|
||||
add_fingerprint(user)
|
||||
|
||||
/obj/item/gun_control/afterattack(atom/targeted_atom, mob/user, flag, params)
|
||||
..()
|
||||
var/obj/machinery/manned_turret/E = user.buckled
|
||||
E.setDir(get_dir(E,targeted_atom))
|
||||
user.setDir(E.dir)
|
||||
E.mouseparams = params
|
||||
switch(E.dir)
|
||||
if(NORTH)
|
||||
E.layer = BELOW_MOB_LAYER
|
||||
@@ -1052,15 +1068,15 @@
|
||||
else
|
||||
cooldown = world.time + cooldown_duration
|
||||
warned = FALSE
|
||||
INVOKE_ASYNC(src, /obj/machinery/manned_turret/.proc/volley)
|
||||
volley(user)
|
||||
|
||||
/obj/machinery/manned_turret/proc/volley()
|
||||
/obj/machinery/manned_turret/proc/volley(mob/user)
|
||||
target_turf = get_turf(target)
|
||||
for(var/i in 1 to number_of_shots)
|
||||
addtimer(CALLBACK(src, /obj/machinery/manned_turret/.proc/fire_helper), i*rate_of_fire)
|
||||
addtimer(CALLBACK(src, /obj/machinery/manned_turret/.proc/fire_helper, user), i*rate_of_fire)
|
||||
|
||||
|
||||
/obj/machinery/manned_turret/proc/fire_helper()
|
||||
/obj/machinery/manned_turret/proc/fire_helper(mob/user)
|
||||
if(!src)
|
||||
return
|
||||
var/turf/targets_from = get_turf(src)
|
||||
@@ -1069,11 +1085,10 @@
|
||||
var/obj/item/projectile/P = new projectile_type(targets_from)
|
||||
P.current = targets_from
|
||||
P.starting = targets_from
|
||||
P.firer = src
|
||||
P.firer = user
|
||||
P.original = target
|
||||
playsound(src, 'sound/weapons/Gunshot_smg.ogg', 75, 1)
|
||||
P.yo = target.y - targets_from.y + rand(-1,1)
|
||||
P.xo = target.x - targets_from.x + rand(-1,1)
|
||||
P.preparePixelProjectile(target, target_turf, user, mouseparams, rand(-9, 9))
|
||||
P.fire()
|
||||
|
||||
/obj/machinery/manned_turret/ultimate // Admin-only proof of concept for autoclicker automatics
|
||||
|
||||
@@ -154,7 +154,7 @@
|
||||
M.forceMove(loc)
|
||||
|
||||
if(prob(30))
|
||||
explosion(get_turf(loc), 0, 0, 1, 3)
|
||||
explosion(get_turf(loc), 0, 0, 1, 3)
|
||||
|
||||
if(wreckage)
|
||||
var/obj/structure/mecha_wreckage/WR = new wreckage(loc, AI)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
/obj/effect/forcefield/cult
|
||||
desc = "An unholy shield that blocks all attacks."
|
||||
name = "glowing wall"
|
||||
icon = 'icons/effects/cult_effects.dmi'
|
||||
icon_state = "cultshield"
|
||||
|
||||
///////////Mimewalls///////////
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
var/range_flash = 3
|
||||
|
||||
/obj/effect/mine/explosive/mineEffect(mob/victim)
|
||||
explosion(loc, range_devastation, range_heavy, range_light, range_flash)
|
||||
explosion(loc, range_devastation, range_heavy, range_light, range_flash)
|
||||
|
||||
|
||||
/obj/effect/mine/stun
|
||||
|
||||
@@ -632,7 +632,14 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
L = get(src, /mob/living/silicon)
|
||||
|
||||
if(L && L.stat != UNCONSCIOUS)
|
||||
to_chat(L, "\icon[src] <b>Message from [source.owner] ([source.ownjob]), </b>\"[msg.message]\"[msg.get_photo_ref()] (<a href='byond://?src=\ref[src];choice=Message;skiprefresh=1;target=\ref[source]'>Reply</a>)")
|
||||
|
||||
var/hrefstart
|
||||
var/hrefend
|
||||
if (isAI(L))
|
||||
hrefstart = "<a href='?src=\ref[L];track=[html_encode(source.owner)]'>"
|
||||
hrefend = "</a>"
|
||||
|
||||
to_chat(L, "\icon[src.icon] <b>Message from [hrefstart][source.owner] ([source.ownjob])[hrefend], </b>\"[msg.message]\"[msg.get_photo_ref()] (<a href='byond://?src=\ref[src];choice=Message;skiprefresh=1;target=\ref[source]'>Reply</a>)")
|
||||
|
||||
update_icon()
|
||||
add_overlay(icon_alert)
|
||||
@@ -890,9 +897,9 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
if(T)
|
||||
T.hotspot_expose(700,125)
|
||||
if(istype(cartridge, /obj/item/weapon/cartridge/syndicate))
|
||||
explosion(T, -1, 1, 3, 4)
|
||||
explosion(T, -1, 1, 3, 4)
|
||||
else
|
||||
explosion(T, -1, -1, 2, 3)
|
||||
explosion(T, -1, -1, 2, 3)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
|
||||
@@ -10,15 +10,14 @@
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF | INDESTRUCTIBLE
|
||||
|
||||
/obj/item/device/paicard/Initialize()
|
||||
..()
|
||||
SSpai.pai_card_list += src
|
||||
add_overlay("pai-off")
|
||||
return ..()
|
||||
|
||||
/obj/item/device/paicard/Destroy()
|
||||
//Will stop people throwing friend pAIs into the singularity so they can respawn
|
||||
SSpai.pai_card_list -= src
|
||||
if(!isnull(pai))
|
||||
pai.death(0)
|
||||
QDEL_NULL(pai)
|
||||
return ..()
|
||||
|
||||
/obj/item/device/paicard/attack_self(mob/user)
|
||||
@@ -26,9 +25,9 @@
|
||||
return
|
||||
user.set_machine(src)
|
||||
var/dat = "<TT><B>Personal AI Device</B><BR>"
|
||||
if(pai && (!pai.master_dna || !pai.master))
|
||||
dat += "<a href='byond://?src=\ref[src];setdna=1'>Imprint Master DNA</a><br>"
|
||||
if(pai)
|
||||
if(!pai.master_dna || !pai.master)
|
||||
dat += "<a href='byond://?src=\ref[src];setdna=1'>Imprint Master DNA</a><br>"
|
||||
dat += "Installed Personality: [pai.name]<br>"
|
||||
dat += "Prime directive: <br>[pai.laws.zeroth]<br>"
|
||||
for(var/slaws in pai.laws.supplied)
|
||||
@@ -86,7 +85,7 @@
|
||||
to_chat(pai, "<span class='danger'>Byte by byte you lose your sense of self.</span>")
|
||||
to_chat(pai, "<span class='userdanger'>Your mental faculties leave you.</span>")
|
||||
to_chat(pai, "<span class='rose'>oblivion... </span>")
|
||||
pai.death(0)
|
||||
removePersonality()
|
||||
if(href_list["wires"])
|
||||
var/wire = text2num(href_list["wires"])
|
||||
if(pai.radio)
|
||||
@@ -119,9 +118,9 @@
|
||||
audible_message("\The [src] plays a cheerful startup noise!")
|
||||
|
||||
/obj/item/device/paicard/proc/removePersonality()
|
||||
src.pai = null
|
||||
src.cut_overlays()
|
||||
src.add_overlay("pai-off")
|
||||
QDEL_NULL(pai)
|
||||
cut_overlays()
|
||||
add_overlay("pai-off")
|
||||
|
||||
/obj/item/device/paicard/proc/setEmotion(emotion)
|
||||
if(pai)
|
||||
|
||||
@@ -141,5 +141,5 @@
|
||||
|
||||
if(power_drained >= max_power)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
explosion(src.loc, 4,8,16,32)
|
||||
explosion(src.loc, 4,8,16,32)
|
||||
qdel(src)
|
||||
|
||||
@@ -504,6 +504,8 @@
|
||||
S.change_head_color(color2)
|
||||
dropped = TRUE
|
||||
|
||||
#define PKBORG_DAMPEN_CYCLE_DELAY 20
|
||||
|
||||
//Peacekeeper Cyborg Projectile Dampenening Field
|
||||
/obj/item/borg/projectile_dampen
|
||||
name = "Hyperkinetic Dampening projector"
|
||||
@@ -526,6 +528,7 @@
|
||||
var/image/projectile_effect
|
||||
var/field_radius = 3
|
||||
var/active = FALSE
|
||||
var/cycle_delay = 0
|
||||
|
||||
/obj/item/borg/projectile_dampen/debug
|
||||
maxenergy = 50000
|
||||
@@ -545,29 +548,31 @@
|
||||
return ..()
|
||||
|
||||
/obj/item/borg/projectile_dampen/attack_self(mob/user)
|
||||
if(!istype(dampening_field))
|
||||
activate_field()
|
||||
active = TRUE
|
||||
if(cycle_delay > world.time)
|
||||
to_chat(user, "<span class='boldwarning'>\the [src] is still recycling its projectors!</span>")
|
||||
return
|
||||
cycle_delay = world.time + PKBORG_DAMPEN_CYCLE_DELAY
|
||||
active = !active
|
||||
if(active)
|
||||
activate_field(user)
|
||||
else
|
||||
deactivate_field()
|
||||
active = FALSE
|
||||
update_icon()
|
||||
to_chat(user, "<span class='boldnotice'>You [active? "activate":"deactivate"] the [src].</span>")
|
||||
|
||||
/obj/item/borg/projectile_dampen/update_icon()
|
||||
. = ..()
|
||||
icon_state = "[initial(icon_state)][active]"
|
||||
|
||||
/obj/item/borg/projectile_dampen/proc/activate_field()
|
||||
if(!istype(dampening_field))
|
||||
dampening_field = make_field(/datum/proximity_monitor/advanced/peaceborg_dampener, list("current_range" = field_radius, "host" = src, "projector" = src))
|
||||
update_icon()
|
||||
if(istype(dampening_field))
|
||||
QDEL_NULL(dampening_field)
|
||||
dampening_field = make_field(/datum/proximity_monitor/advanced/peaceborg_dampener, list("current_range" = field_radius, "host" = src, "projector" = src))
|
||||
|
||||
/obj/item/borg/projectile_dampen/proc/deactivate_field()
|
||||
QDEL_NULL(dampening_field)
|
||||
visible_message("<span class='warning'>The [src] shuts off!</span>")
|
||||
for(var/obj/item/projectile/P in tracked)
|
||||
visible_message("<span class='warning'>\The [src] shuts off!</span>")
|
||||
for(var/P in tracked)
|
||||
restore_projectile(P)
|
||||
update_icon()
|
||||
|
||||
/obj/item/borg/projectile_dampen/dropped()
|
||||
. = ..()
|
||||
|
||||
@@ -196,13 +196,6 @@ GLOBAL_LIST_INIT(sinew_recipes, list ( \
|
||||
user.visible_message("[user] starts cutting hair off \the [src].", "<span class='notice'>You start cutting the hair off \the [src]...</span>", "<span class='italics'>You hear the sound of a knife rubbing against flesh.</span>")
|
||||
if(do_after(user,50, target = src))
|
||||
to_chat(user, "<span class='notice'>You cut the hair from this [src.singular_name].</span>")
|
||||
//Try locating an exisitng stack on the tile and add to there if possible
|
||||
for(var/obj/item/stack/sheet/hairlesshide/HS in user.loc)
|
||||
if(HS.amount < 50)
|
||||
HS.amount++
|
||||
use(1)
|
||||
break
|
||||
//If it gets to here it means it did not find a suitable stack on the tile.
|
||||
var/obj/item/stack/sheet/hairlesshide/HS = new(user.loc)
|
||||
HS.amount = 1
|
||||
use(1)
|
||||
@@ -230,3 +223,9 @@ GLOBAL_LIST_INIT(sinew_recipes, list ( \
|
||||
HS.amount = 1
|
||||
wetness = initial(wetness)
|
||||
src.use(1)
|
||||
|
||||
/obj/item/stack/sheet/wetleather/microwave_act(obj/machinery/microwave/MW)
|
||||
..()
|
||||
var/obj/item/stack/sheet/leather/L = new(loc)
|
||||
L.amount = amount
|
||||
qdel(src)
|
||||
|
||||
@@ -22,6 +22,11 @@ Mineral Sheets
|
||||
/obj/item/stack/sheet/mineral
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
|
||||
/obj/item/stack/sheet/mineral/Initialize(mapload)
|
||||
pixel_x = rand(-4, 4)
|
||||
pixel_y = rand(-4, 4)
|
||||
. = ..()
|
||||
|
||||
/*
|
||||
* Sandstone
|
||||
*/
|
||||
@@ -31,9 +36,7 @@ GLOBAL_LIST_INIT(sandstone_recipes, list ( \
|
||||
new/datum/stack_recipe("sandstone door", /obj/structure/mineral_door/sandstone, 10, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("aesthetic volcanic floor tile", /obj/item/stack/tile/basalt, 2, 2, 4, 20), \
|
||||
new/datum/stack_recipe("Assistant Statue", /obj/structure/statue/sandstone/assistant, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("Breakdown into sand", /obj/item/weapon/ore/glass, 1, one_per_turf = 0, on_floor = 1), \
|
||||
/* new/datum/stack_recipe("sandstone wall", ???), \
|
||||
new/datum/stack_recipe("sandstone floor", ???),\ */
|
||||
new/datum/stack_recipe("Breakdown into sand", /obj/item/weapon/ore/glass, 1, one_per_turf = 0, on_floor = 1) \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/mineral/sandstone
|
||||
@@ -49,9 +52,7 @@ GLOBAL_LIST_INIT(sandstone_recipes, list ( \
|
||||
|
||||
/obj/item/stack/sheet/mineral/sandstone/Initialize(mapload, new_amount, merge = TRUE)
|
||||
recipes = GLOB.sandstone_recipes
|
||||
pixel_x = rand(0,4)-4
|
||||
pixel_y = rand(0,4)-4
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
/obj/item/stack/sheet/mineral/sandstone/thirty
|
||||
amount = 30
|
||||
@@ -74,9 +75,24 @@ GLOBAL_LIST_INIT(sandbag_recipes, list ( \
|
||||
|
||||
/obj/item/stack/sheet/mineral/sandbags/Initialize(mapload, new_amount, merge = TRUE)
|
||||
recipes = GLOB.sandbag_recipes
|
||||
pixel_x = rand(0,4)-4
|
||||
pixel_y = rand(0,4)-4
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
/obj/item/weapon/emptysandbag
|
||||
name = "empty sandbag"
|
||||
desc = "A bag to be filled with sand."
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "sandbag"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
|
||||
/obj/item/weapon/emptysandbag/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W,/obj/item/weapon/ore/glass))
|
||||
to_chat(user, "<span class='notice'>You fill the sandbag.</span>")
|
||||
var/obj/item/stack/sheet/mineral/sandbags/I = new /obj/item/stack/sheet/mineral/sandbags
|
||||
qdel(src)
|
||||
user.put_in_hands(I)
|
||||
qdel(W)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/*
|
||||
* Diamond
|
||||
@@ -99,9 +115,7 @@ GLOBAL_LIST_INIT(diamond_recipes, list ( \
|
||||
|
||||
/obj/item/stack/sheet/mineral/diamond/Initialize(mapload, new_amount, merge = TRUE)
|
||||
recipes = GLOB.diamond_recipes
|
||||
pixel_x = rand(0,4)-4
|
||||
pixel_y = rand(0,4)-4
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
/*
|
||||
* Uranium
|
||||
@@ -123,9 +137,7 @@ GLOBAL_LIST_INIT(uranium_recipes, list ( \
|
||||
|
||||
/obj/item/stack/sheet/mineral/uranium/Initialize(mapload, new_amount, merge = TRUE)
|
||||
recipes = GLOB.uranium_recipes
|
||||
pixel_x = rand(0,4)-4
|
||||
pixel_y = rand(0,4)-4
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
/*
|
||||
* Plasma
|
||||
@@ -149,9 +161,7 @@ GLOBAL_LIST_INIT(plasma_recipes, list ( \
|
||||
|
||||
/obj/item/stack/sheet/mineral/plasma/Initialize(mapload, new_amount, merge = TRUE)
|
||||
recipes = GLOB.plasma_recipes
|
||||
pixel_x = rand(0,4)-4
|
||||
pixel_y = rand(0,4)-4
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
/obj/item/stack/sheet/mineral/plasma/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
|
||||
if(W.is_hot() > 300)//If the temperature of the object is over 300, then ignite
|
||||
@@ -190,9 +200,7 @@ GLOBAL_LIST_INIT(gold_recipes, list ( \
|
||||
|
||||
/obj/item/stack/sheet/mineral/gold/Initialize(mapload, new_amount, merge = TRUE)
|
||||
recipes = GLOB.gold_recipes
|
||||
pixel_x = rand(0,4)-4
|
||||
pixel_y = rand(0,4)-4
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
/*
|
||||
* Silver
|
||||
@@ -217,9 +225,7 @@ GLOBAL_LIST_INIT(silver_recipes, list ( \
|
||||
|
||||
/obj/item/stack/sheet/mineral/silver/Initialize(mapload, new_amount, merge = TRUE)
|
||||
recipes = GLOB.silver_recipes
|
||||
pixel_x = rand(0,4)-4
|
||||
pixel_y = rand(0,4)-4
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
/*
|
||||
* Clown
|
||||
@@ -239,9 +245,7 @@ GLOBAL_LIST_INIT(clown_recipes, list ( \
|
||||
|
||||
/obj/item/stack/sheet/mineral/bananium/Initialize(mapload, new_amount, merge = TRUE)
|
||||
recipes = GLOB.clown_recipes
|
||||
pixel_x = rand(0,4)-4
|
||||
pixel_y = rand(0,4)-4
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
/*
|
||||
* Titanium
|
||||
@@ -265,9 +269,7 @@ GLOBAL_LIST_INIT(titanium_recipes, list ( \
|
||||
|
||||
/obj/item/stack/sheet/mineral/titanium/Initialize(mapload, new_amount, merge = TRUE)
|
||||
recipes = GLOB.titanium_recipes
|
||||
pixel_x = rand(0,4)-4
|
||||
pixel_y = rand(0,4)-4
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
|
||||
/*
|
||||
@@ -292,9 +294,7 @@ GLOBAL_LIST_INIT(plastitanium_recipes, list ( \
|
||||
|
||||
/obj/item/stack/sheet/mineral/plastitanium/Initialize(mapload, new_amount, merge = TRUE)
|
||||
recipes = GLOB.plastitanium_recipes
|
||||
pixel_x = rand(0,4)-4
|
||||
pixel_y = rand(0,4)-4
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
|
||||
/*
|
||||
@@ -316,9 +316,7 @@ GLOBAL_LIST_INIT(snow_recipes, list ( \
|
||||
|
||||
/obj/item/stack/sheet/mineral/snow/Initialize(mapload, new_amount, merge = TRUE)
|
||||
recipes = GLOB.snow_recipes
|
||||
pixel_x = rand(0,4)-4
|
||||
pixel_y = rand(0,4)-4
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
/****************************** Others ****************************/
|
||||
|
||||
@@ -347,7 +345,7 @@ GLOBAL_LIST_INIT(adamantine_recipes, list(
|
||||
|
||||
/obj/item/stack/sheet/mineral/adamantine/Initialize(mapload, new_amount, merge = TRUE)
|
||||
recipes = GLOB.adamantine_recipes
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
/*
|
||||
* Mythril
|
||||
@@ -384,4 +382,4 @@ GLOBAL_LIST_INIT(abductor_recipes, list ( \
|
||||
|
||||
/obj/item/stack/sheet/mineral/abductor/Initialize(mapload, new_amount, merge = TRUE)
|
||||
recipes = GLOB.abductor_recipes
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
@@ -83,6 +83,14 @@
|
||||
var/list/access = list()
|
||||
var/registered_name = null // The name registered_name on the card
|
||||
var/assignment = null
|
||||
var/access_txt // mapping aid
|
||||
|
||||
|
||||
|
||||
/obj/item/weapon/card/id/Initialize(mapload)
|
||||
. = ..()
|
||||
if(mapload && access_txt)
|
||||
access = text2access(access_txt)
|
||||
|
||||
/obj/item/weapon/card/id/attack_self(mob/user)
|
||||
user.visible_message("<span class='notice'>[user] shows you: \icon[src] [src.name].</span>", \
|
||||
|
||||
@@ -54,10 +54,10 @@
|
||||
var/obj/effect/chrono_field/field = null
|
||||
var/turf/startpos = null
|
||||
|
||||
/obj/item/weapon/gun/energy/chrono_gun/New(var/obj/item/weapon/chrono_eraser/T)
|
||||
/obj/item/weapon/gun/energy/chrono_gun/Initialize()
|
||||
. = ..()
|
||||
if(istype(T))
|
||||
TED = T
|
||||
if(istype(loc, /obj/item/weapon/chrono_eraser))
|
||||
TED = loc
|
||||
else //admin must have spawned it
|
||||
TED = new(src.loc)
|
||||
qdel(src)
|
||||
|
||||
@@ -622,6 +622,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
icon = 'icons/obj/clothing/masks.dmi'
|
||||
icon_state = null
|
||||
item_state = null
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
var/chem_volume = 100
|
||||
var/vapetime = 0 //this so it won't puff out clouds every tick
|
||||
var/screw = 0 // kinky
|
||||
@@ -633,8 +634,8 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
return (TOXLOSS|OXYLOSS)
|
||||
|
||||
|
||||
/obj/item/clothing/mask/vape/New(loc, var/param_color = null)
|
||||
..()
|
||||
/obj/item/clothing/mask/vape/Initialize(mapload, param_color)
|
||||
. = ..()
|
||||
create_reagents(chem_volume)
|
||||
reagents.set_reacting(FALSE) // so it doesn't react until you light it
|
||||
reagents.add_reagent("nicotine", 50)
|
||||
|
||||
@@ -23,14 +23,14 @@
|
||||
var/combat = 0 //can we revive through space suits?
|
||||
var/grab_ghost = FALSE // Do we pull the ghost back into their body?
|
||||
|
||||
/obj/item/weapon/defibrillator/New() //starts without a cell for rnd
|
||||
..()
|
||||
/obj/item/weapon/defibrillator/Initialize() //starts without a cell for rnd
|
||||
. = ..()
|
||||
paddles = make_paddles()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/weapon/defibrillator/loaded/New() //starts with hicap
|
||||
..()
|
||||
/obj/item/weapon/defibrillator/loaded/Initialize() //starts with hicap
|
||||
. = ..()
|
||||
paddles = make_paddles()
|
||||
bcell = new(src)
|
||||
update_icon()
|
||||
@@ -237,8 +237,8 @@
|
||||
if(slot == user.getBeltSlot())
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/defibrillator/compact/loaded/New()
|
||||
..()
|
||||
/obj/item/weapon/defibrillator/compact/loaded/Initialize()
|
||||
. = ..()
|
||||
paddles = make_paddles()
|
||||
bcell = new(src)
|
||||
update_icon()
|
||||
@@ -249,8 +249,8 @@
|
||||
combat = 1
|
||||
safety = 0
|
||||
|
||||
/obj/item/weapon/defibrillator/compact/combat/loaded/New()
|
||||
..()
|
||||
/obj/item/weapon/defibrillator/compact/combat/loaded/Initialize()
|
||||
. = ..()
|
||||
paddles = make_paddles()
|
||||
bcell = new /obj/item/weapon/stock_parts/cell/infinite(src)
|
||||
update_icon()
|
||||
|
||||
@@ -14,14 +14,16 @@
|
||||
origin_tech = "combat=1;plasmatech=2;engineering=2"
|
||||
resistance_flags = FIRE_PROOF
|
||||
var/status = 0
|
||||
var/throw_amount = 100
|
||||
var/lit = 0 //on or off
|
||||
var/operating = 0//cooldown
|
||||
var/obj/item/weapon/weldingtool/weldtool = null
|
||||
var/obj/item/device/assembly/igniter/igniter = null
|
||||
var/obj/item/weapon/tank/internals/plasma/ptank = null
|
||||
var/warned_admins = 0 //for the message_admins() when lit
|
||||
|
||||
//variables for prebuilt flamethrowers
|
||||
var/create_full = FALSE
|
||||
var/create_with_tank = FALSE
|
||||
var/igniter_type = /obj/item/device/assembly/igniter
|
||||
|
||||
/obj/item/weapon/flamethrower/Destroy()
|
||||
if(weldtool)
|
||||
@@ -32,9 +34,8 @@
|
||||
qdel(ptank)
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/weapon/flamethrower/process()
|
||||
if(!lit)
|
||||
if(!lit || !igniter)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return null
|
||||
var/turf/location = loc
|
||||
@@ -43,8 +44,7 @@
|
||||
if(M.is_holding(src))
|
||||
location = M.loc
|
||||
if(isturf(location)) //start a fire if possible
|
||||
location.hotspot_expose(700, 2)
|
||||
return
|
||||
igniter.flamethrower_process(location)
|
||||
|
||||
|
||||
/obj/item/weapon/flamethrower/update_icon()
|
||||
@@ -58,6 +58,9 @@
|
||||
item_state = "flamethrower_1"
|
||||
else
|
||||
item_state = "flamethrower_0"
|
||||
if(ismob(loc))
|
||||
var/mob/M = loc
|
||||
M.update_inv_hands()
|
||||
return
|
||||
|
||||
/obj/item/weapon/flamethrower/afterattack(atom/target, mob/user, flag)
|
||||
@@ -82,13 +85,13 @@
|
||||
if(istype(W, /obj/item/weapon/wrench) && !status)//Taking this apart
|
||||
var/turf/T = get_turf(src)
|
||||
if(weldtool)
|
||||
weldtool.loc = T
|
||||
weldtool.forceMove(T)
|
||||
weldtool = null
|
||||
if(igniter)
|
||||
igniter.loc = T
|
||||
igniter.forceMove(T)
|
||||
igniter = null
|
||||
if(ptank)
|
||||
ptank.loc = T
|
||||
ptank.forceMove(T)
|
||||
ptank = null
|
||||
new /obj/item/stack/rods(T)
|
||||
qdel(src)
|
||||
@@ -114,7 +117,10 @@
|
||||
|
||||
else if(istype(W,/obj/item/weapon/tank/internals/plasma))
|
||||
if(ptank)
|
||||
to_chat(user, "<span class='notice'>There is already a plasma tank loaded in [src]!</span>")
|
||||
if(user.transferItemToLoc(W,src))
|
||||
ptank.forceMove(get_turf(src))
|
||||
ptank = W
|
||||
to_chat(user, "<span class='notice'>You swap the plasma tank in [src]!</span>")
|
||||
return
|
||||
if(!user.transferItemToLoc(W, src))
|
||||
return
|
||||
@@ -129,53 +135,26 @@
|
||||
|
||||
|
||||
/obj/item/weapon/flamethrower/attack_self(mob/user)
|
||||
if(user.stat || user.restrained() || user.lying)
|
||||
return
|
||||
user.set_machine(src)
|
||||
toggle_igniter(user)
|
||||
|
||||
|
||||
/obj/item/weapon/flamethrower/proc/toggle_igniter(mob/user)
|
||||
if(!ptank)
|
||||
to_chat(user, "<span class='notice'>Attach a plasma tank first!</span>")
|
||||
return
|
||||
var/dat = text("<TT><B>Flamethrower (<A HREF='?src=\ref[src];light=1'>[lit ? "<font color='red'>Lit</font>" : "Unlit"]</a>)</B><BR>\n Tank Pressure: [ptank.air_contents.return_pressure()]<BR>\nAmount to throw: <A HREF='?src=\ref[src];amount=-100'>-</A> <A HREF='?src=\ref[src];amount=-10'>-</A> <A HREF='?src=\ref[src];amount=-1'>-</A> [throw_amount] <A HREF='?src=\ref[src];amount=1'>+</A> <A HREF='?src=\ref[src];amount=10'>+</A> <A HREF='?src=\ref[src];amount=100'>+</A><BR>\n<A HREF='?src=\ref[src];remove=1'>Remove plasmatank</A> - <A HREF='?src=\ref[src];close=1'>Close</A></TT>")
|
||||
user << browse(dat, "window=flamethrower;size=600x300")
|
||||
onclose(user, "flamethrower")
|
||||
return
|
||||
|
||||
|
||||
/obj/item/weapon/flamethrower/Topic(href,href_list[])
|
||||
if(href_list["close"])
|
||||
usr.unset_machine()
|
||||
usr << browse(null, "window=flamethrower")
|
||||
if(!status)
|
||||
to_chat(user, "<span class='notice'>Secure the igniter first!</span>")
|
||||
return
|
||||
if(usr.stat || usr.restrained() || usr.lying)
|
||||
return
|
||||
usr.set_machine(src)
|
||||
if(href_list["light"])
|
||||
if(!ptank)
|
||||
return
|
||||
if(!status)
|
||||
return
|
||||
lit = !lit
|
||||
if(lit)
|
||||
START_PROCESSING(SSobj, src)
|
||||
if(!warned_admins)
|
||||
message_admins("[ADMIN_LOOKUPFLW(usr)] has lit a flamethrower.")
|
||||
warned_admins = 1
|
||||
if(href_list["amount"])
|
||||
throw_amount = throw_amount + text2num(href_list["amount"])
|
||||
throw_amount = max(50, min(5000, throw_amount))
|
||||
if(href_list["remove"])
|
||||
if(!ptank)
|
||||
return
|
||||
usr.put_in_hands(ptank)
|
||||
ptank = null
|
||||
lit = 0
|
||||
usr.unset_machine()
|
||||
usr << browse(null, "window=flamethrower")
|
||||
for(var/mob/M in viewers(1, loc))
|
||||
if((M.client && M.machine == src))
|
||||
attack_self(M)
|
||||
to_chat(user, "<span class='notice'>You ignite [src]!</span>")
|
||||
lit = !lit
|
||||
if(lit)
|
||||
START_PROCESSING(SSobj, src)
|
||||
if(!warned_admins)
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] has lit a flamethrower.")
|
||||
warned_admins = 1
|
||||
else
|
||||
STOP_PROCESSING(SSobj,src)
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/weapon/flamethrower/CheckParts(list/parts_list)
|
||||
..()
|
||||
@@ -195,19 +174,22 @@
|
||||
for(var/turf/T in turflist)
|
||||
if(T == previousturf)
|
||||
continue //so we don't burn the tile we be standin on
|
||||
if(!T.atmos_adjacent_turfs || !T.atmos_adjacent_turfs[previousturf])
|
||||
var/list/turfs_sharing_with_prev = previousturf.GetAtmosAdjacentTurfs(alldir=1)
|
||||
if(!(T in turfs_sharing_with_prev))
|
||||
break
|
||||
ignite_turf(T)
|
||||
if(igniter)
|
||||
igniter.ignite_turf(src,T)
|
||||
else
|
||||
default_ignite(T)
|
||||
sleep(1)
|
||||
previousturf = T
|
||||
operating = 0
|
||||
for(var/mob/M in viewers(1, loc))
|
||||
if((M.client && M.machine == src))
|
||||
attack_self(M)
|
||||
return
|
||||
|
||||
|
||||
/obj/item/weapon/flamethrower/proc/ignite_turf(turf/target, release_amount = 0.05)
|
||||
/obj/item/weapon/flamethrower/proc/default_ignite(turf/target, release_amount = 0.05)
|
||||
//TODO: DEFERRED Consider checking to make sure tank pressure is high enough before doing this...
|
||||
//Transfer 5% of current tank air contents to turf
|
||||
var/datum/gas_mixture/air_transfer = ptank.air_contents.remove_ratio(release_amount)
|
||||
@@ -218,30 +200,42 @@
|
||||
target.hotspot_expose((ptank.air_contents.temperature*2) + 380,500)
|
||||
//location.hotspot_expose(1000,500,1)
|
||||
SSair.add_to_active(target, 0)
|
||||
return
|
||||
|
||||
|
||||
/obj/item/weapon/flamethrower/full/New(var/loc)
|
||||
..()
|
||||
if(!weldtool)
|
||||
weldtool = new /obj/item/weapon/weldingtool(src)
|
||||
weldtool.status = 0
|
||||
if(!igniter)
|
||||
igniter = new /obj/item/device/assembly/igniter(src)
|
||||
igniter.secured = 0
|
||||
status = 1
|
||||
update_icon()
|
||||
/obj/item/weapon/flamethrower/Initialize(mapload)
|
||||
. = ..()
|
||||
if(create_full)
|
||||
if(!weldtool)
|
||||
weldtool = new /obj/item/weapon/weldingtool(src)
|
||||
weldtool.status = 0
|
||||
if(!igniter)
|
||||
igniter = new igniter_type(src)
|
||||
igniter.secured = 0
|
||||
status = 1
|
||||
if(create_with_tank)
|
||||
ptank = new /obj/item/weapon/tank/internals/plasma/full(src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/flamethrower/full/tank/New(var/loc)
|
||||
..()
|
||||
ptank = new /obj/item/weapon/tank/internals/plasma/full(src)
|
||||
update_icon()
|
||||
/obj/item/weapon/flamethrower/full/tank
|
||||
create_full = TRUE
|
||||
|
||||
/obj/item/weapon/flamethrower/full/tank
|
||||
create_with_tank = TRUE
|
||||
|
||||
/obj/item/weapon/flamethrower/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type)
|
||||
if(ptank && damage && attack_type == PROJECTILE_ATTACK && prob(15))
|
||||
owner.visible_message("<span class='danger'>[attack_text] hits the fueltank on [owner]'s [src], rupturing it! What a shot!</span>")
|
||||
var/target_turf = get_turf(owner)
|
||||
ignite_turf(target_turf, 100)
|
||||
igniter.ignite_turf(src,target_turf, release_amount = 100)
|
||||
qdel(ptank)
|
||||
return 1 //It hit the flamethrower, not them
|
||||
|
||||
|
||||
/obj/item/device/assembly/igniter/proc/flamethrower_process(turf/open/location)
|
||||
location.hotspot_expose(700,2)
|
||||
|
||||
/obj/item/device/assembly/igniter/cold/flamethrower_process(turf/open/location)
|
||||
return
|
||||
|
||||
/obj/item/device/assembly/igniter/proc/ignite_turf(obj/item/weapon/flamethrower/F,turf/open/location,release_amount = 0.05)
|
||||
F.default_ignite(location,release_amount)
|
||||
@@ -59,7 +59,7 @@
|
||||
|
||||
/obj/item/weapon/grenade/iedcasing/prime() //Blowing that can up
|
||||
update_mob()
|
||||
explosion(src.loc,-1,-1,2, flame_range = 4) // small explosion, plus a very large fireball.
|
||||
explosion(src.loc,-1,-1,2, flame_range = 4) // small explosion, plus a very large fireball.
|
||||
qdel(src)
|
||||
|
||||
/obj/item/weapon/grenade/iedcasing/examine(mob/user)
|
||||
|
||||
@@ -235,7 +235,7 @@
|
||||
|
||||
to_chat(user, "<span class='notice'>You start planting the bomb...</span>")
|
||||
|
||||
if(do_after(user, 50, target = AM))
|
||||
if(do_after(user, 30, target = AM))
|
||||
if(!user.temporarilyRemoveItemFromInventory(src))
|
||||
return
|
||||
src.target = AM
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
/obj/item/weapon/grenade/syndieminibomb/prime()
|
||||
update_mob()
|
||||
explosion(src.loc,1,2,4,flame_range = 2)
|
||||
explosion(src.loc,1,2,4,flame_range = 2)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/weapon/grenade/syndieminibomb/concussion
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
/obj/item/weapon/grenade/syndieminibomb/concussion/prime()
|
||||
update_mob()
|
||||
explosion(src.loc,0,2,3,flame_range = 3)
|
||||
explosion(src.loc,0,2,3,flame_range = 3)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/weapon/grenade/syndieminibomb/concussion/frag
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
sharpness = IS_SHARP_ACCURATE
|
||||
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 50)
|
||||
var/bayonet = FALSE //Can this be attached to a gun?
|
||||
|
||||
/obj/item/weapon/kitchen/knife/attack(mob/living/carbon/M, mob/living/carbon/user)
|
||||
if(user.zone_selected == "eyes")
|
||||
@@ -107,7 +108,7 @@
|
||||
throwforce = 20
|
||||
origin_tech = "materials=3;combat=4"
|
||||
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "cut")
|
||||
|
||||
bayonet = TRUE
|
||||
|
||||
/obj/item/weapon/kitchen/knife/combat/survival
|
||||
name = "survival knife"
|
||||
@@ -115,6 +116,7 @@
|
||||
desc = "A hunting grade survival knife."
|
||||
force = 15
|
||||
throwforce = 15
|
||||
bayonet = TRUE
|
||||
|
||||
/obj/item/weapon/kitchen/knife/combat/bone
|
||||
name = "bone dagger"
|
||||
|
||||
@@ -270,4 +270,4 @@
|
||||
|
||||
/obj/item/weapon/pneumatic_cannon/pie/selfcharge/process()
|
||||
if(++charge_tick >= charge_ticks)
|
||||
fill_with_type(/obj/item/weapon/reagent_containers/food/snacks/pie, charge_amount)
|
||||
fill_with_type(/obj/item/weapon/reagent_containers/food/snacks/pie/cream, charge_amount)
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
var/safety = alert(user, "Doing this will have extremely dire consequences for the station and its crew. Be sure you know what you're doing.", "Put in [name]?", "Proceed", "Abort")
|
||||
if(safety == "Abort" || !in_range(src, user) || !src || !W || user.incapacitated())
|
||||
return
|
||||
investigate_log("has become a singularity. Caused by [user.key]","singulo")
|
||||
investigate_log("has become a singularity. Caused by [user.key]", INVESTIGATE_SINGULO)
|
||||
to_chat(user, "<span class='danger'>The Bluespace interfaces of the two devices catastrophically malfunction!</span>")
|
||||
qdel(W)
|
||||
var/obj/singularity/singulo = new /obj/singularity (get_turf(src))
|
||||
@@ -83,7 +83,7 @@
|
||||
|
||||
/obj/item/weapon/storage/backpack/holding/singularity_act(current_size)
|
||||
var/dist = max((current_size - 2),1)
|
||||
explosion(src.loc,(dist),(dist*2),(dist*4))
|
||||
explosion(src.loc,(dist),(dist*2),(dist*4))
|
||||
return
|
||||
|
||||
|
||||
|
||||
@@ -21,10 +21,9 @@
|
||||
user.visible_message("<span class='suicide'>[user] is putting the live [name] in [user.p_their()] mouth! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
return (FIRELOSS)
|
||||
|
||||
/obj/item/weapon/melee/baton/New()
|
||||
..()
|
||||
/obj/item/weapon/melee/baton/Initialize()
|
||||
. = ..()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/weapon/melee/baton/throw_impact(atom/hit_atom)
|
||||
..()
|
||||
@@ -32,10 +31,9 @@
|
||||
if(status && prob(throw_hit_chance) && iscarbon(hit_atom))
|
||||
baton_stun(hit_atom)
|
||||
|
||||
/obj/item/weapon/melee/baton/loaded/New() //this one starts with a cell pre-installed.
|
||||
..()
|
||||
/obj/item/weapon/melee/baton/loaded/Initialize() //this one starts with a cell pre-installed.
|
||||
bcell = new(src)
|
||||
update_icon()
|
||||
. = ..()
|
||||
|
||||
/obj/item/weapon/melee/baton/proc/deductcharge(chrgdeductamt)
|
||||
if(bcell)
|
||||
@@ -188,8 +186,8 @@
|
||||
slot_flags = SLOT_BACK
|
||||
var/obj/item/device/assembly/igniter/sparkler = 0
|
||||
|
||||
/obj/item/weapon/melee/baton/cattleprod/New()
|
||||
..()
|
||||
/obj/item/weapon/melee/baton/cattleprod/Initialize()
|
||||
. = ..()
|
||||
sparkler = new (src)
|
||||
|
||||
/obj/item/weapon/melee/baton/cattleprod/baton_stun()
|
||||
|
||||
@@ -140,7 +140,7 @@
|
||||
item_state = "plasmaman_tank_belt"
|
||||
slot_flags = SLOT_BELT
|
||||
force = 5
|
||||
volume = 3
|
||||
volume = 6
|
||||
w_class = WEIGHT_CLASS_SMALL //thanks i forgot this
|
||||
|
||||
/obj/item/weapon/tank/internals/plasmaman/belt/full/New()
|
||||
|
||||
@@ -48,6 +48,8 @@
|
||||
take_damage(tforce, BRUTE, "melee", 1, get_dir(src, AM))
|
||||
|
||||
/obj/ex_act(severity, target)
|
||||
if(resistance_flags & INDESTRUCTIBLE)
|
||||
return
|
||||
..() //contents explosion
|
||||
if(target == src)
|
||||
qdel(src)
|
||||
@@ -256,4 +258,4 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
|
||||
if(can_break && integrity_failure && current_integrity <= integrity_failure)
|
||||
obj_break(damage_type)
|
||||
return TRUE
|
||||
return FALSE
|
||||
return FALSE
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
/obj/structure/easel
|
||||
name = "easel"
|
||||
desc = "only for the finest of art!"
|
||||
desc = "Only for the finest of art!"
|
||||
icon = 'icons/obj/artstuff.dmi'
|
||||
icon_state = "easel"
|
||||
density = 1
|
||||
@@ -49,7 +49,7 @@ GLOBAL_LIST_INIT(globalBlankCanvases, new(AMT_OF_CANVASES))
|
||||
|
||||
/obj/item/weapon/canvas
|
||||
name = "canvas"
|
||||
desc = "draw out your soul on this canvas!"
|
||||
desc = "Draw out your soul on this canvas!"
|
||||
icon = 'icons/obj/artstuff.dmi'
|
||||
icon_state = "11x11"
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
@@ -161,7 +161,16 @@
|
||||
anchored = 0
|
||||
buildstacktype = /obj/item/stack/sheet/mineral/wood
|
||||
buildstackamount = 10
|
||||
var/mob/living/owner = null
|
||||
|
||||
/obj/structure/bed/dogbed/proc/update_owner(mob/living/M)
|
||||
owner = M
|
||||
name = "[M]'s bed"
|
||||
desc = "[M]'s bed! Looks comfy."
|
||||
|
||||
/obj/structure/bed/dogbed/buckle_mob(mob/living/M, force, check_loc)
|
||||
. = ..()
|
||||
update_owner(M)
|
||||
|
||||
/obj/structure/bed/alien
|
||||
name = "resting contraption"
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
log_game("[key_name(user)] has detonated [src.name].")
|
||||
for(var/atom/movable/AM in src)
|
||||
qdel(AM)
|
||||
explosion(get_turf(src), 0, 1, 5, 5)
|
||||
explosion(get_turf(src), 0, 1, 5, 5)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/closet/crate/secure/weapon
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
return ..()
|
||||
|
||||
//Ash walker eggs: Spawns in ash walker dens in lavaland. Ghosts become unbreathing lizards that worship the Necropolis and are advised to retrieve corpses to create more ash walkers.
|
||||
|
||||
/obj/effect/mob_spawn/human/ash_walker
|
||||
name = "ash walker egg"
|
||||
desc = "A man-sized yellow egg, spawned from some unfathomable creature. A humanoid silhouette lurks within."
|
||||
@@ -36,8 +37,7 @@
|
||||
icon = 'icons/mob/lavaland/lavaland_monsters.dmi'
|
||||
icon_state = "large_egg"
|
||||
mob_species = /datum/species/lizard/ashwalker
|
||||
helmet = /obj/item/clothing/head/helmet/gladiator
|
||||
uniform = /obj/item/clothing/under/gladiator/ash_walker
|
||||
outfit = /datum/outfit/ashwalker
|
||||
roundstart = FALSE
|
||||
death = FALSE
|
||||
anchored = 0
|
||||
@@ -58,12 +58,18 @@
|
||||
H.underwear = "Nude"
|
||||
H.update_body()
|
||||
|
||||
/obj/effect/mob_spawn/human/ash_walker/New()
|
||||
..()
|
||||
/obj/effect/mob_spawn/human/ash_walker/Initialize(mapload)
|
||||
. = ..()
|
||||
var/area/A = get_area(src)
|
||||
if(A)
|
||||
notify_ghosts("An ash walker egg is ready to hatch in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE)
|
||||
|
||||
/datum/outfit/ashwalker
|
||||
name ="Ashwalker"
|
||||
head = /obj/item/clothing/head/helmet/gladiator
|
||||
uniform = /obj/item/clothing/under/gladiator/ash_walker
|
||||
|
||||
|
||||
//Timeless prisons: Spawns in Wish Granter prisons in lavaland. Ghosts become age-old users of the Wish Granter and are advised to seek repentance for their past.
|
||||
/obj/effect/mob_spawn/human/exile
|
||||
name = "timeless prison"
|
||||
@@ -188,38 +194,38 @@
|
||||
conditions of your makeshift shelter, the hostile creatures, and the ash drakes swooping down from the cloudless skies, all you can wish for is the feel of soft grass between your toes and \
|
||||
the fresh air of Earth. These thoughts are dispelled by yet another recollection of how you got here... "
|
||||
|
||||
/obj/effect/mob_spawn/human/hermit/New()
|
||||
/obj/effect/mob_spawn/human/hermit/Initialize(mapload)
|
||||
. = ..()
|
||||
var/arrpee = rand(1,4)
|
||||
switch(arrpee)
|
||||
if(1)
|
||||
flavour_text += "you were a [pick("arms dealer", "shipwright", "docking manager")]'s assistant on a small trading station several sectors from here. Raiders attacked, and there was \
|
||||
only one pod left when you got to the escape bay. You took it and launched it alone, and the crowd of terrified faces crowding at the airlock door as your pod's engines burst to \
|
||||
life and sent you to this hell are forever branded into your memory.</b>"
|
||||
uniform = /obj/item/clothing/under/assistantformal
|
||||
shoes = /obj/item/clothing/shoes/sneakers/black
|
||||
back = /obj/item/weapon/storage/backpack
|
||||
outfit.uniform = /obj/item/clothing/under/assistantformal
|
||||
outfit.shoes = /obj/item/clothing/shoes/sneakers/black
|
||||
outfit.back = /obj/item/weapon/storage/backpack
|
||||
if(2)
|
||||
flavour_text += "you're an exile from the Tiger Cooperative. Their technological fanaticism drove you to question the power and beliefs of the Exolitics, and they saw you as a \
|
||||
heretic and subjected you to hours of horrible torture. You were hours away from execution when a high-ranking friend of yours in the Cooperative managed to secure you a pod, \
|
||||
scrambled its destination's coordinates, and launched it. You awoke from stasis when you landed and have been surviving - barely - ever since.</b>"
|
||||
uniform = /obj/item/clothing/under/rank/prisoner
|
||||
shoes = /obj/item/clothing/shoes/sneakers/orange
|
||||
back = /obj/item/weapon/storage/backpack
|
||||
outfit.uniform = /obj/item/clothing/under/rank/prisoner
|
||||
outfit.shoes = /obj/item/clothing/shoes/sneakers/orange
|
||||
outfit.back = /obj/item/weapon/storage/backpack
|
||||
if(3)
|
||||
flavour_text += "you were a doctor on one of Nanotrasen's space stations, but you left behind that damn corporation's tyranny and everything it stood for. From a metaphorical hell \
|
||||
to a literal one, you find yourself nonetheless missing the recycled air and warm floors of what you left behind... but you'd still rather be here than there.</b>"
|
||||
uniform = /obj/item/clothing/under/rank/medical
|
||||
suit = /obj/item/clothing/suit/toggle/labcoat
|
||||
back = /obj/item/weapon/storage/backpack/medic
|
||||
shoes = /obj/item/clothing/shoes/sneakers/black
|
||||
outfit.uniform = /obj/item/clothing/under/rank/medical
|
||||
outfit.suit = /obj/item/clothing/suit/toggle/labcoat
|
||||
outfit.back = /obj/item/weapon/storage/backpack/medic
|
||||
outfit.shoes = /obj/item/clothing/shoes/sneakers/black
|
||||
if(4)
|
||||
flavour_text += "you were always joked about by your friends for \"not playing with a full deck\", as they so <i>kindly</i> put it. It seems that they were right when you, on a tour \
|
||||
at one of Nanotrasen's state-of-the-art research facilities, were in one of the escape pods alone and saw the red button. It was big and shiny, and it caught your eye. You pressed \
|
||||
it, and after a terrifying and fast ride for days, you landed here. You've had time to wisen up since then, and you think that your old friends wouldn't be laughing now.</b>"
|
||||
uniform = /obj/item/clothing/under/color/grey/glorf
|
||||
shoes = /obj/item/clothing/shoes/sneakers/black
|
||||
back = /obj/item/weapon/storage/backpack
|
||||
..()
|
||||
outfit.uniform = /obj/item/clothing/under/color/grey/glorf
|
||||
outfit.shoes = /obj/item/clothing/shoes/sneakers/black
|
||||
outfit.back = /obj/item/weapon/storage/backpack
|
||||
|
||||
/obj/effect/mob_spawn/human/hermit/Destroy()
|
||||
new/obj/structure/fluff/empty_cryostasis_sleeper(get_turf(src))
|
||||
@@ -241,10 +247,7 @@
|
||||
mob_name = "an escaped prisoner"
|
||||
icon = 'icons/obj/Cryogenic2.dmi'
|
||||
icon_state = "sleeper_s"
|
||||
uniform = /obj/item/clothing/under/rank/prisoner
|
||||
mask = /obj/item/clothing/mask/breath
|
||||
shoes = /obj/item/clothing/shoes/sneakers/orange
|
||||
pocket1 = /obj/item/weapon/tank/internals/emergency_oxygen
|
||||
outfit = /datum/outfit/lavalandprisoner
|
||||
roundstart = FALSE
|
||||
death = FALSE
|
||||
flavour_text = "<font size=3><b>G</b></font><b>ood. It seems as though your ship crashed. You're a prisoner, sentenced to hard work in one of Nanotrasen's labor camps, but it seems as \
|
||||
@@ -254,12 +257,20 @@
|
||||
L.real_name = "NTP #LL-0[rand(111,999)]" //Nanotrasen Prisoner #Lavaland-(numbers)
|
||||
L.name = L.real_name
|
||||
|
||||
/obj/effect/mob_spawn/human/prisoner_transport/New()
|
||||
/obj/effect/mob_spawn/human/prisoner_transport/Initialize(mapload)
|
||||
. = ..()
|
||||
var/list/crimes = list("murder", "larceny", "embezzlement", "unionization", "dereliction of duty", "kidnapping", "gross incompetence", "grand theft", "collaboration with the Syndicate", \
|
||||
"worship of a forbidden deity", "interspecies relations", "mutiny")
|
||||
flavour_text += "[pick(crimes)]. but regardless of that, it seems like your crime doesn't matter now. You don't know where you are, but you know that it's out to kill you, and you're not going \
|
||||
to lose this opportunity. Find a way to get out of this mess and back to where you rightfully belong - your [pick("house", "apartment", "spaceship", "station")]</b>."
|
||||
..()
|
||||
|
||||
/datum/outfit/lavalandprisoner
|
||||
name = "Lavaland Prisoner"
|
||||
uniform = /obj/item/clothing/under/rank/prisoner
|
||||
mask = /obj/item/clothing/mask/breath
|
||||
shoes = /obj/item/clothing/shoes/sneakers/orange
|
||||
r_pocket = /obj/item/weapon/tank/internals/emergency_oxygen
|
||||
|
||||
|
||||
/obj/effect/mob_spawn/human/prisoner_transport/Destroy()
|
||||
new/obj/structure/fluff/empty_sleeper/syndicate(get_turf(src))
|
||||
@@ -272,31 +283,39 @@
|
||||
mob_name = "hotel staff member"
|
||||
icon = 'icons/obj/Cryogenic2.dmi'
|
||||
icon_state = "sleeper_s"
|
||||
uniform = /obj/item/clothing/under/assistantformal
|
||||
shoes = /obj/item/clothing/shoes/laceup
|
||||
pocket1 = /obj/item/device/radio/off
|
||||
back = /obj/item/weapon/storage/backpack
|
||||
objectives = "Cater to visiting guests with your fellow staff. Do not leave your assigned hotel and always remember: The customer is always right!"
|
||||
implants = list(/obj/item/weapon/implant/mindshield)
|
||||
death = FALSE
|
||||
roundstart = FALSE
|
||||
random = TRUE
|
||||
outfit = /datum/outfit/hotelstaff
|
||||
flavour_text = "You are a staff member of a top-of-the-line space hotel! Cater to guests and <font size=6><b>DON'T</b></font> leave the hotel, lest the manager fire you for\
|
||||
dereliction of duty!"
|
||||
|
||||
/datum/outfit/hotelstaff
|
||||
name = "Hotel Staff"
|
||||
uniform = /obj/item/clothing/under/assistantformal
|
||||
shoes = /obj/item/clothing/shoes/laceup
|
||||
r_pocket = /obj/item/device/radio/off
|
||||
back = /obj/item/weapon/storage/backpack
|
||||
implants = list(/obj/item/weapon/implant/mindshield)
|
||||
|
||||
/obj/effect/mob_spawn/human/hotel_staff/security
|
||||
name = "hotel security sleeper"
|
||||
mob_name = "hotel security memeber"
|
||||
uniform = /obj/item/clothing/under/rank/security/blueshirt
|
||||
shoes = /obj/item/clothing/shoes/jackboots
|
||||
suit = /obj/item/clothing/suit/armor/vest/blueshirt
|
||||
helmet = /obj/item/clothing/head/helmet/blueshirt
|
||||
back = /obj/item/weapon/storage/backpack/security
|
||||
belt = /obj/item/weapon/storage/belt/security/full
|
||||
outfit = /datum/outfit/hotelstaff/security
|
||||
flavour_text = "You are a peacekeeper assigned to this hotel to protect the intrests of the company while keeping the peace between \
|
||||
guests and the staff.Do <font size=6><b>NOT</b></font> leave the hotel, as that is grounds for contract termination."
|
||||
objectives = "Do not leave your assigned hotel. Try and keep the peace between staff and guests, non-lethal force heavily advised if possible."
|
||||
|
||||
/datum/outfit/hotelstaff/security
|
||||
name = "Hotel Secuirty"
|
||||
uniform = /obj/item/clothing/under/rank/security/blueshirt
|
||||
shoes = /obj/item/clothing/shoes/jackboots
|
||||
suit = /obj/item/clothing/suit/armor/vest/blueshirt
|
||||
head = /obj/item/clothing/head/helmet/blueshirt
|
||||
back = /obj/item/weapon/storage/backpack/security
|
||||
belt = /obj/item/weapon/storage/belt/security/full
|
||||
|
||||
/obj/effect/mob_spawn/human/hotel_staff/Destroy()
|
||||
new/obj/structure/fluff/empty_sleeper/syndicate(get_turf(src))
|
||||
..()
|
||||
@@ -307,22 +326,17 @@
|
||||
mob_name = "Demonic friend"
|
||||
icon = 'icons/obj/cardboard_cutout.dmi'
|
||||
icon_state = "cutout_basic"
|
||||
uniform = /obj/item/clothing/under/assistantformal
|
||||
shoes = /obj/item/clothing/shoes/laceup
|
||||
pocket1 = /obj/item/device/radio/off
|
||||
back = /obj/item/weapon/storage/backpack
|
||||
implants = list(/obj/item/weapon/implant/mindshield) //No revolutionaries, he's MY friend.
|
||||
outfit = /datum/outfit/demonic_friend
|
||||
death = FALSE
|
||||
roundstart = FALSE
|
||||
random = TRUE
|
||||
has_id = TRUE
|
||||
id_job = "SuperFriend"
|
||||
id_access = "assistant"
|
||||
var/obj/effect/proc_holder/spell/targeted/summon_friend/spell
|
||||
var/datum/mind/owner
|
||||
|
||||
/obj/effect/mob_spawn/human/demonic_friend/Initialize(mapload, datum/mind/owner_mind, obj/effect/proc_holder/spell/targeted/summon_friend/summoning_spell)
|
||||
..()
|
||||
. = ..()
|
||||
owner = owner_mind
|
||||
flavour_text = "You have been given a reprieve from your eternity of torment, to be [owner.name]'s friend for their short mortal coil. Be aware that if you do not live up to [owner.name]'s expectations, they can send you back to hell with a single thought. [owner.name]'s death will also return you to hell."
|
||||
var/area/A = get_area(src)
|
||||
@@ -349,3 +363,11 @@
|
||||
to_chat(L, "<span class='userdanger'>Your owner is already dead! You will soon perish.</span>")
|
||||
addtimer(CALLBACK(L, /mob.proc/dust, 150)) //Give em a few seconds as a mercy.
|
||||
|
||||
/datum/outfit/demonic_friend
|
||||
name = "Demonic Friend"
|
||||
uniform = /obj/item/clothing/under/assistantformal
|
||||
shoes = /obj/item/clothing/shoes/laceup
|
||||
r_pocket = /obj/item/device/radio/off
|
||||
back = /obj/item/weapon/storage/backpack
|
||||
implants = list(/obj/item/weapon/implant/mindshield) //No revolutionaries, he's MY friend.
|
||||
id = /obj/item/weapon/card/id
|
||||
|
||||
@@ -146,49 +146,49 @@
|
||||
|
||||
/obj/structure/sign/biohazard
|
||||
name = "\improper BIOHAZARD"
|
||||
desc = "A warning sign which reads 'BIOHAZARD'"
|
||||
desc = "A warning sign which reads 'BIOHAZARD'."
|
||||
icon_state = "bio"
|
||||
|
||||
/obj/structure/sign/electricshock
|
||||
name = "\improper HIGH VOLTAGE"
|
||||
desc = "A warning sign which reads 'HIGH VOLTAGE'"
|
||||
desc = "A warning sign which reads 'HIGH VOLTAGE'."
|
||||
icon_state = "shock"
|
||||
|
||||
/obj/structure/sign/examroom
|
||||
name = "\improper EXAM ROOM"
|
||||
desc = "A guidance sign which reads 'EXAM ROOM'"
|
||||
desc = "A guidance sign which reads 'EXAM ROOM'."
|
||||
icon_state = "examroom"
|
||||
|
||||
/obj/structure/sign/vacuum
|
||||
name = "\improper HARD VACUUM AHEAD"
|
||||
desc = "A warning sign which reads 'HARD VACUUM AHEAD'"
|
||||
desc = "A warning sign which reads 'HARD VACUUM AHEAD'."
|
||||
icon_state = "space"
|
||||
|
||||
/obj/structure/sign/deathsposal
|
||||
name = "\improper DISPOSAL: LEADS TO SPACE"
|
||||
desc = "A warning sign which reads 'DISPOSAL: LEADS TO SPACE'"
|
||||
desc = "A warning sign which reads 'DISPOSAL: LEADS TO SPACE'."
|
||||
icon_state = "deathsposal"
|
||||
|
||||
/obj/structure/sign/pods
|
||||
name = "\improper ESCAPE PODS"
|
||||
desc = "A warning sign which reads 'ESCAPE PODS'"
|
||||
desc = "A warning sign which reads 'ESCAPE PODS'."
|
||||
icon_state = "pods"
|
||||
|
||||
/obj/structure/sign/fire
|
||||
name = "\improper DANGER: FIRE"
|
||||
desc = "A warning sign which reads 'DANGER: FIRE'"
|
||||
desc = "A warning sign which reads 'DANGER: FIRE'."
|
||||
icon_state = "fire"
|
||||
|
||||
|
||||
/obj/structure/sign/nosmoking_1
|
||||
name = "\improper NO SMOKING"
|
||||
desc = "A warning sign which reads 'NO SMOKING'"
|
||||
desc = "A warning sign which reads 'NO SMOKING'."
|
||||
icon_state = "nosmoking"
|
||||
|
||||
|
||||
/obj/structure/sign/nosmoking_2
|
||||
name = "\improper NO SMOKING"
|
||||
desc = "A warning sign which reads 'NO SMOKING'"
|
||||
desc = "A warning sign which reads 'NO SMOKING'."
|
||||
icon_state = "nosmoking2"
|
||||
|
||||
/obj/structure/sign/radiation
|
||||
@@ -223,7 +223,7 @@
|
||||
|
||||
/obj/structure/sign/nanotrasen
|
||||
name = "\improper NanoTrasen Logo "
|
||||
desc = "A sign with the Nanotrasen Logo on it. Glory to Nanotrasen!"
|
||||
desc = "A sign with the Nanotrasen Logo on it. Glory to Nanotrasen!"
|
||||
icon_state = "nanotrasen"
|
||||
|
||||
/obj/structure/sign/science //These 3 have multiple types, just var-edit the icon_state to whatever one you want on the map
|
||||
@@ -246,6 +246,12 @@
|
||||
desc = "A sign labelling an area as a place where xenobiological entities are researched."
|
||||
icon_state = "xenobio"
|
||||
|
||||
/obj/structure/sign/xeno_warning_mining
|
||||
name = "DANGEROUS ALIEN LIFE"
|
||||
desc = "A sign that warns would-be travellers of hostile alien life in the vicinity."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "xeno_warning"
|
||||
|
||||
/obj/structure/sign/enginesafety
|
||||
name = "\improper ENGINEERING SAFETY"
|
||||
desc = "A sign detailing the various safety protocols when working on-site to ensure a safe shift."
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
density = 1
|
||||
blocks_air = 1
|
||||
|
||||
/turf/closed/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
|
||||
return FALSE
|
||||
|
||||
/turf/closed/indestructible
|
||||
name = "wall"
|
||||
icon = 'icons/turf/walls.dmi'
|
||||
@@ -24,9 +27,6 @@
|
||||
/turf/closed/indestructible/oldshuttle/corner
|
||||
icon_state = "corner"
|
||||
|
||||
|
||||
|
||||
|
||||
/turf/closed/indestructible/splashscreen
|
||||
name = "Space Station 13"
|
||||
icon = 'config/title_screens/images/blank.png'
|
||||
@@ -111,6 +111,11 @@
|
||||
explosion_block = 50
|
||||
baseturf = /turf/closed/indestructible/necropolis
|
||||
|
||||
/turf/closed/indestructible/necropolis/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
|
||||
underlay_appearance.icon = 'icons/turf/floors.dmi'
|
||||
underlay_appearance.icon_state = "necro1"
|
||||
return TRUE
|
||||
|
||||
/turf/closed/indestructible/riveted/hierophant
|
||||
name = "wall"
|
||||
desc = "A wall made out of a strange metal. The squares on it pulse in a predictable pattern."
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user