Click code cleanup

This commit is contained in:
Wild Bill
2014-09-18 14:07:50 +03:00
parent a6ca22efa1
commit 439bda24bc
66 changed files with 890 additions and 2073 deletions

View File

@@ -16,6 +16,7 @@
#include "code\setup.dm" #include "code\setup.dm"
#include "code\stylesheet.dm" #include "code\stylesheet.dm"
#include "code\world.dm" #include "code\world.dm"
#include "code\__HELPERS\adjacency.dm"
#include "code\__HELPERS\cmp.dm" #include "code\__HELPERS\cmp.dm"
#include "code\__HELPERS\experimental.dm" #include "code\__HELPERS\experimental.dm"
#include "code\__HELPERS\files.dm" #include "code\__HELPERS\files.dm"
@@ -42,25 +43,6 @@
#include "code\_hooks\area.dm" #include "code\_hooks\area.dm"
#include "code\_hooks\hooks.dm" #include "code\_hooks\hooks.dm"
#include "code\_hooks\mob.dm" #include "code\_hooks\mob.dm"
#include "code\_onclick\adjacent.dm"
#include "code\_onclick\ai.dm"
#include "code\_onclick\click.dm"
#include "code\_onclick\cyborg.dm"
#include "code\_onclick\drag_drop.dm"
#include "code\_onclick\item_attack.dm"
#include "code\_onclick\observer.dm"
#include "code\_onclick\other_mobs.dm"
#include "code\_onclick\overmind.dm"
#include "code\_onclick\telekinesis.dm"
#include "code\_onclick\hud\_defines.dm"
#include "code\_onclick\hud\alien.dm"
#include "code\_onclick\hud\alien_larva.dm"
#include "code\_onclick\hud\hud.dm"
#include "code\_onclick\hud\human.dm"
#include "code\_onclick\hud\monkey.dm"
#include "code\_onclick\hud\other_mobs.dm"
#include "code\_onclick\hud\robot.dm"
#include "code\_onclick\hud\screen_objects.dm"
#include "code\ATMOSPHERICS\atmospherics.dm" #include "code\ATMOSPHERICS\atmospherics.dm"
#include "code\ATMOSPHERICS\chiller.dm" #include "code\ATMOSPHERICS\chiller.dm"
#include "code\ATMOSPHERICS\datum_pipe_network.dm" #include "code\ATMOSPHERICS\datum_pipe_network.dm"
@@ -222,12 +204,14 @@
#include "code\game\dna\dna2_helpers.dm" #include "code\game\dna\dna2_helpers.dm"
#include "code\game\dna\dna_modifier.dm" #include "code\game\dna\dna_modifier.dm"
#include "code\game\dna\genes\disabilities.dm" #include "code\game\dna\genes\disabilities.dm"
#include "code\game\dna\genes\eyelasers.dm"
#include "code\game\dna\genes\gene.dm" #include "code\game\dna\genes\gene.dm"
#include "code\game\dna\genes\goon_disabilities.dm" #include "code\game\dna\genes\goon_disabilities.dm"
#include "code\game\dna\genes\goon_powers.dm" #include "code\game\dna\genes\goon_powers.dm"
#include "code\game\dna\genes\monkey.dm" #include "code\game\dna\genes\monkey.dm"
#include "code\game\dna\genes\powers.dm" #include "code\game\dna\genes\powers.dm"
#include "code\game\dna\genes\speech.dm" #include "code\game\dna\genes\speech.dm"
#include "code\game\dna\genes\telekinesis.dm"
#include "code\game\dna\genes\vg_disabilities.dm" #include "code\game\dna\genes\vg_disabilities.dm"
#include "code\game\dna\genes\vg_powers.dm" #include "code\game\dna\genes\vg_powers.dm"
#include "code\game\gamemodes\antag_spawner.dm" #include "code\game\gamemodes\antag_spawner.dm"
@@ -1008,6 +992,7 @@
#include "code\modules\mob\say.dm" #include "code\modules\mob\say.dm"
#include "code\modules\mob\transform_procs.dm" #include "code\modules\mob\transform_procs.dm"
#include "code\modules\mob\update_icons.dm" #include "code\modules\mob\update_icons.dm"
#include "code\modules\mob\camera\blob.dm"
#include "code\modules\mob\camera\camera.dm" #include "code\modules\mob\camera\camera.dm"
#include "code\modules\mob\dead\death.dm" #include "code\modules\mob\dead\death.dm"
#include "code\modules\mob\dead\observer\login.dm" #include "code\modules\mob\dead\observer\login.dm"
@@ -1015,6 +1000,14 @@
#include "code\modules\mob\dead\observer\observer.dm" #include "code\modules\mob\dead\observer\observer.dm"
#include "code\modules\mob\dead\observer\say.dm" #include "code\modules\mob\dead\observer\say.dm"
#include "code\modules\mob\dead\observer\spells.dm" #include "code\modules\mob\dead\observer\spells.dm"
#include "code\modules\mob\hud\alien.dm"
#include "code\modules\mob\hud\alien_larva.dm"
#include "code\modules\mob\hud\hud.dm"
#include "code\modules\mob\hud\human.dm"
#include "code\modules\mob\hud\monkey.dm"
#include "code\modules\mob\hud\other_mobs.dm"
#include "code\modules\mob\hud\robot.dm"
#include "code\modules\mob\hud\screen_objects.dm"
#include "code\modules\mob\living\damage_procs.dm" #include "code\modules\mob\living\damage_procs.dm"
#include "code\modules\mob\living\living.dm" #include "code\modules\mob\living\living.dm"
#include "code\modules\mob\living\living_defense.dm" #include "code\modules\mob\living\living_defense.dm"

View File

@@ -0,0 +1,35 @@
//**************************************************************
//
// Adjacency Checks
// --------------------
// This can be optimized more, at the cost of clarity.
//
//**************************************************************
// Adjacency ///////////////////////////////////////////////////
/atom/proc/Adjacent(atom/A)
if((!src.loc) || (!A.loc)) return 0 //If we're at null, no good.
if(get_turf(src) == get_turf(A)) return 1 //If we're on the same tile, it's good.
if(get_dist(src,A) > 1) return 0 //If we're more than 1 tile apart, not good.
if(src.x == A.x || src.y == A.y) //If we're orthogonal, it's simple
if(src.canPassTo(A)) return 1 //If we can reach straight to A, we're good
else //We're diagonal, so we need to check if we can reach around to it
. = get_dir(src,A) //Our diagonal direction //eg south-west
var/dA = . & (. - 1) //One of our cardinal directions //eg south
var/dB = (. - dA) //Our other cardinal direction //eg west
if(!src.canPassTo(get_step(src,dA)) && src.canPassTo(get_step(dA,dB)))
return 1 //If we can use dA then dB, we're good //eg south then west
else if(src.canPassTo(get_step(src,dB)) && src.canPassTo(get_step(dB,dA)))
return 1 //If we can use dB then dA, we're good //eg west then south
return
/atom/proc/canPassTo(atom/A)
for(var/obj/O in get_turf(A)) //We need to check if anything can block us
if((!O.density) || (O == A) || O.throwpass) continue //These things are fine
if(O.flags & ON_BORDER) //If it's only on the border, we need to check its dir
if(O.dir & get_dir(A,src)) return 0 //If it's facing toward us, it blocks us
if(O.dir & (O.dir-1)) return 0 //If it's a full-tile window, it blocks us
. = 1 //If nothing went wrong, we're good to go.
return

View File

@@ -1,137 +0,0 @@
/*
Adjacency proc for determining touch range
This is mostly to determine if a user can enter a square for the purposes of touching something.
Examples include reaching a square diagonally or reaching something on the other side of a glass window.
This is calculated by looking for border items, or in the case of clicking diagonally from yourself, dense items.
This proc will NOT notice if you are trying to attack a window on the other side of a dense object in its turf. There is a window helper for that.
Note that in all cases the neighbor is handled simply; this is usually the user's mob, in which case it is up to you
to check that the mob is not inside of something
*/
/atom/proc/Adjacent(var/atom/neighbor) // basic inheritance, unused
return 0
// Not a sane use of the function and (for now) indicative of an error elsewhere
/area/Adjacent(var/atom/neighbor)
CRASH("Call to /area/Adjacent(), unimplemented proc")
/*
Adjacency (to turf):
* If you are in the same turf, always true
* If you are vertically/horizontally adjacent, ensure there are no border objects
* If you are diagonally adjacent, ensure you can pass through at least one of the mutually adjacent square.
* Passing through in this case ignores anything with the throwpass flag, such as tables, racks, and morgue trays.
*/
/turf/Adjacent(var/atom/neighbor, var/atom/target = null)
var/turf/T0 = get_turf(neighbor)
if(T0 == src)
return 1
if(get_dist(src,T0) > 1)
return 0
if(T0.x == x || T0.y == y)
// Check for border blockages
return T0.ClickCross(get_dir(T0,src), border_only = 1) && src.ClickCross(get_dir(src,T0), border_only = 1, target_atom = target)
// Not orthagonal
var/in_dir = get_dir(neighbor,src) // eg. northwest (1+8)
var/d1 = in_dir&(in_dir-1) // eg west (1+8)&(8) = 8
var/d2 = in_dir - d1 // eg north (1+8) - 8 = 1
for(var/d in list(d1,d2))
if(!T0.ClickCross(d, border_only = 1))
continue // could not leave T0 in that direction
var/turf/T1 = get_step(T0,d)
if(!T1 || T1.density || !T1.ClickCross(get_dir(T1,T0) | get_dir(T1,src), border_only = 0))
continue // couldn't enter or couldn't leave T1
if(!src.ClickCross(get_dir(src,T1), border_only = 1, target_atom = target))
continue // could not enter src
return 1 // we don't care about our own density
return 0
/*
Adjacency (to anything else):
* Must be on a turf
* In the case of a multiple-tile object, all valid locations are checked for adjacency.
Note: Multiple-tile objects are created when the bound_width and bound_height are creater than the tile size.
This is not used in stock /tg/station currently.
*/
/atom/movable/Adjacent(var/atom/neighbor)
if(neighbor == loc) return 1
if(!isturf(loc)) return 0
for(var/turf/T in locs)
if(isnull(T)) continue
if(T.Adjacent(neighbor,src)) return 1
return 0
// This is necessary for storage items not on your person.
/obj/item/Adjacent(var/atom/neighbor, var/recurse = 1)
if(neighbor == loc) return 1
if(istype(loc,/obj/item))
if(recurse > 0)
return loc.Adjacent(neighbor,recurse - 1)
return 0
return ..()
/*
Special case: This allows you to reach a door when it is visally on top of,
but technically behind, a fire door
You could try to rewrite this to be faster, but I'm not sure anything would be.
This can be safely removed if border firedoors are ever moved to be on top of doors
so they can be interacted with without opening the door.
*/
/obj/machinery/door/Adjacent(var/atom/neighbor)
var/obj/machinery/door/firedoor/border_only/BOD = locate() in loc
if(BOD)
BOD.throwpass = 1 // allow click to pass
. = ..()
BOD.throwpass = 0
return .
return ..()
/*
This checks if you there is uninterrupted airspace between that turf and this one.
This is defined as any dense ON_BORDER object, or any dense object without throwpass.
The border_only flag allows you to not objects (for source and destination squares)
*/
/turf/proc/ClickCross(var/target_dir, var/border_only, var/atom/target_atom = null)
for(var/obj/O in src)
if( !O.density || O == target_atom || O.throwpass) continue // throwpass is used for anything you can click through
if( O.flags&ON_BORDER) // windows have throwpass but are on border, check them first
if( O.dir & target_dir || O.dir&(O.dir-1) ) // full tile windows are just diagonals mechanically
return 0
else if( !border_only ) // dense, not on border, cannot pass over
return 0
return 1
/*
Aside: throwpass does not do what I thought it did originally, and is only used for checking whether or not
a thrown object should stop after already successfully entering a square. Currently the throw code involved
only seems to affect hitting mobs, because the checks performed against objects are already performed when
entering or leaving the square. Since throwpass isn't used on mobs, but only on objects, it is effectively
useless. Throwpass may later need to be removed and replaced with a passcheck (bitfield on movable atom passflags).
Since I don't want to complicate the click code rework by messing with unrelated systems it won't be changed here.
*/
/**
/vg/: Hack for full windows on top of panes.
**/
/obj/structure/window/full/Adjacent(var/atom/neighbor)
for(var/obj/structure/window/W in loc)
if(W)
W.throwpass=1
.=..()
for(var/obj/structure/window/W in loc)
if(W)
W.throwpass=0
return .

View File

@@ -1,136 +0,0 @@
/*
AI ClickOn()
Note currently ai restrained() returns 0 in all cases,
therefore restrained code has been removed
The AI can double click to move the camera (this was already true but is cleaner),
or double click a mob to track them.
Note that AI have no need for the adjacency proc, and so this proc is a lot cleaner.
*/
/mob/living/silicon/ai/DblClickOn(var/atom/A, params)
if(client.buildmode) // comes after object.Click to allow buildmode gui objects to be clicked
build_click(src, client.buildmode, params, A)
return
if(control_disabled || stat) return
//next_move = world.time + 9
if(ismob(A))
ai_actual_track(A)
else
A.move_camera_by_click()
/mob/living/silicon/ai/ClickOn(var/atom/A, params)
if(world.time <= next_click)
return
next_click = world.time + 1
if(client.buildmode) // comes after object.Click to allow buildmode gui objects to be clicked
build_click(src, client.buildmode, params, A)
return
if(control_disabled || stat)
return
var/list/modifiers = params2list(params)
if(modifiers["middle"])
MiddleClickOn(A)
return
if(modifiers["shift"])
ShiftClickOn(A)
return
if(modifiers["alt"]) // alt and alt-gr (rightalt)
AltClickOn(A)
return
if(modifiers["ctrl"])
CtrlClickOn(A)
return
if(world.time <= next_move)
return
//next_move = world.time + 9
if(aicamera.in_camera_mode)
aicamera.camera_mode_off()
aicamera.captureimage(A, usr)
return
/*
AI restrained() currently does nothing
if(restrained())
RestrainedClickOn(A)
else
*/
A.add_hiddenprint(src)
A.attack_ai(src)
/*
AI has no need for the UnarmedAttack() and RangedAttack() procs,
because the AI code is not generic; attack_ai() is used instead.
The below is only really for safety, or you can alter the way
it functions and re-insert it above.
*/
/mob/living/silicon/ai/UnarmedAttack(atom/A)
A.attack_ai(src)
/mob/living/silicon/ai/RangedAttack(atom/A)
A.attack_ai(src)
/atom/proc/attack_ai(mob/user as mob)
return
/*
Since the AI handles shift, ctrl, and alt-click differently
than anything else in the game, atoms have separate procs
for AI shift, ctrl, and alt clicking.
*/
/mob/living/silicon/ai/ShiftClickOn(var/atom/A)
A.AIShiftClick(src)
/mob/living/silicon/ai/CtrlClickOn(var/atom/A)
A.AICtrlClick(src)
/mob/living/silicon/ai/AltClickOn(var/atom/A)
A.AIAltClick(src)
/*
The following criminally helpful code is just the previous code cleaned up;
I have no idea why it was in atoms.dm instead of respective files.
*/
/atom/proc/AIShiftClick()
return
/obj/machinery/door/airlock/AIShiftClick() // Opens and closes doors!
if(density)
Topic("aiEnable=7", list("aiEnable"="7"), 1) // 1 meaning no window (consistency!)
else
Topic("aiDisable=7", list("aiDisable"="7"), 1)
return
/atom/proc/AICtrlClick()
return
/obj/machinery/door/airlock/AICtrlClick() // Bolts doors
if(locked)
Topic("aiEnable=4", list("aiEnable"="4"), 1)// 1 meaning no window (consistency!)
else
Topic("aiDisable=4", list("aiDisable"="4"), 1)
/obj/machinery/power/apc/AICtrlClick() // turns off APCs.
Topic("breaker=1", list("breaker"="1"), 0) // 0 meaning no window (consistency! wait...)
/atom/proc/AIAltClick(var/mob/living/silicon/ai/user)
AltClick(user)
return
/obj/machinery/door/airlock/AIAltClick() // Eletrifies doors.
if(!secondsElectrified)
// permenant shock
Topic("aiEnable=6", list("aiEnable"="6"), 1) // 1 meaning no window (consistency!)
else
// disable/6 is not in Topic; disable/5 disables both temporary and permenant shock
Topic("aiDisable=5", list("aiDisable"="5"), 1)
return

