mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 10:12:45 +00:00
Moved gun icons adding/deletion in separate procs. Moved dropping aim in separate procs. Moved gun empty clicking in separate proc because all the copypaste. Fixed issues with aim mode HUD icons not being updated in some cases. Now toggling mode cancels aim properly. Fixed type in firing message.
375 lines
12 KiB
Plaintext
375 lines
12 KiB
Plaintext
/obj/item/weapon/gun/verb/toggle_firerate()
|
|
set name = "Toggle Firerate"
|
|
set category = "Object"
|
|
firerate = !firerate
|
|
if (firerate == 0)
|
|
loc << "You will now continue firing when your target moves."
|
|
else
|
|
loc << "You will now only fire once, then lower your aim, when your target moves."
|
|
|
|
/obj/item/weapon/gun/verb/lower_aim()
|
|
set name = "Lower Aim"
|
|
set category = "Object"
|
|
if(target)
|
|
stop_aim()
|
|
usr.visible_message("\blue \The [usr] lowers \the [src]...")
|
|
|
|
//Clicking gun will still lower aim for guns that don't overwrite this
|
|
/obj/item/weapon/gun/attack_self()
|
|
lower_aim()
|
|
|
|
//Removing the lock and the buttons.
|
|
/obj/item/weapon/gun/dropped(mob/user as mob)
|
|
stop_aim()
|
|
if (user.client)
|
|
user.client.remove_gun_icons()
|
|
return ..()
|
|
|
|
//Removes lock fro mall targets
|
|
/obj/item/weapon/gun/proc/stop_aim()
|
|
if(target)
|
|
for(var/mob/living/M in target)
|
|
if(M)
|
|
M.NotTargeted(src) //Untargeting people.
|
|
del(target)
|
|
|
|
//Compute how to fire.....
|
|
/obj/item/weapon/gun/proc/PreFire(atom/A as mob|obj|turf|area, mob/living/user as mob|obj, params)
|
|
//Lets not spam it.
|
|
if(lock_time > world.time - 2) return
|
|
.
|
|
if(ismob(A) && isliving(A) && !(A in target))
|
|
Aim(A) //Clicked a mob, aim at them
|
|
else //Didn't click someone, check if there is anyone along that guntrace
|
|
var/mob/living/M = GunTrace(usr.x,usr.y,A.x,A.y,usr.z,usr) //Find dat mob.
|
|
if(M && isliving(M) && M in view(user) && !(M in target))
|
|
Aim(M) //Aha! Aim at them!
|
|
else if(!ismob(M) || (ismob(M) && !(M in view(user)))) //Nope! They weren't there!
|
|
Fire(A,user,params) //Fire like normal, then.
|
|
usr.dir = get_cardinal_dir(src, A)
|
|
|
|
//Aiming at the target mob.
|
|
/obj/item/weapon/gun/proc/Aim(var/mob/living/M)
|
|
if(!target || !(M in target))
|
|
lock_time = world.time
|
|
if(target && !automatic) //If they're targeting someone and they have a non automatic weapon.
|
|
for(var/mob/living/L in target)
|
|
if(L)
|
|
L.NotTargeted(src)
|
|
del(target)
|
|
usr.visible_message("\red <b>[usr] turns \the [src] on [M]!</b>")
|
|
else
|
|
usr.visible_message("\red <b>[usr] aims \a [src] at [M]!</b>")
|
|
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) return
|
|
if(!istype(M)) return
|
|
if(src != M.equipped())
|
|
stop_aim()
|
|
M.last_move_intent = world.time
|
|
if(load_into_chamber())
|
|
var/firing_check = in_chamber.check_fire(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.
|
|
if(firing_check > 0)
|
|
if(firing_check == 1)
|
|
Fire(T,usr, reflex = 1)
|
|
else if(!told_cant_shoot)
|
|
M << "\red They can't be hit from here!"
|
|
told_cant_shoot = 1
|
|
spawn(30)
|
|
told_cant_shoot = 0
|
|
else
|
|
click_empty(M)
|
|
|
|
usr.dir = get_cardinal_dir(src, T)
|
|
|
|
if (!firerate) // If firerate is set to lower aim after one shot, untarget the target
|
|
T.NotTargeted(src)
|
|
|
|
//Yay, math!
|
|
|
|
#define SIGN(X) ((X<0)?-1:1)
|
|
|
|
proc/GunTrace(X1,Y1,X2,Y2,Z=1,exc_obj,PX1=16,PY1=16,PX2=16,PY2=16)
|
|
//bluh << "Tracin' [X1],[Y1] to [X2],[Y2] on floor [Z]."
|
|
var/turf/T
|
|
var/mob/living/M
|
|
if(X1==X2)
|
|
if(Y1==Y2) return 0 //Light cannot be blocked on same tile
|
|
else
|
|
var/s = SIGN(Y2-Y1)
|
|
Y1+=s
|
|
while(1)
|
|
T = locate(X1,Y1,Z)
|
|
if(!T) return 0
|
|
M = locate() in T
|
|
if(M) return M
|
|
M = locate() in orange(1,T)-exc_obj
|
|
if(M) return M
|
|
Y1+=s
|
|
else
|
|
var
|
|
m=(32*(Y2-Y1)+(PY2-PY1))/(32*(X2-X1)+(PX2-PX1))
|
|
b=(Y1+PY1/32-0.015625)-m*(X1+PX1/32-0.015625) //In tiles
|
|
signX = SIGN(X2-X1)
|
|
signY = SIGN(Y2-Y1)
|
|
if(X1<X2) b+=m
|
|
while(1)
|
|
var/xvert = round(m*X1+b-Y1)
|
|
if(xvert) Y1+=signY //Line exits tile vertically
|
|
else X1+=signX //Line exits tile horizontally
|
|
T = locate(X1,Y1,Z)
|
|
if(!T) return 0
|
|
M = locate() in T
|
|
if(M) return M
|
|
M = locate() in orange(1,T)-exc_obj
|
|
if(M) return M
|
|
return 0
|
|
|
|
|
|
//Targeting management procs
|
|
mob/var
|
|
list/targeted_by
|
|
target_time = -100
|
|
last_move_intent = -100
|
|
last_target_click = -5
|
|
target_locked = null
|
|
|
|
mob/living/proc/Targeted(var/obj/item/weapon/gun/I) //Self explanitory.
|
|
if(!I.target)
|
|
I.target = list(src)
|
|
else if(I.automatic && I.target.len < 5) //Automatic weapon, they can hold down a room.
|
|
I.target += src
|
|
else if(I.target.len >= 5)
|
|
if(ismob(I.loc))
|
|
I.loc << "You can only target 5 people at once!"
|
|
return
|
|
else
|
|
return
|
|
for(var/mob/living/K in viewers(usr))
|
|
K << 'TargetOn.ogg'
|
|
|
|
if(!targeted_by) 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).
|
|
src << "((\red <b>Your character is being targeted. They have 2 seconds to stop any click or move actions.</b> \black While targeted, they may \
|
|
drag and drop items in or into the map, speak, and click on interface buttons. Clicking on the map, their items \
|
|
(other than a weapon to de-target), or moving will result in being fired upon. \red The aggressor may also fire manually, \
|
|
so try not to get on their bad side.\black ))"
|
|
|
|
if(targeted_by.len == 1)
|
|
spawn(0)
|
|
target_locked = image("icon" = 'icons/effects/Targeted.dmi', "icon_state" = "locking")
|
|
overlays += target_locked
|
|
spawn(0)
|
|
sleep(20)
|
|
if(target_locked)
|
|
target_locked = image("icon" = 'icons/effects/Targeted.dmi', "icon_state" = "locked")
|
|
update_targeted()
|
|
|
|
//Adding the buttons to the controler person
|
|
var/mob/living/T = I.loc
|
|
if(T)
|
|
if(T.client)
|
|
T.client.add_gun_icons()
|
|
else
|
|
I.lower_aim()
|
|
return
|
|
if(m_intent == "run" && T.client.target_can_move == 1 && T.client.target_can_run == 0)
|
|
src << "\red Your move intent is now set to walk, as your targeter permits it." //Self explanitory.
|
|
set_m_intent("walk")
|
|
|
|
//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)
|
|
|
|
mob/living/proc/NotTargeted(var/obj/item/weapon/gun/I)
|
|
if(!I.silenced)
|
|
for(var/mob/living/M in viewers(src))
|
|
M << 'TargetOff.ogg'
|
|
targeted_by -= I
|
|
I.target.Remove(src) //De-target them
|
|
if(!I.target.len)
|
|
del(I.target)
|
|
var/mob/living/T = I.loc //Remove the targeting icons
|
|
if(T && ismob(T) && !I.target)
|
|
T.client.remove_gun_icons()
|
|
if(!targeted_by.len)
|
|
del target_locked //Remove the overlay
|
|
del targeted_by
|
|
spawn(1) update_targeted()
|
|
|
|
mob/living/Move()
|
|
. = ..()
|
|
for(var/obj/item/weapon/gun/G in targeted_by) //Handle moving out of the gunner's view.
|
|
var/mob/living/M = G.loc
|
|
if(!(M in view(src)))
|
|
NotTargeted(G)
|
|
for(var/obj/item/weapon/gun/G in src) //Handle the gunner loosing sight of their target/s
|
|
if(G.target)
|
|
for(var/mob/living/M in G.target)
|
|
if(M && !(M in view(src)))
|
|
M.NotTargeted(G)
|
|
|
|
//If you move out of range, it isn't going to still stay locked on you any more.
|
|
client/var
|
|
target_can_move = 0
|
|
target_can_run = 0
|
|
target_can_click = 0
|
|
gun_mode = 0
|
|
|
|
//These are called by the on-screen buttons, adjusting what the victim can and cannot do.
|
|
client/proc/add_gun_icons()
|
|
if (!usr.item_use_icon)
|
|
usr.item_use_icon = new /obj/screen/gun/item(null)
|
|
usr.item_use_icon.icon_state = "no_item[target_can_click]"
|
|
usr.item_use_icon.name = "[target_can_click ? "Disallow" : "Allow"] Item Use"
|
|
|
|
if (!usr.gun_move_icon)
|
|
usr.gun_move_icon = new /obj/screen/gun/move(null)
|
|
usr.gun_move_icon.icon_state = "no_walk[target_can_move]"
|
|
usr.gun_move_icon.name = "[target_can_move ? "Disallow" : "Allow"] Walking"
|
|
|
|
if (target_can_move && !usr.gun_run_icon)
|
|
usr.gun_run_icon = new /obj/screen/gun/run(null)
|
|
usr.gun_run_icon.icon_state = "no_run[target_can_run]"
|
|
usr.gun_run_icon.name = "[target_can_run ? "Disallow" : "Allow"] Running"
|
|
|
|
screen += usr.item_use_icon
|
|
screen += usr.gun_move_icon
|
|
if (target_can_move)
|
|
screen += usr.gun_run_icon
|
|
|
|
client/proc/remove_gun_icons()
|
|
screen -= usr.item_use_icon
|
|
screen -= usr.gun_move_icon
|
|
if (target_can_move)
|
|
screen -= usr.gun_run_icon
|
|
del usr.gun_move_icon
|
|
del usr.item_use_icon
|
|
del usr.gun_run_icon
|
|
|
|
client/verb/ToggleGunMode()
|
|
set hidden = 1
|
|
gun_mode = !gun_mode
|
|
if(gun_mode)
|
|
usr << "You will now take people captive."
|
|
add_gun_icons()
|
|
else
|
|
usr << "You will now shoot where you target."
|
|
for(var/obj/item/weapon/gun/G in usr)
|
|
G.stop_aim()
|
|
remove_gun_icons()
|
|
if(usr.gun_setting_icon)
|
|
usr.gun_setting_icon.icon_state = "gun[gun_mode]"
|
|
|
|
|
|
client/verb/AllowTargetMove()
|
|
set hidden=1
|
|
|
|
//Changing client's permissions
|
|
target_can_move = !target_can_move
|
|
if(target_can_move)
|
|
usr << "Target may now walk."
|
|
usr.gun_run_icon = new /obj/screen/gun/run(null) //adding icon for running permission
|
|
screen += usr.gun_run_icon
|
|
else
|
|
usr << "Target may no longer move."
|
|
target_can_run = 0
|
|
del(usr.gun_run_icon) //no need for icon for running permission
|
|
|
|
//Updating walking permission button
|
|
if(usr.gun_move_icon)
|
|
usr.gun_move_icon.icon_state = "no_walk[target_can_move]"
|
|
usr.gun_move_icon.name = "[target_can_move ? "Disallow" : "Allow"] Walking"
|
|
|
|
//Handling change for all the guns on client
|
|
for(var/obj/item/weapon/gun/G in usr)
|
|
G.lock_time = world.time + 5
|
|
if(G.target)
|
|
for(var/mob/living/M in G.target)
|
|
if(target_can_move)
|
|
M << "Your character may now <b>walk</b> at the discretion of their targeter."
|
|
if(!target_can_run)
|
|
M << "\red Your move intent is now set to walk, as your targeter permits it."
|
|
M.set_m_intent("walk")
|
|
else
|
|
M << "\red <b>Your character will now be shot if they move.</b>"
|
|
|
|
mob/living/proc/set_m_intent(var/intent)
|
|
if (intent != "walk" && intent != "run")
|
|
return 0
|
|
m_intent = intent
|
|
if(hud_used)
|
|
if (hud_used.move_intent)
|
|
hud_used.move_intent.icon_state = intent == "walk" ? "walking" : "running"
|
|
|
|
client/verb/AllowTargetRun()
|
|
set hidden=1
|
|
|
|
//Changing client's permissions
|
|
target_can_run = !target_can_run
|
|
if(target_can_run)
|
|
usr << "Target may now run."
|
|
else
|
|
usr << "Target may no longer run."
|
|
|
|
//Updating running permission button
|
|
if(usr.gun_run_icon)
|
|
usr.gun_run_icon.icon_state = "no_run[target_can_run]"
|
|
usr.gun_run_icon.name = "[target_can_run ? "Disallow" : "Allow"] Running"
|
|
|
|
//Handling change for all the guns on client
|
|
for(var/obj/item/weapon/gun/G in src)
|
|
G.lock_time = world.time + 5
|
|
if(G.target)
|
|
for(var/mob/living/M in G.target)
|
|
if(target_can_run)
|
|
M << "Your character may now <b>run</b> at the discretion of their targeter."
|
|
else
|
|
M << "\red <b>Your character will now be shot if they run.</b>"
|
|
|
|
client/verb/AllowTargetClick()
|
|
set hidden=1
|
|
|
|
//Changing client's permissions
|
|
target_can_click = !target_can_click
|
|
if(target_can_click)
|
|
usr << "Target may now use items."
|
|
else
|
|
usr << "Target may no longer use items."
|
|
|
|
if(usr.item_use_icon)
|
|
usr.item_use_icon.icon_state = "no_item[target_can_click]"
|
|
usr.item_use_icon.name = "[target_can_click ? "Disallow" : "Allow"] Item Use"
|
|
|
|
//Handling change for all the guns on client
|
|
for(var/obj/item/weapon/gun/G in src)
|
|
G.lock_time = world.time + 5
|
|
if(G.target)
|
|
for(var/mob/living/M in G.target)
|
|
if(target_can_click)
|
|
M << "Your character may now <b>use items</b> at the discretion of their targeter."
|
|
else
|
|
M << "\red <b>Your character will now be shot if they use items.</b>"
|