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:
NanakoAC
2016-06-23 02:14:55 +03:00
committed by skull132
parent d3d53a9c4d
commit 8a4bf1d738
7 changed files with 255 additions and 141 deletions
@@ -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)
+177 -67
View File
@@ -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
+8 -1
View File
@@ -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