View File

@@ -1,393 +0,0 @@
/*
Click code cleanup
~Sayu
*/
// 1 decisecond click delay (above and beyond mob/next_move)
/mob/var/next_click = 0
/*
Before anything else, defer these calls to a per-mobtype handler. This allows us to
remove istype() spaghetti code, but requires the addition of other handler procs to simplify it.
Alternately, you could hardcode every mob's variation in a flat ClickOn() proc; however,
that's a lot of code duplication and is hard to maintain.
Note that this proc can be overridden, and is in the case of screen objects.
*/
/atom/Click(location,control,params)
usr.ClickOn(src, params)
/atom/DblClick(location,control,params)
usr.DblClickOn(src,params)
/*
Standard mob ClickOn()
Handles exceptions: Buildmode, middle click, modified clicks, mech actions
After that, mostly just check your state, check whether you're holding an item,
check whether you're adjacent to the target, then pass off the click to whoever
is recieving it.
The most common are:
* mob/UnarmedAttack(atom,adjacent) - used here only when adjacent, with no item in hand; in the case of humans, checks gloves
* atom/attackby(item,user) - used only when adjacent
* item/afterattack(atom,user,adjacent,params) - used both ranged and adjacent
* mob/RangedAttack(atom,params) - used only ranged, only used for tk and laser eyes but could be changed
*/
/mob/proc/ClickOn( var/atom/A, var/params )
if(world.time <= next_click)
return
next_click = world.time + 1
if(client.buildmode)
build_click(src, client.buildmode, params, A)
return
var/list/modifiers = params2list(params)
if(modifiers["middle"])
MiddleClickOn(A)
return
if(modifiers["shift"])
ShiftClickOn(A)
return
if(modifiers["alt"]) // alt and alt-gr (rightalt)
AltClickOn(A)
return
if(modifiers["ctrl"])
CtrlClickOn(A)
return
if(stat || paralysis || stunned || weakened)
return
face_atom(A) // change direction to face what you clicked on
if(next_move > world.time) // in the year 2000...
return
//world << "next_move is [next_move] and world.time is [world.time]"
if(istype(loc,/obj/mecha))
if(!locate(/turf) in list(A,A.loc)) // Prevents inventory from being drilled
return
var/obj/mecha/M = loc
return M.click_action(A,src)
if(restrained())
RestrainedClickOn(A)
return
if(in_throw_mode)
throw_item(A)
return
var/obj/item/W = get_active_hand()
if(W == A)
/*next_move = world.time + 6
if(W.flags&USEDELAY)
next_move += 5*/
W.attack_self(src)
if(hand)
update_inv_l_hand(0)
else
update_inv_r_hand(0)
return
// operate two levels deep here (item in backpack in src; NOT item in box in backpack in src)
if(A == loc || (A in loc) || (A in contents) || (A.loc in contents))
/*/ faster access to objects already on you
if(A in contents)
next_move = world.time + 6 // on your person
else
next_move = world.time + 8 // in a box/bag or in your square
*/
// No adjacency needed
if(W)
/*
if(W.flags&USEDELAY)
next_move += 5
*/
var/resolved = A.attackby(W,src)
if(ismob(A) || istype(A, /obj/mecha) || isturf(A) || istype(W, /obj/item/weapon/grab))
changeNext_move(10)
if(!resolved && A && W)
W.afterattack(A,src,1,params) // 1 indicates adjacency
else
changeNext_move(10)
else
if(ismob(A) || istype(W, /obj/item/weapon/grab))
changeNext_move(10)
UnarmedAttack(A)
return
if(!isturf(loc)) // This is going to stop you from telekinesing from inside a closet, but I don't shed many tears for that
return
// Allows you to click on a box's contents, if that box is on the ground, but no deeper than that
if(isturf(A) || isturf(A.loc) || (A.loc && isturf(A.loc.loc)))
//next_move = world.time + 10
if(A.Adjacent(src)) // see adjacent.dm
if(W)
/*if(W.flags&USEDELAY)
next_move += 5
*/
// Return 1 in attackby() to prevent afterattack() effects (when safely moving items for example)
if(ismob(A) || istype(A, /obj/mecha) || isturf(A) || istype(W, /obj/item/weapon/grab))
changeNext_move(10)
var/resolved = A.attackby(W,src)
if(!resolved && A && W)
W.afterattack(A,src,1,params) // 1: clicking something Adjacent
else
changeNext_move(10)
else
if(ismob(A) || istype(W, /obj/item/weapon/grab))
changeNext_move(10)
UnarmedAttack(A, 1)
return
else // non-adjacent click
if(W)
if(ismob(A))
changeNext_move(10)
W.afterattack(A,src,0,params) // 0: not Adjacent
else
if(ismob(A))
changeNext_move(10)
RangedAttack(A, params)
return
/mob/proc/changeNext_move(num)
next_move = world.time + num
// Default behavior: ignore double clicks, consider them normal clicks instead
/mob/proc/DblClickOn(var/atom/A, var/params)
//ClickOn(A,params)
return
/*
Translates into attack_hand, etc.
Note: proximity_flag here is used to distinguish between normal usage (flag=1),
and usage when clicking on things telekinetically (flag=0). This proc will
not be called at ranged except with telekinesis.
proximity_flag is not currently passed to attack_hand, and is instead used
in human click code to allow glove touches only at melee range.
*/
/mob/proc/UnarmedAttack(var/atom/A, var/proximity_flag)
if(ismob(A))
changeNext_move(10)
return
/*
Ranged unarmed attack:
This currently is just a default for all mobs, involving
laser eyes and telekinesis. You could easily add exceptions
for things like ranged glove touches, spitting alien acid/neurotoxin,
animals lunging, etc.
*/
/mob/proc/RangedAttack(var/atom/A, var/params)
if(!mutations.len) return
if((M_LASER in mutations) && a_intent == "hurt")
LaserEyes(A) // moved into a proc below
else if(M_TK in mutations)
/*switch(get_dist(src,A))
if(0)
;
if(1 to 5) // not adjacent may mean blocked by window
next_move += 2
if(5 to 7)
next_move += 5
if(8 to tk_maxrange)
next_move += 10
else
return
*/
A.attack_tk(src)
/*
Restrained ClickOn
Used when you are handcuffed and click things.
Not currently used by anything but could easily be.
*/
/mob/proc/RestrainedClickOn(var/atom/A)
return
/*
Middle click
Only used for swapping hands
*/
/mob/proc/MiddleClickOn(var/atom/A)
return
/mob/living/carbon/MiddleClickOn(var/atom/A)
swap_hand()
// In case of use break glass
/*
/atom/proc/MiddleClick(var/mob/M as mob)
return
*/
/*
Shift click
For most mobs, examine.
This is overridden in ai.dm
*/
/mob/proc/ShiftClickOn(var/atom/A)
A.ShiftClick(src)
return
/atom/proc/ShiftClick(var/mob/user)
if(user.client && user.client.eye == user)
examine()
user.face_atom(src)
return
/*
Ctrl click
For most objects, pull
*/
/mob/proc/CtrlClickOn(var/atom/A)
A.CtrlClick(src)
return
/atom/proc/CtrlClick(var/mob/user)
return
/atom/movable/CtrlClick(var/mob/user)
if(Adjacent(user))
user.start_pulling(src)
/*
Alt click
Unused except for AI
*/
/mob/proc/AltClickOn(var/atom/A)
A.AltClick(src)
return
/atom/proc/AltClick(var/mob/user)
var/turf/T = get_turf(src)
if(T && T.Adjacent(user))
if(user.listed_turf == T)
user.listed_turf = null
else
user.listed_turf = T
user.client.statpanel = T.name
return
/*
Misc helpers
Laser Eyes: as the name implies, handles this since nothing else does currently
face_atom: turns the mob towards what you clicked on
*/
/mob/proc/LaserEyes(atom/A)
return
/mob/living/LaserEyes(atom/A)
//next_move = world.time + 6
changeNext_move(4)
var/turf/T = get_turf(src)
var/turf/U = get_turf(A)
var/obj/item/projectile/beam/LE = getFromPool(/obj/item/projectile/beam, loc)
LE.icon = 'icons/effects/genetics.dmi'
LE.icon_state = "eyelasers"
playsound(usr.loc, 'sound/weapons/taser2.ogg', 75, 1)
LE.firer = src
LE.def_zone = get_organ_target()
LE.original = A
LE.current = T
LE.yo = U.y - T.y
LE.xo = U.x - T.x
spawn( 1 )
LE.process()
/mob/living/carbon/human/LaserEyes()
if(nutrition>0)
..()
nutrition = max(nutrition - rand(1,5),0)
handle_regular_hud_updates()
else
src << "\red You're out of energy! You need food!"
/mob/proc/PowerGlove(atom/A)
return
/mob/living/carbon/human/PowerGlove(atom/A)
var/obj/item/clothing/gloves/yellow/power/G = src:gloves
var/time = 100
var/turf/T = get_turf(src)
var/turf/U = get_turf(A)
var/obj/structure/cable/cable = locate() in T
if(!cable || !istype(cable))
return
if(world.time < G.next_shock)
src << "<span class='warning'>[G] aren't ready to shock again!</span>"
return
src.visible_message("<span class='warning'>[name] fires an arc of electricity!</span>", \
"<span class='warning'>You fire an arc of electricity!</span>", \
"You hear the loud crackle of electricity!")
var/datum/powernet/PN = cable.get_powernet()
var/available = 0
var/obj/item/projectile/beam/lightning/L = getFromPool(/obj/item/projectile/beam/lightning, loc)
if(PN)
available = PN.avail
L.damage = PN.get_electrocute_damage()
if(available >= 5000000)
L.damage = 205
if(L.damage >= 200)
apply_damage(15, BURN, (hand ? "l_hand" : "r_hand"))
//usr:Stun(15)
//usr:Weaken(15)
//if(usr:status_flags & CANSTUN) // stun is usually associated with stutter
// usr:stuttering += 20
time = 200
src << "<span class='warning'>[G] overload from the massive current shocking you in the process!"
else if(L.damage >= 100)
apply_damage(5, BURN, (hand ? "l_hand" : "r_hand"))
//usr:Stun(10)
//usr:Weaken(10)
//if(usr:status_flags & CANSTUN) // stun is usually associated with stutter
// usr:stuttering += 10
time = 150
src << "<span class='warning'>[G] overload from the massive current shocking you in the process!"
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
if(L.damage <= 0)
returnToPool(L)
//del(L)
if(L)
playsound(get_turf(src), 'sound/effects/eleczap.ogg', 75, 1)
L.tang = L.adjustAngle(get_angle(U,T))
L.icon = midicon
L.icon_state = "[L.tang]"
L.firer = usr
L.def_zone = get_organ_target()
L.original = src
L.current = U
L.starting = U
L.yo = U.y - T.y
L.xo = U.x - T.x
spawn( 1 )
L.process()
next_move = world.time + 12
G.next_shock = world.time + time
// Simple helper to face what you clicked on, in case it should be needed in more than one place
/mob/proc/face_atom(var/atom/A)
if( stat || buckled || !A || !x || !y || !A.x || !A.y ) return
var/dx = A.x - x
var/dy = A.y - y
if(!dx && !dy) return
if(abs(dx) < abs(dy))
if(dy > 0) usr.dir = NORTH
else usr.dir = SOUTH
else
if(dx > 0) usr.dir = EAST
else usr.dir = WEST

View File

@@ -1,162 +0,0 @@
/*
Cyborg ClickOn()
Cyborgs have no range restriction on attack_robot(), because it is basically an AI click.
However, they do have a range restriction on item use, so they cannot do without the
adjacency code.
*/
/mob/living/silicon/robot/ClickOn(var/atom/A, var/params)
if(world.time <= next_click)
return
next_click = world.time + 1
if(client.buildmode) // comes after object.Click to allow buildmode gui objects to be clicked
build_click(src, client.buildmode, params, A)
return
if(stat || lockcharge || weakened || stunned || paralysis)
return
var/list/modifiers = params2list(params)
if(modifiers["middle"])
MiddleClickOn(A)
return
if(modifiers["shift"])
ShiftClickOn(A)
return
if(modifiers["alt"]) // alt and alt-gr (rightalt)
AltClickOn(A)
return
if(modifiers["ctrl"])
CtrlClickOn(A)
return
if(next_move >= world.time)
return
face_atom(A) // change direction to face what you clicked on
/*
cyborg restrained() currently does nothing
if(restrained())
RestrainedClickOn(A)
return
*/
var/obj/item/W = get_active_hand()
// Cyborgs have no range-checking unless there is item use
if(!W)
A.add_hiddenprint(src)
A.attack_robot(src)
return
// buckled cannot prevent machine interlinking but stops arm movement
if( buckled )
return
if(W == A)
/*next_move = world.time + 8
if(W.flags&USEDELAY)
next_move += 5
*/
W.attack_self(src)
return
// cyborgs are prohibited from using storage items so we can I think safely remove (A.loc in contents)
if(A == loc || (A in loc) || (A in contents))
// No adjacency checks
next_move = world.time + 8
/*if(W.flags&USEDELAY)
next_move += 5
*/
var/resolved = A.attackby(W,src)
if(!resolved && A && W)
W.afterattack(A,src,1,params)
return
if(!isturf(loc))
return
// cyborgs are prohibited from using storage items so we can I think safely remove (A.loc && isturf(A.loc.loc))
if(isturf(A) || isturf(A.loc))
if(A.Adjacent(src)) // see adjacent.dm
/*next_move = world.time + 10
if(W.flags&USEDELAY)
next_move += 5
*/
var/resolved = A.attackby(W, src)
if(!resolved && A && W)
W.afterattack(A, src, 1, params)
return
else
//next_move = world.time + 10
W.afterattack(A, src, 0, params)
return
return
//Middle click cycles through selected modules.
/mob/living/silicon/robot/MiddleClickOn(var/atom/A)
cycle_modules()
return
//Middle click cycles through selected modules.
/mob/living/silicon/robot/AltClickOn(var/atom/A)
//Borgs dont need a quick shock hotkey, just in case
/*
if(istype(A, /obj/machinery/door/airlock))
A.AIAltClick(src)
return
*/
if(isturf(A))
A.AltClick(src)
return
A.RobotAltClick(src)
return
/mob/living/silicon/robot/ShiftClickOn(var/atom/A)
//Borgs can into doors as well
if(istype(A, /obj/machinery/door/airlock))
A.AIShiftClick(src)
return
..()
/mob/living/silicon/robot/CtrlClickOn(var/atom/A)
//Borgs can into doors as well
if(istype(A, /obj/machinery/door/airlock))
A.AICtrlClick(src)
return
..()
/*
As with AI, these are not used in click code,
because the code for robots is specific, not generic.
If you would like to add advanced features to robot
clicks, you can do so here, but you will have to
change attack_robot() above to the proper function
*/
/mob/living/silicon/robot/UnarmedAttack(atom/A)
A.attack_robot(src)
/mob/living/silicon/robot/RangedAttack(atom/A)
A.attack_robot(src)
/atom/proc/attack_robot(mob/user as mob)
attack_ai(user)
return
// /vg/: Alt-click.
/atom/proc/RobotAltClick()
return
// /vg/: Alt-click to open shit
/* not anymore
/obj/machinery/door/airlock/RobotAltClick() // Opens doors
if(density)
Topic("aiEnable=7", list("aiEnable"="7"), 1) // 1 meaning no window (consistency!)
else
Topic("aiDisable=7", list("aiDisable"="7"), 1)*/

View File

@@ -1,18 +0,0 @@
/*
MouseDrop:
Called on the atom you're dragging. In a lot of circumstances we want to use the
recieving object instead, so that's the default action. This allows you to drag
almost anything into a trash can.
*/
/atom/MouseDrop(atom/over)
if(!usr || !over) return
if(!Adjacent(usr) || !over.Adjacent(usr)) return // should stop you from dragging through windows
spawn(0)
over.MouseDrop_T(src,usr)
return
// recieve a mousedrop
/atom/proc/MouseDrop_T(atom/dropping, mob/user)
return

View File

