mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2025-12-27 10:41:42 +00:00
* CI change * world.dm * .dme world.dm * subsystem renaming * .dme for subsystems * ai_laws.dm * armor.dm * emote.dm * logging.dm * spell.dm * air_alarm.dm * crew.dm * decal.dm * emissive_blocker.dm * footstep.dm * spawner.dm * fire.dm * carbon.dm * living.dm * mob.dm * movement.dm * thermal_drill.dm * plasmamen.dm * lavaland.dm * chaplain.dm * lightning.dm * magnet.dm * mimic.dm * wizard.dm * morph.dm * vampire.dm * click.dm * self.dm * radiation_storm.dm * airlock.dm * autolathe.dm * mulebot.dm * nuclearbomb.dm * particle_accelerator.dm * smartfridge.dm * syndicatebomb.dm * vending.dm * wires.dm * sound.dm * mining.dm * syndicate_space_base.dm * monkey.dm * guardian.dm * bomb.dm * standard.dm * nuclear.dm * pinpointer.dm * access.dm * departments.dm * job.dm * science.dm * buttons.dm * cloning.dm * igniter.dm * wishgranter.dm * atmos_control.dm * message.dm * power_monitor.dm * mecha.dm * combat.dm * mining_tools.dm * meteors.dm * spiders.dm * contraband.dm * aliens.dm * uplinks.dm * voice.dm * intercom.dm * lights.dm * robot_items.dm * mineral.dm * dice.dm * extinguisher.dm * paint.dm * signs.dm * staff.dm * smokebomb.dm * boxes.dm * random.dm * janicart.dm * statue.dm * cargo.dm * asteroid.dm * headslug.dm * fulton.dm * atmospherics.dm * pump.dm * corpse.dm * oldstation.dm * gps.dm * preferences.dm * clothing.dm * ears.dm * glasses.dm * boxing.dm * color.dm * renames ninja gear files * recipes.dm * error_handler.dm * anomaly.dm * floorcluwne.dm * undead.dm * overmind.dm * shield.dm * bottle.dm * organ.dm * piano.dm * plasma_fist.dm * language.dm * mob_defines.dm * mob_helpers.dm * damage_procs.dm * _defines.dm * empress.dm and queen.dm * brain.dm * organ file renaming * subsystems.dm * constructs.dm * bot.dm * pet.dm * nature.dm * magic.dm * colors.dm * drugs.dm * medicine.dm * toxins.dm * shuttle.dm * surgery.dm * moves a bunch of define files * traits.dm * names.dm * other_mobs.dm * flags.dm * some final define files * well turns out contractor_pinpointer.dm was taken * I forgot to remove this file * how in the hell did this get unticked * I DID INCLUDE IT, but there was a "w" there * swaps the world definitions * camera renamed to SScamera * examine -> alien_examine
158 lines
4.5 KiB
Plaintext
158 lines
4.5 KiB
Plaintext
#define MAX_THROWING_DIST 512 // 2 z-levels on default width
|
|
#define MAX_TICKS_TO_MAKE_UP 3 //how many missed ticks will we attempt to make up for this run.
|
|
|
|
SUBSYSTEM_DEF(throwing)
|
|
name = "Throwing"
|
|
priority = FIRE_PRIORITY_THROWING
|
|
wait = 1
|
|
flags = SS_NO_INIT|SS_KEEP_TIMING|SS_TICKER
|
|
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
|
offline_implications = "Thrown objects may not react properly. Shuttle call recommended."
|
|
cpu_display = SS_CPUDISPLAY_LOW
|
|
|
|
var/list/currentrun
|
|
var/list/processing = list()
|
|
|
|
/datum/controller/subsystem/throwing/get_stat_details()
|
|
return "P:[length(processing)]"
|
|
|
|
/datum/controller/subsystem/throwing/get_metrics()
|
|
. = ..()
|
|
var/list/cust = list()
|
|
cust["processing"] = length(processing)
|
|
.["custom"] = cust
|
|
|
|
/datum/controller/subsystem/throwing/fire(resumed = 0)
|
|
if(!resumed)
|
|
src.currentrun = processing.Copy()
|
|
|
|
//cache for sanic speed (lists are references anyways)
|
|
var/list/currentrun = src.currentrun
|
|
|
|
while(length(currentrun))
|
|
var/atom/movable/AM = currentrun[currentrun.len]
|
|
var/datum/thrownthing/TT = currentrun[AM]
|
|
currentrun.len--
|
|
if(!AM || !TT)
|
|
processing -= AM
|
|
if(MC_TICK_CHECK)
|
|
return
|
|
continue
|
|
|
|
TT.tick()
|
|
|
|
if(MC_TICK_CHECK)
|
|
return
|
|
|
|
currentrun = null
|
|
|
|
/datum/thrownthing
|
|
var/atom/movable/thrownthing
|
|
var/atom/target
|
|
var/turf/target_turf
|
|
var/init_dir
|
|
var/maxrange
|
|
var/speed
|
|
var/mob/thrower
|
|
var/diagonals_first
|
|
var/dist_travelled = 0
|
|
var/start_time
|
|
var/dist_x
|
|
var/dist_y
|
|
var/dx
|
|
var/dy
|
|
var/force = MOVE_FORCE_DEFAULT
|
|
var/pure_diagonal
|
|
var/diagonal_error
|
|
var/datum/callback/callback
|
|
var/paused = FALSE
|
|
var/delayed_time = 0
|
|
var/last_move = 0
|
|
///When this variable is false, non dense mobs will be hit by a thrown item. useful for things that you dont want to be cheesed by crawling, EG. gravitational anomalies
|
|
var/dodgeable = TRUE
|
|
|
|
/datum/thrownthing/proc/tick()
|
|
var/atom/movable/AM = thrownthing
|
|
if(!isturf(AM.loc) || !AM.throwing)
|
|
finalize()
|
|
return
|
|
|
|
if(paused)
|
|
delayed_time += world.time - last_move
|
|
return
|
|
|
|
if(dist_travelled && hitcheck()) //to catch sneaky things moving on our tile while we slept
|
|
finalize()
|
|
return
|
|
|
|
var/atom/step
|
|
|
|
last_move = world.time
|
|
|
|
//calculate how many tiles to move, making up for any missed ticks.
|
|
var/tilestomove = CEILING(min(((((world.time + world.tick_lag) - start_time + delayed_time) * speed) - (dist_travelled ? dist_travelled : -1)), speed * MAX_TICKS_TO_MAKE_UP) * (world.tick_lag * SSthrowing.wait), 1)
|
|
while(tilestomove-- > 0)
|
|
if((dist_travelled >= maxrange || AM.loc == target_turf) && has_gravity(AM, AM.loc))
|
|
hitcheck() //Just to be sure
|
|
finalize()
|
|
return
|
|
|
|
if(dist_travelled <= max(dist_x, dist_y)) //if we haven't reached the target yet we home in on it, otherwise we use the initial direction
|
|
step = get_step(AM, get_dir(AM, target_turf))
|
|
else
|
|
step = get_step(AM, init_dir)
|
|
|
|
if(!pure_diagonal && !diagonals_first) // not a purely diagonal trajectory and we don't want all diagonal moves to be done first
|
|
if (diagonal_error >= 0 && max(dist_x, dist_y) - dist_travelled != 1) //we do a step forward unless we're right before the target
|
|
step = get_step(AM, dx)
|
|
diagonal_error += (diagonal_error < 0) ? dist_x / 2 : -dist_y
|
|
|
|
if(!step) // going off the edge of the map makes get_step return null, don't let things go off the edge
|
|
finalize()
|
|
return
|
|
|
|
AM.Move(step, get_dir(AM, step))
|
|
|
|
dist_travelled++
|
|
|
|
if(dist_travelled > MAX_THROWING_DIST)
|
|
finalize()
|
|
return
|
|
|
|
/datum/thrownthing/proc/finalize(hit = FALSE, target = null)
|
|
set waitfor = 0
|
|
SSthrowing.processing -= thrownthing
|
|
//done throwing, either because it hit something or it finished moving
|
|
thrownthing.throwing = null
|
|
if(!hit)
|
|
for(var/thing in get_turf(thrownthing)) //looking for our target on the turf we land on.
|
|
var/atom/A = thing
|
|
if(A == target)
|
|
hit = 1
|
|
thrownthing.throw_impact(A, src)
|
|
break
|
|
if(!hit)
|
|
thrownthing.throw_impact(get_turf(thrownthing), src) // we haven't hit something yet and we still must, let's hit the ground.
|
|
thrownthing.newtonian_move(init_dir)
|
|
else
|
|
thrownthing.newtonian_move(init_dir)
|
|
|
|
if(target)
|
|
thrownthing.throw_impact(target, src, speed)
|
|
|
|
if(callback)
|
|
callback.Invoke()
|
|
thrownthing.end_throw()
|
|
|
|
/datum/thrownthing/proc/hit_atom(atom/A)
|
|
finalize(hit = TRUE, target = A)
|
|
|
|
/datum/thrownthing/proc/hitcheck()
|
|
for(var/thing in get_turf(thrownthing))
|
|
var/atom/movable/AM = thing
|
|
if(AM == thrownthing || AM == thrower)
|
|
continue
|
|
if((AM.density || isliving(AM) && !dodgeable) && !(AM.pass_flags & LETPASSTHROW) && !(AM.flags & ON_BORDER))
|
|
finalize(hit = TRUE, target = AM)
|
|
return TRUE
|