mirror of
https://github.com/vgstation-coders/vgstation13.git
synced 2025-12-10 02:16:05 +00:00
Tracker for projectiles (#26026)
This commit is contained in:
@@ -133,6 +133,7 @@
|
|||||||
|
|
||||||
if(istype(D,/atom/movable))
|
if(istype(D,/atom/movable))
|
||||||
body += "<option value='?_src_=vars;teleport_here=\ref[D]'>Teleport Here</option>"
|
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))
|
if(istype(D,/atom))
|
||||||
body += "<option value='?_src_=vars;teleport_to=\ref[D]'>Teleport To</option>"
|
body += "<option value='?_src_=vars;teleport_to=\ref[D]'>Teleport To</option>"
|
||||||
@@ -834,6 +835,48 @@ function loadPage(list) {
|
|||||||
A.alpha = 0
|
A.alpha = 0
|
||||||
animate(A, alpha = 255, time = stealthy_level)
|
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"])
|
else if(href_list["teleport_to"])
|
||||||
if(!check_rights(0))
|
if(!check_rights(0))
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -57,6 +57,8 @@
|
|||||||
|
|
||||||
var/last_explosion_push = 0
|
var/last_explosion_push = 0
|
||||||
|
|
||||||
|
var/list/datum/tracker/trackers = list()
|
||||||
|
|
||||||
/atom/movable/New()
|
/atom/movable/New()
|
||||||
. = ..()
|
. = ..()
|
||||||
if((flags & HEAR) && !ismob(src))
|
if((flags & HEAR) && !ismob(src))
|
||||||
@@ -1060,3 +1062,43 @@
|
|||||||
forceMove(F)
|
forceMove(F)
|
||||||
return TRUE
|
return TRUE
|
||||||
return FALSE
|
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>"
|
dat += "Max [T.max_per_turf] per turf. Lasts up to [T.max_age] rounds.<hr>"
|
||||||
|
|
||||||
usr << browse(dat, "window=persistencepanel;size=350x600")
|
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/makepAI,
|
||||||
/client/proc/set_blob_looks,
|
/client/proc/set_blob_looks,
|
||||||
/client/proc/set_teleport_pref,
|
/client/proc/set_teleport_pref,
|
||||||
/client/proc/deadchat_singularity
|
/client/proc/deadchat_singularity,
|
||||||
|
/client/proc/view_all_rods,
|
||||||
)
|
)
|
||||||
var/list/admin_verbs_spawn = list(
|
var/list/admin_verbs_spawn = list(
|
||||||
/datum/admins/proc/spawn_atom, // Allows us to spawn instances
|
/datum/admins/proc/spawn_atom, // Allows us to spawn instances
|
||||||
@@ -1265,3 +1266,11 @@ var/list/admin_verbs_mod = list(
|
|||||||
holder.PersistencePanel()
|
holder.PersistencePanel()
|
||||||
feedback_add_details("admin_verb","PEP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
feedback_add_details("admin_verb","PEP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||||
return
|
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!
|
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
|
// ----- Religion and stuff
|
||||||
else if(href_list["ashpaper"])
|
else if(href_list["ashpaper"])
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
//As well as hurting all dense mobs
|
//As well as hurting all dense mobs
|
||||||
//Recoded as a projectile for better movement/appearance
|
//Recoded as a projectile for better movement/appearance
|
||||||
|
|
||||||
|
var/list/all_rods = list()
|
||||||
|
|
||||||
/datum/event/immovable_rod
|
/datum/event/immovable_rod
|
||||||
announceWhen = 1
|
announceWhen = 1
|
||||||
|
|
||||||
@@ -71,6 +73,14 @@
|
|||||||
lock_angle = 1
|
lock_angle = 1
|
||||||
clongSound = 'sound/effects/immovablerod_clong.ogg'
|
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()
|
/obj/item/projectile/immovablerod/hyper/New()
|
||||||
..()
|
..()
|
||||||
var/image/I = image('icons/obj/objects_96x96.dmi',"immrod_bottom")
|
var/image/I = image('icons/obj/objects_96x96.dmi',"immrod_bottom")
|
||||||
@@ -188,3 +198,29 @@
|
|||||||
for (var/mob/M in range(loc,20))
|
for (var/mob/M in range(loc,20))
|
||||||
to_chat(M,"<FONT size=[max(0, 5 - round(get_dist(src, M)/4))]>CLANG!</FONT>")
|
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)
|
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/inaccurate = 0
|
||||||
|
|
||||||
var/turf/target = null
|
var/turf/target = null
|
||||||
|
var/datum/tracker/tracker_datum = null
|
||||||
|
var/tracking = FALSE
|
||||||
|
|
||||||
var/dist_x = 0
|
var/dist_x = 0
|
||||||
var/dist_y = 0
|
var/dist_y = 0
|
||||||
var/dx = 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)
|
X.apply_effects(stun, weaken, paralyze, irradiate, stutter, eyeblur, drowsy, agony, blocked)
|
||||||
|
|
||||||
/obj/item/projectile/proc/on_hit(var/atom/atarget, var/blocked = 0)
|
/obj/item/projectile/proc/on_hit(var/atom/atarget, var/blocked = 0)
|
||||||
|
|
||||||
|
qdel(tracker_datum)
|
||||||
|
tracker_datum = null
|
||||||
|
|
||||||
if(blocked >= 100)
|
if(blocked >= 100)
|
||||||
return 0//Full block
|
return 0//Full block
|
||||||
if(!isliving(atarget))
|
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
|
/obj/item/projectile/proc/OnFired(var/proj_target = original) //if assigned, allows for code when the projectile gets fired
|
||||||
target = get_turf(proj_target)
|
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_x = abs(target.x - starting.x)
|
||||||
dist_y = abs(target.y - starting.y)
|
dist_y = abs(target.y - starting.y)
|
||||||
|
|
||||||
@@ -419,6 +436,36 @@ var/list/impact_master = list()
|
|||||||
|
|
||||||
bumped = 0
|
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)
|
sleep(projectile_speed)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user