@@ -1,121 +0,0 @@
/*
These defines specificy screen locations. For more information, see the byond documentation on the screen_loc var.
The short version:
Everything is encoded as strings because apparently that's how Byond rolls.
"1,1" is the bottom left square of the user's screen. This aligns perfectly with the turf grid.
"1:2,3:4" is the square (1,3) with pixel offsets (+2, +4); slightly right and slightly above the turf grid.
Pixel offsets are used so you don't perfectly hide the turf under them, that would be crappy.
The size of the user's screen is defined by client.view (indirectly by world.view), in our case "15x15".
Therefore, the top right corner (except during admin shenanigans) is at "15,15"
*/
//Upper left action buttons, displayed when you pick up an item that has this enabled.
#define ui_action_slot1 "1:6,14:26"
#define ui_action_slot2 "2:8,14:26"
#define ui_action_slot3 "3:10,14:26"
#define ui_action_slot4 "4:12,14:26"
#define ui_action_slot5 "5:14,14:26"
//Lower left, persistant menu
#define ui_inventory "1:6,1:5"
//Lower center, persistant menu
#define ui_sstore1 "3:10,1:5"
#define ui_id "4:12,1:5"
#define ui_belt "5:14,1:5"
#define ui_back "6:14,1:5"
#define ui_rhand "7:16,1:5"
#define ui_lhand "8:16,1:5"
#define ui_equip "7:16,2:5"
#define ui_swaphand1 "7:16,2:5"
#define ui_swaphand2 "8:16,2:5"
#define ui_storage1 "9:18,1:5"
#define ui_storage2 "10:20,1:5"
#define ui_alien_head "4:12,1:5" //aliens
#define ui_alien_oclothing "5:14,1:5" //aliens
#define ui_inv1 "6:16,1:5" //borgs
#define ui_inv2 "7:16,1:5" //borgs
#define ui_inv3 "8:16,1:5" //borgs
#define ui_borg_store "9:16,1:5" //borgs
#define ui_monkey_mask "5:14,1:5" //monkey
#define ui_monkey_back "6:14,1:5" //monkey
//Lower right, persistant menu
#define ui_dropbutton "11:22,1:5"
#define ui_drop_throw "14:28,2:7"
#define ui_pull_resist "13:26,2:7"
#define ui_acti "13:26,1:5"
#define ui_movi "12:24,1:5"
#define ui_zonesel "14:28,1:5"
#define ui_acti_alt "14:28,1:5" //alternative intent switcher for when the interface is hidden (F12)
#define ui_borg_pull "12:24,2:7"
#define ui_borg_module "13:26,2:7"
#define ui_borg_panel "14:28,2:7"
//Gun buttons
#define ui_gun1 "13:26,3:7"
#define ui_gun2 "14:28, 4:7"
#define ui_gun3 "13:26,4:7"
#define ui_gun_select "14:28,3:7"
//Upper-middle right (damage indicators)
#define ui_toxin "14:28,13:27"
#define ui_fire "14:28,12:25"
#define ui_oxygen "14:28,11:23"
#define ui_pressure "14:28,10:21"
#define ui_alien_toxin "14:28,13:25"
#define ui_alien_fire "14:28,12:25"
#define ui_alien_oxygen "14:28,11:25"
//Middle right (status indicators)
#define ui_nutrition "14:28,5:11"
#define ui_temp "14:28,6:13"
#define ui_health "14:28,7:15"
#define ui_internal "14:28,8:17"
//borgs
#define ui_borg_health "14:28,6:13" //borgs have the health display where humans have the pressure damage indicator.
#define ui_alien_health "14:28,6:13" //aliens have the health display where humans have the pressure damage indicator.
#define ui_construct_health "15:00,7:15" //same height as humans, hugging the right border
#define ui_construct_fire "14:16,8:13" //above health, slightly to the left
#define ui_construct_pull "14:28,2:10" //above the zone_sel icon
//Pop-up inventory
#define ui_shoes "2:8,1:5"
#define ui_iclothing "1:6,2:7"
#define ui_oclothing "2:8,2:7"
#define ui_gloves "3:10,2:7"
#define ui_glasses "1:6,3:9"
#define ui_mask "2:8,3:9"
#define ui_ears "3:10,3:9"
#define ui_head "2:8,4:11"
//Intent small buttons
#define ui_help_small "12:8,1:1"
#define ui_disarm_small "12:15,1:18"
#define ui_grab_small "12:32,1:18"
#define ui_harm_small "12:39,1:1"
//#define ui_swapbutton "6:-16,1:5" //Unused
//#define ui_headset "SOUTH,8"
#define ui_hand "6:14,1:5"
#define ui_hstore1 "5,5"
//#define ui_resist "EAST+1,SOUTH-1"
#define ui_sleep "EAST+1, NORTH-13"
#define ui_rest "EAST+1, NORTH-14"
#define ui_iarrowleft "SOUTH-1,11"
#define ui_iarrowright "SOUTH-1,13"

View File

@@ -1,177 +0,0 @@
// Called when the item is in the active hand, and clicked; alternately, there is an 'activate held object' verb or you can hit pagedown.
/obj/item/proc/attack_self(mob/user)
return
// No comment
/atom/proc/attackby(obj/item/W, mob/user)
return
/atom/movable/attackby(obj/item/W, mob/user)
if(W && !(W.flags&NOBLUDGEON))
visible_message("<span class='danger'>[src] has been hit by [user] with [W].</span>")
/mob/living/attackby(obj/item/I, mob/user)
user.changeNext_move(10)
if(istype(I) && ismob(user))
I.attack(src, user)
// Proximity_flag is 1 if this afterattack was called on something adjacent, in your square, or on your person.
// Click parameters is the params string from byond Click() code, see that documentation.
/obj/item/proc/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
return
// Overrides the weapon attack so it can attack any atoms like when we want to have an effect on an object independent of attackby
// It is a powerfull proc but it should be used wisely, if there is other alternatives instead use those
// If it returns 1 it exits click code. Always . = 1 at start of the function if you delete src.
/obj/item/proc/preattack(atom/target, mob/user, proximity_flag, click_parameters)
return
obj/item/proc/get_clamped_volume()
if(src.force && src.w_class)
return Clamp((src.force + src.w_class) * 4, 30, 100)// Add the item's force to its weight class and multiply by 4, then clamp the value between 30 and 100
else if(!src.force && src.w_class)
return Clamp(src.w_class * 6, 10, 100) // Multiply the item's weight class by 6, then clamp the value between 10 and 100
/obj/item/proc/attack(mob/living/M as mob, mob/living/user as mob, def_zone)
if (!istype(M)) // not sure if this is the right thing...
return
//var/messagesource = M
if (can_operate(M)) //Checks if mob is lying down on table for surgery
if (do_surgery(M,user,src))
return
//if (istype(M,/mob/living/carbon/brain))
// messagesource = M:container
if (hitsound)
playsound(loc, hitsound, 50, 1, -1)
/////////////////////////
user.lastattacked = M
M.lastattacker = user
add_logs(user, M, "attacked", object=src.name, addition="(INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])")
//spawn(1800) // this wont work right
// M.lastattacker = null
/////////////////////////
var/power = force
if(M_HULK in user.mutations)
power *= 2
if(!istype(M, /mob/living/carbon/human))
if(istype(M, /mob/living/carbon/slime))
var/mob/living/carbon/slime/slime = M
if(prob(25))
user << "\red [src] passes right through [M]!"
return
if(power > 0)
slime.attacked += 10
if(slime.Discipline && prob(50)) // wow, buddy, why am I getting attacked??
slime.Discipline = 0
if(power >= 3)
if(istype(slime, /mob/living/carbon/slime/adult))
if(prob(5 + round(power/2)))
if(slime.Victim)
if(prob(80) && !slime.client)
slime.Discipline++
slime.Victim = null
slime.anchored = 0
spawn()
if(slime)
slime.SStun = 1
sleep(rand(5,20))
if(slime)
slime.SStun = 0
spawn(0)
if(slime)
slime.canmove = 0
step_away(slime, user)
if(prob(25 + power))
sleep(2)
if(slime && user)
step_away(slime, user)
slime.canmove = 1
else
if(prob(10 + power*2))
if(slime)
if(slime.Victim)
if(prob(80) && !slime.client)
slime.Discipline++
if(slime.Discipline == 1)
slime.attacked = 0
spawn()
if(slime)
slime.SStun = 1
sleep(rand(5,20))
if(slime)
slime.SStun = 0
slime.Victim = null
slime.anchored = 0
spawn(0)
if(slime && user)
step_away(slime, user)
slime.canmove = 0
if(prob(25 + power*4))
sleep(2)
if(slime && user)
step_away(slime, user)
slime.canmove = 1
var/showname = "."
if(user)
showname = " by [user]!"
if(!(user in viewers(M, null)))
showname = "."
if(attack_verb && attack_verb.len)
M.visible_message("<span class='danger'>[M] has been [pick(attack_verb)] with [src][showname]</span>",
"<span class='userdanger'>[M] has been [pick(attack_verb)] with [src][showname]!</span>")
else if(force == 0)
M.visible_message("<span class='danger'>[M] has been [pick("tapped","patted")] with [src][showname]</span>",
"<span class='userdanger'>[M] has been [pick("tapped","patted")] with [src][showname]</span>")
else
M.visible_message("<span class='danger'>[M] has been attacked with [src][showname]</span>",
"<span class='userdanger'>[M] has been attacked with [src][showname]</span>")
if(!showname && user)
if(user.client)
user << "\red <B>You attack [M] with [src]. </B>"
if(istype(M, /mob/living/carbon/human))
M:attacked_by(src, user, def_zone)
else
switch(damtype)
if("brute")
if(istype(src, /mob/living/carbon/slime))
M.adjustBrainLoss(power)
else
M.take_organ_damage(power)
if (prob(33) && src.force) // Added blood for whacking non-humans too
var/turf/location = M.loc
if (istype(location, /turf/simulated))
location:add_blood_floor(M)
if("fire")
if (!(M_RESIST_COLD in M.mutations))
M.take_organ_damage(0, power)
M << "Aargh it burns!"
M.updatehealth()
add_fingerprint(user)
return 1

View File

@@ -1,101 +0,0 @@
/mob/dead/observer/DblClickOn(var/atom/A, var/params)
if(client.buildmode)
build_click(src, client.buildmode, params, A)
return
if(can_reenter_corpse && mind && mind.current)
if(A == mind.current || (mind.current in A)) // double click your corpse or whatever holds it
reenter_corpse() // (cloning scanner, body bag, closet, mech, etc)
return // seems legit.
// Things you might plausibly want to follow
if((ismob(A) && A != src) || istype(A,/obj/machinery/bot) || istype(A,/obj/machinery/singularity))
ManualFollow(A)
// Otherwise jump
else
loc = get_turf(A)
/mob/dead/observer/ClickOn(var/atom/A, var/params)
if(client.buildmode)
build_click(src, client.buildmode, params, A)
return
if(world.time <= next_move)
return
//next_move = world.time + 8
var/list/modifiers = params2list(params)
if(modifiers["middle"])
MiddleClickOn(A)
return
if(modifiers["shift"])
ShiftClickOn(A)
return
if(modifiers["alt"])
AltClickOn(A)
return
if(modifiers["ctrl"])
CtrlClickOn(A)
return
// You are responsible for checking config.ghost_interaction when you override this function
// Not all of them require checking, see below
A.attack_ghost(src)
// We don't need a fucking toggle.
/mob/dead/observer/ShiftClickOn(var/atom/A)
A.examine()
/atom/proc/attack_ghost(mob/user as mob)
var/ghost_flags = 0
if(ghost_read)
ghost_flags |= PERMIT_ALL
if(canGhostRead(user,src,ghost_flags))
src.attack_ai(user)
else
src.examine()
/* Bay edition
// Oh by the way this didn't work with old click code which is why clicking shit didn't spam you
/atom/proc/attack_ghost(mob/dead/observer/user as mob)
if(user.client && user.client.inquisitive_ghost)
examine()
return
*/
// ---------------------------------------
// And here are some good things for free:
// Now you can click through portals, wormholes, gateways, and teleporters while observing. -Sayu
/obj/machinery/teleport/hub/attack_ghost(mob/user as mob)
var/atom/l = loc
var/obj/machinery/computer/teleporter/com = locate(/obj/machinery/computer/teleporter, locate(l.x - 2, l.y, l.z))
if(com.locked)
user.loc = get_turf(com.locked)
/obj/effect/portal/attack_ghost(mob/user as mob)
if(target)
user.loc = get_turf(target)
/obj/machinery/gateway/centerstation/attack_ghost(mob/user as mob)
if(awaygate)
user.loc = awaygate.loc
else
user << "[src] has no destination."
/obj/machinery/gateway/centeraway/attack_ghost(mob/user as mob)
if(stationgate)
user.loc = stationgate.loc
else
user << "[src] has no destination."
// -------------------------------------------
// This was supposed to be used by adminghosts
// I think it is a *terrible* idea
// but I'm leaving it here anyway
// commented out, of course.
/*
/atom/proc/attack_admin(mob/user as mob)
if(!user || !user.client || !user.client.holder)
return
attack_hand(user)
*/

View File

