mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-22 12:29:46 +01:00
Alt-attack and trays (#394)
Added alt-attack function to held items/weapons, triggered by holding alt while clicking. Opens a lot of future possibilities. Works for cyborgs too. Only trays use it right now. Overhauled trays to be useful and not-broken. See changelog for specifics.
This commit is contained in:
@@ -346,16 +346,10 @@
|
||||
|
||||
if(istype(W, /obj/item/weapon/tray))
|
||||
var/obj/item/weapon/tray/T = W
|
||||
if(T.calc_carry() > 0)
|
||||
if(prob(85))
|
||||
user << "\red The tray won't fit in [src]."
|
||||
return
|
||||
else
|
||||
W.loc = user.loc
|
||||
if ((user.client && user.s_active != src))
|
||||
user.client.screen -= W
|
||||
W.dropped(user)
|
||||
user << "\red God damnit!"
|
||||
if(T.current_weight > 0)
|
||||
T.spill(user)
|
||||
user << "\red Trying to place a loaded tray into [src] was a bad idea."
|
||||
return
|
||||
|
||||
W.add_fingerprint(user)
|
||||
return handle_item_insertion(W)
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
/*
|
||||
* Trays - Agouri
|
||||
* Trays - Nanako
|
||||
*/
|
||||
//Use tray on an item to load it, alt+click on anything to attempt to load all the stuff on the tile
|
||||
//To unload, place on a table, then rightclic > Unload tray. Alternatively, alt+click on the tray to unload it
|
||||
//Tray will spill if thrown, dropped on the floor, or used to hit someone with. Spilling scatters contents
|
||||
|
||||
/obj/item/weapon/tray
|
||||
name = "tray"
|
||||
icon = 'icons/obj/food.dmi'
|
||||
@@ -14,26 +18,29 @@
|
||||
flags = CONDUCT
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 3000)
|
||||
var/list/carrying = list() // List of things on the tray. - Doohl
|
||||
var/max_carry = 10
|
||||
var/max_carry = 20
|
||||
var/current_weight = 0
|
||||
|
||||
var/safedrop = 0//Used to tell when we should or shouldn't spill if the tray is dropped.
|
||||
//Safedrop is set true when throwing, because it will spill on impact. And when placing on a table
|
||||
var/list/valid = list( /obj/item/weapon/reagent_containers,
|
||||
/obj/item/weapon/material/kitchen/utensil,
|
||||
/obj/item/weapon/storage/fancy/cigarettes,
|
||||
/obj/item/clothing/mask/smokable,
|
||||
/obj/item/weapon/storage/box/matches,
|
||||
/obj/item/weapon/flame/match,
|
||||
/obj/item/weapon/material/ashtray)
|
||||
|
||||
/obj/item/weapon/tray/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
|
||||
|
||||
// Drop all the things. All of them.
|
||||
overlays.Cut()
|
||||
for(var/obj/item/I in carrying)
|
||||
I.loc = M.loc
|
||||
carrying.Remove(I)
|
||||
if(isturf(I.loc))
|
||||
spawn()
|
||||
for(var/i = 1, i <= rand(1,2), i++)
|
||||
if(I)
|
||||
step(I, pick(NORTH,SOUTH,EAST,WEST))
|
||||
sleep(rand(2,4))
|
||||
spill(user, M.loc)
|
||||
|
||||
|
||||
//Note: Added a robot check to all stun/weaken procs, beccause weakening a robot causes its active modules to bug out
|
||||
if((CLUMSY in user.mutations) && prob(50)) //What if he's a clown?
|
||||
M << "\red You accidentally slam yourself with the [src]!"
|
||||
M.Weaken(1)
|
||||
if(!istype(M,/mob/living/silicon))M.Weaken(1)
|
||||
user.take_organ_damage(2)
|
||||
if(prob(50))
|
||||
playsound(M, 'sound/items/trayhit1.ogg', 50, 1)
|
||||
@@ -46,7 +53,7 @@
|
||||
|
||||
|
||||
if(!(user.zone_sel.selecting == ("eyes" || "head"))) //////////////hitting anything else other than the eyes
|
||||
if(prob(33))
|
||||
if(prob(33) && !istype(M,/mob/living/silicon))//robots dont bleed
|
||||
src.add_blood(H)
|
||||
var/turf/location = H.loc
|
||||
if (istype(location, /turf/simulated))
|
||||
@@ -57,7 +64,7 @@
|
||||
msg_admin_attack("[user.name] ([user.ckey]) used the [src.name] to attack [M.name] ([M.ckey]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
|
||||
|
||||
if(prob(15))
|
||||
M.Weaken(3)
|
||||
if(!istype(M,/mob/living/silicon)) M.Weaken(3)
|
||||
M.take_organ_damage(3)
|
||||
else
|
||||
M.take_organ_damage(5)
|
||||
@@ -75,7 +82,7 @@
|
||||
|
||||
if(istype(M, /mob/living/carbon/human) && ((H.head && H.head.flags & HEADCOVERSEYES) || (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || (H.glasses && H.glasses.flags & GLASSESCOVERSEYES)))
|
||||
M << "\red You get slammed in the face with the tray, against your mask!"
|
||||
if(prob(33))
|
||||
if(prob(33) && !istype(M,/mob/living/silicon))
|
||||
src.add_blood(H)
|
||||
if (H.wear_mask)
|
||||
H.wear_mask.add_blood(H)
|
||||
@@ -96,14 +103,14 @@
|
||||
for(var/mob/O in viewers(M, null))
|
||||
O.show_message(text("\red <B>[] slams [] with the tray!</B>", user, M), 1)
|
||||
if(prob(10))
|
||||
M.Stun(rand(1,3))
|
||||
if(!istype(M,/mob/living/silicon))M.Stun(rand(1,3))
|
||||
M.take_organ_damage(3)
|
||||
return
|
||||
else
|
||||
M.take_organ_damage(5)
|
||||
return
|
||||
|
||||
else //No eye or head protection, tough luck!
|
||||
else if (!istype(M,/mob/living/silicon))//No eye or head protection, tough luck!
|
||||
M << "\red You get slammed in the face with the tray!"
|
||||
if(prob(33))
|
||||
src.add_blood(M)
|
||||
@@ -133,76 +140,179 @@
|
||||
/obj/item/weapon/tray/var/cooldown = 0 //shield bash cooldown. based on world.time
|
||||
|
||||
/obj/item/weapon/tray/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if (istype(user,/mob/living/silicon/robot))//safety to stop robots losing their items
|
||||
return
|
||||
|
||||
if (istype(W, /obj/item/weapon/tray))//safety to prevent tray stacking
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/weapon/material/kitchen/rollingpin))
|
||||
if(cooldown < world.time - 25)
|
||||
user.visible_message("<span class='warning'>[user] bashes [src] with [W]!</span>")
|
||||
playsound(user.loc, 'sound/effects/shieldbash.ogg', 50, 1)
|
||||
cooldown = world.time
|
||||
|
||||
else
|
||||
..()
|
||||
var/obj/item/I = W
|
||||
attempt_load_item(I, user)
|
||||
//..()
|
||||
|
||||
/*
|
||||
===============~~~~~================================~~~~~====================
|
||||
= =
|
||||
= Code for trays carrying things. By Doohl for Doohl erryday Doohl Doohl~ =
|
||||
= =
|
||||
===============~~~~~================================~~~~~====================
|
||||
============~~~~~==============~~~~~=============
|
||||
= =
|
||||
= Code for trays carrying things. By Nanako.
|
||||
= =
|
||||
============~~~~~============~~~~~===============
|
||||
*/
|
||||
/obj/item/weapon/tray/proc/calc_carry()
|
||||
// calculate the weight of the items on the tray
|
||||
var/val = 0 // value to return
|
||||
|
||||
for(var/obj/item/I in carrying)
|
||||
if(I.w_class == 1.0)
|
||||
val ++
|
||||
else if(I.w_class == 2.0)
|
||||
val += 3
|
||||
//Clicking an item individually loads it. clicking a table places the tray on it safely
|
||||
/obj/item/weapon/tray/afterattack(atom/target, mob/user as mob, proximity)
|
||||
if (proximity)
|
||||
if (istype(target, /obj/item))
|
||||
var/obj/item/I = target
|
||||
attempt_load_item(I,user,1)
|
||||
|
||||
if (istype(target,/obj/structure/table))
|
||||
safedrop = 1
|
||||
|
||||
|
||||
//Alt+click with the tray in hand attempts to grab everything on the tile
|
||||
/obj/item/weapon/tray/alt_attack(var/atom/A, var/mob/user)
|
||||
var/dist
|
||||
var/tile
|
||||
if (istype(A,/turf))
|
||||
dist = get_dist(A,user.loc)
|
||||
tile = A
|
||||
else
|
||||
dist = get_dist(A.loc,user.loc)
|
||||
tile = A.loc
|
||||
|
||||
if (dist == 1)//checking that we're adjacent
|
||||
var/addedSomething = 0
|
||||
for(var/obj/item/I in tile)
|
||||
if (attempt_load_item(I, usr,0))
|
||||
addedSomething++
|
||||
if ( addedSomething == 1)
|
||||
usr.visible_message("\blue [user] loads an item onto their service tray.")
|
||||
else if ( addedSomething )
|
||||
usr.visible_message("\blue [user] loads [addedSomething] items onto their service tray.")
|
||||
else
|
||||
val += 5
|
||||
user << "The tray is full or there's nothing valid here"
|
||||
return 1
|
||||
return 0//This prevents the alt-click from doing any farther actions
|
||||
return 1
|
||||
|
||||
return val
|
||||
/obj/item/weapon/tray/AltClick(var/mob/user)
|
||||
unload(user)
|
||||
|
||||
/obj/item/weapon/tray/pickup(mob/user)
|
||||
|
||||
if(!isturf(loc))
|
||||
/obj/item/weapon/tray/proc/attempt_load_item(var/obj/item/I, var/mob/user, var/messages = 1)
|
||||
if( I != src && !I.anchored && !istype(I, /obj/item/projectile) )
|
||||
var/match = 0
|
||||
for (var/T in valid)
|
||||
if (istype(I,T))
|
||||
match = 1
|
||||
var/remaining = max_carry - current_weight
|
||||
if (remaining >= I.w_class)
|
||||
load_item(I,user)
|
||||
if (messages)user << "You place [I] on the tray"
|
||||
return 1
|
||||
else
|
||||
if (messages)
|
||||
user << "The tray can't take that much weight"
|
||||
if (!match && messages)user << "That item isn't suitable for a tray"
|
||||
return 0
|
||||
|
||||
|
||||
/obj/item/weapon/tray/proc/load_item(var/obj/item/I, var/mob/user)
|
||||
user.remove_from_mob(I)
|
||||
I.loc = src
|
||||
current_weight += I.w_class
|
||||
carrying.Add(I)
|
||||
overlays += image("icon" = I.icon, "icon_state" = I.icon_state, "layer" = 30 + I.layer, "pixel_x" = I.pixel_x, "pixel_y" = I.pixel_y)
|
||||
//rand(0, (max_offset_y*2)-3)-(max_offset_y)-3
|
||||
|
||||
/obj/item/weapon/tray/verb/unload()
|
||||
set name = "Unload Tray"
|
||||
set category = "Object"
|
||||
set src in view(1)
|
||||
|
||||
if (!istype(loc,/turf))//check that we're not being held by a mob
|
||||
usr << "Place the tray down first!"
|
||||
return
|
||||
else
|
||||
var/turf/dropspot = loc
|
||||
|
||||
for(var/obj/item/I in loc)
|
||||
if( I != src && !I.anchored && !istype(I, /obj/item/clothing/under) && !istype(I, /obj/item/clothing/suit) && !istype(I, /obj/item/projectile) )
|
||||
var/add = 0
|
||||
if(I.w_class == 1.0)
|
||||
add = 1
|
||||
else if(I.w_class == 2.0)
|
||||
add = 3
|
||||
for(var/obj/item/I in carrying)
|
||||
I.loc = dropspot
|
||||
carrying.Remove(I)
|
||||
overlays.Cut()
|
||||
current_weight = 0
|
||||
usr.visible_message("[usr] unloads the tray.", "You unload the tray.")
|
||||
|
||||
/obj/item/weapon/tray/proc/unload_at_loc(var/turf/dropspot = null, var/mob/user)
|
||||
if (!istype(loc,/turf) && !dropspot)//check that we're not being held by a mob
|
||||
usr << "Place the tray down first!"
|
||||
return
|
||||
else
|
||||
if (!dropspot)
|
||||
dropspot = loc
|
||||
|
||||
for(var/obj/item/I in carrying)
|
||||
I.loc = dropspot
|
||||
carrying.Remove(I)
|
||||
overlays.Cut()
|
||||
current_weight = 0
|
||||
usr.visible_message("[usr] unloads the tray.", "You unload the tray.")
|
||||
|
||||
|
||||
/obj/item/weapon/tray/proc/spill(var/mob/user = null, var/turf/dropspot = null)
|
||||
//This proc is called when a tray is thrown or dropped on the floor
|
||||
//its also called when a cyborg uses its tray on the floor
|
||||
if (current_weight > 0)//can't spill a tray with nothing on it
|
||||
|
||||
overlays.Cut()
|
||||
|
||||
//First we have to find where the items are being dropped, unless a location has been passed in
|
||||
if (!dropspot)
|
||||
if (istype(src.loc, /mob))//If the tray is still held by a mob
|
||||
dropspot = src.loc.loc
|
||||
else
|
||||
add = 5
|
||||
if(calc_carry() + add >= max_carry)
|
||||
break
|
||||
dropspot = src.loc
|
||||
|
||||
I.loc = src
|
||||
carrying.Add(I)
|
||||
overlays += image("icon" = I.icon, "icon_state" = I.icon_state, "layer" = 30 + I.layer)
|
||||
|
||||
/obj/item/weapon/tray/dropped(mob/user)
|
||||
|
||||
var/mob/living/M
|
||||
for(M in src.loc) //to handle hand switching
|
||||
return
|
||||
|
||||
var/foundtable = 0
|
||||
for(var/obj/structure/table/T in loc)
|
||||
foundtable = 1
|
||||
break
|
||||
|
||||
overlays.Cut()
|
||||
|
||||
for(var/obj/item/I in carrying)
|
||||
I.loc = loc
|
||||
carrying.Remove(I)
|
||||
if(!foundtable && isturf(loc))
|
||||
// if no table, presume that the person just shittily dropped the tray on the ground and made a mess everywhere!
|
||||
for(var/obj/item/I in carrying)
|
||||
I.loc = dropspot
|
||||
carrying.Remove(I)
|
||||
spawn()
|
||||
for(var/i = 1, i <= rand(1,2), i++)
|
||||
if(I)
|
||||
step(I, pick(NORTH,SOUTH,EAST,WEST))
|
||||
sleep(rand(2,4))
|
||||
if (user)
|
||||
user.visible_message("\blue [user] spills their tray all over the floor.")
|
||||
else
|
||||
src.visible_message("\blue The tray scatters its contents all over the area.")
|
||||
current_weight = 0
|
||||
if(prob(50))
|
||||
playsound(dropspot, 'sound/items/trayhit1.ogg', 50, 1)
|
||||
else
|
||||
playsound(dropspot, 'sound/items/trayhit2.ogg', 50, 1)
|
||||
|
||||
/obj/item/weapon/tray/throw_impact(atom/hit_atom)
|
||||
spill(null, src.loc)
|
||||
|
||||
/obj/item/weapon/tray/throw_at(/var/atom/target, var/throw_range, var/throw_speed, /var/mob/user)
|
||||
safedrop = 1//we dont want the tray to spill when thrown, it will spill on impact instead
|
||||
..()
|
||||
|
||||
/obj/item/weapon/tray/dropped(mob/user)
|
||||
spawn(1)//A hack to avoid race conditions. Dropped procs too quickly
|
||||
if (istype(src.loc, /mob))
|
||||
//If this is true, then the tray has just switched hands and is still held by a mob
|
||||
return
|
||||
|
||||
if (!safedrop)
|
||||
spill(user, src.loc)
|
||||
|
||||
safedrop = 0
|
||||
@@ -6,4 +6,11 @@
|
||||
/obj/item/weapon/Bump(mob/M as mob)
|
||||
spawn(0)
|
||||
..()
|
||||
return
|
||||
return
|
||||
|
||||
//Called when the user alt-clicks on something with this item in their active hand
|
||||
//this function is designed to be overridden by individual weapons
|
||||
/obj/item/weapon/proc/alt_attack(var/atom/target, var/mob/user)
|
||||
return 1
|
||||
//A return value of 1 continues on to do the normal alt-click action.
|
||||
//A return value of 0 does not continue, and will not do the alt-click
|
||||
Reference in New Issue
Block a user