Skip to content
5 changes: 5 additions & 0 deletions code/_hooks/events.dm
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@
// atom/movable/mover: the movable itself.
/event/moved

// Called whenever an /atom/movable relay-moves.
// Arguments:
// atom/movable/mover: the movable itself.
/event/relaymoved

// Called right before an /atom/movable attempts to move or change dir.
/event/before_move

Expand Down
2 changes: 1 addition & 1 deletion code/game/atoms.dm
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ its easier to just keep the beam vertical.
bug.removed(usr)

/atom/proc/relaymove()
return
INVOKE_EVENT(src, /event/relaymoved, "mover" = src)

// Try to override a mob's eastface(), westface() etc. (CTRL+RIGHTARROW, CTRL+LEFTARROW). Return 1 if successful, which blocks the mob's own eastface() etc.
// Called first on the mob's loc (turf, locker, mech), then on whatever the mob is buckled to, if anything.
Expand Down
1 change: 1 addition & 0 deletions code/game/mecha/mecha.dm
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@
//////////////////////////////////

/obj/mecha/relaymove(mob/user,direction)
..()
if(user != src.occupant) //While not "realistic", this piece is player friendly.
user.forceMove(get_turf(src))
to_chat(user, "You climb out from [src]")
Expand Down
1 change: 1 addition & 0 deletions code/game/objects/structures/vehicles/vehicle.dm
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@


/obj/structure/bed/chair/vehicle/relaymove(var/mob/living/user, direction)
..()
if(user.incapacitated())
unlock_atom(user)
return
Expand Down
1 change: 0 additions & 1 deletion code/modules/mob/mob_movement.dm
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,6 @@
var/old_dir = mob.dir

mob.delayNextMove(move_delay)
mob.last_move_intent = world.time + 10
mob.set_glide_size(DELAY2GLIDESIZE(move_delay)) //Since we're moving OUT OF OUR OWN VOLITION AND BY OURSELVES we can update our glide_size here!

INVOKE_EVENT(mob, /event/before_move)
Expand Down
1 change: 0 additions & 1 deletion code/modules/projectiles/gun.dm
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@
var/tmp/lock_time = -100
var/mouthshoot = 0 ///To stop people from suiciding twice... >.>
var/automatic = 0 //Used to determine if you can target multiple people.
var/tmp/mob/living/last_moved_mob //Used to fire faster at more than one person.
var/tmp/told_cant_shoot = 0 //So that it doesn't spam them with the fact they cannot hit them.
var/firerate = 1 // 0 for one bullet after tarrget moves and aim is lowered,
//1 for keep shooting until aim is lowered
Expand Down
8 changes: 5 additions & 3 deletions code/modules/projectiles/projectile.dm
Original file line number Diff line number Diff line change
Expand Up @@ -773,9 +773,11 @@ var/list/impact_master = list()
return //cannot shoot yourself
if(istype(A, /obj/item/projectile))
return
if(istype(A, /mob/living))
result = 2 //We hit someone, return 1!
return
if(ismovable(A))
var/atom/movable/AM = A
if(isliving(AM) || (locate(/mob/living) in AM) || (locate(/mob/living) in AM.locked_atoms))
result = 2 //We hit someone, return 1!
return
result = 1
return

Expand Down
94 changes: 52 additions & 42 deletions code/modules/projectiles/targeting.dm
Original file line number Diff line number Diff line change
Expand Up @@ -76,21 +76,35 @@
M.Targeted(src)

//HE MOVED, SHOOT HIM!
/obj/item/weapon/gun/proc/TargetActed(var/mob/living/T)
var/mob/living/M = loc
if(M == T)
/obj/item/weapon/gun/proc/TargetMoved(mob/living/mover)
TargetActed(mover) //alias just so events work

/obj/item/weapon/gun/proc/TargetActed(mob/living/user,modifiers,atom/target)
if(world.time <= lock_time)
return
if(!istype(M))
if(target && (isturf(target) || istype(target,/obj/abstract/screen))) // these are okay to click
return
if(src != M.get_active_hand())
lock_time = world.time + 15
//if(last_moved_mob == user) //If they were the last ones to move, give them more of a grace period, so that an automatic weapon can hold down a room better.
//lock_time = world.time + 15 //just look at the logic of this... it did nothing!!! uncomment if you want this to work again too. be sure to add the variable back.
var/mob/living/M = loc
if(M == user || !istype(M))
return
if(!M.client || src != M.get_active_hand())
stop_aim()
return
M.last_move_intent = world.time
if(M.client.target_can_click && target) // this var only gets filled in from the click event calls, so that's a way of knowing
return
if(M.client.target_can_move)
if(!M.client.target_can_run && !user.locked_to && user.m_intent != "run") // if the user is relaymoving i'm pretty sure that's NOT walking
return
else if(!target)
return
if(canbe_fired())
var/firing_check = can_hit(T,usr) //0 if it cannot hit them, 1 if it is capable of hitting, and 2 if a special check is preventing it from firing.
var/firing_check = can_hit(user,M) //0 if it cannot hit them, 1 if it is capable of hitting, and 2 if a special check is preventing it from firing.
if(firing_check > 0)
if(firing_check == 1)
Fire(T,usr, reflex = 1)
Fire(user,M, reflex = 1)
else if(!told_cant_shoot)
to_chat(M, "<span class='warning'>They can't be hit from here!</span>")
told_cant_shoot = 1
Expand All @@ -99,10 +113,10 @@
else
click_empty(M)