@@ -1,376 +0,0 @@
/atom/DblClick(location, control, params) //TODO: DEFERRED: REWRITE
if(!usr) return
// ------- TIME SINCE LAST CLICK -------
if (world.time <= usr:lastDblClick+1)
return
else
usr:lastDblClick = world.time
//Putting it here for now. It diverts stuff to the mech clicking procs. Putting it here stops us drilling items in our inventory Carn
if(istype(usr.loc,/obj/mecha))
if(usr.client && (src in usr.client.screen))
return
var/obj/mecha/Mech = usr.loc
Mech.click_action(src,usr)
return
// ------- DIR CHANGING WHEN CLICKING ------
if( iscarbon(usr) && !usr.buckled )
if( src.x && src.y && usr.x && usr.y )
var/dx = src.x - usr.x
var/dy = src.y - usr.y
if(dy || dx)
if(abs(dx) < abs(dy))
if(dy > 0) usr.dir = NORTH
else usr.dir = SOUTH
else
if(dx > 0) usr.dir = EAST
else usr.dir = WEST
else
if(pixel_y > 16) usr.dir = NORTH
else if(pixel_y < -16) usr.dir = SOUTH
else if(pixel_x > 16) usr.dir = EAST
else if(pixel_x < -16) usr.dir = WEST
// ------- AI -------
else if (istype(usr, /mob/living/silicon/ai))
var/mob/living/silicon/ai/ai = usr
if (ai.control_disabled)
return
// ------- CYBORG -------
else if (istype(usr, /mob/living/silicon/robot))
var/mob/living/silicon/robot/bot = usr
if (bot.lockcharge) return
..()
// ------- SHIFT-CLICK -------
if(params)
var/parameters = params2list(params)
if(parameters["shift"]){
if(!isAI(usr))
ShiftClick(usr)
else
AIShiftClick(usr)
return
}
// ------- ALT-CLICK -------
if(parameters["alt"]){
if(!isAI(usr))
AltClick(usr)
else
AIAltClick(usr)
return
}
// ------- CTRL-CLICK -------
if(parameters["ctrl"]){
if(!isAI(usr))
CtrlClick(usr)
else
AICtrlClick(usr)
return
}
// ------- MIDDLE-CLICK -------
if(parameters["middle"]){
if(!isAI(usr))
MiddleClick(usr)
return
}
// ------- THROW -------
if(usr.in_throw_mode)
return usr:throw_item(src)
// ------- ITEM IN HAND DEFINED -------
var/obj/item/W = usr.get_active_hand()
/* Now handled by get_active_hand()
// ------- ROBOT -------
if(istype(usr, /mob/living/silicon/robot))
if(!isnull(usr:module_active))
W = usr:module_active
else
W = null
*/
// ------- ATTACK SELF -------
if (W == src && usr.stat == 0)
W.attack_self(usr)
if(usr.hand)
usr.update_inv_l_hand(0) //update in-hand overlays
else
usr.update_inv_r_hand(0)
return
// ------- PARALYSIS, STUN, WEAKENED, DEAD, (And not AI) -------
if (((usr.paralysis || usr.stunned || usr.weakened) && !istype(usr, /mob/living/silicon/ai)) || usr.stat != 0)
return
// ------- CLICKING STUFF IN CONTAINERS -------
if ((!( src in usr.contents ) && (((!( isturf(src) ) && (!( isturf(src.loc) ) && (src.loc && !( isturf(src.loc.loc) )))) || !( isturf(usr.loc) )) && (src.loc != usr.loc && (!( istype(src, /obj/screen) ) && !( usr.contents.Find(src.loc) ))))))
if (istype(usr, /mob/living/silicon/ai))
var/mob/living/silicon/ai/ai = usr
if (ai.control_disabled || ai.malfhacking)
return
else
return
// ------- 1 TILE AWAY -------
var/t5
// ------- AI CAN CLICK ANYTHING -------
if(istype(usr, /mob/living/silicon/ai))
t5 = 1
// ------- CYBORG CAN CLICK ANYTHING WHEN NOT HOLDING STUFF -------
else if(istype(usr, /mob/living/silicon/robot) && !W)
t5 = 1
else
t5 = in_range(src, usr) || src.loc == usr
// world << "according to dblclick(), t5 is [t5]"
// ------- ACTUALLY DETERMINING STUFF -------
if (((t5 || (W && (W.flags & USEDELAY))) && !( istype(src, /obj/screen) )))
// ------- ( CAN USE ITEM OR HAS 1 SECOND USE DELAY ) AND NOT CLICKING ON SCREEN -------
if (usr.next_move < world.time)
usr.prev_move = usr.next_move
usr.next_move = world.time + 10
else
// ------- ALREADY USED ONE ITEM WITH USE DELAY IN THE PREVIOUS SECOND -------
return
// ------- DELAY CHECK PASSED -------
if ((src.loc && (get_dist(src, usr) < 2 || src.loc == usr.loc)))
// ------- CLICKED OBJECT EXISTS IN GAME WORLD, DISTANCE FROM PERSON TO OBJECT IS 1 SQUARE OR THEY'RE ON THE SAME SQUARE -------
var/direct = get_dir(usr, src)
var/obj/item/weapon/dummy/D = new /obj/item/weapon/dummy( usr.loc )
var/ok = 0
if ( (direct - 1) & direct)
// ------- CLICKED OBJECT IS LOCATED IN A DIAGONAL POSITION FROM THE PERSON -------
var/turf/Step_1
var/turf/Step_2
switch(direct)
if(5.0)
Step_1 = get_step(usr, NORTH)
Step_2 = get_step(usr, EAST)
if(6.0)
Step_1 = get_step(usr, SOUTH)
Step_2 = get_step(usr, EAST)
if(9.0)
Step_1 = get_step(usr, NORTH)
Step_2 = get_step(usr, WEST)
if(10.0)
Step_1 = get_step(usr, SOUTH)
Step_2 = get_step(usr, WEST)
else
if(Step_1 && Step_2)
// ------- BOTH CARDINAL DIRECTIONS OF THE DIAGONAL EXIST IN THE GAME WORLD -------
var/check_1 = 0
var/check_2 = 0
if(step_to(D, Step_1))
check_1 = 1
for(var/obj/border_obstacle in Step_1)
if(border_obstacle.flags & ON_BORDER)
if(!border_obstacle.CheckExit(D, src))
check_1 = 0
// ------- YOU TRIED TO CLICK ON AN ITEM THROUGH A WINDOW (OR SIMILAR THING THAT LIMITS ON BORDERS) ON ONE OF THE DIRECITON TILES -------
for(var/obj/border_obstacle in get_turf(src))
if((border_obstacle.flags & ON_BORDER) && (src != border_obstacle))
if(!border_obstacle.CanPass(D, D.loc, 1, 0))
// ------- YOU TRIED TO CLICK ON AN ITEM THROUGH A WINDOW (OR SIMILAR THING THAT LIMITS ON BORDERS) ON THE TILE YOU'RE ON -------
check_1 = 0
D.loc = usr.loc
if(step_to(D, Step_2))
check_2 = 1
for(var/obj/border_obstacle in Step_2)
if(border_obstacle.flags & ON_BORDER)
if(!border_obstacle.CheckExit(D, src))
check_2 = 0
for(var/obj/border_obstacle in get_turf(src))
if((border_obstacle.flags & ON_BORDER) && (src != border_obstacle))
if(!border_obstacle.CanPass(D, D.loc, 1, 0))
check_2 = 0
if(check_1 || check_2)
ok = 1
// ------- YOU CAN REACH THE ITEM THROUGH AT LEAST ONE OF THE TWO DIRECTIONS. GOOD. -------
/*
More info:
If you're trying to click an item in the north-east of your mob, the above section of code will first check if tehre's a tile to the north or you and to the east of you
These two tiles are Step_1 and Step_2. After this, a new dummy object is created on your location. It then tries to move to Step_1, If it succeeds, objects on the turf you're on and
the turf that Step_1 is are checked for items which have the ON_BORDER flag set. These are itmes which limit you on only one tile border. Windows, for the most part.
CheckExit() and CanPass() are use to determine this. The dummy object is then moved back to your location and it tries to move to Step_2. Same checks are performed here.
If at least one of the two checks succeeds, it means you can reach the item and ok is set to 1.
*/
else
// ------- OBJECT IS ON A CARDINAL TILE (NORTH, SOUTH, EAST OR WEST OR THE TILE YOU'RE ON) -------
if(loc == usr.loc)
ok = 1
// ------- OBJECT IS ON THE SAME TILE AS YOU -------
else
ok = 1
//Now, check objects to block exit that are on the border
for(var/obj/border_obstacle in usr.loc)
if(border_obstacle.flags & ON_BORDER)
if(!border_obstacle.CheckExit(D, src))
ok = 0
//Next, check objects to block entry that are on the border
for(var/obj/border_obstacle in get_turf(src))
if((border_obstacle.flags & ON_BORDER) && (src != border_obstacle))
if(!border_obstacle.CanPass(D, D.loc, 1, 0))
ok = 0
/*
See the previous More info, for... more info...
*/
//del(D)
// Garbage Collect Dummy
D.loc = null
D = null
// ------- DUMMY OBJECT'S SERVED IT'S PURPOSE, IT'S REWARDED WITH A SWIFT DELETE -------
if (!( ok ))
// ------- TESTS ABOVE DETERMINED YOU CANNOT REACH THE TILE -------
return 0
if (!( usr.restrained() || (usr.lying && usr.buckled!=src) ))
// ------- YOU ARE NOT REASTRAINED -------
if (W)
// ------- YOU HAVE AN ITEM IN YOUR HAND - HANDLE ATTACKBY AND AFTERATTACK -------
var/ignoreAA = 0 //Ignore afterattack(). Surgery uses this.
if (t5)
ignoreAA = src.attackby(W, usr)
if (W && !ignoreAA)
W.afterattack(src, usr, (t5 ? 1 : 0), params)
else
// ------- YOU DO NOT HAVE AN ITEM IN YOUR HAND -------
if (istype(usr, /mob/living/carbon/human))
// ------- YOU ARE HUMAN -------
src.attack_hand(usr, usr.hand)
else
// ------- YOU ARE NOT HUMAN. WHAT ARE YOU - DETERMINED HERE AND PROPER ATTACK_MOBTYPE CALLED -------
if (istype(usr, /mob/living/carbon/monkey))
src.attack_paw(usr, usr.hand)
else if (istype(usr, /mob/living/carbon/alien/humanoid))
if(usr.m_intent == "walk" && istype(usr, /mob/living/carbon/alien/humanoid/hunter))
usr.m_intent = "run"
usr.hud_used.move_intent.icon_state = "running"
usr.update_icons()
src.attack_alien(usr, usr.hand)
else if (istype(usr, /mob/living/carbon/alien/larva))
src.attack_larva(usr)
else if (istype(usr, /mob/living/silicon/ai) || istype(usr, /mob/living/silicon/robot))
src.attack_ai(usr, usr.hand)
else if(istype(usr, /mob/living/carbon/slime))
src.attack_slime(usr)
else if(istype(usr, /mob/living/simple_animal))
src.attack_animal(usr)
else
// ------- YOU ARE RESTRAINED. DETERMINE WHAT YOU ARE AND ATTACK WITH THE PROPER HAND_X PROC -------
if (istype(usr, /mob/living/carbon/human))
src.hand_h(usr, usr.hand)
else if (istype(usr, /mob/living/carbon/monkey))
src.hand_p(usr, usr.hand)
else if (istype(usr, /mob/living/carbon/alien/humanoid))
src.hand_al(usr, usr.hand)
else if (istype(usr, /mob/living/silicon/ai) || istype(usr, /mob/living/silicon/robot))
src.hand_a(usr, usr.hand)
else
// ------- ITEM INACESSIBLE OR CLICKING ON SCREEN -------
if (istype(src, /obj/screen))
// ------- IT'S THE HUD YOU'RE CLICKING ON -------
usr.prev_move = usr.next_move
usr:lastDblClick = world.time + 2
if (usr.next_move < world.time)
usr.next_move = world.time + 2
else
return
// ------- 2 DECISECOND DELAY FOR CLICKING PASSED -------
if (!( usr.restrained() ))
// ------- YOU ARE NOT RESTRAINED -------
if ((W && !( istype(src, /obj/screen) )))
// ------- IT SHOULD NEVER GET TO HERE, DUE TO THE ISTYPE(SRC, /OBJ/SCREEN) FROM PREVIOUS IF-S - I TESTED IT WITH A DEBUG OUTPUT AND I COULDN'T GET THIST TO SHOW UP. -------
src.attackby(W, usr)
if (W)
W.afterattack(src, usr,, params)
else
// ------- YOU ARE NOT RESTRAINED, AND ARE CLICKING A HUD OBJECT -------
if (istype(usr, /mob/living/carbon/human))
src.attack_hand(usr, usr.hand)
else if (istype(usr, /mob/living/carbon/monkey))
src.attack_paw(usr, usr.hand)
else if (istype(usr, /mob/living/carbon/alien/humanoid))
src.attack_alien(usr, usr.hand)
else
// ------- YOU ARE RESTRAINED CLICKING ON A HUD OBJECT -------
if (istype(usr, /mob/living/carbon/human))
src.hand_h(usr, usr.hand)
else if (istype(usr, /mob/living/carbon/monkey))
src.hand_p(usr, usr.hand)
else if (istype(usr, /mob/living/carbon/alien/humanoid))
src.hand_al(usr, usr.hand)
else
// ------- YOU ARE CLICKING ON AN OBJECT THAT'S INACCESSIBLE TO YOU AND IS NOT YOUR HUD -------
if((M_LASER in usr:mutations) && usr:a_intent == "harm" && world.time >= usr.next_move)
// ------- YOU HAVE THE M_LASER MUTATION, YOUR INTENT SET TO HURT AND IT'S BEEN MORE THAN A DECISECOND SINCE YOU LAS TATTACKED -------
var/turf/T = get_turf(usr)
var/turf/U = get_turf(src)
if(istype(usr, /mob/living/carbon/human))
usr:nutrition -= rand(1,5)
usr:handle_regular_hud_updates()
var/obj/item/projectile/beam/A = new /obj/item/projectile/beam( usr.loc )
A.icon = 'icons/effects/genetics.dmi'
A.icon_state = "eyelasers"
playsound(usr.loc, 'sound/weapons/taser2.ogg', 75, 1)
A.firer = usr
A.def_zone = usr:get_organ_target()
A.original = src
A.current = T
A.yo = U.y - T.y
A.xo = U.x - T.x
spawn( 1 )
A.process()
usr.next_move = world.time + 6
return

View File

@@ -1,130 +0,0 @@
/*
Humans:
Adds an exception for gloves, to allow special glove types like the ninja ones.
Otherwise pretty standard.
*/
/mob/living/carbon/human/UnarmedAttack(var/atom/A, var/proximity)
var/obj/item/clothing/gloves/G = gloves // not typecast specifically enough in defines
// Special glove functions:
// If the gloves do anything, have them return 1 to stop
// normal attack_hand() here.
if(proximity && istype(G) && G.Touch(A,1))
return
A.attack_hand(src)
/atom/proc/attack_hand(mob/user as mob)
return
/mob/living/carbon/human/RestrainedClickOn(var/atom/A)
return
/mob/living/carbon/human/RangedAttack(var/atom/A)
if(!gloves && !mutations.len) return
if(gloves)
var/obj/item/clothing/gloves/G = gloves
if(istype(G, /obj/item/clothing/gloves/yellow/power))
if(a_intent == "hurt")
PowerGlove(A)
return
else if(istype(G) && G.Touch(A,0)) // for magic gloves
return
if(mutations.len)
if((M_LASER in mutations) && a_intent == "hurt")
LaserEyes(A) // moved into a proc below
else if(M_TK in mutations)
/*switch(get_dist(src,A))
if(1 to 5) // not adjacent may mean blocked by window
Next_move += 2
if(5 to 7)
Next_move += 5
if(8 to 15)
Next_move += 10
if(16 to 128)
return
*/
A.attack_tk(src)
/*
Animals & All Unspecified
*/
/mob/living/UnarmedAttack(var/atom/A)
A.attack_animal(src)
/atom/proc/attack_animal(mob/user as mob)
return
/mob/living/RestrainedClickOn(var/atom/A)
return
/*
Monkeys
*/
/mob/living/carbon/monkey/UnarmedAttack(var/atom/A)
A.attack_paw(src)
/atom/proc/attack_paw(mob/user as mob)
return
/*
Monkey RestrainedClickOn() was apparently the
one and only use of all of the restrained click code
(except to stop you from doing things while handcuffed);
moving it here instead of various hand_p's has simplified
things considerably
*/
/mob/living/carbon/monkey/RestrainedClickOn(var/atom/A)
if(a_intent != "hurt" || !ismob(A)) return
if(istype(wear_mask, /obj/item/clothing/mask/muzzle))
return
var/mob/living/carbon/ML = A
var/dam_zone = ran_zone(pick("chest", "l_hand", "r_hand", "l_leg", "r_leg"))
var/armor = ML.run_armor_check(dam_zone, "melee")
if(prob(75))
ML.apply_damage(rand(1,3), BRUTE, dam_zone, armor)
for(var/mob/O in viewers(ML, null))
O.show_message("\red <B>[name] has bit [ML]!</B>", 1)
if(armor >= 2) return
if(ismonkey(ML))
for(var/datum/disease/D in viruses)
if(istype(D, /datum/disease/jungle_fever))
ML.contract_disease(D,1,0)
else
for(var/mob/O in viewers(ML, null))
O.show_message("\red <B>[src] has attempted to bite [ML]!</B>", 1)
/*
Aliens
Defaults to same as monkey in most places
*/
/mob/living/carbon/alien/UnarmedAttack(var/atom/A)
A.attack_alien(src)
/atom/proc/attack_alien(mob/user as mob)
attack_paw(user)
return
/mob/living/carbon/alien/RestrainedClickOn(var/atom/A)
return
// Babby aliens
/mob/living/carbon/alien/larva/UnarmedAttack(var/atom/A)
A.attack_larva(src)
/atom/proc/attack_larva(mob/user as mob)
return
/*
Slimes
Nothing happening here
*/
/mob/living/carbon/slime/UnarmedAttack(var/atom/A)
A.attack_slime(src)
/atom/proc/attack_slime(mob/user as mob)
return
/mob/living/carbon/slime/RestrainedClickOn(var/atom/A)
return
/*
New Players:
Have no reason to click on anything at all.
*/
/mob/new_player/ClickOn()
return

View File

@@ -1,17 +0,0 @@
// Blob Overmind Controls
/mob/camera/blob/CtrlClickOn(var/atom/A) // Expand blob
var/turf/T = get_turf(A)
if(T)
expand_blob(T)
/mob/camera/blob/MiddleClickOn(var/atom/A) // Rally spores
var/turf/T = get_turf(A)
if(T)
rally_spores(T)
/mob/camera/blob/AltClickOn(var/atom/A) // Create a shield
var/turf/T = get_turf(A)
if(T)
create_shield(T)

View File

