Merge branch 'master' into upstream-merge-27669
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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -124,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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,7 +853,7 @@ 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
|
||||
@@ -854,7 +863,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
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>")
|
||||
|
||||
@@ -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)
|
||||
chunk.remove(eye)
|
||||
qdel(eye)
|
||||
eye = null
|
||||
user.remote_control = null
|
||||
QDEL_NULL(eye)
|
||||
|
||||
user = null
|
||||
if(hologram)
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
diff a/code/datums/holocall.dm b/code/datums/holocall.dm (rejected hunks)
|
||||
@@ -45,7 +45,7 @@
|
||||
var/user_good = !QDELETED(user)
|
||||
if(user_good)
|
||||
user.reset_perspective()
|
||||
- user.remote_control = null
|
||||
+ user.remote_control = null
|
||||
|
||||
if(!QDELETED(eye))
|
||||
if(user_good && user.client)
|
||||
@@ -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
|
||||
|
||||
+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)
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
+35
-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,6 @@
|
||||
return
|
||||
|
||||
/atom/proc/ex_act(severity, target)
|
||||
set waitfor = FALSE
|
||||
contents_explosion(severity, target)
|
||||
|
||||
/atom/proc/blob_act(obj/structure/blob/B)
|
||||
@@ -506,10 +508,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)
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
diff a/code/game/gamemodes/gang/gang.dm b/code/game/gamemodes/gang/gang.dm (rejected hunks)
|
||||
@@ -255,11 +255,13 @@ GLOBAL_LIST_INIT(gang_colors_pool, list("red","orange","yellow","green","blue","
|
||||
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)))
|
||||
+ 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.")
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
diff a/code/game/gamemodes/gang/recaller.dm b/code/game/gamemodes/gang/recaller.dm (rejected hunks)
|
||||
@@ -165,7 +165,7 @@
|
||||
if(!can_use(user))
|
||||
return 0
|
||||
|
||||
- if(SSticker.mode.forced_shuttle)
|
||||
+ if(SSshuttle.emergencyNoRecall)
|
||||
return 0
|
||||
|
||||
if(recalling)
|
||||
@@ -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)
|
||||
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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
. = ..()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -45,6 +45,9 @@
|
||||
|
||||
/turf/open/indestructible/hierophant/two
|
||||
|
||||
/turf/open/indestructible/hierophant/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
|
||||
return FALSE
|
||||
|
||||
/turf/open/indestructible/paper
|
||||
name = "notebook floor"
|
||||
desc = "A floor made of invulnerable notebook paper."
|
||||
|
||||
@@ -22,6 +22,10 @@
|
||||
if(!drop_stuff())
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/turf/open/chasm/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
|
||||
underlay_appearance.icon = 'icons/turf/floors.dmi'
|
||||
underlay_appearance.icon_state = "basalt"
|
||||
return TRUE
|
||||
|
||||
/turf/open/chasm/attackby(obj/item/C, mob/user, params, area/area_restriction)
|
||||
..()
|
||||
@@ -171,6 +175,11 @@
|
||||
planetary_atmos = TRUE
|
||||
initial_gas_mix = "o2=14;n2=23;TEMP=300"
|
||||
|
||||
/turf/open/chasm/jungle/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
|
||||
underlay_appearance.icon = 'icons/turf/floors.dmi'
|
||||
underlay_appearance.icon_state = "dirt"
|
||||
return TRUE
|
||||
|
||||
/turf/open/chasm/straight_down/jungle
|
||||
icon = 'icons/turf/floors/junglechasm.dmi'
|
||||
planetary_atmos = TRUE
|
||||
|
||||
@@ -140,7 +140,7 @@
|
||||
floor_tile = /obj/item/stack/tile/carpet
|
||||
broken_states = list("damaged")
|
||||
smooth = SMOOTH_TRUE
|
||||
canSmoothWith = list(/turf/open/floor/carpet, /turf/open/chasm)
|
||||
canSmoothWith = list(/turf/open/floor/carpet)
|
||||
flags = NONE
|
||||
|
||||
/turf/open/floor/carpet/Initialize()
|
||||
@@ -175,15 +175,22 @@
|
||||
burnt = 1
|
||||
update_icon()
|
||||
|
||||
/turf/open/floor/carpet/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
|
||||
return FALSE
|
||||
|
||||
|
||||
turf/open/floor/fakepit
|
||||
/turf/open/floor/fakepit
|
||||
desc = "A clever illusion designed to look like a bottomless pit."
|
||||
smooth = SMOOTH_TRUE | SMOOTH_BORDER | SMOOTH_MORE
|
||||
canSmoothWith = list(/turf/open/floor/fakepit, /turf/open/chasm)
|
||||
canSmoothWith = list(/turf/open/floor/fakepit)
|
||||
icon = 'icons/turf/floors/Chasms.dmi'
|
||||
icon_state = "smooth"
|
||||
|
||||
/turf/open/floor/fakepit/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
|
||||
underlay_appearance.icon = 'icons/turf/floors.dmi'
|
||||
underlay_appearance.icon_state = "basalt"
|
||||
return TRUE
|
||||
|
||||
/turf/open/floor/fakespace
|
||||
icon = 'icons/turf/space.dmi'
|
||||
icon_state = "0"
|
||||
@@ -193,4 +200,10 @@ turf/open/floor/fakepit
|
||||
|
||||
/turf/open/floor/fakespace/Initialize()
|
||||
..()
|
||||
icon_state = "[rand(0,25)]"
|
||||
icon_state = SPACE_ICON_STATE
|
||||
|
||||
/turf/open/floor/fakespace/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
|
||||
underlay_appearance.icon = 'icons/turf/space.dmi'
|
||||
underlay_appearance.icon_state = SPACE_ICON_STATE
|
||||
underlay_appearance.plane = PLANE_SPACE
|
||||
return TRUE
|
||||
|
||||
@@ -38,6 +38,11 @@
|
||||
/turf/open/floor/plating/lava/make_plating()
|
||||
return
|
||||
|
||||
/turf/open/floor/plating/lava/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
|
||||
underlay_appearance.icon = 'icons/turf/floors.dmi'
|
||||
underlay_appearance.icon_state = "basalt"
|
||||
return TRUE
|
||||
|
||||
/turf/open/floor/plating/lava/GetHeatCapacity()
|
||||
. = 700000
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
/turf/closed/mineral/Initialize()
|
||||
if (!canSmoothWith)
|
||||
canSmoothWith = list(/turf/closed)
|
||||
canSmoothWith = list(/turf/closed/mineral, /turf/closed/indestructible)
|
||||
pixel_y = -4
|
||||
pixel_x = -4
|
||||
icon = smooth_icon
|
||||
@@ -42,6 +42,13 @@
|
||||
setDir(angle2dir(rotation+dir2angle(dir)))
|
||||
queue_smooth(src)
|
||||
|
||||
/turf/closed/mineral/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
|
||||
if(turf_type)
|
||||
underlay_appearance.icon = initial(turf_type.icon)
|
||||
underlay_appearance.icon_state = initial(turf_type.icon_state)
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
|
||||
/turf/closed/mineral/attackby(obj/item/weapon/pickaxe/P, mob/user, params)
|
||||
if (!user.IsAdvancedToolUser())
|
||||
|
||||
@@ -175,6 +175,7 @@
|
||||
desc = "A light-weight titanium wall used in shuttles."
|
||||
icon = 'icons/turf/walls/shuttle_wall.dmi'
|
||||
icon_state = "map-shuttle"
|
||||
flags = CAN_BE_DIRTY | CHECK_RICOCHET
|
||||
sheet_type = /obj/item/stack/sheet/mineral/titanium
|
||||
smooth = SMOOTH_MORE|SMOOTH_DIAGONAL
|
||||
canSmoothWith = list(/turf/closed/wall/mineral/titanium, /obj/machinery/door/airlock/shuttle, /obj/machinery/door/airlock/, /turf/closed/wall/shuttle, /obj/structure/window/shuttle, /obj/structure/shuttle/engine/heater, /obj/structure/falsewall/titanium)
|
||||
|
||||
@@ -28,6 +28,20 @@
|
||||
/turf/closed/wall/attack_tk()
|
||||
return
|
||||
|
||||
/turf/closed/wall/handle_ricochet(obj/item/projectile/P) //A huge pile of shitcode!
|
||||
var/turf/p_turf = get_turf(P)
|
||||
var/face_direction = get_dir(src, p_turf)
|
||||
var/face_angle = dir2angle(face_direction)
|
||||
var/incidence_s = get_angle_of_incidence(face_angle, P.Angle)
|
||||
var/new_angle = face_angle + incidence_s
|
||||
var/new_angle_s = new_angle
|
||||
while(new_angle_s > 180) // Translate to regular projectile degrees
|
||||
new_angle_s -= 360
|
||||
while(new_angle_s < -180)
|
||||
new_angle_s += 360
|
||||
P.Angle = new_angle_s
|
||||
return TRUE
|
||||
|
||||
/turf/closed/wall/proc/dismantle_wall(devastated=0, explode=0)
|
||||
if(devastated)
|
||||
devastate_wall()
|
||||
|
||||
@@ -160,6 +160,12 @@
|
||||
/turf/open/space/acid_act(acidpwr, acid_volume)
|
||||
return 0
|
||||
|
||||
/turf/open/space/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
|
||||
underlay_appearance.icon = 'icons/turf/space.dmi'
|
||||
underlay_appearance.icon_state = SPACE_ICON_STATE
|
||||
underlay_appearance.plane = PLANE_SPACE
|
||||
return TRUE
|
||||
|
||||
|
||||
/turf/open/space/rcd_vals(mob/user, obj/item/weapon/construction/rcd/the_rcd)
|
||||
if(!CanBuildHere())
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
baseturf = /turf/open/space/transit
|
||||
flags = NOJAUNT //This line goes out to every wizard that ever managed to escape the den. I'm sorry.
|
||||
|
||||
/turf/open/space/transit/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
|
||||
. = ..()
|
||||
underlay_appearance.icon_state = "speedspace_ns_[get_transit_state(asking_turf)]"
|
||||
underlay_appearance.transform = turn(matrix(), get_transit_angle(asking_turf))
|
||||
|
||||
/turf/open/space/transit/south
|
||||
dir = SOUTH
|
||||
|
||||
@@ -69,25 +74,32 @@
|
||||
throw_atom(AM)
|
||||
|
||||
/turf/open/space/transit/proc/update_icon()
|
||||
var/p = 9
|
||||
var/angle = 0
|
||||
var/state = 1
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
angle = 180
|
||||
state = ((-p*x+y) % 15) + 1
|
||||
if(state < 1)
|
||||
state += 15
|
||||
if(EAST)
|
||||
angle = 90
|
||||
state = ((x+p*y) % 15) + 1
|
||||
if(WEST)
|
||||
angle = -90
|
||||
state = ((x-p*y) % 15) + 1
|
||||
if(state < 1)
|
||||
state += 15
|
||||
else
|
||||
state = ((p*x+y) % 15) + 1
|
||||
icon_state = "speedspace_ns_[get_transit_state(src)]"
|
||||
transform = turn(matrix(), get_transit_angle(src))
|
||||
|
||||
icon_state = "speedspace_ns_[state]"
|
||||
transform = turn(matrix(), angle)
|
||||
/proc/get_transit_state(turf/T)
|
||||
var/p = 9
|
||||
. = 1
|
||||
switch(T.dir)
|
||||
if(NORTH)
|
||||
. = ((-p*T.x+T.y) % 15) + 1
|
||||
if(. < 1)
|
||||
. += 15
|
||||
if(EAST)
|
||||
. = ((T.x+p*T.y) % 15) + 1
|
||||
if(WEST)
|
||||
. = ((T.x-p*T.y) % 15) + 1
|
||||
if(. < 1)
|
||||
. += 15
|
||||
else
|
||||
. = ((p*T.x+T.y) % 15) + 1
|
||||
|
||||
/proc/get_transit_angle(turf/T)
|
||||
. = 0
|
||||
switch(T.dir)
|
||||
if(NORTH)
|
||||
. = 180
|
||||
if(EAST)
|
||||
. = 90
|
||||
if(WEST)
|
||||
. = -90
|
||||
@@ -394,6 +394,12 @@
|
||||
if(ismob(A) || .)
|
||||
A.ratvar_act()
|
||||
|
||||
/turf/proc/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
|
||||
underlay_appearance.icon = icon
|
||||
underlay_appearance.icon_state = icon_state
|
||||
underlay_appearance.dir = adjacency_dir
|
||||
return TRUE
|
||||
|
||||
/turf/proc/add_blueprints(atom/movable/AM)
|
||||
var/image/I = new
|
||||
I.appearance = AM.appearance
|
||||
|
||||
+20
-20
@@ -37,7 +37,7 @@
|
||||
body += " \[<A href='?_src_=holder;revive=\ref[M]'>Heal</A>\] "
|
||||
|
||||
if(M.client)
|
||||
body += "<br>\[<b>Player Age:</b> [M.client.player_age]\]\[<b>Byond Age:</b> [M.client.account_age]\]"
|
||||
body += "<br>\[<b>First Seen:</b> [M.client.player_join_date]\]\[<b>Byond account registered on:</b> [M.client.account_join_date]\]"
|
||||
body += "<br><b>Show related accounts by:</b> "
|
||||
body += "\[ <a href='?_src_=holder;showrelatedacc=cid;client=\ref[M.client]'>CID</a> | "
|
||||
body += "<a href='?_src_=holder;showrelatedacc=ip;client=\ref[M.client]'>IP</a> \]"
|
||||
@@ -48,7 +48,7 @@
|
||||
body += "<a href='?priv_msg=[M.ckey]'>PM</a> - "
|
||||
body += "<a href='?_src_=holder;subtlemessage=\ref[M]'>SM</a> - "
|
||||
body += "<a href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a> - "
|
||||
body += "<a href='?_src_=holder;individuallog=\ref[M]'>LOGS</a>\] <b><br>"
|
||||
body += "<a href='?_src_=holder;individuallog=\ref[M]'>LOGS</a>\] <br>"
|
||||
|
||||
body += "<b>Mob type</b> = [M.type]<br><br>"
|
||||
|
||||
@@ -239,21 +239,21 @@
|
||||
if(6)
|
||||
dat+="<B><FONT COLOR='maroon'>ERROR: Could not submit Feed story to Network.</B></FONT><HR><BR>"
|
||||
if(src.admincaster_feed_channel.channel_name=="")
|
||||
dat+="<FONT COLOR='maroon'>Invalid receiving channel name.</FONT><BR>"
|
||||
dat+="<FONT COLOR='maroon'>Invalid receiving channel name.</FONT><BR>"
|
||||
if(src.admincaster_feed_message.returnBody(-1) == "" || src.admincaster_feed_message.returnBody(-1) == "\[REDACTED\]")
|
||||
dat+="<FONT COLOR='maroon'>Invalid message body.</FONT><BR>"
|
||||
dat+="<FONT COLOR='maroon'>Invalid message body.</FONT><BR>"
|
||||
dat+="<BR><A href='?src=\ref[src];ac_setScreen=[3]'>Return</A><BR>"
|
||||
if(7)
|
||||
dat+="<B><FONT COLOR='maroon'>ERROR: Could not submit Feed Channel to Network.</B></FONT><HR><BR>"
|
||||
if(src.admincaster_feed_channel.channel_name =="" || src.admincaster_feed_channel.channel_name == "\[REDACTED\]")
|
||||
dat+="<FONT COLOR='maroon'>Invalid channel name.</FONT><BR>"
|
||||
dat+="<FONT COLOR='maroon'>Invalid channel name.</FONT><BR>"
|
||||
var/check = 0
|
||||
for(var/datum/newscaster/feed_channel/FC in GLOB.news_network.network_channels)
|
||||
if(FC.channel_name == src.admincaster_feed_channel.channel_name)
|
||||
check = 1
|
||||
break
|
||||
if(check)
|
||||
dat+="<FONT COLOR='maroon'>Channel name already in use.</FONT><BR>"
|
||||
dat+="<FONT COLOR='maroon'>Channel name already in use.</FONT><BR>"
|
||||
dat+="<BR><A href='?src=\ref[src];ac_setScreen=[2]'>Return</A><BR>"
|
||||
if(9)
|
||||
dat+="<B>[admincaster_feed_channel.channel_name]: </B><FONT SIZE=1>\[created by: <FONT COLOR='maroon'>[admincaster_feed_channel.returnAuthor(-1)]</FONT>\]</FONT><HR>"
|
||||
@@ -354,9 +354,9 @@
|
||||
if(16)
|
||||
dat+="<B><FONT COLOR='maroon'>ERROR: Wanted Issue rejected by Network.</B></FONT><HR><BR>"
|
||||
if(src.admincaster_wanted_message.criminal =="" || src.admincaster_wanted_message.criminal == "\[REDACTED\]")
|
||||
dat+="<FONT COLOR='maroon'>Invalid name for person wanted.</FONT><BR>"
|
||||
dat+="<FONT COLOR='maroon'>Invalid name for person wanted.</FONT><BR>"
|
||||
if(src.admincaster_wanted_message.body == "" || src.admincaster_wanted_message.body == "\[REDACTED\]")
|
||||
dat+="<FONT COLOR='maroon'>Invalid description.</FONT><BR>"
|
||||
dat+="<FONT COLOR='maroon'>Invalid description.</FONT><BR>"
|
||||
dat+="<BR><A href='?src=\ref[src];ac_setScreen=[0]'>Return</A><BR>"
|
||||
if(17)
|
||||
dat+="<B>Wanted Issue successfully deleted from Circulation</B><BR>"
|
||||
@@ -419,18 +419,18 @@
|
||||
set desc="Restarts the world immediately"
|
||||
if (!usr.client.holder)
|
||||
return
|
||||
|
||||
var/list/options = list("Regular Restart", "Hard Restart (No Delay/Feeback Reason)", "Hardest Restart (No actions, just reboot)")
|
||||
var result = input(usr, "Select reboot method", "World Reboot", options[1]) as null|anything in options
|
||||
if(result)
|
||||
|
||||
var/list/options = list("Regular Restart", "Hard Restart (No Delay/Feeback Reason)", "Hardest Restart (No actions, just reboot)")
|
||||
var result = input(usr, "Select reboot method", "World Reboot", options[1]) as null|anything in options
|
||||
if(result)
|
||||
SSblackbox.add_details("admin_verb","Reboot World") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
switch(result)
|
||||
if("Regular Restart")
|
||||
SSticker.Reboot("Initiated by [usr.client.holder.fakekey ? "Admin" : usr.key].", "end_error", "admin reboot - by [usr.key] [usr.client.holder.fakekey ? "(stealth)" : ""]", 10)
|
||||
if("Hard Restart (No Delay, No Feeback Reason)")
|
||||
world.Reboot()
|
||||
if("Hardest Restart (No actions, just reboot)")
|
||||
world.Reboot(fast_track = TRUE)
|
||||
switch(result)
|
||||
if("Regular Restart")
|
||||
SSticker.Reboot("Initiated by [usr.client.holder.fakekey ? "Admin" : usr.key].", "admin reboot - by [usr.key] [usr.client.holder.fakekey ? "(stealth)" : ""]", 10)
|
||||
if("Hard Restart (No Delay, No Feeback Reason)")
|
||||
world.Reboot()
|
||||
if("Hardest Restart (No actions, just reboot)")
|
||||
world.Reboot(fast_track = TRUE)
|
||||
|
||||
/datum/admins/proc/end_round()
|
||||
set category = "Server"
|
||||
@@ -607,7 +607,7 @@
|
||||
if(3)
|
||||
var/count = 0
|
||||
for(var/mob/living/carbon/monkey/Monkey in world)
|
||||
if(Monkey.z == 1)
|
||||
if(Monkey.z == ZLEVEL_STATION)
|
||||
count++
|
||||
return "Kill all [count] of the monkeys on the station"
|
||||
if(4)
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
for(var/turf/T in get_area_turfs(thearea.type))
|
||||
L+=T
|
||||
var/loc = pick(L)
|
||||
explosion(loc,explosiondev,explosionmed,explosionlight)
|
||||
explosion(loc,explosiondev,explosionmed,explosionlight)
|
||||
reload = 0
|
||||
|
||||
/*/mob/proc/openfire()
|
||||
|
||||
@@ -377,6 +377,10 @@
|
||||
icon_state = "sleeper"
|
||||
flavour_text = "You are a beach bum!"
|
||||
|
||||
/obj/effect/mob_spawn/human/beach/equip(mob/living/carbon/human/H)
|
||||
..()
|
||||
H.dna.add_mutation(STONER)
|
||||
|
||||
/////////////////Officers+Nanotrasen Security//////////////////////
|
||||
|
||||
/obj/effect/mob_spawn/human/bridgeofficer
|
||||
|
||||
@@ -46,8 +46,8 @@
|
||||
//Syndicate sub-machine guns.
|
||||
/obj/item/weapon/gun/ballistic/automatic/c20r/sc_c20r
|
||||
|
||||
/obj/item/weapon/gun/ballistic/automatic/c20r/sc_c20r/New()
|
||||
..()
|
||||
/obj/item/weapon/gun/ballistic/automatic/c20r/sc_c20r/Initialize()
|
||||
. = ..()
|
||||
for(var/ammo in magazine.stored_ammo)
|
||||
if(prob(95)) //95% chance
|
||||
magazine.stored_ammo -= ammo
|
||||
@@ -55,8 +55,8 @@
|
||||
//Barman's shotgun
|
||||
/obj/item/weapon/gun/ballistic/shotgun/sc_pump
|
||||
|
||||
/obj/item/weapon/gun/ballistic/shotgun/sc_pump/New()
|
||||
..()
|
||||
/obj/item/weapon/gun/ballistic/shotgun/sc_pump/Initialize()
|
||||
. = ..()
|
||||
for(var/ammo in magazine.stored_ammo)
|
||||
if(prob(95)) //95% chance
|
||||
magazine.stored_ammo -= ammo
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
explosion(M, 1, 0, 0, 0)
|
||||
explosion(M, 1, 0, 0, 0)
|
||||
qdel(src)
|
||||
|
||||
/////For the Wishgranter///////////
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
|
||||
// Plasma. The oil of 26 century. The reason why you are here.
|
||||
/datum/export/material/plasma
|
||||
cost = 500
|
||||
cost = 300
|
||||
material_id = MAT_PLASMA
|
||||
message = "cm3 of plasma"
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
|
||||
// Plastitanium.
|
||||
/datum/export/material/plastitanium
|
||||
cost = 750
|
||||
cost = 550
|
||||
material_id = MAT_TITANIUM // code can only check for one material_id; plastitanium is half plasma, half titanium, so ((250 x 250) + (250 x 500)) / 250
|
||||
message = "cm3 of plastitanium"
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
diff a/code/modules/cargo/exports/materials.dm b/code/modules/cargo/exports/materials.dm (rejected hunks)
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
// Plasma. The oil of 26 century. The reason why you are here.
|
||||
/datum/export/material/plasma
|
||||
- cost = 500
|
||||
+ cost = 300
|
||||
k_elasticity = 0
|
||||
material_id = MAT_PLASMA
|
||||
message = "cm3 of plasma"
|
||||
@@ -1582,7 +1582,7 @@
|
||||
name = "Contraband Crate"
|
||||
contraband = TRUE
|
||||
cost = 3000
|
||||
num_contained = 6
|
||||
num_contained = 5
|
||||
contains = list(/obj/item/weapon/poster/random_contraband,
|
||||
/obj/item/weapon/storage/fancy/cigarettes/cigpack_shadyjims,
|
||||
/obj/item/weapon/storage/fancy/cigarettes/cigpack_midori,
|
||||
|
||||
@@ -420,8 +420,8 @@
|
||||
var/badmin_mode = FALSE
|
||||
var/static/list/blacklisted_vars = list("locs", "loc", "contents", "x", "y", "z")
|
||||
|
||||
/obj/item/weapon/gun/energy/laser/chameleon/New()
|
||||
..()
|
||||
/obj/item/weapon/gun/energy/laser/chameleon/Initialize()
|
||||
. = ..()
|
||||
chameleon_action = new(src)
|
||||
chameleon_action.chameleon_type = /obj/item/weapon/gun
|
||||
chameleon_action.chameleon_name = "Gun"
|
||||
|
||||
@@ -39,8 +39,9 @@
|
||||
vision_flags = SEE_TURFS
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
|
||||
glass_colour_type = /datum/client_colour/glass_colour/lightgreen
|
||||
var/static/list/meson_mining_failure_excuses = list("seismic activity", "excessive lava", "ambient radiation", "electromagnetic storms", "bluespace disruption", \
|
||||
"gravity", "dust", "dense rock", "ash", "badly understood science", "radiant heat")
|
||||
var/static/list/meson_mining_failure_excuses = list("badly understood science", "damaged meson generators", "electromagnetic storms", "bluespace disruption", "ancient structures", \
|
||||
"ambient radiation", "seismic activity", "extreme weather", "strange signals", "excessive lava", "giant monsters", "a loose wire", "lens warping", "radiant heat", "volcanic ash", \
|
||||
"budget cuts","alien life","dense rock", "gravity", "dust")
|
||||
var/picked_excuse
|
||||
var/mesons_on = TRUE
|
||||
|
||||
@@ -65,7 +66,7 @@
|
||||
|
||||
if(iscarbon(user)) //only carbons can wear glasses
|
||||
var/mob/living/carbon/C = user
|
||||
if(!mesons_on)
|
||||
if(mesons_on)
|
||||
to_chat(C, "<span class='notice'>Your Meson Scanners have reactivated.</span>")
|
||||
else if(picked_excuse)
|
||||
to_chat(C, "<span class='warning'>Due to [picked_excuse], your Meson Scanners will not be able to display terrain layouts in this area.</span>")
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
/obj/item/clothing/head/hunter
|
||||
name = "hunter hat"
|
||||
desc = "It's a flimsy looking hat."
|
||||
icon_state = "hunter"
|
||||
icon = 'icons/obj/clothing/cit_hats.dmi'
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user