mirror of
https://github.com/vgstation-coders/vgstation13.git
synced 2025-12-09 16:14:13 +00:00
Tracker for projectiles (#26026)
This commit is contained in:
@@ -133,6 +133,7 @@
|
||||
|
||||
if(istype(D,/atom/movable))
|
||||
body += "<option value='?_src_=vars;teleport_here=\ref[D]'>Teleport Here</option>"
|
||||
body += "<option value='?_src_=vars;throw_a_fucking_rod_at_it=\ref[D]'>Throw a rod at it</option>"
|
||||
|
||||
if(istype(D,/atom))
|
||||
body += "<option value='?_src_=vars;teleport_to=\ref[D]'>Teleport To</option>"
|
||||
@@ -834,6 +835,48 @@ function loadPage(list) {
|
||||
A.alpha = 0
|
||||
animate(A, alpha = 255, time = stealthy_level)
|
||||
|
||||
else if(href_list["throw_a_fucking_rod_at_it"])
|
||||
if(!check_rights(R_FUN))
|
||||
to_chat(usr, "<span class='warning'>You do not have sufficient permissions to do this.</span>")
|
||||
return
|
||||
|
||||
var/atom/movable/A = locate(href_list["throw_a_fucking_rod_at_it"])
|
||||
if(!istype(A))
|
||||
to_chat(usr, "<span class='warning'>This can only be done to instances of movable atoms.</span>")
|
||||
return
|
||||
|
||||
var/rod_size = input("What type of rod do you want to throw?","Throwing an Immovable Rod",null) as null|anything in list("Normal", "Pillar", "Monolith")
|
||||
var/rod_type
|
||||
|
||||
if (!rod_size)
|
||||
return
|
||||
|
||||
switch (rod_size)
|
||||
if ("Normal")
|
||||
rod_type = /obj/item/projectile/immovablerod
|
||||
if ("Pillar")
|
||||
rod_type = /obj/item/projectile/immovablerod/big
|
||||
if ("Monolith")
|
||||
rod_type = /obj/item/projectile/immovablerod/hyper
|
||||
|
||||
if(alert("Are you sure you want to do this?","Confirm","Yes","No") != "Yes")
|
||||
return
|
||||
|
||||
var/obj/item/projectile/immovablerod/rod = new rod_type(random_start_turf(A.z))
|
||||
rod.tracking = TRUE
|
||||
rod.throw_at(A)
|
||||
|
||||
var/log_data = "[A]"
|
||||
if (ismob(A))
|
||||
var/mob/M = A
|
||||
if (M.client)
|
||||
log_data += " ([M.client.ckey])"
|
||||
|
||||
log_admin("[key_name(usr)] threw a rod at [log_data].")
|
||||
message_admins("<span class='notice'>[key_name(usr)] threw a rod at [log_data].</span>")
|
||||
to_chat(usr, "<span class='danger'>If you changed your mind, you can always stop the tracking by using the verb 'VIEW-ALL-RODS' and click the 'Untrack' link.</span>")
|
||||
return
|
||||
|
||||
else if(href_list["teleport_to"])
|
||||
if(!check_rights(0))
|
||||
return
|
||||
|
||||
@@ -57,6 +57,8 @@
|
||||
|
||||
var/last_explosion_push = 0
|
||||
|
||||
var/list/datum/tracker/trackers = list()
|
||||
|
||||
/atom/movable/New()
|
||||
. = ..()
|
||||
if((flags & HEAR) && !ismob(src))
|
||||
@@ -1060,3 +1062,43 @@
|
||||
forceMove(F)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
// -- trackers
|
||||
|
||||
/atom/movable/proc/add_tracker(var/datum/tracker/T)
|
||||
on_moved.Add(T, "recieve_position")
|
||||
|
||||
/datum/tracker
|
||||
var/name = "Tracker"
|
||||
var/active = TRUE
|
||||
var/changed = FALSE
|
||||
|
||||
var/turf/target
|
||||
|
||||
var/tick_refresh = 5 // The number of moved events before we update the position.
|
||||
var/current_tick = 1
|
||||
|
||||
var/lost_position_probability = 0 // Probability of losing the target
|
||||
var/lost_position_distance = 0 // Distance at which the tracker loses the target
|
||||
|
||||
/datum/tracker/proc/recieve_position(var/list/loc)
|
||||
|
||||
ASSERT(loc)
|
||||
|
||||
if (!active)
|
||||
return
|
||||
if (current_tick < tick_refresh)
|
||||
current_tick++
|
||||
return
|
||||
|
||||
if (prob(lost_position_probability))
|
||||
active = FALSE
|
||||
return
|
||||
|
||||
var/target_loc = loc["loc"]
|
||||
if (target != target_loc)
|
||||
changed = TRUE
|
||||
|
||||
target = get_turf(target_loc)
|
||||
|
||||
current_tick = 1
|
||||
@@ -1618,3 +1618,17 @@ proc/formatPlayerPanel(var/mob/U,var/text="PP")
|
||||
dat += "Max [T.max_per_turf] per turf. Lasts up to [T.max_age] rounds.<hr>"
|
||||
|
||||
usr << browse(dat, "window=persistencepanel;size=350x600")
|
||||
|
||||
/datum/admins/proc/ViewAllRods()
|
||||
if(!check_rights(0))
|
||||
return
|
||||
|
||||
var/dat = "<center><B>View all active rods</B></center><hr>"
|
||||
|
||||
for (var/obj/item/projectile/immovablerod/rod in all_rods)
|
||||
dat += "<b>[rod]</b> in z = [rod.z] (<a href='?_src_=vars;Vars=\ref[rod]'>\[VV\]</A>)"
|
||||
if (rod.tracking)
|
||||
dat += "- <A href='?src=\ref[src];rod_to_untrack=\ref[rod]'>(UNTRACK)</A>"
|
||||
dat += "<br/>"
|
||||
|
||||
usr << browse(dat, "window=rodswindow;size=350x300")
|
||||
@@ -128,7 +128,8 @@ var/list/admin_verbs_fun = list(
|
||||
/client/proc/makepAI,
|
||||
/client/proc/set_blob_looks,
|
||||
/client/proc/set_teleport_pref,
|
||||
/client/proc/deadchat_singularity
|
||||
/client/proc/deadchat_singularity,
|
||||
/client/proc/view_all_rods,
|
||||
)
|
||||
var/list/admin_verbs_spawn = list(
|
||||
/datum/admins/proc/spawn_atom, // Allows us to spawn instances
|
||||
@@ -1265,3 +1266,11 @@ var/list/admin_verbs_mod = list(
|
||||
holder.PersistencePanel()
|
||||
feedback_add_details("admin_verb","PEP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
return
|
||||
|
||||
/client/proc/view_all_rods()
|
||||
set name = "VIEW-ALL-RODS"
|
||||
set category = "Fun"
|
||||
if(holder)
|
||||
holder.ViewAllRods()
|
||||
feedback_add_details("admin_verb","V-ROD") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
return
|
||||
@@ -5375,6 +5375,30 @@
|
||||
|
||||
PersistencePanel() //refresh!
|
||||
|
||||
// --- Rod tracking
|
||||
|
||||
else if (href_list["rod_to_untrack"])
|
||||
if(!check_rights(R_FUN))
|
||||
return
|
||||
var/obj/item/projectile/P = locate(href_list["rod_to_untrack"])
|
||||
|
||||
if (!P)
|
||||
return
|
||||
|
||||
P.tracking = FALSE
|
||||
P.tracker_datum = null
|
||||
qdel(P.tracker_datum)
|
||||
|
||||
var/log_data = "[P.original]"
|
||||
if (ismob(P.original))
|
||||
var/mob/M = P.original
|
||||
if (M.client)
|
||||
log_data += " (M.client.ckey)"
|
||||
|
||||
log_admin("[key_name(usr)] stopped a rod thrown at [log_data].")
|
||||
message_admins("<span class='notice'>[key_name(usr)] stopped a rod thrown at [log_data].</span>")
|
||||
|
||||
ViewAllRods()
|
||||
|
||||
// ----- Religion and stuff
|
||||
else if(href_list["ashpaper"])
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
//As well as hurting all dense mobs
|
||||
//Recoded as a projectile for better movement/appearance
|
||||
|
||||
var/list/all_rods = list()
|
||||
|
||||
/datum/event/immovable_rod
|
||||
announceWhen = 1
|
||||
|
||||
@@ -71,6 +73,14 @@
|
||||
lock_angle = 1
|
||||
clongSound = 'sound/effects/immovablerod_clong.ogg'
|
||||
|
||||
/obj/item/projectile/immovablerod/New()
|
||||
all_rods += src
|
||||
..()
|
||||
|
||||
/obj/item/projectile/immovablerod/Destroy()
|
||||
all_rods -= src
|
||||
..()
|
||||
|
||||
/obj/item/projectile/immovablerod/hyper/New()
|
||||
..()
|
||||
var/image/I = image('icons/obj/objects_96x96.dmi',"immrod_bottom")
|
||||
@@ -188,3 +198,29 @@
|
||||
for (var/mob/M in range(loc,20))
|
||||
to_chat(M,"<FONT size=[max(0, 5 - round(get_dist(src, M)/4))]>CLANG!</FONT>")
|
||||
M.playsound_local(loc, clongSound, 100 - (get_dist(src,M)*5), 1)
|
||||
|
||||
/proc/random_start_turf(var/z)
|
||||
var/startx
|
||||
var/starty
|
||||
var/chosen_dir = pick(NORTH, SOUTH, EAST, WEST)
|
||||
|
||||
switch(chosen_dir)
|
||||
|
||||
if(NORTH) //North, along the y = max edge
|
||||
starty = world.maxy - (TRANSITIONEDGE + 2)
|
||||
startx = rand((TRANSITIONEDGE + 2), world.maxx - (TRANSITIONEDGE + 2))
|
||||
|
||||
if(SOUTH) //South, along the y = 0 edge
|
||||
starty = (TRANSITIONEDGE + 2)
|
||||
startx = rand((TRANSITIONEDGE + 2), world.maxx - (TRANSITIONEDGE + 2))
|
||||
|
||||
if(EAST) //East, along the x = max edge
|
||||
starty = rand((TRANSITIONEDGE + 2), world.maxy - (TRANSITIONEDGE + 2))
|
||||
startx = world.maxx - (TRANSITIONEDGE + 2)
|
||||
|
||||
if(WEST) //West, along the x = 0 edge
|
||||
starty = rand((TRANSITIONEDGE + 2), world.maxy - (TRANSITIONEDGE + 2))
|
||||
startx = (TRANSITIONEDGE + 2)
|
||||
|
||||
var/turf/T = locate(startx, starty, z)
|
||||
return T
|
||||
@@ -71,6 +71,9 @@ var/list/impact_master = list()
|
||||
var/inaccurate = 0
|
||||
|
||||
var/turf/target = null
|
||||
var/datum/tracker/tracker_datum = null
|
||||
var/tracking = FALSE
|
||||
|
||||
var/dist_x = 0
|
||||
var/dist_y = 0
|
||||
var/dx = 0
|
||||
@@ -115,6 +118,10 @@ var/list/impact_master = list()
|
||||
X.apply_effects(stun, weaken, paralyze, irradiate, stutter, eyeblur, drowsy, agony, blocked)
|
||||
|
||||
/obj/item/projectile/proc/on_hit(var/atom/atarget, var/blocked = 0)
|
||||
|
||||
qdel(tracker_datum)
|
||||
tracker_datum = null
|
||||
|
||||
if(blocked >= 100)
|
||||
return 0//Full block
|
||||
if(!isliving(atarget))
|
||||
@@ -362,6 +369,16 @@ var/list/impact_master = list()
|
||||
|
||||
/obj/item/projectile/proc/OnFired(var/proj_target = original) //if assigned, allows for code when the projectile gets fired
|
||||
target = get_turf(proj_target)
|
||||
|
||||
if (tracking)
|
||||
if (istype(proj_target, /atom/movable))
|
||||
var/atom/movable/the_target = proj_target
|
||||
var/datum/tracker/T = new
|
||||
T.name = "[src] tracker on [proj_target]"
|
||||
T.target = target
|
||||
src.tracker_datum = T
|
||||
the_target.add_tracker(T)
|
||||
|
||||
dist_x = abs(target.x - starting.x)
|
||||
dist_y = abs(target.y - starting.y)
|
||||
|
||||
@@ -419,6 +436,36 @@ var/list/impact_master = list()
|
||||
|
||||
bumped = 0
|
||||
|
||||
if (tracker_datum && tracker_datum.changed)
|
||||
tracker_datum.changed = FALSE
|
||||
var/dist = get_dist(tracker_datum.target, src)
|
||||
if (tracker_datum.lost_position_distance && (dist > tracker_datum.lost_position_distance))
|
||||
tracker_datum.active = FALSE
|
||||
else
|
||||
target = tracker_datum.target
|
||||
var/turf/current = get_turf(src)
|
||||
|
||||
// recalculate trajectory based on new tracker data
|
||||
if (target.x > current.x)
|
||||
dx = EAST
|
||||
else
|
||||
dx = WEST
|
||||
|
||||
if (target.y > current.y)
|
||||
dy = NORTH
|
||||
else
|
||||
dy = SOUTH
|
||||
|
||||
dist_x = abs(target.x - current.x)
|
||||
dist_y = abs(target.y - current.y)
|
||||
|
||||
if(dist_x > dist_y)
|
||||
error = dist_x/2 - dist_y
|
||||
else
|
||||
error = dist_y/2 - dist_x
|
||||
if(rotate)
|
||||
target_angle = round(Get_Angle(current,target))
|
||||
|
||||
sleep(projectile_speed)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user