@@ -1,212 +0,0 @@
/*
Telekinesis
This needs more thinking out, but I might as well.
*/
var/const/tk_maxrange = 15
/*
Telekinetic attack:
By default, emulate the user's unarmed attack
*/
/atom/proc/attack_tk(mob/user)
if(user.stat) return
user.UnarmedAttack(src,0) // attack_hand, attack_paw, etc
return
/*
This is similar to item attack_self, but applies to anything
that you can grab with a telekinetic grab.
It is used for manipulating things at range, for example, opening and closing closets.
There are not a lot of defaults at this time, add more where appropriate.
*/
/atom/proc/attack_self_tk(mob/user)
return
/obj/attack_tk(mob/user)
if(user.stat) return
if(anchored)
..()
return
var/obj/item/tk_grab/O = new(src)
user.put_in_active_hand(O)
O.host = user
O.focus_object(src)
return
/obj/item/attack_tk(mob/user)
if(user.stat || !isturf(loc)) return
if((M_TK in user.mutations) && !user.get_active_hand()) // both should already be true to get here
var/obj/item/tk_grab/O = new(src)
user.put_in_active_hand(O)
O.host = user
O.focus_object(src)
else
warning("Strange attack_tk(): TK([M_TK in user.mutations]) empty hand([!user.get_active_hand()])")
return
/mob/attack_tk(mob/user)
return // needs more thinking about
/*
TK Grab Item (the workhorse of old TK)
* If you have not grabbed something, do a normal tk attack
* If you have something, throw it at the target. If it is already adjacent, do a normal attackby()
* If you click what you are holding, or attack_self(), do an attack_self_tk() on it.
* Deletes itself if it is ever not in your hand, or if you should have no access to TK.
*/
/obj/item/tk_grab
name = "Telekinetic Grab"
desc = "Magic"
icon = 'icons/obj/magic.dmi'//Needs sprites
icon_state = "2"
flags = NOBLUDGEON
//item_state = null
w_class = 10.0
layer = 20
var/last_throw = 0
var/atom/movable/focus = null
var/mob/living/host = null
dropped(mob/user as mob)
if(focus && user && loc != user && loc != user.loc) // drop_item() gets called when you tk-attack a table/closet with an item
if(focus.Adjacent(loc))
focus.loc = loc
del(src)
return
//stops TK grabs being equipped anywhere but into hands
equipped(var/mob/user, var/slot)
if( (slot == slot_l_hand) || (slot== slot_r_hand) ) return
del(src)
return
attack_self(mob/user as mob)
if(focus)
focus.attack_self_tk(user)
afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, proximity)//TODO: go over this
if(!target || !user) return
if(last_throw+3 > world.time) return
if(!host || host != user)
del(src)
return
if(!(M_TK in host.mutations))
del(src)
return
if(isobj(target) && !isturf(target.loc))
return
var/d = get_dist(user, target)
if(focus)
d = max(d,get_dist(user,focus)) // whichever is further
/*switch(d)
if(0)
;
if(1 to 5) // not adjacent may mean blocked by window
if(!proximity)
user.next_move += 2
if(5 to 7)
user.next_move += 5
if(8 to tk_maxrange)
user.next_move += 10
else
user << "\blue Your mind won't reach that far."
return*/
if(d > tk_maxrange)
user << "<span class='warning'>Your mind won't reach that far.</span>"
return
if(!focus)
focus_object(target, user)
return
if(target == focus)
target.attack_self_tk(user)
return // todo: something like attack_self not laden with assumptions inherent to attack_self
if(!istype(target, /turf) && istype(focus,/obj/item) && target.Adjacent(focus))
var/obj/item/I = focus
var/resolved = target.attackby(I, user, user:get_organ_target())
if(!resolved && target && I)
I.afterattack(target,user,1) // for splashing with beakers
else
apply_focus_overlay()
focus.throw_at(target, 10, 1)
last_throw = world.time
return
attack(mob/living/M as mob, mob/living/user as mob, def_zone)
return
proc/focus_object(var/obj/target, var/mob/living/user)
if(!istype(target,/obj)) return//Cant throw non objects atm might let it do mobs later
if(target.anchored || !isturf(target.loc))
del src
return
focus = target
update_icon()
apply_focus_overlay()
return
proc/apply_focus_overlay()
if(!focus) return
var/obj/effect/overlay/O = new /obj/effect/overlay(locate(focus.x,focus.y,focus.z))
O.name = "sparkles"
O.anchored = 1
O.density = 0
O.layer = FLY_LAYER
O.dir = pick(cardinal)
O.icon = 'icons/effects/effects.dmi'
O.icon_state = "nothing"
flick("empdisable",O)
spawn(5)
qdel(O)
return
update_icon()
overlays.Cut()
if(focus && focus.icon && focus.icon_state)
overlays += icon(focus.icon,focus.icon_state)
return
/*Not quite done likely needs to use something thats not get_step_to
proc/check_path()
var/turf/ref = get_turf(src.loc)
var/turf/target = get_turf(focus.loc)
if(!ref || !target) return 0
var/distance = get_dist(ref, target)
if(distance >= 10) return 0
for(var/i = 1 to distance)
ref = get_step_to(ref, target, 0)
if(ref != target) return 0
return 1
*/
//equip_to_slot_or_del(obj/item/W, slot, del_on_fail = 1)
/*
if(istype(user, /mob/living/carbon))
if(user:mutations & M_TK && get_dist(source, user) <= 7)
if(user:get_active_hand()) return 0
var/X = source:x
var/Y = source:y
var/Z = source:z
*/

View File

@@ -16,6 +16,7 @@
var/pass_flags = 0 var/pass_flags = 0
var/throwpass = 0 var/throwpass = 0
var/germ_level = 0 // The higher the germ level, the more germ on the atom. var/germ_level = 0 // The higher the germ level, the more germ on the atom.
var/delayAttacks = 0 //Can a user spam-click on us? (combat balance)
///Chemistry. ///Chemistry.
var/datum/reagents/reagents = null var/datum/reagents/reagents = null
@@ -27,6 +28,97 @@
//Detective Work, used for the duplicate data points kept in the scanners //Detective Work, used for the duplicate data points kept in the scanners
var/list/original_atom var/list/original_atom
// Getting Clicked /////////////////////////////////////////////
// A lot of this is just special-snowflake bullshit
/atom/Click(location,control,params)
return usr.ClickOn(src,params)
/atom/DblClick(location,control,params)
return usr.DblClickOn(src,params)
/atom/proc/CtrlClick(mob/user)
return
/atom/movable/CtrlClick(mob/user)
if(user.canTouch(src)) user.start_pulling(src)
return
/atom/proc/AltClick(mob/user)
var/turf/T = get_turf(src)
if(T && T.Adjacent(user))
if(user.listed_turf == T)
user.listed_turf = null
else
user.listed_turf = T
user.client.statpanel = T.name
return
/atom/proc/attack_animal(mob/user)
return
/atom/proc/attack_hand(mob/user)
return
/atom/proc/attack_ai(mob/user)
return
/atom/proc/AIShiftClick()
return
/atom/proc/AICtrlClick()
return
/atom/proc/AIAltClick(var/mob/living/silicon/ai/user)
return src.AltClick(user)
/atom/proc/attack_paw(mob/user)
return
/atom/proc/attack_alien(mob/user)
return attack_paw(user)
/atom/proc/attack_larva(mob/user)
return
/atom/proc/attack_slime(mob/user as mob)
return
/atom/proc/attack_robot(mob/user)
return src.attack_ai(user)
/atom/proc/RobotAltClick()
return
/atom/proc/attack_ghost(mob/user)
var/ghost_flags = 0
if(ghost_read) ghost_flags |= PERMIT_ALL
if(canGhostRead(user,src,ghost_flags)) src.attack_ai(user)
else src.examine()
return
/atom/proc/attack_tk(mob/user)
if(user.stat) return
return user.UnarmedAttack(src)
/atom/proc/attack_self_tk(mob/user)
return
// Drag n Drop /////////////////////////////////////////////////
/atom/MouseDrop(atom/over)
if(over && over.Adjacent(usr) && src.Adjacent(usr))
over.MouseDrop_T(src,usr)
return
/atom/proc/MouseDrop_T(atom/dropping,mob/user)
return
////////////////////////////////////////////////////////////////
/atom/proc/attackby(obj/item/W,mob/user)
return
/atom/proc/throw_impact(atom/hit_atom, var/speed) /atom/proc/throw_impact(atom/hit_atom, var/speed)
if(istype(hit_atom,/mob/living)) if(istype(hit_atom,/mob/living))
var/mob/living/M = hit_atom var/mob/living/M = hit_atom

View File

@@ -39,6 +39,12 @@
..() ..()
/atom/movable/attackby(obj/item/W,mob/user)
if(W && (!(W.flags & NOBLUDGEON)))
//This is dumb as fuck
user.visible_message("<span class='danger'>[src] has been hit by [user] with [W].</span>")
return
// Used in shuttle movement and AI eye stuff. // Used in shuttle movement and AI eye stuff.
// Primarily used to notify objects being moved by a shuttle/bluespace fuckup. // Primarily used to notify objects being moved by a shuttle/bluespace fuckup.
/atom/movable/proc/setLoc(var/T, var/teleported=0) /atom/movable/proc/setLoc(var/T, var/teleported=0)

View File

@@ -0,0 +1,31 @@
//**************************************************************
// Eye Lasers
//**************************************************************
/mob/proc/shootEyeLasers(atom/target)
return
/mob/living/shootEyeLasers(atom/target)
var/turf/T = get_turf(src)
var/turf/U = get_turf(target)
var/obj/item/projectile/beam/LE = getFromPool(/obj/item/projectile/beam, loc)
LE.icon = 'icons/effects/genetics.dmi'
LE.icon_state = "eyelasers"
playsound(usr.loc, 'sound/weapons/taser2.ogg', 75, 1)
LE.firer = src
LE.def_zone = get_organ_target()
LE.original = target
LE.current = T
LE.yo = U.y - T.y
LE.xo = U.x - T.x
spawn() LE.process()
return
/mob/living/carbon/human/shootEyeLasers(atom/target)
if(src.nutrition > 0)
..()
nutrition = max(nutrition - rand(1,5),0)
handle_regular_hud_updates()
else src << "<span class='warning'> You're out of energy! You need food!</span>"
return

View File

@@ -0,0 +1,98 @@
//**************************************************************
// Telekinetic Grab
//**************************************************************
/obj/item/tk_grab
name = "Telekinetic Grab"
desc = "Magic"
icon = 'icons/obj/magic.dmi'
icon_state = "2"
flags = NOBLUDGEON
w_class = 10.0
layer = 20
var/last_throw = 0
var/atom/movable/focus = null
var/mob/living/host = null
/obj/item/tk_grab/dropped(mob/user)
if(src.focus && user && src.loc != user && src.loc != user.loc && focus.Adjacent(loc))
focus.loc = src.loc
del(src)
return
/obj/item/tk_grab/equipped(var/mob/user,var/slot)
if( (slot == slot_l_hand) || (slot== slot_r_hand) ) return
del(src)
return
/obj/item/tk_grab/attack_self(mob/user)
if(focus) focus.attack_self_tk(user)
return
/obj/item/tk_grab/afterattack(atom/target,mob/living/user) //TODO: Rewrite this
if(!target || !user) return
if(last_throw+3 > world.time) return
if(!host || host != user)
del(src)
return
if(!(M_TK in host.mutations))
del(src)
return
if(isobj(target) && !isturf(target.loc))
return
var/d = get_dist(user, target)
if(focus)
d = max(d,get_dist(user,focus)) // whichever is further
if(d > tk_maxrange)
user << "<span class='warning'>Your mind won't reach that far.</span>"
return
if(!focus)
focus_object(target, user)
return
if(target == focus)
target.attack_self_tk(user)
return // todo: something like attack_self not laden with assumptions inherent to attack_self
if(!istype(target, /turf) && istype(focus,/obj/item) && target.Adjacent(focus))
var/obj/item/I = focus
var/resolved = target.attackby(I, user, user:get_organ_target())
if(!resolved && target && I)
I.afterattack(target,user,1) // for splashing with beakers
else
apply_focus_overlay()
focus.throw_at(target, 10, 1)
last_throw = world.time
return
/obj/item/tk_grab/attack(mob/living/target,mob/living/user,def_zone)
return
/obj/item/tk_grab/proc/focus_object(var/obj/target,var/mob/living/user)
if(istype(target,/obj))
if(!target.anchored && isturf(target.loc))
src.focus = target
src.update_icon()
src.apply_focus_overlay()
else del(src)
return
/obj/item/tk_grab/proc/apply_focus_overlay()
if(src.focus)
var/obj/effect/overlay/O = new(locate(src.focus.x,src.focus.y,src.focus.z))
O.name = "sparkles"
O.anchored = 1
O.density = 0
O.layer = FLY_LAYER
O.dir = pick(cardinal)
O.icon = 'icons/effects/effects.dmi'
O.icon_state = "nothing"
flick("empdisable",O)
spawn(5) qdel(O)
return
/obj/item/tk_grab/update_icon()
src.overlays.Cut()
if(src.focus && src.focus.icon && src.focus.icon_state)
src.overlays += icon(focus.icon,focus.icon_state)
return

View File

@@ -125,7 +125,6 @@
/obj/effect/blob/attackby(var/obj/item/weapon/W, var/mob/user) /obj/effect/blob/attackby(var/obj/item/weapon/W, var/mob/user)
user.changeNext_move(10)
playsound(get_turf(src), 'sound/effects/attackblob.ogg', 50, 1) playsound(get_turf(src), 'sound/effects/attackblob.ogg', 50, 1)
src.visible_message("\red <B>The [src.name] has been attacked with \the [W][(user ? " by [user]." : ".")]") src.visible_message("\red <B>The [src.name] has been attacked with \the [W][(user ? " by [user]." : ".")]")
var/damage = 0 var/damage = 0

View File

@@ -1188,3 +1188,26 @@ About the new airlock wires panel:
open() open()
locked = 1 locked = 1
return return
/obj/machinery/door/airlock/AIShiftClick() // Opens and closes doors!
if(density)
Topic("aiEnable=7", list("aiEnable"="7"), 1) // 1 meaning no window (consistency!)
else
Topic("aiDisable=7", list("aiDisable"="7"), 1)
return
/obj/machinery/door/airlock/AICtrlClick() // Bolts doors
if(locked)
Topic("aiEnable=4", list("aiEnable"="4"), 1)// 1 meaning no window (consistency!)
else
Topic("aiDisable=4", list("aiDisable"="4"), 1)
/obj/machinery/door/airlock/AIAltClick() // Eletrifies doors.
if(!secondsElectrified)
// permenant shock
Topic("aiEnable=6", list("aiEnable"="6"), 1) // 1 meaning no window (consistency!)
else
// disable/6 is not in Topic; disable/5 disables both temporary and permenant shock
Topic("aiDisable=5", list("aiDisable"="5"), 1)
return

View File

@@ -152,7 +152,6 @@
if(istype(user, /mob/living/carbon/alien/humanoid) || istype(user, /mob/living/carbon/slime/adult)) if(istype(user, /mob/living/carbon/alien/humanoid) || istype(user, /mob/living/carbon/slime/adult))
if(src.operating) if(src.operating)
return return
user.changeNext_move(8)
src.health = max(0, src.health - 25) src.health = max(0, src.health - 25)
playsound(get_turf(src), 'sound/effects/Glasshit.ogg', 75, 1) playsound(get_turf(src), 'sound/effects/Glasshit.ogg', 75, 1)
visible_message("\red <B>[user] smashes against the [src.name].</B>", 1) visible_message("\red <B>[user] smashes against the [src.name].</B>", 1)
@@ -193,7 +192,6 @@
//If it's a weapon, smash windoor. Unless it's an id card, agent card, ect.. then ignore it (Cards really shouldnt damage a door anyway) //If it's a weapon, smash windoor. Unless it's an id card, agent card, ect.. then ignore it (Cards really shouldnt damage a door anyway)
if(src.density && istype(I, /obj/item/weapon) && !istype(I, /obj/item/weapon/card)) if(src.density && istype(I, /obj/item/weapon) && !istype(I, /obj/item/weapon/card))
var/aforce = I.force var/aforce = I.force
user.changeNext_move(8)
if(I.damtype == BRUTE || I.damtype == BURN) if(I.damtype == BRUTE || I.damtype == BURN)
src.health = max(0, src.health - aforce) src.health = max(0, src.health - aforce)
playsound(get_turf(src), 'sound/effects/Glasshit.ogg', 75, 1) playsound(get_turf(src), 'sound/effects/Glasshit.ogg', 75, 1)

View File

@@ -348,7 +348,6 @@ Status: []<BR>"},
user << "\red Access denied." user << "\red Access denied."
else else
user.changeNext_move(10)
// if the turret was attacked with the intention of harming it: // if the turret was attacked with the intention of harming it:
src.health -= W.force * 0.5 src.health -= W.force * 0.5
if (src.health <= 0) if (src.health <= 0)

View File

