forked from goonstation/goonstation
-
Notifications
You must be signed in to change notification settings - Fork 0
/
throwing_controls.dm
136 lines (124 loc) · 3.98 KB
/
throwing_controls.dm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/datum/thrown_thing
var/atom/movable/thing
var/atom/target
var/error
var/speed
var/dx
var/dy
var/dist_x
var/dist_y
var/range
var/target_x
var/target_y
var/matrix/transform_original
var/list/params
var/turf/thrown_from
var/atom/return_target
var/bonus_throwforce = 0
var/end_throw_callback
var/mob/user
var/hitAThing = FALSE
var/dist_travelled = 0
var/speed_error = 0
New(atom/movable/thing, atom/target, error, speed, dx, dy, dist_x, dist_y, range,
target_x, target_y, matrix/transform_original, list/params, turf/thrown_from, atom/return_target,
bonus_throwforce=0, end_throw_callback=null)
src.thing = thing
src.target = target
src.error = error
src.speed = speed
src.dx = dx
src.dy = dy
src.dist_x = dist_x
src.dist_y = dist_y
src.range = range
src.target_x = target_x
src.target_y = target_y
src.transform_original = transform_original
src.params = params
src.thrown_from = thrown_from
src.return_target = return_target
src.bonus_throwforce = bonus_throwforce
src.end_throw_callback = end_throw_callback
src.user = usr // ew
..()
proc/get_throw_travelled()
. = src.dist_travelled //dist traveled is super innacurrate, especially when stacking throws
if (src.thrown_from) //if we have this param we should use it to get the REAL distance.
. = get_dist(get_turf(thing), get_turf(src.thrown_from))
var/global/datum/controller/throwing/throwing_controller = new
/datum/controller/throwing
var/list/datum/thrown_thing/thrown
var/running = FALSE
/datum/controller/throwing/proc/start()
if(src.running)
return
src.running = TRUE
SPAWN_DBG(0)
while(src.tick())
sleep(0.1 SECONDS)
src.running = FALSE
/datum/controller/throwing/proc/tick()
if(!length(thrown))
return FALSE
for(var/_thr in thrown)
var/datum/thrown_thing/thr = _thr
var/atom/movable/thing = thr.thing
var/end_throwing = FALSE
var/int_speed = round(thr.speed + thr.speed_error)
thr.speed_error += thr.speed - int_speed
for(var/i in 1 to int_speed)
if(!thing || thing.disposed)
end_throwing = TRUE
break
var/turf/T = thing.loc
if( !(
thr.target && thing.throwing && isturf(T) && \
(
(
(thr.target_x != thing.x || thr.target_y != thing.y ) && \
thr.dist_travelled < thr.range
) || \
T?.throw_unlimited || \
thing.throw_unlimited
)
))
end_throwing = TRUE
break
var/choose_x = thr.error > 0
if(thr.dist_y > thr.dist_x) choose_x = !choose_x
var/turf/next = get_step(thing, choose_x ? thr.dx : thr.dy)
if(!next || next == T) // going off the edge of the map makes get_step return null, don't let things go off the edge
end_throwing = TRUE
break
thing.glide_size = (32 / (1/thr.speed)) * world.tick_lag
if (!thing.Move(next)) // Grayshift: Race condition fix. Bump proc calls are delayed past the end of the loop and won't trigger end condition
thr.hitAThing = TRUE // of !throwing on their own, so manually checking if Move failed as end condition
end_throwing = TRUE
break
thing.glide_size = (32 / (1/thr.speed)) * world.tick_lag
var/hit_thing = thing.hit_check(thr)
thr.error += thr.error > 0 ? -min(thr.dist_x, thr.dist_y) : max(thr.dist_x, thr.dist_y)
thr.dist_travelled++
if(!thing.throwing || hit_thing)
end_throwing = TRUE
break
if(end_throwing)
thrown -= thr
if(thr.end_throw_callback)
if(call(thr.end_throw_callback)(thr)) // return 1 to continue the throw, might be useful!
thrown += thr
continue
if(!thing || thing.disposed)
continue
animate(thing)
thing.throw_end(thr.params, thrown_from=thr.thrown_from)
if(thr.hitAThing)
thr.params = null// if we hit something don't use the pixel x/y from the click params
thing.throwing = 0
thing.throw_unlimited = 0
thing.throw_impact(get_turf(thing), thr)
thing.throwforce -= thr.bonus_throwforce
if(thr.target != thr.return_target && thing.throw_return)
thing.throw_at(thr.return_target, thing.throw_range, thing.throw_speed)
return TRUE