mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2025-12-17 05:31:53 +00:00
Evreything works but timers
This commit is contained in:
@@ -20,7 +20,7 @@ var/global/list/datum/pipe_network/pipe_networks = list() // TODO - Move into SS
|
||||
gases.Cut() // Do not qdel the gases, we don't own them
|
||||
return ..()
|
||||
|
||||
proc/process()
|
||||
process()
|
||||
//Equalize gases amongst pipe if called for
|
||||
if(update)
|
||||
update = 0
|
||||
|
||||
@@ -20,7 +20,7 @@ datum/pipeline
|
||||
edges = null
|
||||
. = ..()
|
||||
|
||||
proc/process()//This use to be called called from the pipe networks
|
||||
process()//This use to be called called from the pipe networks
|
||||
|
||||
//Check to see if pressure is within acceptable limits
|
||||
var/pressure = air.return_pressure()
|
||||
|
||||
@@ -34,8 +34,8 @@ if(current_step == this_step || (initial_step && !resumed)) /* So we start at st
|
||||
|
||||
#define NEW_SS_GLOBAL(varname) if(varname != src){if(istype(varname)){Recover();qdel(varname);}varname = src;}
|
||||
|
||||
#define START_PROCESSING(Processor, Datum) if (!Datum.isprocessing) {Datum.isprocessing = 1;Processor.processing += Datum}
|
||||
#define STOP_PROCESSING(Processor, Datum) Datum.isprocessing = 0;Processor.processing -= Datum
|
||||
#define START_PROCESSING(Processor, Datum) if (!Datum.is_processing) {Datum.is_processing = 1;Processor.processing += Datum}
|
||||
#define STOP_PROCESSING(Processor, Datum) Datum.is_processing = 0;Processor.processing -= Datum
|
||||
|
||||
//SubSystem flags (Please design any new flags so that the default is off, to make adding flags to subsystems easier)
|
||||
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
// Credits to Nickr5 for the useful procs I've taken from his library resource.
|
||||
// This file is quadruple wrapped for your pleasure
|
||||
// (
|
||||
|
||||
#define NUM_E 2.71828183
|
||||
|
||||
#define INFINITY 1e31 //closer then enough
|
||||
|
||||
#define SHORT_REAL_LIMIT 16777216 // 2^24 - Maximum integer that can be exactly represented in a float (BYOND num var)
|
||||
|
||||
//"fancy" math for calculating time in ms from tick_usage percentage and the length of ticks
|
||||
//percent_of_tick_used * (ticklag * 100(to convert to ms)) / 100(percent ratio)
|
||||
//collapsed to percent_of_tick_used * tick_lag
|
||||
@@ -9,15 +19,57 @@
|
||||
#define REALTIMEOFDAY (world.timeofday + (MIDNIGHT_ROLLOVER * MIDNIGHT_ROLLOVER_CHECK))
|
||||
#define MIDNIGHT_ROLLOVER_CHECK ( rollovercheck_last_timeofday != world.timeofday ? update_midnight_rollover() : midnight_rollovers )
|
||||
|
||||
#define SHORT_REAL_LIMIT 16777216 // 2^24 - Maximum integer that can be exactly represented in a float (BYOND num var)
|
||||
#define SIGN(x) ( (x)!=0 ? (x) / abs(x) : 0 )
|
||||
|
||||
#define CEILING(x, y) ( -round(-(x) / (y)) * (y) )
|
||||
// round() acts like floor(x, 1) by default but can't handle other values
|
||||
#define FLOOR(x, y) ( round((x) / (y)) * (y) )
|
||||
// Check if a BYOND dir var is a cardinal direction (power of two)
|
||||
#define IS_CARDINAL(x) ((x & (x - 1)) == 0)
|
||||
|
||||
#define CLAMP(CLVALUE,CLMIN,CLMAX) ( max( (CLMIN), min((CLVALUE), (CLMAX)) ) )
|
||||
|
||||
// Similar to clamp but the bottom rolls around to the top and vice versa. min is inclusive, max is exclusive
|
||||
#define WRAP(val, min, max) ( min == max ? min : (val) - (round(((val) - (min))/((max) - (min))) * ((max) - (min))) )
|
||||
|
||||
// Real modulus that handles decimals
|
||||
#define MODULUS(x, y) ( (x) - (y) * round((x) / (y)) )
|
||||
|
||||
#define CLAMP(CLVALUE,CLMIN,CLMAX) ( max( (CLMIN), min((CLVALUE), (CLMAX)) ) )
|
||||
// Check if a BYOND dir var is a cardinal direction (power of two)
|
||||
#define IS_CARDINAL(x) ((x & (x - 1)) == 0)
|
||||
|
||||
// Tangent
|
||||
#define TAN(x) (sin(x) / cos(x))
|
||||
|
||||
// Cotangent
|
||||
#define COT(x) (1 / TAN(x))
|
||||
|
||||
// Secant
|
||||
#define SEC(x) (1 / cos(x))
|
||||
|
||||
// Cosecant
|
||||
#define CSC(x) (1 / sin(x))
|
||||
|
||||
#define ATAN2(x, y) ( !(x) && !(y) ? 0 : (y) >= 0 ? arccos((x) / sqrt((x)*(x) + (y)*(y))) : -arccos((x) / sqrt((x)*(x) + (y)*(y))) )
|
||||
|
||||
#define TODEGREES(radians) ((radians) * 57.2957795)
|
||||
|
||||
#define TORADIANS(degrees) ((degrees) * 0.0174532925)
|
||||
|
||||
// Will filter out extra rotations and negative rotations
|
||||
// E.g: 540 becomes 180. -180 becomes 180.
|
||||
#define SIMPLIFY_DEGREES(degrees) (MODULUS((degrees), 360))
|
||||
|
||||
#define GET_ANGLE_OF_INCIDENCE(face, input) (MODULUS((face) - (input), 360))
|
||||
|
||||
//Finds the shortest angle that angle A has to change to get to angle B. Aka, whether to move clock or counterclockwise.
|
||||
/proc/closer_angle_difference(a, b)
|
||||
if(!isnum(a) || !isnum(b))
|
||||
return
|
||||
a = SIMPLIFY_DEGREES(a)
|
||||
b = SIMPLIFY_DEGREES(b)
|
||||
var/inc = b - a
|
||||
if(inc < 0)
|
||||
inc += 360
|
||||
var/dec = a - b
|
||||
if(dec < 0)
|
||||
dec += 360
|
||||
. = inc > dec? -dec : inc
|
||||
|
||||
@@ -23,8 +23,6 @@
|
||||
#define CLAMP01(x) max(0, min(1, x))
|
||||
#define QUANTIZE(variable) (round(variable,0.0001))
|
||||
|
||||
#define INFINITY 1.#INF
|
||||
|
||||
#define TICKS_IN_DAY 24*60*60*10
|
||||
#define TICKS_IN_SECOND 10
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
|
||||
#define INIT_ORDER_ATOMS 15
|
||||
#define INIT_ORDER_MACHINES 10
|
||||
#define INIT_ORDER_SHUTTLES 3
|
||||
#define INIT_ORDER_TIMER 1
|
||||
#define INIT_ORDER_DEFAULT 0
|
||||
#define INIT_ORDER_LIGHTING 0
|
||||
#define INIT_ORDER_AIR -1
|
||||
@@ -72,6 +73,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
|
||||
#define FIRE_PRIORITY_GARBAGE 15
|
||||
#define FIRE_PRIORITY_AIRFLOW 30
|
||||
#define FIRE_PRIORITY_AIR 35
|
||||
#define FIRE_PRIORITY_PROCESS 35
|
||||
#define FIRE_PRIORITY_DEFAULT 50
|
||||
#define FIRE_PRIORITY_PLANETS 75
|
||||
#define FIRE_PRIORITY_MACHINES 100
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#define TICKS *world.tick_lag
|
||||
|
||||
#define DS2TICKS(DS) (DS/world.tick_lag) // Convert deciseconds to ticks
|
||||
#define TICKS2DS(T) (T TICKS) // Convert ticks to deciseconds
|
||||
#define TICKS2DS(T) ((T) TICKS) // Convert ticks to deciseconds
|
||||
|
||||
/proc/get_game_time()
|
||||
var/global/time_offset = 0
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
if(!locate(/turf) in list(A, A.loc)) // Prevents inventory from being drilled
|
||||
return
|
||||
var/obj/mecha/M = loc
|
||||
return M.click_action(A, src)
|
||||
return M.click_action(A, src, params)
|
||||
|
||||
if(restrained())
|
||||
setClickCooldown(10)
|
||||
@@ -282,10 +282,10 @@
|
||||
Laser Eyes: as the name implies, handles this since nothing else does currently
|
||||
face_atom: turns the mob towards what you clicked on
|
||||
*/
|
||||
/mob/proc/LaserEyes(atom/A)
|
||||
/mob/proc/LaserEyes(atom/A, params)
|
||||
return
|
||||
|
||||
/mob/living/LaserEyes(atom/A)
|
||||
/mob/living/LaserEyes(atom/A, params)
|
||||
setClickCooldown(4)
|
||||
var/turf/T = get_turf(src)
|
||||
|
||||
@@ -293,8 +293,11 @@
|
||||
LE.icon = 'icons/effects/genetics.dmi'
|
||||
LE.icon_state = "eyelasers"
|
||||
playsound(usr.loc, 'sound/weapons/taser2.ogg', 75, 1)
|
||||
LE.launch(A)
|
||||
/mob/living/carbon/human/LaserEyes()
|
||||
LE.firer = src
|
||||
LE.preparePixelProjectile(A, src, params)
|
||||
LE.fire()
|
||||
|
||||
/mob/living/carbon/human/LaserEyes(atom/A, params)
|
||||
if(nutrition>0)
|
||||
..()
|
||||
nutrition = max(nutrition - rand(1,5),0)
|
||||
|
||||
@@ -13,11 +13,3 @@ PROCESSING_SUBSYSTEM_DEF(projectiles)
|
||||
var/obj/item/projectile/P = i
|
||||
if(istype(P)) //there's non projectiles on this too.
|
||||
P.set_pixel_speed(new_speed)
|
||||
|
||||
/datum/controller/subsystem/processing/projectiles/vv_edit_var(var_name, var_value)
|
||||
switch(var_name)
|
||||
if(NAMEOF(src, global_pixel_speed))
|
||||
set_pixel_speed(var_value)
|
||||
return TRUE
|
||||
else
|
||||
return ..()
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
/datum
|
||||
var/gc_destroyed //Time when this object was destroyed.
|
||||
var/weakref/weakref // Holder of weakref instance pointing to this datum
|
||||
var/list/active_timers //for SStimer
|
||||
var/is_processing = FALSE // If this datum is in an MC processing list, this will be set to its name.
|
||||
|
||||
#ifdef TESTING
|
||||
@@ -18,6 +19,15 @@
|
||||
// Return the appropriate QDEL_HINT; in most cases this is QDEL_HINT_QUEUE.
|
||||
/datum/proc/Destroy(force=FALSE)
|
||||
weakref = null // Clear this reference to ensure it's kept for as brief duration as possible.
|
||||
|
||||
var/list/timers = active_timers
|
||||
active_timers = null
|
||||
for(var/thing in timers)
|
||||
var/datum/timedevent/timer = thing
|
||||
if (timer.spent)
|
||||
continue
|
||||
qdel(timer)
|
||||
|
||||
tag = null
|
||||
GLOB.nanomanager.close_uis(src)
|
||||
return QDEL_HINT_QUEUE
|
||||
|
||||
@@ -532,7 +532,8 @@ proc/findNullRod(var/atom/target)
|
||||
/obj/item/weapon/spell/construct/projectile/on_ranged_cast(atom/hit_atom, mob/living/user)
|
||||
if(set_up(hit_atom, user))
|
||||
var/obj/item/projectile/new_projectile = make_projectile(spell_projectile, user)
|
||||
new_projectile.launch(hit_atom)
|
||||
new_projectile.old_style_target(hit_atom)
|
||||
new_projectile.fire()
|
||||
log_and_message_admins("has casted [src] at \the [hit_atom].")
|
||||
if(fire_sound)
|
||||
playsound(get_turf(src), fire_sound, 75, 1)
|
||||
|
||||
@@ -309,7 +309,7 @@ var/global/datum/controller/gameticker/ticker
|
||||
to_chat(M, "Colony Directorship not forced on anyone.")
|
||||
|
||||
|
||||
proc/process()
|
||||
process()
|
||||
if(current_state != GAME_STATE_PLAYING)
|
||||
return 0
|
||||
|
||||
|
||||
@@ -75,9 +75,10 @@
|
||||
H.update_action_buttons()
|
||||
..()
|
||||
|
||||
/obj/item/clothing/suit/armor/tesla/proc/shoot_lightning(var/mob/target, var/power)
|
||||
var/obj/item/projectile/beam/lightning/lightning = new(src)
|
||||
/obj/item/clothing/suit/armor/tesla/proc/shoot_lightning(mob/target, power)
|
||||
var/obj/item/projectile/beam/lightning/lightning = new(get_turf(src))
|
||||
lightning.power = power
|
||||
lightning.launch(target)
|
||||
lightning.old_style_target(target)
|
||||
lightning.fire()
|
||||
visible_message("<span class='danger'>\The [src] strikes \the [target] with lightning!</span>")
|
||||
playsound(get_turf(src), 'sound/weapons/gauss_shoot.ogg', 75, 1)
|
||||
@@ -165,14 +165,15 @@
|
||||
while(i)
|
||||
var/obj/item/projectile/beam/lightning/energy_siphon/lightning = new(get_turf(source))
|
||||
lightning.firer = user
|
||||
lightning.launch(user)
|
||||
lightning.old_style_target(user)
|
||||
lightning.fire()
|
||||
i--
|
||||
sleep(3)
|
||||
|
||||
/obj/item/projectile/beam/lightning/energy_siphon
|
||||
name = "energy stream"
|
||||
icon_state = "lightning"
|
||||
kill_count = 6 // Backup plan in-case the effect somehow misses the Technomancer.
|
||||
range = 6 // Backup plan in-case the effect somehow misses the Technomancer.
|
||||
power = 5 // This fires really fast, so this may add up if someone keeps standing in the beam.
|
||||
penetrating = 5
|
||||
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
/obj/item/weapon/spell/projectile/on_ranged_cast(atom/hit_atom, mob/living/user)
|
||||
if(set_up(hit_atom, user))
|
||||
var/obj/item/projectile/new_projectile = make_projectile(spell_projectile, user)
|
||||
new_projectile.launch(hit_atom)
|
||||
new_projectile.old_style_target(hit_atom)
|
||||
new_projectile.fire()
|
||||
log_and_message_admins("has casted [src] at \the [hit_atom].")
|
||||
if(fire_sound)
|
||||
playsound(get_turf(src), fire_sound, 75, 1)
|
||||
|
||||
@@ -722,7 +722,10 @@ var/list/turret_icons
|
||||
def_zone = pick(BP_TORSO, BP_GROIN)
|
||||
|
||||
//Shooting Code:
|
||||
A.launch(target, def_zone)
|
||||
A.firer = src
|
||||
A.old_style_target(target)
|
||||
A.def_zone = def_zone
|
||||
A.fire()
|
||||
|
||||
// Reset the time needed to go back down, since we just tried to shoot at someone.
|
||||
timeout = 10
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/action(atom/target)
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/action(atom/target, params)
|
||||
if(!action_checks(target))
|
||||
return
|
||||
var/turf/curloc = chassis.loc
|
||||
@@ -39,7 +39,7 @@
|
||||
playsound(chassis, fire_sound, fire_volume, 1)
|
||||
projectiles--
|
||||
var/P = new projectile(curloc)
|
||||
Fire(P, target)
|
||||
Fire(P, target, params)
|
||||
if(i == 1)
|
||||
set_ready_state(0)
|
||||
if(fire_cooldown)
|
||||
@@ -60,11 +60,12 @@
|
||||
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/proc/Fire(atom/A, atom/target)
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/proc/Fire(atom/A, atom/target, params)
|
||||
var/obj/item/projectile/P = A
|
||||
P.dispersion = deviation
|
||||
process_accuracy(P, chassis.occupant, target)
|
||||
P.launch(target)
|
||||
P.preparePixelProjectile(target, chassis.occupant, params)
|
||||
P.fire()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/proc/process_accuracy(obj/projectile, mob/living/user, atom/target)
|
||||
var/obj/item/projectile/P = projectile
|
||||
|
||||
@@ -308,7 +308,7 @@
|
||||
// return ..()
|
||||
*/
|
||||
|
||||
/obj/mecha/proc/click_action(atom/target,mob/user)
|
||||
/obj/mecha/proc/click_action(atom/target,mob/user, params)
|
||||
if(!src.occupant || src.occupant != user ) return
|
||||
if(user.stat) return
|
||||
if(state)
|
||||
@@ -330,7 +330,7 @@
|
||||
if(selected && selected.is_ranged())
|
||||
selected.action(target)
|
||||
else if(selected && selected.is_melee())
|
||||
selected.action(target)
|
||||
selected.action(target, params)
|
||||
else
|
||||
src.melee_action(target)
|
||||
return
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
icon_state = "nothing"
|
||||
layer = ABOVE_MOB_LAYER
|
||||
anchored = TRUE
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
mouse_opacity = 0
|
||||
appearance_flags = 0
|
||||
|
||||
/obj/effect/projectile/singularity_pull()
|
||||
@@ -54,7 +54,7 @@
|
||||
/obj/effect/projectile_lighting
|
||||
var/owner
|
||||
|
||||
/obj/effect/projectile_lighting/Initialize(mapload, color, range, intensity, owner_key)
|
||||
/obj/effect/projectile_lighting/New(loc, color, range, intensity, owner_key)
|
||||
. = ..()
|
||||
set_light(range, intensity, color)
|
||||
owner = owner_key
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
icon_state = "nothing"
|
||||
anchored = TRUE
|
||||
layer = ABOVE_MOB_LAYER
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
mouse_opacity = 0
|
||||
var/duration = 10 //in deciseconds
|
||||
var/randomdir = TRUE
|
||||
var/timerid
|
||||
|
||||
/obj/effect/temp_visual/Initialize()
|
||||
/obj/effect/temp_visual/New()
|
||||
. = ..()
|
||||
if(randomdir)
|
||||
setDir(pick(GLOB.cardinals))
|
||||
dir = pick(list(NORTH, SOUTH, EAST, WEST))
|
||||
|
||||
timerid = QDEL_IN(src, duration)
|
||||
|
||||
@@ -31,9 +31,9 @@
|
||||
/obj/effect/temp_visual/dir_setting
|
||||
randomdir = FALSE
|
||||
|
||||
/obj/effect/temp_visual/dir_setting/Initialize(mapload, set_dir)
|
||||
/obj/effect/temp_visual/dir_setting/New(loc, set_dir)
|
||||
if(set_dir)
|
||||
setDir(set_dir)
|
||||
dir = set_dir
|
||||
. = ..()
|
||||
|
||||
|
||||
|
||||
@@ -50,9 +50,10 @@
|
||||
var/fragment_type = pickweight(fragtypes)
|
||||
var/obj/item/projectile/bullet/pellet/fragment/P = new fragment_type(T)
|
||||
P.pellets = fragments_per_projectile
|
||||
P.shot_from = src.name
|
||||
P.shot_from = name
|
||||
|
||||
P.launch(O)
|
||||
P.old_style_target(O)
|
||||
P.fire()
|
||||
|
||||
//Make sure to hit any mobs in the source turf
|
||||
for(var/mob/living/M in T)
|
||||
|
||||
@@ -61,7 +61,8 @@
|
||||
var/obj/item/projectile/P = new shot_type(T)
|
||||
P.shot_from = src.name
|
||||
|
||||
P.launch(O)
|
||||
P.old_style_target(O)
|
||||
P.fire()
|
||||
|
||||
//Make sure to hit any mobs in the source turf
|
||||
for(var/mob/living/M in T)
|
||||
|
||||
@@ -432,7 +432,7 @@
|
||||
P.pass_flags = initial(copy_projectile.pass_flags)
|
||||
P.fire_sound = initial(copy_projectile.fire_sound)
|
||||
P.hitscan = initial(copy_projectile.hitscan)
|
||||
P.step_delay = initial(copy_projectile.step_delay)
|
||||
P.speed = initial(copy_projectile.speed)
|
||||
P.muzzle_type = initial(copy_projectile.muzzle_type)
|
||||
P.tracer_type = initial(copy_projectile.tracer_type)
|
||||
P.impact_type = initial(copy_projectile.impact_type)
|
||||
|
||||
@@ -68,8 +68,9 @@
|
||||
playsound(loc, emagged ? 'sound/weapons/Laser.ogg' : 'sound/weapons/Taser.ogg', 50, 1)
|
||||
var/obj/item/projectile/P = new projectile(loc)
|
||||
|
||||
P.launch(A)
|
||||
return
|
||||
P.firer = src
|
||||
P.old_style_target(A)
|
||||
P.fire()
|
||||
|
||||
// Assembly
|
||||
|
||||
|
||||
@@ -142,7 +142,8 @@
|
||||
visible_message("<span class='warning'>[src] spits [spit_name] at \the [A]!</span>", "<span class='alium'>You spit [spit_name] at \the [A].</span>")
|
||||
var/obj/item/projectile/P = new spit_projectile(get_turf(src))
|
||||
P.firer = src
|
||||
P.launch(A)
|
||||
P.old_style_target(A)
|
||||
P.fire()
|
||||
playsound(loc, 'sound/weapons/pierce.ogg', 25, 0)
|
||||
else
|
||||
..()
|
||||
|
||||
@@ -1350,18 +1350,19 @@
|
||||
return 0
|
||||
|
||||
//Shoot a bullet at someone
|
||||
/mob/living/simple_animal/proc/Shoot(var/target, var/start, var/user, var/bullet = 0)
|
||||
/mob/living/simple_animal/proc/Shoot(atom/target, atom/start, mob/user, var/bullet = 0)
|
||||
if(target == start)
|
||||
return
|
||||
|
||||
var/obj/item/projectile/A = new projectiletype(user:loc)
|
||||
var/obj/item/projectile/A = new projectiletype(user.loc)
|
||||
playsound(user, projectilesound, 100, 1)
|
||||
if(!A) return
|
||||
|
||||
// if (!istype(target, /turf))
|
||||
// qdel(A)
|
||||
// return
|
||||
A.launch(target)
|
||||
A.old_style_target(target)
|
||||
A.fire()
|
||||
return
|
||||
|
||||
//We can't see the target
|
||||
|
||||
@@ -142,7 +142,8 @@
|
||||
|
||||
var/obj/item/projectile/beam/emitter/A = get_emitter_beam()
|
||||
A.damage = round(power_per_shot/EMITTER_DAMAGE_POWER_TRANSFER)
|
||||
A.launch( get_step(src.loc, src.dir) )
|
||||
A.firer = src
|
||||
A.fire(dir2angle(dir))
|
||||
|
||||
/obj/machinery/power/emitter/attackby(obj/item/W, mob/user)
|
||||
|
||||
|
||||
@@ -435,7 +435,8 @@
|
||||
P.shot_from = src.name
|
||||
P.silenced = silenced
|
||||
|
||||
P.launch(target)
|
||||
P.old_style_target(target)
|
||||
P.fire()
|
||||
|
||||
last_shot = world.time
|
||||
|
||||
@@ -610,24 +611,17 @@
|
||||
/obj/item/weapon/gun/proc/process_projectile(obj/projectile, mob/user, atom/target, var/target_zone, var/params=null)
|
||||
var/obj/item/projectile/P = projectile
|
||||
if(!istype(P))
|
||||
return 0 //default behaviour only applies to true projectiles
|
||||
|
||||
if(params)
|
||||
P.set_clickpoint(params)
|
||||
return FALSE //default behaviour only applies to true projectiles
|
||||
|
||||
//shooting while in shock
|
||||
var/x_offset = 0
|
||||
var/y_offset = 0
|
||||
var/forcespread
|
||||
if(istype(user, /mob/living/carbon))
|
||||
var/mob/living/carbon/mob = user
|
||||
if(mob.shock_stage > 120)
|
||||
y_offset = rand(-2,2)
|
||||
x_offset = rand(-2,2)
|
||||
forcespread = rand(50, 50)
|
||||
else if(mob.shock_stage > 70)
|
||||
y_offset = rand(-1,1)
|
||||
x_offset = rand(-1,1)
|
||||
|
||||
var/launched = !P.launch_from_gun(target, user, src, target_zone, x_offset, y_offset)
|
||||
forcespread = rand(-25, 25)
|
||||
var/launched = !P.launch_from_gun(target, target_zone, user, params, null, forcespread, src)
|
||||
|
||||
if(launched)
|
||||
play_fire_sound(user, P)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
icon_state = "dart"
|
||||
damage = 5
|
||||
var/reagent_amount = 15
|
||||
kill_count = 15 //shorter range
|
||||
range = 15 //shorter range
|
||||
|
||||
muzzle_type = null
|
||||
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
icon_state = "bullet"
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
unacidable = TRUEs
|
||||
unacidable = TRUE
|
||||
pass_flags = PASSTABLE
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
mouse_opacity = 0
|
||||
|
||||
////TG PROJECTILE SYTSEM
|
||||
//Projectile stuff
|
||||
@@ -205,7 +205,7 @@
|
||||
|
||||
/obj/item/projectile/Crossed(atom/movable/AM) //A mob moving on a tile with a projectile is hit by it.
|
||||
..()
|
||||
if(isliving(AM) && (AM.density || AM == original) && !(src.pass_flags & PASSMOB))
|
||||
if(isliving(AM) && (AM.density || AM == original))
|
||||
Bump(AM)
|
||||
|
||||
/obj/item/projectile/proc/process_homing() //may need speeding up in the future performance wise.
|
||||
@@ -281,10 +281,7 @@
|
||||
|
||||
/obj/item/projectile/proc/fire(angle, atom/direct_target)
|
||||
//If no angle needs to resolve it from xo/yo!
|
||||
if(!log_override && firer && original)
|
||||
log_combat(firer, original, "fired at", src, "from [get_area_name(src, TRUE)]")
|
||||
if(direct_target)
|
||||
if(prehit(direct_target))
|
||||
direct_target.bullet_act(src, def_zone)
|
||||
qdel(src)
|
||||
return
|
||||
@@ -323,7 +320,6 @@
|
||||
|
||||
/obj/item/projectile/proc/before_z_change(atom/oldloc, atom/newloc)
|
||||
|
||||
|
||||
/obj/item/projectile/proc/before_move()
|
||||
return
|
||||
|
||||
@@ -385,7 +381,7 @@
|
||||
var/y = text2num(screen_loc_Y[1]) * 32 + text2num(screen_loc_Y[2]) - 32
|
||||
|
||||
//Calculate the "resolution" of screen based on client's view and world's icon size. This will work if the user can view more tiles than average.
|
||||
var/list/screenview = getviewsize(user.client.view)
|
||||
var/list/screenview = user.client? getviewsize(user.client.view) : world.view
|
||||
var/screenviewX = screenview[1] * world.icon_size
|
||||
var/screenviewY = screenview[2] * world.icon_size
|
||||
|
||||
@@ -394,9 +390,14 @@
|
||||
angle = ATAN2(y - oy, x - ox)
|
||||
return list(angle, p_x, p_y)
|
||||
|
||||
/obj/item/projectile/proc/redirect(x, y, starting, source)
|
||||
old_style_target(locate(x, y, z), starting? get_turf(starting) : get_turf(source))
|
||||
|
||||
/obj/item/projectile/proc/old_style_target(atom/target, atom/source)
|
||||
if(!source)
|
||||
source = get_turf(src)
|
||||
starting = source
|
||||
original = target
|
||||
setAngle(Get_Angle(source, target))
|
||||
|
||||
/obj/item/projectile/Destroy()
|
||||
@@ -456,37 +457,19 @@
|
||||
|
||||
//Returns true if the target atom is on our current turf and above the right layer
|
||||
/obj/item/projectile/proc/can_hit_target(atom/target, var/list/passthrough)
|
||||
return (target && ((target.layer >= PROJECTILE_HIT_THRESHHOLD_LAYER) || ismob(target)) && (loc == get_turf(target)) && (!(target in passthrough)))
|
||||
return (target && ((target.layer >= TABLE_LAYER) || ismob(target)) && (loc == get_turf(target)) && (!(target in passthrough)))
|
||||
|
||||
/obj/item/projectile/Bump(atom/A)
|
||||
var/datum/point/pcache = trajectory.copy_to()
|
||||
if(A in permutated)
|
||||
return FALSE
|
||||
if(check_ricochet(A) && check_ricochet_flag(A) && ricochets < ricochets_max)
|
||||
ricochets++
|
||||
if(A.handle_ricochet(src))
|
||||
on_ricochet(A)
|
||||
ignore_source_check = TRUE
|
||||
range = initial(range)
|
||||
if(hitscan)
|
||||
store_hitscan_collision(pcache)
|
||||
return TRUE
|
||||
if(firer && !ignore_source_check)
|
||||
if(A == firer || (A == firer.loc && ismecha(A))) //cannot shoot yourself or your mech
|
||||
if(firer && !reflected)
|
||||
if(A == firer || (A == firer.loc && istype(A, /obj/mecha))) //cannot shoot yourself or your mech
|
||||
trajectory_ignore_forcemove = TRUE
|
||||
forceMove(get_turf(A))
|
||||
trajectory_ignore_forcemove = FALSE
|
||||
return FALSE
|
||||
|
||||
var/distance = get_dist(get_turf(A), starting) // Get the distance between the turf shot from and the mob we hit and use that for the calculations.
|
||||
def_zone = ran_zone(def_zone, max(100-(7*distance), 5)) //Lower accurancy/longer range tradeoff. 7 is a balanced number to use.
|
||||
|
||||
if(isturf(A) && hitsound_wall)
|
||||
var/volume = CLAMP(vol_by_damage() + 20, 0, 100)
|
||||
if(suppressed)
|
||||
volume = 5
|
||||
playsound(loc, hitsound_wall, volume, 1, -1)
|
||||
|
||||
var/distance = get_dist(starting, get_turf(src))
|
||||
var/turf/target_turf = get_turf(A)
|
||||
var/passthrough = FALSE
|
||||
|
||||
@@ -520,7 +503,6 @@
|
||||
for(var/mob/living/M in A)
|
||||
attack_mob(M, distance)
|
||||
|
||||
|
||||
//penetrating projectiles can pass through things that otherwise would not let them
|
||||
if(!passthrough && penetrating > 0)
|
||||
if(check_penetrate(A))
|
||||
@@ -550,7 +532,6 @@
|
||||
|
||||
//called when the projectile stops flying because it Bump'd with something
|
||||
/obj/item/projectile/proc/on_impact(atom/A)
|
||||
impact_effect(effect_transform) // generate impact effect
|
||||
if(damage && damage_type == BURN)
|
||||
var/turf/T = get_turf(A)
|
||||
if(T)
|
||||
@@ -627,7 +608,7 @@
|
||||
return fire(angle_override, direct_target)
|
||||
|
||||
//called to launch a projectile from a gun
|
||||
/obj/item/projectile/proc/_launch_from_gun(atom/target, target_zone, mob/user, params, angle_override, forced_spread, obj/item/weapon/gun/launcher)
|
||||
/obj/item/projectile/proc/launch_from_gun(atom/target, target_zone, mob/user, params, angle_override, forced_spread, obj/item/weapon/gun/launcher)
|
||||
|
||||
shot_from = launcher.name
|
||||
silenced = launcher.silenced
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
/obj/item/projectile/arc
|
||||
name = "arcing shot"
|
||||
icon_state = "fireball" // WIP
|
||||
step_delay = 2 // Travel a bit slower, to really sell the arc visuals.
|
||||
speed = 2 // Travel a bit slower, to really sell the arc visuals.
|
||||
plane = ABOVE_PLANE // Since projectiles are 'in the air', they might visually overlap mobs while in flight, so the projectile needs to be above their plane.
|
||||
var/target_distance = null // How many tiles the impact site is.
|
||||
var/fired_dir = null // Which direction was the projectile fired towards. Needed to invert the projectile turning based on if facing left or right.
|
||||
@@ -36,18 +36,17 @@
|
||||
new /obj/effect/explosion(T)
|
||||
return ..()
|
||||
|
||||
/obj/item/projectile/arc/launch(atom/target, target_zone, x_offset=0, y_offset=0, angle_offset=0)
|
||||
/obj/item/projectile/arc/old_style_target(target, source)
|
||||
var/expected_distance = get_dist(target, loc)
|
||||
kill_count = expected_distance // So the projectile "hits the ground."
|
||||
range = expected_distance // So the projectile "hits the ground."
|
||||
target_distance = expected_distance
|
||||
fired_dir = get_dir(loc, target)
|
||||
..() // Does the regular launching stuff.
|
||||
..()
|
||||
if(fired_dir & EAST)
|
||||
transform = turn(transform, -45)
|
||||
else if(fired_dir & WEST)
|
||||
transform = turn(transform, 45)
|
||||
|
||||
|
||||
// Visuals.
|
||||
/obj/item/projectile/arc/after_move()
|
||||
// Handle projectile turning in flight.
|
||||
@@ -73,7 +72,7 @@
|
||||
var/projectile_position = arc_progress / target_distance
|
||||
var/sine_position = projectile_position * 180
|
||||
var/pixel_z_position = arc_max_height * sin(sine_position)
|
||||
animate(src, pixel_z = pixel_z_position, time = step_delay)
|
||||
animate(src, pixel_z = pixel_z_position, time = speed)
|
||||
|
||||
// Update our shadow.
|
||||
shadow.forceMove(loc)
|
||||
|
||||
@@ -246,12 +246,12 @@
|
||||
incendiary = 2
|
||||
flammability = 4
|
||||
agony = 30
|
||||
kill_count = 4
|
||||
range = 4
|
||||
vacuum_traversal = 0
|
||||
|
||||
/obj/item/projectile/bullet/incendiary/flamethrower/large
|
||||
damage = 15
|
||||
kill_count = 6
|
||||
range = 6
|
||||
|
||||
/obj/item/projectile/bullet/blank
|
||||
invisibility = 101
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
icon_state = "bullet"
|
||||
fire_sound = 'sound/weapons/gunshot/gunshot_pistol.ogg'
|
||||
damage = 5
|
||||
kill_count = 15 //if the shell hasn't hit anything after travelling this far it just explodes.
|
||||
range = 15 //if the shell hasn't hit anything after travelling this far it just explodes.
|
||||
var/flash_range = 0
|
||||
var/brightness = 7
|
||||
var/light_colour = "#ffffff"
|
||||
@@ -162,7 +162,7 @@
|
||||
icon_state = "plasma_stun"
|
||||
fire_sound = 'sound/weapons/blaster.ogg'
|
||||
armor_penetration = 10
|
||||
kill_count = 4
|
||||
range = 4
|
||||
damage = 5
|
||||
agony = 55
|
||||
damage_type = BURN
|
||||
@@ -214,20 +214,20 @@
|
||||
/obj/item/projectile/energy/phase
|
||||
name = "phase wave"
|
||||
icon_state = "phase"
|
||||
kill_count = 6
|
||||
range = 6
|
||||
damage = 5
|
||||
SA_bonus_damage = 45 // 50 total on animals
|
||||
SA_vulnerability = SA_ANIMAL
|
||||
|
||||
/obj/item/projectile/energy/phase/light
|
||||
kill_count = 4
|
||||
range = 4
|
||||
SA_bonus_damage = 35 // 40 total on animals
|
||||
|
||||
/obj/item/projectile/energy/phase/heavy
|
||||
kill_count = 8
|
||||
range = 8
|
||||
SA_bonus_damage = 55 // 60 total on animals
|
||||
|
||||
/obj/item/projectile/energy/phase/heavy/cannon
|
||||
kill_count = 10
|
||||
range = 10
|
||||
damage = 15
|
||||
SA_bonus_damage = 60 // 75 total on animals
|
||||
@@ -34,7 +34,7 @@
|
||||
penetrating = 2
|
||||
embed_chance = 0
|
||||
armor_penetration = 40
|
||||
kill_count = 20
|
||||
range = 20
|
||||
|
||||
var/searing = 0 //Does this fuelrod ignore shields?
|
||||
var/detonate_travel = 0 //Will this fuelrod explode when it reaches maximum distance?
|
||||
@@ -50,7 +50,7 @@
|
||||
|
||||
if(energetic_impact)
|
||||
var/eye_coverage = 0
|
||||
for(var/mob/living/carbon/M in viewers(world.view, location))
|
||||
for(var/mob/living/carbon/M in viewers(world.view, get_turf(src)))
|
||||
eye_coverage = 0
|
||||
if(iscarbon(M))
|
||||
eye_coverage = M.eyecheck()
|
||||
@@ -103,7 +103,7 @@
|
||||
armor_penetration = 100
|
||||
penetrating = 100 //Theoretically, this shouldn't stop flying for a while, unless someone lines it up with a wall or fires it into a mountain.
|
||||
irradiate = 120
|
||||
kill_count = 75
|
||||
range = 75
|
||||
searing = 1
|
||||
detonate_travel = 1
|
||||
detonate_mob = 1
|
||||
|
||||
@@ -9,10 +9,6 @@
|
||||
var/base_spread = 90 //lower means the pellets spread more across body parts. If zero then this is considered a shrapnel explosion instead of a shrapnel cone
|
||||
var/spread_step = 10 //higher means the pellets spread more across body parts with distance
|
||||
|
||||
/obj/item/projectile/bullet/pellet/Bumped()
|
||||
. = ..()
|
||||
bumped = 0 //can hit all mobs in a tile. pellets is decremented inside attack_mob so this should be fine.
|
||||
|
||||
/obj/item/projectile/bullet/pellet/proc/get_pellets(var/distance)
|
||||
var/pellet_loss = round((distance - 1)/range_step) //pellets lost due to distance
|
||||
return max(pellets - pellet_loss, 1)
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
qdel(src)
|
||||
return hit
|
||||
|
||||
/obj/item/projectile/test/Collide(atom/A)
|
||||
/obj/item/projectile/test/Bump(atom/A)
|
||||
if(A != src)
|
||||
hit |= A
|
||||
return ..()
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
var/spell/targeted/projectile/carried
|
||||
|
||||
penetrating = 0
|
||||
kill_count = 10 //set by the duration of the spell
|
||||
range = 10 //set by the duration of the spell
|
||||
|
||||
var/proj_trail = 0 //if it leaves a trail
|
||||
var/proj_trail_lifespan = 0 //deciseconds
|
||||
|
||||
@@ -29,12 +29,13 @@ If the spell_projectile is seeking, it will update its target every process and
|
||||
|
||||
projectile.shot_from = user //fired from the user
|
||||
projectile.hitscan = !proj_step_delay
|
||||
projectile.step_delay = proj_step_delay
|
||||
projectile.speed = proj_step_delay
|
||||
if(istype(projectile, /obj/item/projectile/spell_projectile))
|
||||
var/obj/item/projectile/spell_projectile/SP = projectile
|
||||
SP.carried = src //casting is magical
|
||||
projectile.launch(target, target_zone="chest")
|
||||
return
|
||||
projectile.def_zone = check_zone("chest")
|
||||
projectile.old_style_target(target)
|
||||
projectile.fire()
|
||||
|
||||
/spell/targeted/projectile/proc/choose_prox_targets(mob/user = usr, var/atom/movable/spell_holder)
|
||||
var/list/targets = list()
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 18 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.8 KiB |
Reference in New Issue
Block a user