@@ -298,7 +298,6 @@
return return
/obj/machinery/turret/attackby(obj/item/weapon/W, mob/user)//I can't believe no one added this before/N /obj/machinery/turret/attackby(obj/item/weapon/W, mob/user)//I can't believe no one added this before/N
user.changeNext_move(10)
..() ..()
playsound(get_turf(src), 'sound/weapons/smash.ogg', 60, 1) playsound(get_turf(src), 'sound/weapons/smash.ogg', 60, 1)
src.spark_system.start() src.spark_system.start()

View File

@@ -31,6 +31,7 @@
anchored = 1 anchored = 1
var/health = 200 var/health = 200
var/turf/linked_turf var/turf/linked_turf
delayAttacks = 1
wall wall
name = "resin wall" name = "resin wall"
@@ -107,7 +108,6 @@
return return
/obj/effect/alien/resin/attack_hand() /obj/effect/alien/resin/attack_hand()
usr.changeNext_move(10)
if (M_HULK in usr.mutations) if (M_HULK in usr.mutations)
usr << "\blue You easily destroy the [name]." usr << "\blue You easily destroy the [name]."
for(var/mob/O in oviewers(src)) for(var/mob/O in oviewers(src))
@@ -160,7 +160,6 @@
else else
user << "\red This wall is already occupied." user << "\red This wall is already occupied."
return */ return */
user.changeNext_move(10)
var/aforce = W.force var/aforce = W.force
health = max(0, health - aforce) health = max(0, health - aforce)
playsound(loc, 'sound/effects/attackblob.ogg', 100, 1) playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
@@ -286,7 +285,6 @@ Alien plants should do something if theres a lot of poison
return return
/obj/effect/alien/weeds/attackby(var/obj/item/weapon/W, var/mob/user) /obj/effect/alien/weeds/attackby(var/obj/item/weapon/W, var/mob/user)
user.changeNext_move(10)
if(W.attack_verb.len) if(W.attack_verb.len)
visible_message("\red <B>\The [src] have been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]") visible_message("\red <B>\The [src] have been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]")
else else
@@ -474,7 +472,6 @@ Alien plants should do something if theres a lot of poison
/obj/effect/alien/egg/attackby(var/obj/item/weapon/W, var/mob/user) /obj/effect/alien/egg/attackby(var/obj/item/weapon/W, var/mob/user)
if(health <= 0) if(health <= 0)
return return
user.changeNext_move(10)
if(W.attack_verb.len) if(W.attack_verb.len)
src.visible_message("\red <B>\The [src] has been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]") src.visible_message("\red <B>\The [src] has been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]")
else else

View File

