mirror of
https://github.com/goonstation/goonstation-2016.git
synced 2026-07-19 21:12:41 +01:00
392 lines
8.4 KiB
Plaintext
392 lines
8.4 KiB
Plaintext
/var/global/list/railway_vehicles = list()
|
|
|
|
/proc/find_adaption_points(var/obj/O, var/adT)
|
|
var/turf/T = get_turf(O)
|
|
var/list/ret = list()
|
|
for (var/D in cardinal)
|
|
var/turf/N = get_step(T, D)
|
|
if (N)
|
|
if (locate(adT) in N)
|
|
ret += D
|
|
return ret
|
|
|
|
/proc/minlist(var/list/L)
|
|
if (!L.len)
|
|
return null
|
|
var/minv = L[1]
|
|
for (var/A in L)
|
|
if (A < minv)
|
|
minv = A
|
|
return minv
|
|
|
|
/proc/railway_adapt(var/obj/railway/this, var/ad_adj = 1)
|
|
var/list/AP = find_adaption_points(this, /obj/railway)
|
|
var/skip_adj = 0
|
|
switch (AP.len)
|
|
if (0)
|
|
this.dir1 = 0
|
|
this.dir2 = this.dir
|
|
skip_adj = 1
|
|
if (1)
|
|
this.dir1 = 0
|
|
this.dir2 = AP[1]
|
|
else
|
|
this.dir1 = minlist(AP)
|
|
AP -= this.dir1
|
|
this.dir2 = minlist(AP)
|
|
if (ad_adj && !skip_adj)
|
|
if (this.dir1)
|
|
var/turf/N = get_step(this.loc, this.dir1)
|
|
if (N)
|
|
var/obj/railway/R = locate() in N
|
|
if (R)
|
|
R.adapt(0)
|
|
|
|
if (this.dir2)
|
|
var/turf/N = get_step(this.loc, this.dir2)
|
|
var/obj/railway/R = locate() in N
|
|
if (N)
|
|
if (R)
|
|
R.adapt(0)
|
|
|
|
this.set_icon_state()
|
|
|
|
|
|
/obj/railway
|
|
name = "rail"
|
|
var/dir1
|
|
var/dir2
|
|
icon = 'icons/obj/railway.dmi'
|
|
icon_state = "1-2"
|
|
var/indestructible = 0
|
|
|
|
New()
|
|
..()
|
|
setup_dirs()
|
|
|
|
proc/setup_dirs()
|
|
if (length(icon_state) == 3)
|
|
var/list/cardinal_str = list("0", "1", "2", "4", "8")
|
|
var/asc_0 = 48
|
|
var/s1_asc = text2ascii(icon_state,1)
|
|
var/s1 = ascii2text(s1_asc)
|
|
var/s2 = ascii2text(text2ascii(icon_state,2))
|
|
var/s3_asc = text2ascii(icon_state,3)
|
|
var/s3 = ascii2text(s3_asc)
|
|
if (s2 == "-" && (s1 in cardinal_str) && (s3 in cardinal_str) && s1 != s3 && s3_asc > s1_asc)
|
|
dir1 = s1_asc - asc_0
|
|
dir2 = s3_asc - asc_0
|
|
|
|
proc/entering(var/obj/railway_vehicle/V)
|
|
|
|
proc/set_icon_state()
|
|
icon_state = "[dir1]-[dir2]"
|
|
|
|
onVarChanged(variable, oldVal, val)
|
|
..()
|
|
if (variable == "dir1" || variable == "dir2")
|
|
if (dir1 > dir2)
|
|
var/D = dir2
|
|
dir2 = dir1
|
|
dir1 = D
|
|
set_icon_state()
|
|
else if (variable == "icon_state")
|
|
setup_dirs()
|
|
|
|
proc/may_pass(var/moving_dir)
|
|
if (dir1 == moving_dir || dir2 == moving_dir)
|
|
var/turf/N = get_step(loc, moving_dir)
|
|
if (N)
|
|
var/obj/railway/R = locate() in N
|
|
var/from_dir = turn(moving_dir, 180)
|
|
if (R && (R.dir1 == from_dir || R.dir2 == from_dir))
|
|
return 1
|
|
return 0
|
|
|
|
proc/get_travel_dir(var/last_travel_dir)
|
|
if (last_travel_dir != 0)
|
|
var/camefrom = turn(last_travel_dir, 180)
|
|
if (dir1 == camefrom)
|
|
return dir2
|
|
else if (dir2 == camefrom)
|
|
return dir1
|
|
else
|
|
if (dir1 == 0)
|
|
return dir2
|
|
else if (dir2 == 0)
|
|
return dir1
|
|
else
|
|
return pick(dir1, dir2)
|
|
|
|
if (dir1 == last_travel_dir || dir2 == last_travel_dir)
|
|
return last_travel_dir
|
|
else
|
|
return pick(dir1, dir2)
|
|
|
|
proc/adapt(var/ad_adj)
|
|
|
|
adaptive
|
|
New()
|
|
..()
|
|
adapt()
|
|
|
|
adapt(var/ad_adj = 1)
|
|
railway_adapt(src, ad_adj)
|
|
|
|
|
|
traffic_control
|
|
name = "rail"
|
|
var/hold_range = 15
|
|
|
|
proc/traverse_check(var/obj/railway/current, var/last_travel_dir, var/distance)
|
|
if (distance == 0)
|
|
return
|
|
if (current == src)
|
|
return 1
|
|
if (locate(/obj/railway_vehicle) in get_turf(current))
|
|
return 0
|
|
if (istype(current, /obj/railway/traffic_control))
|
|
return 1
|
|
|
|
var/next_dir = current.get_travel_dir(last_travel_dir)
|
|
if (next_dir)
|
|
var/turf/T = get_step(get_turf(current), next_dir)
|
|
if (T)
|
|
var/obj/railway/NR = locate() in T
|
|
if (NR)
|
|
return traverse_check(NR, next_dir, distance - 1)
|
|
return 1
|
|
|
|
may_pass(var/moving_dir)
|
|
if (!..())
|
|
return 0
|
|
var/turf/N = get_step(loc, moving_dir)
|
|
if (N)
|
|
var/obj/railway/R = locate() in N
|
|
var/from_dir = turn(moving_dir, 180)
|
|
if (R && (R.dir1 == from_dir || R.dir2 == from_dir))
|
|
return traverse_check(R, moving_dir, hold_range)
|
|
else
|
|
return 0
|
|
|
|
adaptive
|
|
New()
|
|
..()
|
|
adapt()
|
|
|
|
adapt(var/ad_adj = 1)
|
|
railway_adapt(src, ad_adj)
|
|
|
|
trigger
|
|
name = "rail"
|
|
|
|
entering(var/obj/railway_vehicle/V)
|
|
..()
|
|
V.on_trigger()
|
|
|
|
adaptive
|
|
New()
|
|
..()
|
|
adapt()
|
|
|
|
adapt(var/ad_adj = 1)
|
|
railway_adapt(src, ad_adj)
|
|
|
|
ex_act()
|
|
if (indestructible)
|
|
return
|
|
..()
|
|
|
|
meteorhit()
|
|
if (indestructible)
|
|
return
|
|
..()
|
|
|
|
blob_act()
|
|
if (indestructible)
|
|
return
|
|
..()
|
|
|
|
bullet_act()
|
|
if (indestructible)
|
|
return
|
|
return
|
|
|
|
/obj/railway_vehicle
|
|
var/obj/railway/current = null
|
|
var/moving_dir = 0
|
|
var/active = 1
|
|
var/magically_destructive = 0
|
|
var/free_moving = 0
|
|
var/self_powered = 0
|
|
var/distance = 0
|
|
var/indestructible = 0
|
|
var/default_distance = 10
|
|
var/speed = 2
|
|
var/waited = 0
|
|
|
|
icon = 'icons/obj/Cryogenic2.dmi'
|
|
icon_state = "sleeper_0"
|
|
|
|
name = "railway vehicle"
|
|
density = 1
|
|
anchored = 1
|
|
var/road_rage_force = 40
|
|
|
|
New()
|
|
..()
|
|
railway_vehicles.Add(src)
|
|
if (isturf(loc) && (locate(/obj/railway) in loc))
|
|
start_path(loc)
|
|
|
|
Bumped(var/mob/M)
|
|
if (!istype(M) || !isturf(loc))
|
|
return
|
|
if (!current)
|
|
current = locate() in loc
|
|
if (current && free_moving && !moving_dir && active)
|
|
var/bump_dir = get_dir(M, src)
|
|
if (current.dir1 == bump_dir || current.dir2 == bump_dir)
|
|
start_path_towards(loc, bump_dir)
|
|
|
|
proc/start_path(var/turf/T, var/last_travel_dir = 0)
|
|
if (!istype(T))
|
|
return
|
|
var/obj/railway/R = locate() in T
|
|
if (R == null)
|
|
return
|
|
var/MD = R.get_travel_dir(last_travel_dir)
|
|
if (MD)
|
|
start_path_towards(T, MD)
|
|
distance = 5 // human force *shrug*
|
|
|
|
proc/start_path_towards(var/turf/T, var/towards_dir = 0)
|
|
if (!istype(T))
|
|
return
|
|
if (towards_dir == 0)
|
|
return
|
|
var/obj/railway/R = locate() in T
|
|
if (R == null)
|
|
return
|
|
if (R.dir1 != towards_dir && R.dir2 != towards_dir)
|
|
return
|
|
current = R
|
|
moving_dir = towards_dir
|
|
dir = moving_dir
|
|
set_loc(T)
|
|
current.entering(src)
|
|
distance = default_distance
|
|
on_start_path()
|
|
waited = 0
|
|
|
|
proc/process()
|
|
if (!moving_dir || !active)
|
|
return
|
|
if (!current)
|
|
current = locate() in loc
|
|
if (!current)
|
|
return
|
|
if (!current.may_pass(moving_dir))
|
|
return
|
|
waited++
|
|
if (waited < speed)
|
|
return
|
|
waited = 0
|
|
var/turf/next = get_step(loc, moving_dir)
|
|
if (next)
|
|
var/obj/railway/NR = locate() in next
|
|
if (NR)
|
|
if (locate(/obj/railway_vehicle) in next)
|
|
return // defer
|
|
for (var/obj/O in next)
|
|
if (O == src || istype(O, /obj/railway) || !O.density)
|
|
continue
|
|
if (O.anchored && !magically_destructive)
|
|
visible_message("<span style=\"color:red\">[src] bumps against [O].</span>")
|
|
moving_dir = 0
|
|
on_end_path()
|
|
return
|
|
current = NR
|
|
moving_dir = current.get_travel_dir(moving_dir)
|
|
dir = moving_dir
|
|
current.entering(src)
|
|
set_loc(next)
|
|
if (!self_powered)
|
|
distance -= 1
|
|
if (moving_dir == 0 || (!self_powered && distance <= 0))
|
|
moving_dir = 0
|
|
on_end_path()
|
|
return
|
|
|
|
moving_dir = 0
|
|
on_end_path()
|
|
|
|
set_loc(var/dest)
|
|
var/turf/from_t = loc
|
|
..()
|
|
var/turf/dest_t = dest
|
|
if (from_t == dest_t)
|
|
return
|
|
if (get_dist(from_t, dest_t) > 1)
|
|
return
|
|
if (istype(from_t) && istype(dest_t))
|
|
var/knock_dir = get_dir(from_t, dest_t)
|
|
for (var/mob/living/M in dest_t)
|
|
M.TakeDamage("chest", src.road_rage_force, 0)
|
|
M.visible_message("<span style=\"color:red\"><b>[M] was hit by [src]!</b></span>", "<span style=\"color:red\"><b>You were hit by [src]!</b></span>")
|
|
playsound(src.loc, "sound/misc/meteorimpact.ogg", 40, 1)
|
|
spawn
|
|
M.throw_at(get_edge_target_turf(M, knock_dir), 10, 2)
|
|
for (var/obj/O in dest_t)
|
|
if (O == src || istype(O, /obj/railway) || !O.density)
|
|
continue
|
|
playsound(src.loc, "sound/misc/meteorimpact.ogg", 40, 1)
|
|
if (O.anchored && magically_destructive)
|
|
visible_message("<span style=\"color:red\"><b>[src] crashes into [O].</b></span>")
|
|
qdel(O)
|
|
else if (!O.anchored)
|
|
spawn
|
|
visible_message("<span style=\"color:red\"><b>[O] was hit by [src]!</b></span>")
|
|
O.throw_at(get_edge_target_turf(O, knock_dir), 10, 2)
|
|
|
|
|
|
ex_act()
|
|
if (indestructible)
|
|
return
|
|
..()
|
|
|
|
meteorhit()
|
|
if (indestructible)
|
|
return
|
|
..()
|
|
|
|
blob_act()
|
|
if (indestructible)
|
|
return
|
|
..()
|
|
|
|
bullet_act()
|
|
if (indestructible)
|
|
return
|
|
return
|
|
|
|
proc/on_start_path()
|
|
proc/on_trigger()
|
|
proc/on_end_path()
|
|
|
|
arrival_pod
|
|
indestructible = 1
|
|
magically_destructive = 1
|
|
self_powered = 1
|
|
var/dump_angle = 90
|
|
|
|
on_trigger()
|
|
if (contents.len > 0)
|
|
var/dump_dir = turn(dir, dump_angle)
|
|
var/turf/T = get_step(loc, dump_dir)
|
|
for (var/atom/movable/AM in src)
|
|
visible_message("<span style='color:blue'><b>[src] dumps out [AM].</b></span>")
|
|
AM.set_loc(T)
|
|
|
|
on_end_path()
|
|
qdel(src) |