mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-01 04:21:42 +00:00
* SSthrowing + callbacks! Throwing is now a subsystem. It's low priority, but is a ticker subsystem so is ran before most other subsystems. To allow for shit to run after the throw finishes, throwing now supports a callback. A callback datum system was created, conversion of addtimer is planned for another PR. Throwing now has a limit of 2048 turfs (was 600) Throwing now ticks every world.tick, and properly converts the speed arg from 1ds to what ever tick_lag is. Throwing now properly accounts for missed ticks. Throwing no longer uses sleep. Throwing should no longer lag since it's not filling the sleep queue up * Smoother tentacles * Some improvements * Missed a spot. * Makes shit quicker. Inlines the thrownthing.tick() proc. Raises missed ticks value Lowers max dist value Inlines the two sister overrides for /atom/movable/Moved() because that just seemed like a waste * >PRs open that use procs i'm removing. * STOP THE PRESSES! * throw_at now runs the first throw tick() immediately This will help some with throwing while running. * Item throwing now imparts the momentum of the user throwing. (ie, running in the direction you are throwing makes you throw faster, running away from the direction you are throwing makes you throw the item slower) * Moves throwing momentum from carbon/throw_item to movable/throw_at. There are other things that cause a mob to "throw" an item, I figured we keep this universal since thrower is already an arg. * Explosions throw shit faster. This was stupid, "Hey, lets set the item's throw_speed to 4 so embedding works, but lets make it throw at the base 2 throw speed for no reason." * Fixes explosion embedding. This also acts as a nice example of how to override a callback in an override of throw_at properly.
140 lines
3.8 KiB
Plaintext
140 lines
3.8 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.
|
|
var/datum/subsystem/throwing/SSthrowing
|
|
|
|
/datum/subsystem/throwing
|
|
name = "Throwing"
|
|
priority = 25
|
|
wait = 1
|
|
flags = SS_NO_INIT|SS_KEEP_TIMING|SS_TICKER
|
|
|
|
var/list/currentrun
|
|
var/list/processing
|
|
|
|
/datum/subsystem/throwing/New()
|
|
NEW_SS_GLOBAL(SSthrowing)
|
|
processing = list()
|
|
|
|
|
|
/datum/subsystem/throwing/stat_entry()
|
|
..("P:[processing.len]")
|
|
|
|
|
|
/datum/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/pure_diagonal
|
|
var/diagonal_error
|
|
var/datum/callback/callback
|
|
|
|
/datum/thrownthing/proc/tick()
|
|
var/atom/movable/AM = thrownthing
|
|
if (!isturf(AM.loc) || !AM.throwing)
|
|
finialize()
|
|
return
|
|
|
|
if (dist_travelled && hitcheck()) //to catch sneaky things moving on our tile while we slept
|
|
finialize()
|
|
return
|
|
|
|
var/atom/step
|
|
|
|
//calculate how many tiles to move, making up for any missed ticks.
|
|
var/tilestomove = round(min(((((world.time+world.tick_lag) - start_time) * speed) - (dist_travelled ? dist_travelled : -1)), speed*MAX_TICKS_TO_MAKE_UP) * (world.tick_lag * SSthrowing.wait))
|
|
while (tilestomove-- > 0)
|
|
if ((dist_travelled >= maxrange || AM.loc == target_turf) && AM.has_gravity(AM.loc))
|
|
finialize()
|
|
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
|
|
finialize()
|
|
return
|
|
|
|
AM.Move(step, get_dir(AM, step))
|
|
|
|
if (!AM.throwing) // we hit something during our move
|
|
finialize(hit = TRUE)
|
|
return
|
|
|
|
dist_travelled++
|
|
|
|
if (dist_travelled > MAX_THROWING_DIST)
|
|
finialize()
|
|
return
|
|
|
|
/datum/thrownthing/proc/finialize(hit = FALSE)
|
|
set waitfor = 0
|
|
SSthrowing.processing -= thrownthing
|
|
//done throwing, either because it hit something or it finished moving
|
|
thrownthing.throwing = 0
|
|
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)
|
|
break
|
|
if (!hit)
|
|
thrownthing.throw_impact(get_turf(thrownthing)) // 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 (callback)
|
|
callback.Invoke()
|
|
|
|
/datum/thrownthing/proc/hitcheck()
|
|
for (var/thing in get_turf(thrownthing))
|
|
var/atom/movable/AM = thing
|
|
if (AM == thrownthing)
|
|
continue
|
|
if (AM.density && !(AM.pass_flags & LETPASSTHROW) && !(AM.flags & ON_BORDER))
|
|
thrownthing.throwing = 0
|
|
thrownthing.throw_impact(AM)
|
|
return 1
|