@@ -877,7 +877,6 @@ steam.start() -- spawns the effect
return return
attack_hand(var/mob/user) attack_hand(var/mob/user)
user.changeNext_move(10)
if ((M_HULK in user.mutations) || (prob(75 - metal*25))) if ((M_HULK in user.mutations) || (prob(75 - metal*25)))
user << "\blue You smash through the metal foam wall." user << "\blue You smash through the metal foam wall."
for(var/mob/O in oviewers(user)) for(var/mob/O in oviewers(user))
@@ -890,7 +889,6 @@ steam.start() -- spawns the effect
attackby(var/obj/item/I, var/mob/user) attackby(var/obj/item/I, var/mob/user)
user.changeNext_move(10)
if (istype(I, /obj/item/weapon/grab)) if (istype(I, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = I var/obj/item/weapon/grab/G = I
G.affecting.loc = src.loc G.affecting.loc = src.loc

View File

@@ -14,6 +14,8 @@
pressure_resistance = 5 pressure_resistance = 5
// causeerrorheresoifixthis // causeerrorheresoifixthis
var/obj/item/master = null var/obj/item/master = null
var/attackDelay = 8 //How often a user can attack with this item (lower is faster)
var/heat_protection = 0 //flags which determine which body parts are protected from heat. Use the HEAD, UPPER_TORSO, LOWER_TORSO, etc. flags. See setup.dm var/heat_protection = 0 //flags which determine which body parts are protected from heat. Use the HEAD, UPPER_TORSO, LOWER_TORSO, etc. flags. See setup.dm
var/cold_protection = 0 //flags which determine which body parts are protected from cold. Use the HEAD, UPPER_TORSO, LOWER_TORSO, etc. flags. See setup.dm var/cold_protection = 0 //flags which determine which body parts are protected from cold. Use the HEAD, UPPER_TORSO, LOWER_TORSO, etc. flags. See setup.dm
@@ -52,9 +54,107 @@
src:my_atom = null*/ src:my_atom = null*/
..() ..()
/obj/item/proc/preAttack(atom/target,mob/user,forceMod=1)
if(user.canTouch(target))
//TODO: Attackby() needs to take more specific instructions.
// It would allow us to avoid this inelegant shit.
if(forceMod && (src.damtype == "brute"))
. = src.force
src.force *= forceMod
target.attackby(src,user)
src.afterattack(target,user,1)
src.force = .
else
target.attackby(src,user)
src.afterattack(target,user,1)
return
/obj/item/proc/attack_self(mob/user)
return
/obj/item/proc/afterattack(atom/target,mob/user,proximity)
return
/obj/item/device /obj/item/device
icon = 'icons/obj/device.dmi' icon = 'icons/obj/device.dmi'
obj/item/proc/get_clamped_volume()
if(src.w_class)
if(src.force) . = Clamp(((src.force + src.w_class)*4),30,100)
else . = Clamp((src.w_class*6),10,100)
return
/obj/item/proc/attack(mob/living/target,mob/living/user,def_zone)
if(!isliving(target)) return
if(can_operate(target) && do_surgery(target,user,src)) return
if(src.hitsound) playsound(src.loc,src.hitsound,50,1,-1)
user.lastattacked = target
target.lastattacker = user
spawn() add_logs(user,target,"attacked",object=src.name,addition="(INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])")
var/power = src.force
//TODO: Should be in attackArmed()
if(istype(target,/mob/living/carbon/human)) target:attacked_by(src,user,def_zone)
else //TODO: Should be in mob code
switch(src.damtype)
if("brute")
if(istype(src,/mob/living/carbon/slime))
target.adjustBrainLoss(power)
else
if(src.force && prob(33))
var/turf/T = get_turf(target)
if(istype(T,/turf/simulated)) T:add_blood_floor(target)
target.take_organ_damage(power)
if("fire")
if(!(M_RESIST_COLD in target.mutations))
target.take_organ_damage(0,power)
target << "<span class='danger'>Aargh it burns!</span>"
target.updatehealth()
if(istype(target,/mob/living/carbon/slime)) //TODO: Should be in slime code
var/mob/living/carbon/slime/slime = target
if(prob(25))
user << "<span class='warning'>[src] passes right through [slime]!</span>"
return
if(power > 0) slime.attacked += 10
if(prob(50)) slime.Discipline--
if((power >= 3) && prob(5+round(power/2)))
if(slime.Victim && prob(80) && !slime.client)
slime.Discipline++
slime.Victim = null
slime.anchored = 0
slime.SStun = 1
spawn(rand(5,20))
if(slime) slime.SStun = 0
step_away(slime,user)
if(prob(25+power))
spawn(2)
if(slime && user) step_away(slime, user)
var/showname = "." //TODO: Should be in a logging proc
if(user) showname = " by [user]!"
if(!(user in viewers(target,null))) showname = "."
spawn()
if(attack_verb && attack_verb.len)
target.visible_message("<span class='danger'>[target] has been [pick(attack_verb)] with [src][showname]</span>",
"<span class='userdanger'>[target] has been [pick(attack_verb)] with [src][showname]!</span>")
else if(force == 0)
target.visible_message("<span class='danger'>[target] has been [pick("tapped","patted")] with [src][showname]</span>",
"<span class='userdanger'>[target] has been [pick("tapped","patted")] with [src][showname]</span>")
else
target.visible_message("<span class='danger'>[target] has been attacked with [src][showname]</span>",
"<span class='userdanger'>[target] has been attacked with [src][showname]</span>")
if(!showname && user && user.client) user << "<span class='danger'>You attack [target] with [src].<span>"
src.add_fingerprint(user)
return 1
/obj/item/attack_tk(mob/user)
if(user.stat || (!isturf(src.loc))) return
if((M_TK in user.mutations) && !user.get_active_hand())
var/obj/item/tk_grab/O = new(src)
user.put_in_active_hand(O)
O.host = user
O.focus_object(src)
else warning("Strange attack_tk(): TK([M_TK in user.mutations]) empty hand([!user.get_active_hand()])")
return
/obj/item/ex_act(severity) /obj/item/ex_act(severity)
switch(severity) switch(severity)
if(1.0) if(1.0)
@@ -74,6 +174,9 @@
/obj/item/blob_act() /obj/item/blob_act()
del(src) del(src)
/obj/item/proc/is_used_on(obj/O,mob/user)
return
//user: The mob that is suiciding //user: The mob that is suiciding
//damagetype: The type of damage the item will inflict on the user //damagetype: The type of damage the item will inflict on the user
//BRUTELOSS = 1 //BRUTELOSS = 1

View File

@@ -39,7 +39,15 @@
..() ..()
/obj/item/proc/is_used_on(obj/O, mob/user) /obj/attack_tk(mob/user)
if(!user.stat)
if(!src.anchored)
var/obj/item/tk_grab/O = new(src)
user.put_in_active_hand(O)
O.host = user
O.focus_object(src)
else . = ..()
return
/obj/recycle(var/datum/materials/rec) /obj/recycle(var/datum/materials/rec)
if (src.m_amt == 0 && src.g_amt == 0) if (src.m_amt == 0 && src.g_amt == 0)

View File

@@ -380,7 +380,6 @@
//okay, so the closet is either welded or locked... resist!!! //okay, so the closet is either welded or locked... resist!!!
//user.next_move = world.time + 100 //user.next_move = world.time + 100
user.changeNext_move(100)
user.last_special = world.time + 100 user.last_special = world.time + 100
user << "<span class='notice'>You lean on the back of [src] and start pushing the door open. (this will take about [breakout_time] minutes.)</span>" user << "<span class='notice'>You lean on the back of [src] and start pushing the door open. (this will take about [breakout_time] minutes.)</span>"
for(var/mob/O in viewers(src)) for(var/mob/O in viewers(src))

View File

@@ -4,6 +4,7 @@
icon_state="box_glass" icon_state="box_glass"
var/obj/item/weapon/circuitboard/airlock/circuit=null var/obj/item/weapon/circuitboard/airlock/circuit=null
var/state=0 var/state=0
delayAttacks = 1
/obj/structure/displaycase_frame/attackby(obj/item/weapon/W as obj, mob/user as mob) /obj/structure/displaycase_frame/attackby(obj/item/weapon/W as obj, mob/user as mob)
var/pstate=state var/pstate=state
@@ -209,7 +210,6 @@
new /obj/machinery/constructable_frame/machine_frame(T) new /obj/machinery/constructable_frame/machine_frame(T)
del(src) del(src)
if(user.a_intent == "hurt") if(user.a_intent == "hurt")
user.changeNext_move(10)
src.health -= W.force src.health -= W.force
src.healthcheck() src.healthcheck()
..() ..()
@@ -239,7 +239,6 @@
update_icon() update_icon()
else else
if(user.a_intent == "hurt") if(user.a_intent == "hurt")
user.changeNext_move(10)
user.visible_message("\red [user.name] kicks \the [src]!", \ user.visible_message("\red [user.name] kicks \the [src]!", \
"\red You kick \the [src]!", \ "\red You kick \the [src]!", \
"You hear glass crack.") "You hear glass crack.")

View File

@@ -11,6 +11,7 @@
explosion_resistance = 5 explosion_resistance = 5
var/health = 10 var/health = 10
var/destroyed = 0 var/destroyed = 0
delayAttacks = 1
/obj/structure/grille/fence/east_west /obj/structure/grille/fence/east_west
//width=80 //width=80
@@ -39,7 +40,6 @@
attack_hand(user) attack_hand(user)
/obj/structure/grille/attack_hand(mob/user as mob) /obj/structure/grille/attack_hand(mob/user as mob)
user.changeNext_move(8)
playsound(loc, 'sound/effects/grillehit.ogg', 80, 1) playsound(loc, 'sound/effects/grillehit.ogg', 80, 1)
user.visible_message("<span class='warning'>[user] kicks [src].</span>", \ user.visible_message("<span class='warning'>[user] kicks [src].</span>", \
"<span class='warning'>You kick [src].</span>", \ "<span class='warning'>You kick [src].</span>", \
@@ -55,7 +55,6 @@
/obj/structure/grille/attack_alien(mob/user as mob) /obj/structure/grille/attack_alien(mob/user as mob)
if(istype(user, /mob/living/carbon/alien/larva)) return if(istype(user, /mob/living/carbon/alien/larva)) return
user.changeNext_move(8)
playsound(loc, 'sound/effects/grillehit.ogg', 80, 1) playsound(loc, 'sound/effects/grillehit.ogg', 80, 1)
user.visible_message("<span class='warning'>[user] mangles [src].</span>", \ user.visible_message("<span class='warning'>[user] mangles [src].</span>", \
"<span class='warning'>You mangle [src].</span>", \ "<span class='warning'>You mangle [src].</span>", \
@@ -68,7 +67,6 @@
/obj/structure/grille/attack_slime(mob/user as mob) /obj/structure/grille/attack_slime(mob/user as mob)
if(!istype(user, /mob/living/carbon/slime/adult)) return if(!istype(user, /mob/living/carbon/slime/adult)) return
user.changeNext_move(8)
playsound(loc, 'sound/effects/grillehit.ogg', 80, 1) playsound(loc, 'sound/effects/grillehit.ogg', 80, 1)
user.visible_message("<span class='warning'>[user] smashes against [src].</span>", \ user.visible_message("<span class='warning'>[user] smashes against [src].</span>", \
"<span class='warning'>You smash against [src].</span>", \ "<span class='warning'>You smash against [src].</span>", \
@@ -79,9 +77,7 @@
return return
/obj/structure/grille/attack_animal(var/mob/living/simple_animal/M as mob) /obj/structure/grille/attack_animal(var/mob/living/simple_animal/M as mob)
M.changeNext_move(8)
if(M.melee_damage_upper == 0) return if(M.melee_damage_upper == 0) return
playsound(loc, 'sound/effects/grillehit.ogg', 80, 1) playsound(loc, 'sound/effects/grillehit.ogg', 80, 1)
M.visible_message("<span class='warning'>[M] smashes against [src].</span>", \ M.visible_message("<span class='warning'>[M] smashes against [src].</span>", \
"<span class='warning'>You smash against [src].</span>", \ "<span class='warning'>You smash against [src].</span>", \
@@ -109,7 +105,6 @@
return 0 return 0
/obj/structure/grille/attackby(obj/item/weapon/W as obj, mob/user as mob) /obj/structure/grille/attackby(obj/item/weapon/W as obj, mob/user as mob)
user.changeNext_move(8)
if(iswirecutter(W)) if(iswirecutter(W))
if(!shock(user, 100)) if(!shock(user, 100))
playsound(loc, 'sound/items/Wirecutter.ogg', 100, 1) playsound(loc, 'sound/items/Wirecutter.ogg', 100, 1)

View File

@@ -235,7 +235,6 @@
if(M_HULK in user.mutations) if(M_HULK in user.mutations)
user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
visible_message("<span class='danger'>[user] smashes the [src] apart!</span>") visible_message("<span class='danger'>[user] smashes the [src] apart!</span>")
user.changeNext_move(8)
destroy() destroy()

View File

@@ -16,6 +16,7 @@
var/sheets = 1 // Number of sheets needed to build this window (determines how much shit is spawned by destroy()) var/sheets = 1 // Number of sheets needed to build this window (determines how much shit is spawned by destroy())
// var/silicate = 0 // number of units of silicate // var/silicate = 0 // number of units of silicate
// var/icon/silicateIcon = null // the silicated icon // var/icon/silicateIcon = null // the silicated icon
delayAttacks = 1
/obj/structure/window/examine() /obj/structure/window/examine()
..() ..()
@@ -123,16 +124,13 @@
if(pdiff>0) if(pdiff>0)
message_admins("Window destroyed by hulk [user.real_name] ([formatPlayerPanel(user,user.ckey)]) with pdiff [pdiff] at [formatJumpTo(loc)]!") message_admins("Window destroyed by hulk [user.real_name] ([formatPlayerPanel(user,user.ckey)]) with pdiff [pdiff] at [formatJumpTo(loc)]!")
log_admin("Window destroyed by hulk [user.real_name] ([user.ckey]) with pdiff [pdiff] at [loc]!") log_admin("Window destroyed by hulk [user.real_name] ([user.ckey]) with pdiff [pdiff] at [loc]!")
user.changeNext_move(8)
destroy() destroy()
else if (usr.a_intent == "hurt") else if (usr.a_intent == "hurt")
user.changeNext_move(8) // not so polite
playsound(get_turf(src), 'sound/effects/glassknock.ogg', 80, 1) playsound(get_turf(src), 'sound/effects/glassknock.ogg', 80, 1)
usr.visible_message("\red [usr.name] bangs against the [src.name]!", \ usr.visible_message("\red [usr.name] bangs against the [src.name]!", \
"\red You bang against the [src.name]!", \ "\red You bang against the [src.name]!", \
"You hear a banging sound.") "You hear a banging sound.")
else else
user.changeNext_move(10)
playsound(get_turf(src), 'sound/effects/glassknock.ogg', 80, 1) playsound(get_turf(src), 'sound/effects/glassknock.ogg', 80, 1)
usr.visible_message("[usr.name] knocks on the [src.name].", \ usr.visible_message("[usr.name] knocks on the [src.name].", \
"You knock on the [src.name].", \ "You knock on the [src.name].", \
@@ -144,9 +142,7 @@
return attack_hand(user) return attack_hand(user)
/obj/structure/window/proc/attack_generic(mob/user as mob, damage = 0) //used by attack_alien, attack_animal, and attack_slime /obj/structure/window/proc/attack_generic(mob/user as mob, damage = 0) //used by attack_alien, attack_animal, and attack_slime
user.changeNext_move(10)
health -= damage health -= damage
user.changeNext_move(8)
if(health <= 0) if(health <= 0)
user.visible_message("<span class='danger'>[user] smashes through [src]!</span>") user.visible_message("<span class='danger'>[user] smashes through [src]!</span>")
var/pdiff=performWallPressureCheck(src.loc) var/pdiff=performWallPressureCheck(src.loc)
@@ -239,7 +235,6 @@
user << (state ? "<span class='notice'>You have pried the window into the frame.</span>" : "<span class='notice'>You have pried the window out of the frame.</span>") user << (state ? "<span class='notice'>You have pried the window into the frame.</span>" : "<span class='notice'>You have pried the window out of the frame.</span>")
else else
if(W.damtype == BRUTE || W.damtype == BURN) if(W.damtype == BRUTE || W.damtype == BURN)
user.changeNext_move(10)
hit(W.force) hit(W.force)
if(health <= 7) if(health <= 7)
anchored = 0 anchored = 0

View File

@@ -104,7 +104,6 @@
dismantle_wall() dismantle_wall()
/turf/simulated/wall/attack_paw(mob/user as mob) /turf/simulated/wall/attack_paw(mob/user as mob)
user.changeNext_move(8)
if ((M_HULK in user.mutations)) if ((M_HULK in user.mutations))
if (prob(hardness)) if (prob(hardness))
usr << text("\blue You smash through the wall.") usr << text("\blue You smash through the wall.")
@@ -118,7 +117,6 @@
return src.attack_hand(user) return src.attack_hand(user)
/turf/simulated/wall/attack_animal(var/mob/living/simple_animal/M) /turf/simulated/wall/attack_animal(var/mob/living/simple_animal/M)
M.changeNext_move(8)
if(M.environment_smash >= 2) if(M.environment_smash >= 2)
if(istype(src, /turf/simulated/wall/r_wall)) if(istype(src, /turf/simulated/wall/r_wall))
if(M.environment_smash == 3) if(M.environment_smash == 3)
@@ -132,7 +130,6 @@
return return
/turf/simulated/wall/attack_hand(mob/user as mob) /turf/simulated/wall/attack_hand(mob/user as mob)
user.changeNext_move(8)
if (M_HULK in user.mutations) if (M_HULK in user.mutations)
if (prob(hardness) || rotting) if (prob(hardness) || rotting)
usr << text("\blue You smash through the wall.") usr << text("\blue You smash through the wall.")
@@ -154,7 +151,6 @@
return return
/turf/simulated/wall/attackby(obj/item/weapon/W as obj, mob/user as mob) /turf/simulated/wall/attackby(obj/item/weapon/W as obj, mob/user as mob)
user.changeNext_move(8)
if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
user << "<span class='warning'>You don't have the dexterity to do this!</span>" user << "<span class='warning'>You don't have the dexterity to do this!</span>"
return return

View File

@@ -61,37 +61,6 @@
feedback_add_details("admin_verb","DAST") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! feedback_add_details("admin_verb","DAST") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
*/ */
/client/proc/fix_next_move()
set category = "Debug"
set name = "Unfreeze Everyone"
var/largest_move_time = 0
var/largest_click_time = 0
var/mob/largest_move_mob = null
var/mob/largest_click_mob = null
for(var/mob/M in world)
if(!M.client)
continue
if(M.next_move >= largest_move_time)
largest_move_mob = M
if(M.next_move > world.time)
largest_move_time = M.next_move - world.time
else
largest_move_time = 1
if(M.next_click >= largest_click_time)
largest_click_mob = M
if(M.next_click > world.time)
largest_click_time = M.next_click - world.time
else
largest_click_time = 0
log_admin("DEBUG: [key_name(M)] next_move = [M.next_move] next_click = [M.next_click] world.time = [world.time]")
M.next_move = 1
M.next_click = 0
message_admins("[key_name_admin(largest_move_mob)] had the largest move delay with [largest_move_time] frames / [largest_move_time/10] seconds!", 1)
message_admins("[key_name_admin(largest_click_mob)] had the largest click delay with [largest_click_time] frames / [largest_click_time/10] seconds!", 1)
message_admins("world.time = [world.time]", 1)
feedback_add_details("admin_verb","UFE") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
/client/proc/radio_report() /client/proc/radio_report()
set category = "Debug" set category = "Debug"
set name = "Radio report" set name = "Radio report"

View File

@@ -0,0 +1,54 @@
//**************************************************************
//
// Power Gloves
// -------------------
// Allows the user to shock people from a distance
// User must be standing on a wire
// Above shockLimit, the user also takes damage (10%)
// TODO: Align shock dmg with powernets
//
//**************************************************************
/obj/item/clothing/gloves/yellow/power
var/shockLimit = 100
/obj/item/clothing/gloves/yellow/power/Touch(atom/target)
if(world.time < src.next_shock)
user << "<span class='warning'>[src] aren't ready to shock again!</span>"
return
var/mob/user = src.loc
var/turf/T = get_turf(src)
var/obj/structure/cable/cable = locate(obj/structure/cable) in T
var/datum/powernet/PN = cable.get_powernet()
var/damage
if(PN.avail >= 5000000) damage = 205 //TODO: Align with powernets
else damage = PN.get_electrocute_damage()
if(damage > 0)
if(damage >= src.shockLimit)
apply_damage((damage/10),BURN,(hand ? "l_hand" : "r_hand"))
user << "<span class='warning'>[src] overload from the massive current shocking you in the process!"
var/obj/item/projectile/beam/lightning/L = getFromPool(/obj/item/projectile/beam/lightning,loc)
L.damage = damage
var/datum/effect/effect/system/spark_spread/s = new
s.set_up(5,1,src)
s.start()
playsound(get_turf(src),'sound/effects/eleczap.ogg',75,1)
var/turf/U = get_turf(target)
L.tang = L.adjustAngle(get_angle(U,T))
L.icon = midicon
L.icon_state = "[L.tang]"
L.firer = user
L.def_zone = get_organ_target()
L.original = user
L.current = U
L.starting = U
L.yo = U.y - T.y
L.xo = U.x - T.x
spawn() L.process()
user.visible_message(
"<span class='warning'>[user.name] fires an arc of electricity!</span>",
"<span class='notice'>You fire an arc of electricity!</span>",
"You hear the loud crackle of electricity!")
src.next_shock = world.time + min(100,damage)
return

View File

@@ -0,0 +1,23 @@
//**************************************************************
//
// Blobs
// -----------
// TODO: Move the rest of blob code here.
//
//**************************************************************
/mob/camera/blob/CtrlClickOn(atom/target)
target = get_turf(target)
if(target) expand_blob(target)
return
/mob/camera/blob/MiddleClickOn(atom/target)
target = get_turf(target)
if(target) rally_spores(target)
return
/mob/camera/blob/AltClickOn(atom/target)
target = get_turf(target)
if(target) create_shield(target)
return

View File

@@ -93,6 +93,20 @@
real_name = name real_name = name
..() ..()
// Clicking ////////////////////////////////////////////////////
/mob/dead/observer/DblClickOn(atom/target,params)
if((ismob(target) && (target != src)) || istype(target,/obj/machinery/bot) || istype(target,/obj/machinery/singularity))
src.ManualFollow(target)
else src.loc = get_turf(target)
return
/mob/dead/observer/ClickOn(atom/target,params)
target.attack_ghost(src)
return
////////////////////////////////////////////////////////////////
/mob/dead/observer/hasFullAccess() /mob/dead/observer/hasFullAccess()
return isAdminGhost(src) return isAdminGhost(src)

View File

@@ -30,6 +30,13 @@
var/heat_protection = 0.5 var/heat_protection = 0.5
/mob/living/carbon/alien/UnarmedAttack(atom/A)
A.attack_alien(src)
return
/mob/living/carbon/alien/RestrainedClickOn(atom/A)
return
/mob/living/carbon/alien/adjustToxLoss(amount) /mob/living/carbon/alien/adjustToxLoss(amount)
storedPlasma = min(max(storedPlasma + amount,0),max_plasma) //upper limit of max_plasma, lower limit of 0 storedPlasma = min(max(storedPlasma + amount,0),max_plasma) //upper limit of max_plasma, lower limit of 0
return return

View File

@@ -24,6 +24,10 @@
regenerate_icons() regenerate_icons()
..() ..()
/mob/living/carbon/alien/larva/UnarmedAttack(atom/A)
A.attack_larva(src)
return
//This is fine, works the same as a human //This is fine, works the same as a human
/mob/living/carbon/alien/larva/Bump(atom/movable/AM as mob|obj, yes) /mob/living/carbon/alien/larva/Bump(atom/movable/AM as mob|obj, yes)

View File

@@ -3,6 +3,14 @@
update_hud() update_hud()
return return
// Clicking ////////////////////////////////////////////////////
/mob/living/carbon/MiddleClickOn(atom/target)
src.swap_hand()
return
////////////////////////////////////////////////////////////////
/mob/living/carbon/Move(NewLoc,Dir=0,step_x=0,step_y=0) /mob/living/carbon/Move(NewLoc,Dir=0,step_x=0,step_y=0)
. = ..() . = ..()

View File

@@ -7,7 +7,7 @@
var/list/hud_list[9] var/list/hud_list[9]
var/datum/species/species //Contains icon generation and language information, set during New(). var/datum/species/species //Contains icon generation and language information, set during New().
var/embedded_flag //To check if we've need to roll for damage on movement while an item is imbedded in us. var/embedded_flag //To check if we've need to roll for damage on movement while an item is imbedded in us.
/mob/living/carbon/human/dummy /mob/living/carbon/human/dummy
real_name = "Test Dummy" real_name = "Test Dummy"
status_flags = GODMODE|CANPUSH status_flags = GODMODE|CANPUSH
@@ -75,6 +75,31 @@
if(!delay_ready_dna) if(!delay_ready_dna)
dna.ready_dna(src) dna.ready_dna(src)
// Attacking ///////////////////////////////////////////////////
/mob/living/carbon/human/UnarmedAttack(atom/target)
if(src.gloves && src.gloves.Touch(target,src.canTouch(target)))
return 1
else if(src.mutations.len)
if((M_LASER in mutations) && a_intent == "hurt")
src.shootEyeLasers(target)
return 1
else if(M_TK in mutations)
target.attack_tk(src)
return 1
if(src.canTouch(target))
if(target.delayAttacks)
if(src.nextAllowedAttack > world.time) return 1
else src.nextAllowedAttack = world.time + src.attackDelayUnarmed
target.attack_hand(src)
return
/mob/living/carbon/human/getForceModifier()
if(M_HULK in src.mutations) . = 2
return
////////////////////////////////////////////////////////////////
/mob/living/carbon/human/Bump(atom/movable/AM as mob|obj, yes) /mob/living/carbon/human/Bump(atom/movable/AM as mob|obj, yes)
if ((!( yes ) || now_pushing)) if ((!( yes ) || now_pushing))
return return

View File

@@ -31,7 +31,7 @@
var/obj/item/w_uniform = null var/obj/item/w_uniform = null
var/obj/item/shoes = null var/obj/item/shoes = null
var/obj/item/belt = null var/obj/item/belt = null
var/obj/item/gloves = null var/obj/item/clothing/gloves/gloves = null
var/obj/item/clothing/glasses/glasses = null var/obj/item/clothing/glasses/glasses = null
var/obj/item/head = null var/obj/item/head = null
var/obj/item/ears = null var/obj/item/ears = null

View File

@@ -50,6 +50,13 @@
var/coretype = /obj/item/slime_extract/grey var/coretype = /obj/item/slime_extract/grey
var/list/slime_mutation[4] var/list/slime_mutation[4]
/mob/living/carbon/slime/UnarmedAttack(atom/A)
A.attack_slime(src)
return
/mob/living/carbon/slime/RestrainedClickOn(atom/A)
return
/mob/living/carbon/slime/adult /mob/living/carbon/slime/adult
name = "adult slime" name = "adult slime"
icon = 'icons/mob/slimes.dmi' icon = 'icons/mob/slimes.dmi'

View File

@@ -107,6 +107,29 @@
greaterform = "Diona" greaterform = "Diona"
add_language("Rootspeak") add_language("Rootspeak")
/mob/living/carbon/monkey/UnarmedAttack(var/atom/A)
A.attack_paw(src)
/mob/living/carbon/monkey/RestrainedClickOn(var/atom/A)
if(a_intent != "hurt" || !ismob(A)) return
if(istype(wear_mask, /obj/item/clothing/mask/muzzle)) return
var/mob/living/carbon/ML = A
var/dam_zone = ran_zone(pick("chest", "l_hand", "r_hand", "l_leg", "r_leg"))
var/armor = ML.run_armor_check(dam_zone, "melee")
if(prob(75))
ML.apply_damage(rand(1,3), BRUTE, dam_zone, armor)
for(var/mob/O in viewers(ML, null))
O.show_message("\red <B>[name] has bit [ML]!</B>", 1)
if(armor >= 2) return
if(ismonkey(ML))
for(var/datum/disease/D in viruses)
if(istype(D, /datum/disease/jungle_fever))
ML.contract_disease(D,1,0)
else
for(var/mob/O in viewers(ML, null))
O.show_message("\red <B>[src] has attempted to bite [ML]!</B>", 1)
return
/mob/living/carbon/monkey/movement_delay() /mob/living/carbon/monkey/movement_delay()
var/tally = 0 var/tally = 0
if(reagents) if(reagents)

View File

@@ -29,6 +29,22 @@
special_role = null special_role = null
current << "\red <FONT size = 3><B>The fog clouding your mind clears. You remember nothing from the moment you were implanted until now..(You don't remember who enslaved you)</B></FONT>" current << "\red <FONT size = 3><B>The fog clouding your mind clears. You remember nothing from the moment you were implanted until now..(You don't remember who enslaved you)</B></FONT>"
*/ */
// Clicking ////////////////////////////////////////////////////
/mob/living/UnarmedAttack(var/atom/A)
A.attack_animal(src)
return
/mob/living/RestrainedClickOn(var/atom/A)
return
////////////////////////////////////////////////////////////////
/mob/living/attackby(obj/item/I,mob/user)
if(istype(I) && ismob(user)) I.attack(src,user)
return
/mob/living/verb/succumb() /mob/living/verb/succumb()
set hidden = 1 set hidden = 1
if ((src.health < 0 && src.health > -95.0)) if ((src.health < 0 && src.health > -95.0))

View File

@@ -127,6 +127,42 @@ var/list/ai_list = list()
ai_list -= src ai_list -= src
..() ..()
// Clicking ////////////////////////////////////////////////////
/mob/living/silicon/ai/DblClickOn(atom/target,params)
if(src.control_disabled || src.stat) return
if(ismob(target)) ai_actual_track(target)
else target.move_camera_by_click()
return
/mob/living/silicon/ai/ClickOn(atom/target,params)
if(src.control_disabled||src.stat) return
else if(findtext(params,"middle")) src.MiddleClickOn(target)
else if(findtext(params,"shift")) src.ShiftClickOn(target)
else if(findtext(params,"ctrl")) src.CtrlClickOn(target)
else if(findtext(params,"alt")) src.AltClickOn(target)
else if(aicamera.in_camera_mode)
aicamera.camera_mode_off()
aicamera.captureimage(target,src)
else
target.add_hiddenprint(src)
target.attack_ai(src)
return
/mob/living/silicon/ai/ShiftClickOn(atom/target)
target.AIShiftClick(src)
return
/mob/living/silicon/ai/CtrlClickOn(atom/target)
target.AICtrlClick(src)
return
/mob/living/silicon/ai/AltClickOn(atom/target)
target.AIAltClick(src)
return
////////////////////////////////////////////////////////////////
/mob/living/silicon/ai/verb/pick_icon() /mob/living/silicon/ai/verb/pick_icon()
set category = "AI Commands" set category = "AI Commands"
set name = "Set AI Core Display" set name = "Set AI Core Display"

View File

@@ -139,6 +139,41 @@
playsound(loc, startup_sound, 75, 1) playsound(loc, startup_sound, 75, 1)
// Clicking ////////////////////////////////////////////////////
/mob/living/silicon/robot/isAbleBodied()
return (!(src.stat || src.lockcharge || src.weakened || src.stunned || src.paralysis))
//Middle click cycles through selected modules.
/mob/living/silicon/robot/MiddleClickOn(atom/target)
src.cycle_modules()
return
/mob/living/silicon/robot/AltClickOn(atom/target)
if(isturf(target)) target.AltClick(src)
else target.RobotAltClick(src)
return
/mob/living/silicon/robot/ShiftClickOn(atom/target)
if(istype(target,/obj/machinery/door/airlock)) target.AIShiftClick(src)
else . = ..()
return
/mob/living/silicon/robot/CtrlClickOn(var/atom/A)
if(istype(A,/obj/machinery/door/airlock)) A.AICtrlClick(src)
else . = ..()
return
/mob/living/silicon/robot/UnarmedAttack(atom/target)
target.attack_robot(src)
return 1
////////////////////////////////////////////////////////////////
// setup the PDA and its name // setup the PDA and its name
/mob/living/silicon/robot/proc/setup_PDA() /mob/living/silicon/robot/proc/setup_PDA()
if (!rbPDA) if (!rbPDA)

View File

@@ -22,7 +22,6 @@
return return
/obj/effect/spider/attackby(var/obj/item/weapon/W, var/mob/user) /obj/effect/spider/attackby(var/obj/item/weapon/W, var/mob/user)
user.changeNext_move(10)
if(W.attack_verb.len) if(W.attack_verb.len)
visible_message("\red <B>\The [src] have been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]") visible_message("\red <B>\The [src] have been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]")
else else

View File

@@ -388,7 +388,6 @@
/mob/living/simple_animal/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri /mob/living/simple_animal/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri
if(istype(O, /obj/item/stack/medical)) if(istype(O, /obj/item/stack/medical))
user.changeNext_move(4)
if(stat != DEAD) if(stat != DEAD)
var/obj/item/stack/medical/MED = O var/obj/item/stack/medical/MED = O
if(health < maxHealth) if(health < maxHealth)
@@ -406,7 +405,6 @@
if(istype(O, /obj/item/weapon/kitchenknife) || istype(O, /obj/item/weapon/butch)) if(istype(O, /obj/item/weapon/kitchenknife) || istype(O, /obj/item/weapon/butch))
harvest() harvest()
else else
user.changeNext_move(8)
if(O.force) if(O.force)
var/damage = O.force var/damage = O.force
if (O.damtype == HALLOSS) if (O.damtype == HALLOSS)

View File

@@ -1,3 +1,72 @@
// Clicking/Attacking //////////////////////////////////////////
// This is simple shit, people overcomplicated it.
// ClickOn() is called by atom/Click(), which is called by BYOND.
// Attacking is handled in a complex chain at the moment.
// It must be simplified in the future.
/mob/proc/isAbleBodied()
return (!(src.stat||src.paralysis||src.stunned||src.weakened))
/mob/proc/canTouch(atom/target)
if(istype(src.loc,/turf) && target.Adjacent(src)) . = 1
return
/mob/proc/ClickOn(atom/target,params)
if(src.client.buildmode) build_click(src,client.buildmode,params,target)
else if(findtext(params,"middle")) src.MiddleClickOn(target)
else if(findtext(params,"shift")) src.ShiftClickOn(target)
else if(findtext(params,"ctrl")) src.CtrlClickOn(target)
else if(findtext(params,"alt")) src.AltClickOn(target)
else if(istype(src.loc,/obj/mecha)) src.loc:click_action(target,src)
else if(src.in_throw_mode) src.throw_item(target)
else if(src.isAbleBodied())
src.faceAtom(target)
var/obj/item/item = src.get_active_hand()
if(item)
if(item == target) item.attack_self(src)
else src.attackArmed(target,item)
else src.UnarmedAttack(target)
return
/mob/proc/DblClickOn(atom/target,params)
return
/mob/proc/MiddleClickOn(atom/target)
return
/mob/proc/CtrlClickOn(atom/target)
target.CtrlClick(src)
return
/mob/proc/ShiftClickOn(atom/target)
src.faceAtom(target)
target.examine(src)
return
/mob/proc/AltClickOn(atom/target)
target.AltClick(src)
return
/mob/proc/attackArmed(atom/target,obj/item/item)
if(target.delayAttacks)
if(src.nextAllowedAttack > world.time) return
else src.nextAllowedAttack = world.time + item.attackDelay
item.preAttack(target,src,src.getForceModifier())
return
/mob/proc/RestrainedClickOn(atom/target) //Only used for monkey mode
return
/mob/proc/UnarmedAttack(atom/target)
return
/mob/proc/getForceModifier()
return
////////////////////////////////////////////////////////////////
/mob/recycle(var/datum/materials) /mob/recycle(var/datum/materials)
return RECYK_BIOLOGICAL return RECYK_BIOLOGICAL

View File

@@ -8,6 +8,12 @@
// flags = NOREACT // flags = NOREACT
var/datum/mind/mind var/datum/mind/mind
//Combat-related
delayAttacks = 1 //For balance, so we can't get spam-attacked
var/nextAllowedAttack //When we can next attack a protected entity
var/attackDelayUnarmed = 8 //Ticks between unarmed attacks
var/stat = 0 //Whether a mob is alive or dead. TODO: Move this to living - Nodrak var/stat = 0 //Whether a mob is alive or dead. TODO: Move this to living - Nodrak
//Not in use yet //Not in use yet

View File

@@ -500,4 +500,9 @@ proc/is_blind(A)
for(var/mob/M in targets) for(var/mob/M in targets)
var/turf/targetturf = get_turf(M) var/turf/targetturf = get_turf(M)
if((targetturf.z == sourceturf.z)) if((targetturf.z == sourceturf.z))
M.show_message("<span class='info'>\icon[icon] [message]</span>", 1) M.show_message("<span class='info'>\icon[icon] [message]</span>", 1)
/mob/proc/faceAtom(atom/target)
if(src.isAbleBodied() && target.loc && src.loc)
src.dir = get_dir(src,target)
return

View File

@@ -458,3 +458,6 @@ Round Duration: [round(hours)]h [round(mins)]m<br>"}
proc/close_spawn_windows() proc/close_spawn_windows()
src << browse(null, "window=latechoices") //closes late choices window src << browse(null, "window=latechoices") //closes late choices window
src << browse(null, "window=playersetup") //closes the player setup window src << browse(null, "window=playersetup") //closes the player setup window
/mob/new_player/ClickOn()
return

View File

@@ -631,7 +631,6 @@
/obj/machinery/power/apc/attack_alien(mob/living/carbon/alien/humanoid/user) /obj/machinery/power/apc/attack_alien(mob/living/carbon/alien/humanoid/user)
if(!user) if(!user)
return return
user.changeNext_move(8)
user.visible_message("\red [user.name] slashes at the [src.name]!", "\blue You slash at the [src.name]!") user.visible_message("\red [user.name] slashes at the [src.name]!", "\blue You slash at the [src.name]!")
playsound(get_turf(src), 'sound/weapons/slash.ogg', 100, 1) playsound(get_turf(src), 'sound/weapons/slash.ogg', 100, 1)
@@ -1311,4 +1310,8 @@ obj/machinery/power/apc/proc/autoset(var/val, var/on)
else else
return 0 return 0
/obj/machinery/power/apc/AICtrlClick()
Topic("breaker=1",list("breaker"="1"),0)
return
#undef APC_UPDATE_ICON_COOLDOWN #undef APC_UPDATE_ICON_COOLDOWN

View File

@@ -337,7 +337,6 @@
// attack with item - insert light (if right type), otherwise try to break the light // attack with item - insert light (if right type), otherwise try to break the light
/obj/machinery/light/attackby(obj/item/W, mob/user) /obj/machinery/light/attackby(obj/item/W, mob/user)
user.changeNext_move(8)
//Light replacer code //Light replacer code
if(istype(W, /obj/item/device/lightreplacer)) if(istype(W, /obj/item/device/lightreplacer))
var/obj/item/device/lightreplacer/LR = W var/obj/item/device/lightreplacer/LR = W

View File

@@ -51,6 +51,11 @@
for(var/obj/O in contents) for(var/obj/O in contents)
O.emp_act(severity) O.emp_act(severity)
/obj/item/weapon/gun/preAttack(atom/target,mob/user)
if(user.a_intent != "help") //If the user wants to shoot
src.Fire(target,user) //Just shoot, fuck everything else!
return
/obj/item/weapon/gun/afterattack(atom/A as mob|obj|turf|area, mob/living/user as mob|obj, flag, params) /obj/item/weapon/gun/afterattack(atom/A as mob|obj|turf|area, mob/living/user as mob|obj, flag, params)
if(flag) return //we're placing gun on a table or in backpack if(flag) return //we're placing gun on a table or in backpack
if(istype(target, /obj/machinery/recharger) && istype(src, /obj/item/weapon/gun/energy)) return//Shouldnt flag take care of this? if(istype(target, /obj/machinery/recharger) && istype(src, /obj/item/weapon/gun/energy)) return//Shouldnt flag take care of this?

View File

@@ -22,9 +22,6 @@
if(istype(A, /obj/effect/proc_holder/spell)) if(istype(A, /obj/effect/proc_holder/spell))
return return
user.changeNext_move(8)
if(istype(A, /obj/structure/reagent_dispensers) && get_dist(src,A) <= 1) //this block copypasted from reagent_containers/glass, for lack of a better solution if(istype(A, /obj/structure/reagent_dispensers) && get_dist(src,A) <= 1) //this block copypasted from reagent_containers/glass, for lack of a better solution
if(!A.reagents.total_volume && A.reagents) if(!A.reagents.total_volume && A.reagents)
user << "<span class='notice'>\The [A] is empty.</span>" user << "<span class='notice'>\The [A] is empty.</span>"

View File

@@ -872,3 +872,133 @@ var/list/RESTRICTED_CAMERA_NETWORKS = list( //Those networks can only be accesse
#define AUTOIGNITION_WOOD 573.15 #define AUTOIGNITION_WOOD 573.15
#define AUTOIGNITION_PAPER 519.15 #define AUTOIGNITION_PAPER 519.15
var/const/tk_maxrange = 15
// HUD /////////////////////////////////////////////////////////
/*
These defines specificy screen locations. For more information, see the byond documentation on the screen_loc var.
The short version:
Everything is encoded as strings because apparently that's how Byond rolls.
"1,1" is the bottom left square of the user's screen. This aligns perfectly with the turf grid.
"1:2,3:4" is the square (1,3) with pixel offsets (+2, +4); slightly right and slightly above the turf grid.
Pixel offsets are used so you don't perfectly hide the turf under them, that would be crappy.
The size of the user's screen is defined by client.view (indirectly by world.view), in our case "15x15".
Therefore, the top right corner (except during admin shenanigans) is at "15,15"
*/
//Upper left action buttons, displayed when you pick up an item that has this enabled.
#define ui_action_slot1 "1:6,14:26"
#define ui_action_slot2 "2:8,14:26"
#define ui_action_slot3 "3:10,14:26"
#define ui_action_slot4 "4:12,14:26"
#define ui_action_slot5 "5:14,14:26"
//Lower left, persistant menu
#define ui_inventory "1:6,1:5"
//Lower center, persistant menu
#define ui_sstore1 "3:10,1:5"
#define ui_id "4:12,1:5"
#define ui_belt "5:14,1:5"
#define ui_back "6:14,1:5"
#define ui_rhand "7:16,1:5"
#define ui_lhand "8:16,1:5"
#define ui_equip "7:16,2:5"
#define ui_swaphand1 "7:16,2:5"
#define ui_swaphand2 "8:16,2:5"
#define ui_storage1 "9:18,1:5"
#define ui_storage2 "10:20,1:5"
#define ui_alien_head "4:12,1:5" //aliens
#define ui_alien_oclothing "5:14,1:5" //aliens
#define ui_inv1 "6:16,1:5" //borgs
#define ui_inv2 "7:16,1:5" //borgs
#define ui_inv3 "8:16,1:5" //borgs
#define ui_borg_store "9:16,1:5" //borgs
#define ui_monkey_mask "5:14,1:5" //monkey
#define ui_monkey_back "6:14,1:5" //monkey
//Lower right, persistant menu
#define ui_dropbutton "11:22,1:5"
#define ui_drop_throw "14:28,2:7"
#define ui_pull_resist "13:26,2:7"
#define ui_acti "13:26,1:5"
#define ui_movi "12:24,1:5"
#define ui_zonesel "14:28,1:5"
#define ui_acti_alt "14:28,1:5" //alternative intent switcher for when the interface is hidden (F12)
#define ui_borg_pull "12:24,2:7"
#define ui_borg_module "13:26,2:7"
#define ui_borg_panel "14:28,2:7"
//Gun buttons
#define ui_gun1 "13:26,3:7"
#define ui_gun2 "14:28, 4:7"
#define ui_gun3 "13:26,4:7"
#define ui_gun_select "14:28,3:7"
//Upper-middle right (damage indicators)
#define ui_toxin "14:28,13:27"
#define ui_fire "14:28,12:25"
#define ui_oxygen "14:28,11:23"
#define ui_pressure "14:28,10:21"
#define ui_alien_toxin "14:28,13:25"
#define ui_alien_fire "14:28,12:25"
#define ui_alien_oxygen "14:28,11:25"
//Middle right (status indicators)
#define ui_nutrition "14:28,5:11"
#define ui_temp "14:28,6:13"
#define ui_health "14:28,7:15"
#define ui_internal "14:28,8:17"
//borgs
#define ui_borg_health "14:28,6:13" //borgs have the health display where humans have the pressure damage indicator.
#define ui_alien_health "14:28,6:13" //aliens have the health display where humans have the pressure damage indicator.
#define ui_construct_health "15:00,7:15" //same height as humans, hugging the right border
#define ui_construct_fire "14:16,8:13" //above health, slightly to the left
#define ui_construct_pull "14:28,2:10" //above the zone_sel icon
//Pop-up inventory
#define ui_shoes "2:8,1:5"
#define ui_iclothing "1:6,2:7"
#define ui_oclothing "2:8,2:7"
#define ui_gloves "3:10,2:7"
#define ui_glasses "1:6,3:9"
#define ui_mask "2:8,3:9"
#define ui_ears "3:10,3:9"
#define ui_head "2:8,4:11"
//Intent small buttons
#define ui_help_small "12:8,1:1"
#define ui_disarm_small "12:15,1:18"
#define ui_grab_small "12:32,1:18"
#define ui_harm_small "12:39,1:1"
//#define ui_swapbutton "6:-16,1:5" //Unused
//#define ui_headset "SOUTH,8"
#define ui_hand "6:14,1:5"
#define ui_hstore1 "5,5"
//#define ui_resist "EAST+1,SOUTH-1"
#define ui_sleep "EAST+1, NORTH-13"
#define ui_rest "EAST+1, NORTH-14"
#define ui_iarrowleft "SOUTH-1,11"
#define ui_iarrowright "SOUTH-1,13"
////////////////////////////////////////////////////////////////
#define MOB_ATTACK_DELAY 8