usr.dir = get_cardinal_dir(src, T)
M.dir = get_cardinal_dir(src, user)

if (!firerate) // If firerate is set to lower aim after one shot, untarget the target
T.NotTargeted(src)
user.NotTargeted(src)

/proc/GunTrace(X1,Y1,X2,Y2,Z=1,exc_obj,PX1=16,PY1=16,PX2=16,PY2=16)
// to_chat(bluh, "Tracin' [X1],[Y1] to [X2],[Y2] on floor [Z].")
Expand Down Expand Up @@ -153,9 +167,6 @@
//Targeting management procs
/mob
var/list/targeted_by
var/target_time = -100
var/last_move_intent = -100
var/last_target_click = -5
var/target_locked = null

/mob/living/proc/Targeted(var/obj/item/weapon/gun/I) //Self explanitory.
Expand All @@ -176,10 +187,6 @@
targeted_by = list()
targeted_by += I
I.lock_time = world.time + 20 //Target has 2 second to realize they're targeted and stop (or target the opponent).
to_chat(src, "((<span class='danger'>Your character is being targeted. They have 2 seconds to stop any click or move actions. </span>While targeted, they may \
drag and drop items in or into the map, speak, and click on interface buttons. Clicking on the map objects (floors and walls are fine), their items \
(other than a weapon to de-target), or moving will result in being fired upon. <span class='warning'>The aggressor may also fire manually, </span>\
so try not to get on their bad side.\black ))")

if(targeted_by.len == 1)
spawn(0)
Expand All @@ -199,34 +206,37 @@
else
I.lower_aim()
return
if(m_intent == "run" && T.client.target_can_move == 1 && T.client.target_can_run == 0 && (ishuman(T)))
to_chat(src, "<spanclass='warning'>Your captive is allowing you to walk. Make sure to change your move intent to walk before trying to move, or you will be fired upon.</span>")//Self explanitory.

var/msg = ""
if(!T.client.target_can_click)
msg += "While targeted, they may drag and drop items in or into the map, speak, and click on interface buttons. \
Clicking on the map objects (floors and walls are fine), their items (other than a weapon to de-target) will result in being fired upon.\n"
if(!T.client.target_can_move)
msg += "Moving will result in being fired upon.\n"
else if(m_intent == "run" && !T.client.target_can_run && (ishuman(T))) //Self explanitory.
msg += "<span class='warning'>Your captive is allowing you to walk. \
Make sure to change your move intent to walk before trying to move, or you will be fired upon.</span>\n"
to_chat(src, "<span class='danger'>Your character is being targeted. They have 2 seconds to stop any of the following actions: </span>\n \
[msg]\n \
<span class='warning'>The aggressor may also fire manually, so try not to get on their bad side.</span>")

//set_m_intent("walk") -there's a real fucked up exploit behind this, so it's been removed. Needs testing. -Angelite-

//Processing the aiming. Should be probably in separate object with process() but lasy.
while(targeted_by && T.client)
if((last_move_intent > I.lock_time + 10) && !T.client.target_can_move) //If target moved when not allowed to
I.TargetActed(src)
if(I.last_moved_mob == src) //If they were the last ones to move, give them more of a grace period, so that an automatic weapon can hold down a room better.
I.lock_time = world.time + 5
I.lock_time = world.time + 5
I.last_moved_mob = src
else if((last_move_intent > I.lock_time + 10) && !T.client.target_can_run && m_intent == "run") //If the target ran while targeted
I.TargetActed(src)
if(I.last_moved_mob == src) //If they were the last ones to move, give them more of a grace period, so that an automatic weapon can hold down a room better.
I.lock_time = world.time + 5
I.lock_time = world.time + 5
I.last_moved_mob = src
if((last_target_click > I.lock_time + 10) && !T.client.target_can_click) //If the target clicked the map to pick something up/shoot/etc
I.TargetActed(src)
if(I.last_moved_mob == src) //If they were the last ones to move, give them more of a grace period, so that an automatic weapon can hold down a room better.
I.lock_time = world.time + 5
I.lock_time = world.time + 5
I.last_moved_mob = src
sleep(1)

if(!T.client.target_can_move || !T.client.target_can_run)
register_event(/event/moved, I, nameof(I::TargetMoved()))
register_event(/event/relaymoved, I, nameof(I::TargetMoved()))
if(!T.client.target_can_click)
register_event(/event/clickon, I, nameof(I::TargetActed()))
register_event(/event/logout, T, nameof(src::TargeterLogout()))

/mob/living/proc/TargeterLogout(mob/living/user)
for(var/obj/item/weapon/gun/G in user)
NotTargeted(G)
unregister_event(/event/logout, user, nameof(src::TargeterLogout()))

/mob/living/proc/NotTargeted(var/obj/item/weapon/gun/I)
unregister_event(/event/moved, I, nameof(I::TargetMoved()))
unregister_event(/event/relaymoved, I, nameof(I::TargetMoved()))
unregister_event(/event/clickon, I, nameof(I::TargetActed()))
if(!I.silenced)
for(var/mob/living/M in viewers(src))
M << 'sound/weapons/TargetOff.ogg'
Expand Down
Loading