mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-19 11:05:03 +01:00
-tg- Move Refactor
This commit ports /tg/'s move refactor. The throwing system has been replaced entirely, removing the necessity of throw_at_fast and resolving multiple outstanding issues, such as crossbows being unusable. Spacedrifting has also been upgraded to function with the new throwing system. It is now it's own process. Tickcomp has been killed, and the config values have been adjusted to more or less match live Paradise. All mobs now share a common Bump() proc. There are only four mobtypes which do not, including humans and simple animals. With the exception of mob types that do not ever want to Bump() or be Bumped(), they should call the parent proc. Human movement slowdown has been moderately tweaked in how it stacks effects; It shouldn't be significantly different from a player perspective. Mobs will now spread fire if they bump into another mob. I don't want to set the world on fiiiire, I just want start a flame in your heart~ For player facing changes: Input delay has been reduced by roughly ~50ms for any direction keys, by advantage of a previously unknown flag on byond verbs which allow them to operate independently from the tick rate of the server. You may need to clear your interface.dmf file if you have a custom skin for this change to function.
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
#define CALLBACK new /datum/callback
|
||||
#define INVOKE_ASYNC ImmediateInvokeAsync
|
||||
@@ -70,3 +70,6 @@
|
||||
#define WEAPON_LIGHT 0
|
||||
#define WEAPON_MEDIUM 1
|
||||
#define WEAPON_HEAVY 2
|
||||
|
||||
// Embedded objects
|
||||
#define EMBED_THROWSPEED_THRESHOLD 15
|
||||
@@ -77,11 +77,12 @@
|
||||
#define SAFE 16
|
||||
|
||||
//flags for pass_flags
|
||||
#define PASSTABLE 1
|
||||
#define PASSGLASS 2
|
||||
#define PASSGRILLE 4
|
||||
#define PASSBLOB 8
|
||||
#define PASSMOB 16
|
||||
#define PASSTABLE 1
|
||||
#define PASSGLASS 2
|
||||
#define PASSGRILLE 4
|
||||
#define PASSBLOB 8
|
||||
#define PASSMOB 16
|
||||
#define LETPASSTHROW 32
|
||||
|
||||
//turf-only flags
|
||||
#define NOJAUNT 1
|
||||
|
||||
@@ -329,4 +329,7 @@
|
||||
#define TENDRIL_CLEAR_SCORE "Tendrils Killed"
|
||||
|
||||
// The number of station goals generated each round.
|
||||
#define STATION_GOAL_BUDGET 1
|
||||
#define STATION_GOAL_BUDGET 1
|
||||
|
||||
#define FIRST_DIAG_STEP 1
|
||||
#define SECOND_DIAG_STEP 2
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
#define HUMAN_STRIP_DELAY 40 //takes 40ds = 4s to strip someone.
|
||||
#define ALIEN_SELECT_AFK_BUFFER 1 // How many minutes that a person can be AFK before not being allowed to be an alien.
|
||||
#define SHOES_SLOWDOWN -1.0 // How much shoes slow you down by default. Negative values speed you up
|
||||
#define SHOES_SLOWDOWN 0 // How much shoes slow you down by default. Negative values speed you up
|
||||
|
||||
|
||||
//Mob attribute defaults.
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
* 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.
|
||||
* Passing through in this case ignores anything with the LETPASSTHROW flag, such as tables, racks, and morgue trays.
|
||||
*/
|
||||
/turf/Adjacent(var/atom/neighbor, var/atom/target = null)
|
||||
var/turf/T0 = get_turf(neighbor)
|
||||
@@ -82,26 +82,18 @@
|
||||
|
||||
/*
|
||||
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.
|
||||
This is defined as any dense ON_BORDER object, or any dense object without LETPASSTHROW.
|
||||
The border_only flag allows you to not objects (for source and destination squares)
|
||||
*/
|
||||
/turf/proc/ClickCross(var/target_dir, var/border_only, var/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.density || O == target_atom || (O.pass_flags & LETPASSTHROW))
|
||||
continue // LETPASSTHROW 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.flags&ON_BORDER) // windows 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.
|
||||
*/
|
||||
return 1
|
||||
@@ -0,0 +1,53 @@
|
||||
var/global/datum/controller/process/spacedrift/drift_master
|
||||
|
||||
/datum/controller/process/spacedrift
|
||||
var/list/processing_list = list()
|
||||
|
||||
/datum/controller/process/spacedrift/setup()
|
||||
name = "spacedrift"
|
||||
schedule_interval = 5
|
||||
start_delay = 20
|
||||
log_startup_progress("Spacedrift starting up.")
|
||||
|
||||
/datum/controller/process/spacedrift/statProcess()
|
||||
..()
|
||||
stat(null, "P:[processing_list.len]")
|
||||
|
||||
/datum/controller/process/spacedrift/doWork()
|
||||
var/list/currentrun = processing_list.Copy()
|
||||
|
||||
while(currentrun.len)
|
||||
var/atom/movable/AM = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
if(!AM)
|
||||
processing_list -= AM
|
||||
SCHECK
|
||||
continue
|
||||
|
||||
if(AM.inertia_next_move > world.time)
|
||||
SCHECK
|
||||
continue
|
||||
|
||||
if(!AM.loc || AM.loc != AM.inertia_last_loc || AM.Process_Spacemove(0))
|
||||
AM.inertia_dir = 0
|
||||
|
||||
if(!AM.inertia_dir)
|
||||
AM.inertia_last_loc = null
|
||||
processing_list -= AM
|
||||
SCHECK
|
||||
continue
|
||||
|
||||
var/old_dir = AM.dir
|
||||
var/old_loc = AM.loc
|
||||
AM.inertia_moving = TRUE
|
||||
step(AM, AM.inertia_dir)
|
||||
AM.inertia_moving = FALSE
|
||||
AM.inertia_next_move = world.time + AM.inertia_move_delay
|
||||
if(AM.loc == old_loc)
|
||||
AM.inertia_dir = 0
|
||||
|
||||
AM.setDir(old_dir)
|
||||
AM.inertia_last_loc = AM.loc
|
||||
SCHECK
|
||||
|
||||
DECLARE_GLOBAL_CONTROLLER(spacedrift, drift_master)
|
||||
@@ -0,0 +1,138 @@
|
||||
#define MAX_THROWING_DIST 512 // 2 z-levels on default width
|
||||
#define MAX_TICKS_TO_MAKE_UP 3 //how many missed ticks will we attempt to make up for this run.
|
||||
|
||||
var/global/datum/controller/process/throwing/throw_master
|
||||
|
||||
/datum/controller/process/throwing
|
||||
var/list/processing_list
|
||||
|
||||
/datum/controller/process/throwing/setup()
|
||||
name = "throwing"
|
||||
schedule_interval = 1
|
||||
start_delay = 20
|
||||
log_startup_progress("Throw ticker starting up.")
|
||||
|
||||
/datum/controller/process/throwing/statProcess()
|
||||
..()
|
||||
stat(null, "P:[processing_list.len]")
|
||||
|
||||
/datum/controller/process/throwing/started()
|
||||
..()
|
||||
if(!processing_list)
|
||||
processing_list = list()
|
||||
|
||||
/datum/controller/process/throwing/doWork()
|
||||
for(last_object in processing_list)
|
||||
var/atom/movable/AM = last_object
|
||||
if(istype(AM) && isnull(AM.gcDestroyed))
|
||||
var/datum/thrownthing/TT = processing_list[AM]
|
||||
if(istype(TT) && isnull(TT.gcDestroyed))
|
||||
TT.tick()
|
||||
SCHECK
|
||||
else
|
||||
catchBadType(TT)
|
||||
processing_list -= AM
|
||||
AM.throwing = null
|
||||
else
|
||||
catchBadType(AM)
|
||||
processing_list -= AM
|
||||
SCHECK
|
||||
|
||||
DECLARE_GLOBAL_CONTROLLER(throwing, throw_master)
|
||||
|
||||
/datum/thrownthing
|
||||
var/atom/movable/thrownthing
|
||||
var/atom/target
|
||||
var/turf/target_turf
|
||||
var/init_dir
|
||||
var/maxrange
|
||||
var/speed
|
||||
var/mob/thrower
|
||||
var/diagonals_first
|
||||
var/dist_travelled = 0
|
||||
var/start_time
|
||||
var/dist_x
|
||||
var/dist_y
|
||||
var/dx
|
||||
var/dy
|
||||
var/pure_diagonal
|
||||
var/diagonal_error
|
||||
var/datum/callback/callback
|
||||
|
||||
/datum/thrownthing/proc/tick()
|
||||
var/atom/movable/AM = thrownthing
|
||||
if(!isturf(AM.loc) || !AM.throwing)
|
||||
finalize()
|
||||
return
|
||||
|
||||
if(dist_travelled && hitcheck()) //to catch sneaky things moving on our tile while we slept
|
||||
finalize()
|
||||
return
|
||||
|
||||
var/atom/step
|
||||
|
||||
// calculate how many tiles to move, making up for any missed ticks.
|
||||
if((dist_travelled >= maxrange || AM.loc == target_turf) && has_gravity(AM, AM.loc))
|
||||
finalize()
|
||||
return
|
||||
|
||||
if(dist_travelled <= max(dist_x, dist_y)) //if we haven't reached the target yet we home in on it, otherwise we use the initial direction
|
||||
step = get_step(AM, get_dir(AM, target_turf))
|
||||
else
|
||||
step = get_step(AM, init_dir)
|
||||
|
||||
if(!pure_diagonal && !diagonals_first) // not a purely diagonal trajectory and we don't want all diagonal moves to be done first
|
||||
if(diagonal_error >= 0 && max(dist_x, dist_y) - dist_travelled != 1) // we do a step forward unless we're right before the target
|
||||
step = get_step(AM, dx)
|
||||
diagonal_error += (diagonal_error < 0) ? dist_x / 2 : -dist_y
|
||||
|
||||
if(!step) // going off the edge of the map makes get_step return null, don't let things go off the edge
|
||||
finalize()
|
||||
return
|
||||
|
||||
AM.Move(step, get_dir(AM, step))
|
||||
|
||||
if(!AM.throwing) // we hit something during our move
|
||||
finalize(hit = TRUE)
|
||||
return
|
||||
|
||||
dist_travelled++
|
||||
|
||||
if(dist_travelled > MAX_THROWING_DIST)
|
||||
finalize()
|
||||
return
|
||||
|
||||
/datum/thrownthing/proc/finalize(hit = FALSE)
|
||||
set waitfor = 0
|
||||
throw_master.processing_list -= thrownthing
|
||||
// done throwning, either because it hit something or it finished moving
|
||||
thrownthing.throwing = null
|
||||
if(!hit)
|
||||
for(var/thing in get_turf(thrownthing)) //looking for our target on the turf we land on.
|
||||
var/atom/A = thing
|
||||
if(A == target)
|
||||
hit = 1
|
||||
thrownthing.throw_impact(A, src)
|
||||
break
|
||||
if(!hit)
|
||||
thrownthing.throw_impact(get_turf(thrownthing), src) // we haven't hit something yet and we still must, let's hit the ground.
|
||||
thrownthing.newtonian_move(init_dir)
|
||||
else
|
||||
thrownthing.newtonian_move(init_dir)
|
||||
if(callback)
|
||||
callback.Invoke()
|
||||
|
||||
/datum/thrownthing/proc/hit_atom(atom/A)
|
||||
thrownthing.throw_impact(A, src)
|
||||
thrownthing.newtonian_move(init_dir)
|
||||
finalize(TRUE)
|
||||
|
||||
/datum/thrownthing/proc/hitcheck()
|
||||
for(var/thing in get_turf(thrownthing))
|
||||
var/atom/movable/AM = thing
|
||||
if(AM == thrownthing)
|
||||
continue
|
||||
if(AM.density && !(AM.pass_flags & LETPASSTHROW) && !(AM.flags & ON_BORDER))
|
||||
thrownthing.throwing = null
|
||||
thrownthing.throw_impact(AM, src)
|
||||
return TRUE
|
||||
@@ -39,7 +39,6 @@
|
||||
var/allow_Metadata = 0 // Metadata is supported.
|
||||
var/popup_admin_pm = 0 //adminPMs to non-admins show in a pop-up 'reply' window when set to 1.
|
||||
var/Ticklag = 0.5
|
||||
var/Tickcomp = 0
|
||||
var/socket_talk = 0 // use socket_talk to communicate with other processes
|
||||
var/list/resource_urls = null
|
||||
var/antag_hud_allowed = 0 // Ghosts can turn on Antagovision to see a HUD of who is the bad guys this round.
|
||||
@@ -445,9 +444,6 @@
|
||||
if("socket_talk")
|
||||
socket_talk = text2num(value)
|
||||
|
||||
if("tickcomp")
|
||||
Tickcomp = 1
|
||||
|
||||
if("allow_antag_hud")
|
||||
config.antag_hud_allowed = 1
|
||||
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
USAGE:
|
||||
|
||||
var/datum/callback/C = new(object|null, /proc/type/path|"procstring", arg1, arg2, ... argn)
|
||||
var/timerid = addtimer(C, time, timertype)
|
||||
OR
|
||||
var/timerid = addtimer(CALLBACK(object|null, /proc/type/path|procstring, arg1, arg2, ... argn), time, timertype)
|
||||
|
||||
Note: proc strings can only be given for datum proc calls, global procs must be proc paths
|
||||
Also proc strings are strongly advised against because they don't compile error if the proc stops existing
|
||||
See the note on proc typepath shortcuts
|
||||
|
||||
INVOKING THE CALLBACK:
|
||||
var/result = C.Invoke(args, to, add) //additional args are added after the ones given when the callback was created
|
||||
OR
|
||||
var/result = C.InvokeAsync(args, to, add) //Sleeps will not block, returns . on the first sleep (then continues on in the "background" after the sleep/block ends), otherwise operates normally.
|
||||
OR
|
||||
INVOKE_ASYNC(<CALLBACK args>) to immediately create and call InvokeAsync
|
||||
|
||||
PROC TYPEPATH SHORTCUTS (these operate on paths, not types, so to these shortcuts, datum is NOT a parent of atom, etc...)
|
||||
|
||||
global proc while in another global proc:
|
||||
.procname
|
||||
Example:
|
||||
CALLBACK(GLOBAL_PROC, .some_proc_here)
|
||||
|
||||
proc defined on current(src) object (when in a /proc/ and not an override) OR overridden at src or any of it's parents:
|
||||
.procname
|
||||
Example:
|
||||
CALLBACK(src, .some_proc_here)
|
||||
|
||||
|
||||
when the above doesn't apply:
|
||||
.proc/procname
|
||||
Example:
|
||||
CALLBACK(src, .proc/some_proc_here)
|
||||
|
||||
proc defined on a parent of a some type:
|
||||
/some/type/.proc/some_proc_here
|
||||
|
||||
|
||||
|
||||
Other wise you will have to do the full typepath of the proc (/type/of/thing/proc/procname)
|
||||
|
||||
*/
|
||||
|
||||
/datum/callback
|
||||
var/datum/object = GLOBAL_PROC
|
||||
var/delegate
|
||||
var/list/arguments
|
||||
|
||||
/datum/callback/New(thingtocall, proctocall, ...)
|
||||
if(thingtocall)
|
||||
object = thingtocall
|
||||
delegate = proctocall
|
||||
if(length(args) > 2)
|
||||
arguments = args.Copy(3)
|
||||
|
||||
/proc/ImmediateInvokeAsync(thingtocall, proctocall, ...)
|
||||
set waitfor = FALSE
|
||||
|
||||
if(!thingtocall)
|
||||
return
|
||||
|
||||
var/list/calling_arguments = length(args) > 2 ? args.Copy(3) : null
|
||||
|
||||
if(thingtocall == GLOBAL_PROC)
|
||||
call(proctocall)(arglist(calling_arguments))
|
||||
else
|
||||
call(thingtocall, proctocall)(arglist(calling_arguments))
|
||||
|
||||
/datum/callback/proc/Invoke(...)
|
||||
if(!object)
|
||||
return
|
||||
var/list/calling_arguments = arguments
|
||||
if(length(args))
|
||||
if(length(arguments))
|
||||
calling_arguments = calling_arguments + args //not += so that it creates a new list so the arguments list stays clean
|
||||
else
|
||||
calling_arguments = args
|
||||
if(object == GLOBAL_PROC)
|
||||
return call(delegate)(arglist(calling_arguments))
|
||||
return call(object, delegate)(arglist(calling_arguments))
|
||||
|
||||
//copy and pasted because fuck proc overhead
|
||||
/datum/callback/proc/InvokeAsync(...)
|
||||
set waitfor = FALSE
|
||||
if(!object)
|
||||
return
|
||||
var/list/calling_arguments = arguments
|
||||
if(length(args))
|
||||
if(length(arguments))
|
||||
calling_arguments = calling_arguments + args //not += so that it creates a new list so the arguments list stays clean
|
||||
else
|
||||
calling_arguments = args
|
||||
if(object == GLOBAL_PROC)
|
||||
return call(delegate)(arglist(calling_arguments))
|
||||
return call(object, delegate)(arglist(calling_arguments))
|
||||
+7
-5
@@ -9,7 +9,6 @@
|
||||
var/blood_color
|
||||
var/last_bumped = 0
|
||||
var/pass_flags = 0
|
||||
var/throwpass = 0
|
||||
var/germ_level = GERM_LEVEL_AMBIENT // The higher the germ level, the more germ on the atom.
|
||||
var/simulated = 1 //filter for actions - used by lighting overlays
|
||||
var/atom_say_verb = "says"
|
||||
@@ -236,10 +235,13 @@
|
||||
/atom/proc/emag_act()
|
||||
return
|
||||
|
||||
/atom/proc/hitby(atom/movable/AM as mob|obj)
|
||||
if(density)
|
||||
AM.throwing = 0
|
||||
return
|
||||
/atom/proc/hitby(atom/movable/AM, skipcatch, hitpush, blocked)
|
||||
if(density && !has_gravity(AM)) //thrown stuff bounces off dense stuff in no grav, unless the thrown stuff ends up inside what it hit(embedding, bola, etc...).
|
||||
addtimer(src, "hitby_react", 2, TRUE, AM)
|
||||
|
||||
/atom/proc/hitby_react(atom/movable/AM)
|
||||
if(AM && isturf(AM.loc))
|
||||
step(AM, turn(AM.dir, 180))
|
||||
|
||||
/atom/proc/add_hiddenprint(mob/living/M as mob)
|
||||
if(isnull(M)) return
|
||||
|
||||
+117
-145
@@ -6,15 +6,21 @@
|
||||
// var/elevation = 2 - not used anywhere
|
||||
var/move_speed = 10
|
||||
var/l_move_time = 1
|
||||
var/throwing = 0
|
||||
var/thrower
|
||||
var/turf/throw_source = null
|
||||
var/throw_speed = 2
|
||||
var/datum/thrownthing/throwing = null
|
||||
var/throw_speed = 2 //How many tiles to move per ds when being thrown. Float values are fully supported
|
||||
var/throw_range = 7
|
||||
var/no_spin_thrown = 0 //set this to 1 if you don't want an item that you throw to spin, no matter what. -Fox
|
||||
var/no_spin = 0
|
||||
var/no_spin_thrown = 0
|
||||
var/moved_recently = 0
|
||||
var/mob/pulledby = null
|
||||
|
||||
var/inertia_dir = 0
|
||||
var/atom/inertia_last_loc
|
||||
var/inertia_moving = 0
|
||||
var/inertia_next_move = 0
|
||||
var/inertia_move_delay = 5
|
||||
|
||||
var/moving_diagonally = 0 //0: not doing a diagonal move. 1 and 2: doing the first/second step of the diagonal move
|
||||
|
||||
var/area/areaMaster
|
||||
|
||||
@@ -71,61 +77,74 @@
|
||||
if(!(direct & (direct - 1))) //Cardinal move
|
||||
. = ..()
|
||||
else //Diagonal move, split it into cardinal moves
|
||||
moving_diagonally = FIRST_DIAG_STEP
|
||||
if(direct & 1)
|
||||
if(direct & 4)
|
||||
if(step(src, NORTH))
|
||||
moving_diagonally = SECOND_DIAG_STEP
|
||||
. = step(src, EAST)
|
||||
else if(step(src, EAST))
|
||||
moving_diagonally = SECOND_DIAG_STEP
|
||||
. = step(src, NORTH)
|
||||
else if(direct & 8)
|
||||
if(step(src, NORTH))
|
||||
moving_diagonally = SECOND_DIAG_STEP
|
||||
. = step(src, WEST)
|
||||
else if(step(src, WEST))
|
||||
moving_diagonally = SECOND_DIAG_STEP
|
||||
. = step(src, NORTH)
|
||||
else if(direct & 2)
|
||||
if(direct & 4)
|
||||
if(step(src, SOUTH))
|
||||
moving_diagonally = SECOND_DIAG_STEP
|
||||
. = step(src, EAST)
|
||||
else if(step(src, EAST))
|
||||
moving_diagonally = SECOND_DIAG_STEP
|
||||
. = step(src, SOUTH)
|
||||
else if(direct & 8)
|
||||
if(step(src, SOUTH))
|
||||
moving_diagonally = SECOND_DIAG_STEP
|
||||
. = step(src, WEST)
|
||||
else if(step(src, WEST))
|
||||
moving_diagonally = SECOND_DIAG_STEP
|
||||
. = step(src, SOUTH)
|
||||
|
||||
moving_diagonally = 0
|
||||
return
|
||||
|
||||
if(!loc || (loc == oldloc && oldloc != newloc))
|
||||
last_move = 0
|
||||
return
|
||||
|
||||
if(.)
|
||||
Moved(oldloc, direct)
|
||||
|
||||
last_move = direct
|
||||
src.move_speed = world.time - src.l_move_time
|
||||
src.l_move_time = world.time
|
||||
|
||||
spawn(5) // Causes space drifting. /tg/station has no concept of speed, we just use 5
|
||||
if(loc && direct && last_move == direct)
|
||||
if(loc == newloc) //Remove this check and people can accelerate. Not opening that can of worms just yet.
|
||||
newtonian_move(last_move)
|
||||
|
||||
if(. && buckled_mob && !handle_buckled_mob_movement(loc, direct)) //movement failed due to buckled mob
|
||||
. = 0
|
||||
|
||||
// Called after a successful Move(). By this point, we've already moved
|
||||
/atom/movable/proc/Moved(atom/OldLoc, Dir)
|
||||
if(!inertia_moving)
|
||||
inertia_next_move = world.time + inertia_move_delay
|
||||
newtonian_move(Dir)
|
||||
return 1
|
||||
|
||||
// Previously known as Crossed()
|
||||
// Previously known as HasEntered()
|
||||
// This is automatically called when something enters your square
|
||||
/atom/movable/Crossed(atom/movable/AM)
|
||||
return
|
||||
|
||||
/atom/movable/Bump(var/atom/A as mob|obj|turf|area, sendBump)
|
||||
if(src.throwing)
|
||||
src.throw_impact(A)
|
||||
|
||||
if(A && sendBump)
|
||||
A.last_bumped = world.time
|
||||
/atom/movable/Bump(atom/A, yes) //the "yes" arg is to differentiate our Bump proc from byond's, without it every Bump() call would become a double Bump().
|
||||
if(A && yes)
|
||||
if(throwing)
|
||||
throwing.hit_atom(A)
|
||||
. = 1
|
||||
if(!A || qdeleted(A))
|
||||
return
|
||||
A.Bumped(src)
|
||||
else
|
||||
..()
|
||||
|
||||
/atom/movable/proc/forceMove(atom/destination)
|
||||
var/turf/old_loc = loc
|
||||
@@ -166,29 +185,6 @@
|
||||
update_canmove() //if the mob was asleep inside a container and then got forceMoved out we need to make them fall.
|
||||
|
||||
|
||||
//called when src is thrown into hit_atom
|
||||
/atom/movable/proc/throw_impact(atom/hit_atom, var/speed)
|
||||
if(istype(hit_atom,/mob/living))
|
||||
var/mob/living/M = hit_atom
|
||||
M.hitby(src,speed)
|
||||
|
||||
else if(isobj(hit_atom))
|
||||
var/obj/O = hit_atom
|
||||
if(!O.anchored)
|
||||
step(O, src.dir)
|
||||
O.hitby(src,speed)
|
||||
|
||||
else if(isturf(hit_atom))
|
||||
src.throwing = 0
|
||||
var/turf/T = hit_atom
|
||||
if(T.density)
|
||||
spawn(2)
|
||||
step(src, turn(src.dir, 180))
|
||||
if(istype(src,/mob/living))
|
||||
var/mob/living/M = src
|
||||
M.turf_collision(T, speed)
|
||||
|
||||
|
||||
//Called whenever an object moves and by mobs when they attempt to move themselves through space
|
||||
//And when an object or action applies a force on src, see newtonian_move() below
|
||||
//Return 0 to have src start/keep drifting in a no-grav area and 1 to stop/not start drifting
|
||||
@@ -201,13 +197,15 @@
|
||||
if(pulledby && !pulledby.pulling)
|
||||
return 1
|
||||
|
||||
if(throwing)
|
||||
return 1
|
||||
|
||||
if(locate(/obj/structure/lattice) in range(1, get_turf(src))) //Not realistic but makes pushing things in space easier
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/atom/movable/proc/newtonian_move(direction) //Only moves the object if it's under no gravity
|
||||
|
||||
if(!loc || Process_Spacemove(0))
|
||||
inertia_dir = 0
|
||||
return 0
|
||||
@@ -216,119 +214,93 @@
|
||||
if(!direction)
|
||||
return 1
|
||||
|
||||
var/old_dir = dir
|
||||
. = step(src, direction)
|
||||
dir = old_dir
|
||||
inertia_last_loc = loc
|
||||
drift_master.processing_list[src] = src
|
||||
return 1
|
||||
|
||||
//decided whether a movable atom being thrown can pass through the turf it is in.
|
||||
/atom/movable/proc/hit_check(var/speed)
|
||||
if(src.throwing)
|
||||
for(var/atom/A in get_turf(src))
|
||||
if(A == src) continue
|
||||
if(istype(A,/mob/living))
|
||||
if(A:lying) continue
|
||||
src.throw_impact(A,speed)
|
||||
if(isobj(A))
|
||||
if(A.density && !A.throwpass) // **TODO: Better behaviour for windows which are dense, but shouldn't always stop movement
|
||||
src.throw_impact(A,speed)
|
||||
|
||||
/atom/movable/proc/throw_at_fast(atom/target, range, speed, thrower, no_spin)
|
||||
//called when src is thrown into hit_atom
|
||||
/atom/movable/proc/throw_impact(atom/hit_atom, throwingdatum)
|
||||
set waitfor = 0
|
||||
throw_at(target, range, speed, thrower, no_spin)
|
||||
return hit_atom.hitby(src)
|
||||
|
||||
/atom/movable/proc/throw_at(atom/target, range, speed, thrower, no_spin)
|
||||
if(!target || !src || (flags & NODROP))
|
||||
/atom/movable/hitby(atom/movable/AM, skipcatch, hitpush = 1, blocked)
|
||||
if(!anchored && hitpush)
|
||||
step(src, AM.dir)
|
||||
..()
|
||||
|
||||
/atom/movable/proc/throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, diagonals_first = FALSE, var/datum/callback/callback)
|
||||
if(!target || (flags & NODROP) || speed <= 0)
|
||||
return 0
|
||||
//use a modified version of Bresenham's algorithm to get from the atom's current position to that of the target
|
||||
|
||||
src.throwing = 1
|
||||
src.thrower = thrower
|
||||
src.throw_source = get_turf(src) //store the origin turf
|
||||
if(target.allow_spin) // turns out 1000+ spinning objects being thrown at the singularity creates lag - Iamgoofball
|
||||
if(!no_spin_thrown && !no_spin)
|
||||
SpinAnimation(5, 1)
|
||||
if(pulledby)
|
||||
pulledby.stop_pulling()
|
||||
|
||||
// They are moving! Wouldn't it be cool if we calculated their momentum and added it to the throw?
|
||||
if(thrower && thrower.last_move && thrower.client && thrower.client.move_delay >= world.time + world.tick_lag * 2)
|
||||
var/user_momentum = thrower.movement_delay()
|
||||
if(!user_momentum) // no movement_delay, this means they move once per byond tick, let's calculate from that instead
|
||||
user_momentum = world.tick_lag
|
||||
|
||||
user_momentum = 1 / user_momentum // convert from ds to the tiles per ds that throw_at uses
|
||||
|
||||
if(get_dir(thrower, target) & last_move)
|
||||
user_momentum = user_momentum // basically a noop, but needed
|
||||
else if(get_dir(target, thrower) & last_move)
|
||||
user_momentum = -user_momentum // we are moving away from the target, lets slowdown the throw accordingly
|
||||
else
|
||||
user_momentum = 0
|
||||
|
||||
if(user_momentum)
|
||||
// first lets add that momentum to range
|
||||
range *= (user_momentum / speed) + 1
|
||||
//then lets add it to speed
|
||||
speed += user_momentum
|
||||
if(speed <= 0)
|
||||
return //no throw speed, the user was moving too fast.
|
||||
|
||||
var/datum/thrownthing/TT = new()
|
||||
TT.thrownthing = src
|
||||
TT.target = target
|
||||
TT.target_turf = get_turf(target)
|
||||
TT.init_dir = get_dir(src, target)
|
||||
TT.maxrange = range
|
||||
TT.speed = speed
|
||||
TT.thrower = thrower
|
||||
TT.diagonals_first = diagonals_first
|
||||
TT.callback = callback
|
||||
|
||||
var/dist_x = abs(target.x - src.x)
|
||||
var/dist_y = abs(target.y - src.y)
|
||||
var/dx = (target.x > src.x) ? EAST : WEST
|
||||
var/dy = (target.y > src.y) ? NORTH : SOUTH
|
||||
|
||||
var/dx
|
||||
if(target.x > src.x)
|
||||
dx = EAST
|
||||
else
|
||||
dx = WEST
|
||||
if(dist_x == dist_y)
|
||||
TT.pure_diagonal = 1
|
||||
|
||||
var/dy
|
||||
if(target.y > src.y)
|
||||
dy = NORTH
|
||||
else
|
||||
dy = SOUTH
|
||||
var/dist_travelled = 0
|
||||
var/dist_since_sleep = 0
|
||||
var/area/a = get_area(src.loc)
|
||||
if(dist_x > dist_y)
|
||||
var/error = dist_x/2 - dist_y
|
||||
while(src && target &&((((src.x < target.x && dx == EAST) || (src.x > target.x && dx == WEST)) && dist_travelled < range) || (a && a.has_gravity == 0) || istype(src.loc, /turf/space)) && src.throwing && istype(src.loc, /turf))
|
||||
// only stop when we've gone the whole distance (or max throw range) and are on a non-space tile, or hit something, or hit the end of the map, or someone picks it up
|
||||
if(error < 0)
|
||||
var/atom/step = get_step(src, dy)
|
||||
if(!step) // going off the edge of the map makes get_step return null, don't let things go off the edge
|
||||
break
|
||||
src.Move(step, get_dir(loc, step))
|
||||
hit_check(speed)
|
||||
error += dist_x
|
||||
dist_travelled++
|
||||
dist_since_sleep++
|
||||
if(dist_since_sleep >= speed)
|
||||
dist_since_sleep = 0
|
||||
sleep(1)
|
||||
else
|
||||
var/atom/step = get_step(src, dx)
|
||||
if(!step) // going off the edge of the map makes get_step return null, don't let things go off the edge
|
||||
break
|
||||
src.Move(step)
|
||||
hit_check(speed)
|
||||
error -= dist_y
|
||||
dist_travelled++
|
||||
dist_since_sleep++
|
||||
if(dist_since_sleep >= speed)
|
||||
dist_since_sleep = 0
|
||||
sleep(1)
|
||||
a = get_area(src.loc)
|
||||
else
|
||||
var/error = dist_y/2 - dist_x
|
||||
while(src && target &&((((src.y < target.y && dy == NORTH) || (src.y > target.y && dy == SOUTH)) && dist_travelled < range) || (a && a.has_gravity == 0) || istype(src.loc, /turf/space)) && src.throwing && istype(src.loc, /turf))
|
||||
// only stop when we've gone the whole distance (or max throw range) and are on a non-space tile, or hit something, or hit the end of the map, or someone picks it up
|
||||
if(error < 0)
|
||||
var/atom/step = get_step(src, dx)
|
||||
if(!step) // going off the edge of the map makes get_step return null, don't let things go off the edge
|
||||
break
|
||||
src.Move(step)
|
||||
hit_check(speed)
|
||||
error += dist_y
|
||||
dist_travelled++
|
||||
dist_since_sleep++
|
||||
if(dist_since_sleep >= speed)
|
||||
dist_since_sleep = 0
|
||||
sleep(1)
|
||||
else
|
||||
var/atom/step = get_step(src, dy)
|
||||
if(!step) // going off the edge of the map makes get_step return null, don't let things go off the edge
|
||||
break
|
||||
src.Move(step)
|
||||
hit_check(speed)
|
||||
error -= dist_x
|
||||
dist_travelled++
|
||||
dist_since_sleep++
|
||||
if(dist_since_sleep >= speed)
|
||||
dist_since_sleep = 0
|
||||
sleep(1)
|
||||
else if(dist_x <= dist_y)
|
||||
var/olddist_x = dist_x
|
||||
var/olddx = dx
|
||||
dist_x = dist_y
|
||||
dist_y = olddist_x
|
||||
dx = dy
|
||||
dy = olddx
|
||||
TT.dist_x = dist_x
|
||||
TT.dist_y = dist_y
|
||||
TT.dx = dx
|
||||
TT.dy = dy
|
||||
TT.diagonal_error = dist_x / 2 - dist_y
|
||||
TT.start_time = world.time
|
||||
|
||||
a = get_area(src.loc)
|
||||
if(pulledby)
|
||||
pulledby.stop_pulling()
|
||||
|
||||
//done throwing, either because it hit something or it finished moving
|
||||
if(isobj(src)) src.throw_impact(get_turf(src),speed)
|
||||
src.throwing = 0
|
||||
src.thrower = null
|
||||
src.throw_source = null
|
||||
throwing = TT
|
||||
if(spin && !no_spin && !no_spin_thrown)
|
||||
SpinAnimation(5, 1)
|
||||
|
||||
throw_master.processing_list[src] = TT
|
||||
TT.tick()
|
||||
|
||||
|
||||
//Overlays
|
||||
|
||||
@@ -498,7 +498,7 @@
|
||||
icon_state = "hoop"
|
||||
anchored = 1
|
||||
density = 1
|
||||
throwpass = 1
|
||||
pass_flags = LETPASSTHROW
|
||||
|
||||
/obj/structure/holohoop/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
|
||||
if(istype(W, /obj/item/weapon/grab) && get_dist(src,user)<2)
|
||||
|
||||
@@ -167,18 +167,16 @@
|
||||
..()
|
||||
|
||||
//When an object is thrown at the window
|
||||
/obj/machinery/door/window/hitby(AM as mob|obj)
|
||||
|
||||
/obj/machinery/door/window/hitby(atom/movable/AM)
|
||||
..()
|
||||
var/tforce = 0
|
||||
if(ismob(AM))
|
||||
tforce = 40
|
||||
else
|
||||
tforce = AM:throwforce
|
||||
else if(isobj(AM))
|
||||
var/obj/O = AM
|
||||
tforce = O.throwforce
|
||||
playsound(loc, 'sound/effects/Glasshit.ogg', 100, 1)
|
||||
take_damage(tforce)
|
||||
//..() //Does this really need to be here twice? The parent proc doesn't even do anything yet. - Nodrak
|
||||
return
|
||||
|
||||
/obj/machinery/door/window/mech_melee_attack(obj/mecha/M)
|
||||
if(M.damtype == "brute")
|
||||
|
||||
@@ -94,51 +94,49 @@
|
||||
|
||||
|
||||
/obj/machinery/shield/hitby(AM as mob|obj)
|
||||
|
||||
//Super realistic, resource-intensive, real-time damage calculations.
|
||||
..()
|
||||
var/tforce = 0
|
||||
if(ismob(AM))
|
||||
tforce = 40
|
||||
else
|
||||
tforce = AM:throwforce
|
||||
else if(isobj(AM))
|
||||
var/obj/O = AM
|
||||
tforce = O.throwforce
|
||||
|
||||
src.health -= tforce
|
||||
health -= tforce
|
||||
|
||||
//This seemed to be the best sound for hitting a force field.
|
||||
playsound(src.loc, 'sound/effects/EMPulse.ogg', 100, 1)
|
||||
playsound(loc, 'sound/effects/EMPulse.ogg', 100, 1)
|
||||
|
||||
//Handle the destruction of the shield
|
||||
if(src.health <= 0)
|
||||
if(health <= 0)
|
||||
visible_message("<span class='notice'>The [src] dissipates</span>")
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
//The shield becomes dense to absorb the blow.. purely asthetic.
|
||||
opacity = 1
|
||||
spawn(20) if(src) opacity = 0
|
||||
|
||||
..()
|
||||
return
|
||||
|
||||
spawn(20)
|
||||
if(src)
|
||||
opacity = 0
|
||||
|
||||
|
||||
/obj/machinery/shieldgen
|
||||
name = "Emergency shield projector"
|
||||
desc = "Used to seal minor hull breaches."
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "shieldoff"
|
||||
density = 1
|
||||
opacity = 0
|
||||
anchored = 0
|
||||
pressure_resistance = 2*ONE_ATMOSPHERE
|
||||
req_access = list(access_engine)
|
||||
var/const/max_health = 100
|
||||
var/health = max_health
|
||||
var/active = 0
|
||||
var/malfunction = 0 //Malfunction causes parts of the shield to slowly dissapate
|
||||
var/list/deployed_shields = list()
|
||||
var/is_open = 0 //Whether or not the wires are exposed
|
||||
var/locked = 0
|
||||
name = "Emergency shield projector"
|
||||
desc = "Used to seal minor hull breaches."
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "shieldoff"
|
||||
density = 1
|
||||
opacity = 0
|
||||
anchored = 0
|
||||
pressure_resistance = 2*ONE_ATMOSPHERE
|
||||
req_access = list(access_engine)
|
||||
var/const/max_health = 100
|
||||
var/health = max_health
|
||||
var/active = 0
|
||||
var/malfunction = 0 //Malfunction causes parts of the shield to slowly dissapate
|
||||
var/list/deployed_shields = list()
|
||||
var/is_open = 0 //Whether or not the wires are exposed
|
||||
var/locked = 0
|
||||
|
||||
/obj/machinery/shieldgen/Destroy()
|
||||
QDEL_LIST(deployed_shields)
|
||||
|
||||
@@ -368,9 +368,12 @@
|
||||
breakthrough = 1
|
||||
|
||||
else
|
||||
throwing = 0 //so mechas don't get stuck when landing after being sent by a Mass Driver
|
||||
if(throwing)
|
||||
throwing.finalize(FALSE)
|
||||
crashing = null
|
||||
|
||||
..()
|
||||
|
||||
if(breakthrough)
|
||||
if(crashing)
|
||||
spawn(1)
|
||||
@@ -524,7 +527,7 @@
|
||||
user.create_attack_log("<font color='red'>attacked [name]</font>")
|
||||
return
|
||||
|
||||
/obj/mecha/hitby(atom/movable/A as mob|obj) //wrapper
|
||||
/obj/mecha/hitby(atom/movable/A) //wrapper
|
||||
..()
|
||||
log_message("Hit by [A].",1)
|
||||
|
||||
@@ -537,6 +540,7 @@
|
||||
dam_coeff = B.damage_coeff
|
||||
counter_tracking = 1
|
||||
break
|
||||
|
||||
if(istype(A, /obj/item/mecha_parts/mecha_tracking))
|
||||
if(!counter_tracking)
|
||||
A.forceMove(src)
|
||||
|
||||
@@ -104,9 +104,9 @@
|
||||
/obj/structure/alien/resin/hitby(atom/movable/AM)
|
||||
..()
|
||||
var/tforce = 0
|
||||
if(!isobj(AM))
|
||||
if(ismob(AM))
|
||||
tforce = 10
|
||||
else
|
||||
else if(isobj(AM))
|
||||
var/obj/O = AM
|
||||
tforce = O.throwforce
|
||||
playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
/obj/item/clothing/gloves/color/black = 20,
|
||||
/obj/item/clothing/head/hardhat = 10,
|
||||
/obj/item/clothing/head/hardhat/red = 10,
|
||||
/obj/item/clothing/head/that{throwforce = 1; throwing = 1} = 10,
|
||||
/obj/item/clothing/head/that = 10,
|
||||
/obj/item/clothing/head/ushanka = 10,
|
||||
/obj/item/clothing/head/welding = 10,
|
||||
/obj/item/clothing/mask/gas = 10,
|
||||
|
||||
+21
-34
@@ -61,6 +61,8 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d
|
||||
var/block_chance = 0
|
||||
var/hit_reaction_chance = 0 //If you want to have something unrelated to blocking/armour piercing etc. Maybe not needed, but trying to think ahead/allow more freedom
|
||||
|
||||
var/mob/thrownby = null
|
||||
|
||||
var/toolspeed = 1 // If this item is a tool, the speed multiplier
|
||||
|
||||
/* Species-specific sprites, concept stolen from Paradise//vg/.
|
||||
@@ -217,7 +219,8 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d
|
||||
var/obj/item/weapon/storage/S = src.loc
|
||||
S.remove_from_storage(src)
|
||||
|
||||
src.throwing = 0
|
||||
if(throwing)
|
||||
throwing.finalize(FALSE)
|
||||
if(loc == user)
|
||||
if(!user.unEquip(src))
|
||||
return 0
|
||||
@@ -231,36 +234,6 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d
|
||||
user.put_in_active_hand(src)
|
||||
return 1
|
||||
|
||||
|
||||
/obj/item/attack_alien(mob/user as mob)
|
||||
|
||||
if(isalien(user)) // -- TLE
|
||||
var/mob/living/carbon/alien/A = user
|
||||
|
||||
if(!A.has_fine_manipulation)
|
||||
if(src in A.contents) // To stop Aliens having items stuck in their pockets
|
||||
A.unEquip(src)
|
||||
to_chat(user, "Your claws aren't capable of such fine manipulation.")
|
||||
return
|
||||
|
||||
if(istype(src.loc, /obj/item/weapon/storage))
|
||||
for(var/mob/M in range(1, src.loc))
|
||||
if(M.s_active == src.loc)
|
||||
if(M.client)
|
||||
M.client.screen -= src
|
||||
src.throwing = 0
|
||||
if(src.loc == user)
|
||||
if(!user.unEquip(src))
|
||||
return
|
||||
else
|
||||
if(istype(src.loc, /mob/living))
|
||||
return
|
||||
src.pickup(user)
|
||||
|
||||
user.put_in_active_hand(src)
|
||||
return
|
||||
|
||||
|
||||
/obj/item/attack_alien(mob/user as mob)
|
||||
var/mob/living/carbon/alien/A = user
|
||||
|
||||
@@ -323,9 +296,6 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d
|
||||
/obj/item/proc/talk_into(mob/M, var/text, var/channel=null)
|
||||
return
|
||||
|
||||
/obj/item/proc/moved(mob/user, old_loc)
|
||||
return
|
||||
|
||||
/obj/item/proc/dropped(mob/user)
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
@@ -546,6 +516,23 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d
|
||||
throw_at(S,14,3)
|
||||
else ..()
|
||||
|
||||
/obj/item/throw_impact(atom/A)
|
||||
if(A && !qdeleted(A))
|
||||
var/itempush = 1
|
||||
if(w_class < 4)
|
||||
itempush = 0 // too light to push anything
|
||||
return A.hitby(src, 0, itempush)
|
||||
|
||||
/obj/item/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback)
|
||||
thrownby = thrower
|
||||
callback = CALLBACK(src, .proc/after_throw, callback) //replace their callback with our own
|
||||
. = ..(target, range, speed, thrower, spin, diagonals_first, callback)
|
||||
|
||||
/obj/item/proc/after_throw(datum/callback/callback)
|
||||
if(callback) //call the original callback
|
||||
. = callback.Invoke()
|
||||
throw_speed = initial(throw_speed) //explosions change this.
|
||||
|
||||
/obj/item/proc/pwr_drain()
|
||||
return 0 // Process Kill
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@ var/list/tape_roll_applications = list()
|
||||
if(!density) return 1
|
||||
if(height==0) return 1
|
||||
|
||||
if((mover.pass_flags & PASSTABLE || istype(mover, /obj/effect/meteor) || mover.throwing == 1) )
|
||||
if((mover.pass_flags & PASSTABLE || istype(mover, /obj/effect/meteor) || mover.throwing))
|
||||
return 1
|
||||
else if(ismob(mover) && allowed(mover))
|
||||
return 1
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
last = C
|
||||
break
|
||||
|
||||
/obj/item/weapon/twohanded/rcl/moved(mob/user, turf/old_loc, direct)
|
||||
/obj/item/weapon/twohanded/rcl/on_mob_move(direct, mob/user)
|
||||
if(active)
|
||||
trigger(user)
|
||||
|
||||
|
||||
@@ -111,10 +111,10 @@
|
||||
/obj/item/weapon/dice/attack_self(mob/user as mob)
|
||||
diceroll(user)
|
||||
|
||||
/obj/item/weapon/dice/throw_at(atom/target, range, speed, mob/user as mob)
|
||||
/obj/item/weapon/dice/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback)
|
||||
if(!..())
|
||||
return
|
||||
diceroll(user)
|
||||
diceroll(thrower)
|
||||
|
||||
/obj/item/weapon/dice/proc/diceroll(mob/user)
|
||||
result = rand(1, sides)
|
||||
@@ -133,7 +133,7 @@
|
||||
user.visible_message("<span class='notice'>[user] has thrown [src]. It lands on [result]. [comment]</span>", \
|
||||
"<span class='notice'>You throw [src]. It lands on [result]. [comment]</span>", \
|
||||
"<span class='italics'>You hear [src] rolling, it sounds like a [fake_result].</span>")
|
||||
else if(src.throwing == 0) //Dice was thrown and is coming to rest
|
||||
else if(!throwing) //Dice was thrown and is coming to rest
|
||||
visible_message("<span class='notice'>[src] rolls to a stop, landing on [result]. [comment]</span>")
|
||||
|
||||
/obj/item/weapon/dice/d20/e20/diceroll(mob/user as mob, thrown)
|
||||
|
||||
@@ -316,4 +316,7 @@ a {
|
||||
for(var/obj/item/Item in contents) //Empty out the contents
|
||||
Item.forceMove(new_loc)
|
||||
if(burn)
|
||||
Item.fire_act() //Set them on fire, too
|
||||
Item.fire_act() //Set them on fire, too
|
||||
|
||||
/obj/proc/on_mob_move(dir, mob/user)
|
||||
return
|
||||
@@ -56,7 +56,7 @@
|
||||
if(throwing) // you keep some momentum when getting out of a thrown closet
|
||||
step(AM, dir)
|
||||
if(throwing)
|
||||
throwing = 0
|
||||
throwing.finalize(FALSE)
|
||||
|
||||
/obj/structure/closet/proc/open()
|
||||
if(opened)
|
||||
@@ -327,7 +327,7 @@
|
||||
/obj/structure/closet/attack_hand(mob/user)
|
||||
add_fingerprint(user)
|
||||
toggle(user)
|
||||
|
||||
|
||||
/obj/structure/closet/attack_ghost(mob/user)
|
||||
if(user.can_advanced_admin_interact())
|
||||
toggle(user)
|
||||
|
||||
@@ -297,8 +297,8 @@
|
||||
tforce = 5
|
||||
else if(isobj(AM))
|
||||
if(prob(50))
|
||||
var/obj/item/I = AM
|
||||
tforce = max(0, I.throwforce * 0.5)
|
||||
var/obj/O = AM
|
||||
tforce = max(0, O.throwforce * 0.5)
|
||||
else if(anchored && !broken)
|
||||
var/turf/T = get_turf(src)
|
||||
var/obj/structure/cable/C = T.get_cable_node()
|
||||
|
||||
@@ -190,7 +190,7 @@
|
||||
layer = 2.0
|
||||
var/obj/structure/morgue/connected = null
|
||||
anchored = 1.0
|
||||
throwpass = 1
|
||||
pass_flags = LETPASSTHROW
|
||||
|
||||
|
||||
/obj/structure/m_tray/attack_hand(mob/user as mob)
|
||||
@@ -432,7 +432,7 @@
|
||||
layer = 2.0
|
||||
var/obj/structure/crematorium/connected = null
|
||||
anchored = 1.0
|
||||
throwpass = 1
|
||||
pass_flags = LETPASSTHROW
|
||||
|
||||
/obj/structure/c_tray/attack_hand(mob/user as mob)
|
||||
if(connected)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
density = 1
|
||||
anchored = 1.0
|
||||
layer = 2.8
|
||||
throwpass = 1 //You can throw objects over this, despite it's density.")
|
||||
pass_flags = LETPASSTHROW
|
||||
climbable = 1
|
||||
|
||||
var/parts = /obj/item/weapon/table_parts
|
||||
@@ -127,7 +127,8 @@
|
||||
return
|
||||
|
||||
/obj/structure/table/CanPass(atom/movable/mover, turf/target, height=0)
|
||||
if(height==0) return 1
|
||||
if(height == 0)
|
||||
return 1
|
||||
if(istype(mover,/obj/item/projectile))
|
||||
return (check_cover(mover,target))
|
||||
if(ismob(mover))
|
||||
@@ -136,6 +137,8 @@
|
||||
return 1
|
||||
if(istype(mover) && mover.checkpass(PASSTABLE))
|
||||
return 1
|
||||
if(mover.throwing)
|
||||
return 1
|
||||
if(locate(/obj/structure/table) in get_turf(mover))
|
||||
return 1
|
||||
if(flipped)
|
||||
@@ -526,7 +529,7 @@
|
||||
icon_state = "rack"
|
||||
density = 1
|
||||
anchored = 1.0
|
||||
throwpass = 1 //You can throw objects over this, despite it's density.
|
||||
pass_flags = LETPASSTHROW
|
||||
var/parts = /obj/item/weapon/rack_parts
|
||||
var/health = 5
|
||||
|
||||
@@ -563,6 +566,8 @@
|
||||
return 1
|
||||
if(istype(mover) && mover.checkpass(PASSTABLE))
|
||||
return 1
|
||||
if(mover.throwing)
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
|
||||
@@ -108,22 +108,24 @@ var/global/wcCommon = pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e", "#8f
|
||||
|
||||
return 1
|
||||
|
||||
/obj/structure/window/hitby(atom/movable/AM)
|
||||
if(!CanPass(AM, get_step(src, AM.dir))) //So thrown objects that cross a tile with non-full windows will no longer hit the window even if it isn't visually obstructing the path.
|
||||
..()
|
||||
var/tforce = 0
|
||||
if(isobj(AM))
|
||||
var/obj/item/I = AM
|
||||
tforce = I.throwforce
|
||||
if(reinf) tforce *= 0.25
|
||||
playsound(loc, 'sound/effects/Glasshit.ogg', 100, 1)
|
||||
health = max(0, health - tforce)
|
||||
if(health <= 7 && !reinf)
|
||||
anchored = 0
|
||||
update_nearby_icons()
|
||||
step(src, get_dir(AM, src))
|
||||
if(health <= 0)
|
||||
destroy()
|
||||
/obj/structure/window/hitby(atom/movable/AM)
|
||||
..()
|
||||
var/tforce = 0
|
||||
if(ismob(AM))
|
||||
tforce = 10
|
||||
else if(isobj(AM))
|
||||
var/obj/O = AM
|
||||
tforce = O.throwforce
|
||||
if(reinf)
|
||||
tforce *= 0.25
|
||||
playsound(loc, 'sound/effects/Glasshit.ogg', 100, 1)
|
||||
health = max(0, health - tforce)
|
||||
if(health <= 7 && !reinf)
|
||||
anchored = 0
|
||||
update_nearby_icons()
|
||||
step(src, get_dir(AM, src))
|
||||
if(health <= 0)
|
||||
destroy()
|
||||
|
||||
|
||||
/obj/structure/window/attack_hand(mob/user as mob)
|
||||
|
||||
@@ -2,8 +2,3 @@
|
||||
name = "weapon"
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
hitsound = "swing_hit"
|
||||
|
||||
/obj/item/weapon/Bump(mob/M as mob)
|
||||
spawn(0)
|
||||
..()
|
||||
return
|
||||
@@ -15,9 +15,6 @@
|
||||
world.tick_lag = newtick
|
||||
feedback_add_details("admin_verb","TICKLAG") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
switch(alert("Enable Tick Compensation?","Tick Comp is currently: [config.Tickcomp]","Yes","No"))
|
||||
if("Yes") config.Tickcomp = 1
|
||||
else config.Tickcomp = 0
|
||||
else
|
||||
to_chat(src, "<span class='warning'>Error: ticklag(): Invalid world.ticklag value. No changes made.</span>")
|
||||
|
||||
|
||||
@@ -42,9 +42,9 @@
|
||||
attempt_capture(P, -20) //attempting a melee capture reduces the mob's effective run_chance by 20% to balance the risk of triggering a trap mob
|
||||
return 1
|
||||
|
||||
/obj/effect/nanomob/hitby(obj/item/O)
|
||||
if(istype(O, /obj/item/device/pda))
|
||||
var/obj/item/device/pda/P = O
|
||||
/obj/effect/nanomob/hitby(atom/movable/AM)
|
||||
if(istype(AM, /obj/item/device/pda))
|
||||
var/obj/item/device/pda/P = AM
|
||||
attempt_capture(P) //attempting a ranged capture does not affect the mob's effective run_chance but does prevent you from being shocked by a trap mob
|
||||
return 1
|
||||
|
||||
|
||||
@@ -985,11 +985,6 @@
|
||||
// AIs are a bit slower than regular and ignore move intent.
|
||||
wearer_move_delay = world.time + ai_controlled_move_delay
|
||||
|
||||
var/tickcomp = 0
|
||||
if(config.Tickcomp)
|
||||
tickcomp = ((1/(world.tick_lag))*1.3) - 1.3
|
||||
wearer_move_delay += tickcomp
|
||||
|
||||
if(wearer.buckled) //if we're buckled to something, tell it we moved.
|
||||
return wearer.buckled.relaymove(wearer, direction)
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
icon_state = "tank1"
|
||||
density = 0
|
||||
anchored = 0
|
||||
throwpass = 0
|
||||
pass_flags = 0
|
||||
|
||||
var/tank_type = "" // Type of aquarium, used for icon updating
|
||||
var/water_capacity = 0 // Number of units the tank holds (varies with tank type)
|
||||
@@ -38,8 +38,7 @@
|
||||
icon_state = "bowl1"
|
||||
density = 0 // Small enough to not block stuff
|
||||
anchored = 0 // Small enough to move even when filled
|
||||
throwpass = 1 // Just like at the county fair, you can't seem to throw the ball in to win the goldfish
|
||||
pass_flags = PASSTABLE // Small enough to pull onto a table
|
||||
pass_flags = PASSTABLE | LETPASSTHROW // Just like at the county fair, you can't seem to throw the ball in to win the goldfish, and it's small enough to pull onto a table
|
||||
|
||||
tank_type = "bowl"
|
||||
water_capacity = 50 // Not very big, therefore it can't hold much
|
||||
@@ -57,7 +56,7 @@
|
||||
icon_state = "tank1"
|
||||
density = 1
|
||||
anchored = 1
|
||||
throwpass = 1 // You can throw objects over this, despite it's density, because it's short enough.
|
||||
pass_flags = LETPASSTHROW
|
||||
|
||||
tank_type = "tank"
|
||||
water_capacity = 200 // Decent sized, holds almost 2 full buckets
|
||||
@@ -75,7 +74,7 @@
|
||||
icon_state = "wall1"
|
||||
density = 1
|
||||
anchored = 1
|
||||
throwpass = 0 // This thing is the size of a wall, you can't throw past it.
|
||||
pass_flags = 0 // This thing is the size of a wall, you can't throw past it.
|
||||
|
||||
tank_type = "wall"
|
||||
water_capacity = 500 // This thing fills an entire tile, it holds a lot.
|
||||
|
||||
@@ -180,49 +180,6 @@ Gunshots/explosions/opening doors/less rare audio (done)
|
||||
..()
|
||||
name = "alien hunter ([rand(1, 1000)])"
|
||||
|
||||
/obj/effect/hallucination/simple/xeno/throw_at(atom/target, range, speed) // TODO : Make diagonal trhow into proc/property
|
||||
if(!target || !src || (flags & NODROP))
|
||||
return 0
|
||||
|
||||
throwing = 1
|
||||
|
||||
var/dist_x = abs(target.x - x)
|
||||
var/dist_y = abs(target.y - y)
|
||||
var/dist_travelled = 0
|
||||
var/dist_since_sleep = 0
|
||||
|
||||
var/tdist_x = dist_x;
|
||||
var/tdist_y = dist_y;
|
||||
|
||||
if(dist_x <= dist_y)
|
||||
tdist_x = dist_y;
|
||||
tdist_y = dist_x;
|
||||
|
||||
var/error = tdist_x/2 - tdist_y
|
||||
while(target && (((((dist_x > dist_y) && ((x < target.x) || (x > target.x))) || ((dist_x <= dist_y) && ((y < target.y) || (y > target.y))) || (x > target.x)) && dist_travelled < range) || !has_gravity(src)))
|
||||
if(!throwing)
|
||||
break
|
||||
if(!istype(loc, /turf))
|
||||
break
|
||||
|
||||
var/atom/step = get_step(src, get_dir(src, target))
|
||||
if(!step)
|
||||
break
|
||||
Move(step, get_dir(src, step))
|
||||
hit_check()
|
||||
error += (error < 0) ? tdist_x : -tdist_y;
|
||||
dist_travelled++
|
||||
dist_since_sleep++
|
||||
if(dist_since_sleep >= speed)
|
||||
dist_since_sleep = 0
|
||||
sleep(1)
|
||||
|
||||
|
||||
throwing = 0
|
||||
throw_impact(get_turf(src))
|
||||
|
||||
return 1
|
||||
|
||||
/obj/effect/hallucination/simple/xeno/throw_impact(A)
|
||||
update_icon("alienh_pounce")
|
||||
if(A == target)
|
||||
@@ -247,12 +204,12 @@ Gunshots/explosions/opening doors/less rare audio (done)
|
||||
if(!xeno)
|
||||
return
|
||||
xeno.update_icon("alienh_leap",'icons/mob/alienleap.dmi',-32,-32)
|
||||
xeno.throw_at(target,7,1)
|
||||
xeno.throw_at(target,7,1, spin = 0, diagonals_first = 1)
|
||||
sleep(10)
|
||||
if(!xeno)
|
||||
return
|
||||
xeno.update_icon("alienh_leap",'icons/mob/alienleap.dmi',-32,-32)
|
||||
xeno.throw_at(pump,7,1)
|
||||
xeno.throw_at(pump,7,1, spin = 0, diagonals_first = 1)
|
||||
sleep(10)
|
||||
if(!xeno)
|
||||
return
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/mob/living/carbon/alien/hitby(atom/movable/AM)
|
||||
..(AM, 1)
|
||||
/mob/living/carbon/alien/hitby(atom/movable/AM, skipcatch, hitpush)
|
||||
..(AM, hitpush = 0)
|
||||
|
||||
/*Code for aliens attacking aliens. Because aliens act on a hivemind, I don't see them as very aggressive with each other.
|
||||
As such, they can either help or harm other aliens. Help works like the human help command while harm is a simple nibble.
|
||||
|
||||
@@ -79,17 +79,18 @@
|
||||
else //Maybe uses plasma in the future, although that wouldn't make any sense...
|
||||
leaping = 1
|
||||
update_icons()
|
||||
throw_at(A,MAX_ALIEN_LEAP_DIST,1)
|
||||
leaping = 0
|
||||
update_icons()
|
||||
throw_at(A, MAX_ALIEN_LEAP_DIST, 1, spin = 0, diagonals_first = 1, callback = CALLBACK(src, .leap_end))
|
||||
|
||||
/mob/living/carbon/alien/humanoid/hunter/proc/leap_end()
|
||||
leaping = 0
|
||||
update_icons()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/hunter/throw_impact(atom/A)
|
||||
|
||||
if(!leaping)
|
||||
return ..()
|
||||
|
||||
if(A)
|
||||
if(istype(A, /mob/living))
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
var/blocked = 0
|
||||
if(ishuman(A))
|
||||
@@ -126,46 +127,3 @@
|
||||
if(leaping)
|
||||
return
|
||||
..()
|
||||
|
||||
|
||||
//Modified throw_at() that will use diagonal dirs where appropriate
|
||||
//instead of locking it to cardinal dirs
|
||||
/mob/living/carbon/alien/humanoid/throw_at(atom/target, range, speed)
|
||||
if(!target || !src) return 0
|
||||
|
||||
src.throwing = 1
|
||||
|
||||
var/dist_x = abs(target.x - src.x)
|
||||
var/dist_y = abs(target.y - src.y)
|
||||
var/dist_travelled = 0
|
||||
var/dist_since_sleep = 0
|
||||
|
||||
var/tdist_x = dist_x;
|
||||
var/tdist_y = dist_y;
|
||||
|
||||
if(dist_x <= dist_y)
|
||||
tdist_x = dist_y;
|
||||
tdist_y = dist_x;
|
||||
|
||||
var/error = tdist_x/2 - tdist_y
|
||||
while(target && (((((dist_x > dist_y) && ((src.x < target.x) || (src.x > target.x))) || ((dist_x <= dist_y) && ((src.y < target.y) || (src.y > target.y))) || (src.x > target.x)) && dist_travelled < range) || !has_gravity(src)))
|
||||
|
||||
if(!src.throwing) break
|
||||
if(!istype(src.loc, /turf)) break
|
||||
|
||||
var/atom/step = get_step(src, get_dir(src,target))
|
||||
if(!step)
|
||||
break
|
||||
src.Move(step, get_dir(src, step))
|
||||
hit_check()
|
||||
error += (error < 0) ? tdist_x : -tdist_y;
|
||||
dist_travelled++
|
||||
dist_since_sleep++
|
||||
if(dist_since_sleep >= speed)
|
||||
dist_since_sleep = 0
|
||||
sleep(1)
|
||||
|
||||
|
||||
src.throwing = 0
|
||||
|
||||
return 1
|
||||
|
||||
@@ -24,32 +24,6 @@
|
||||
add_language("Hivemind")
|
||||
..()
|
||||
|
||||
//This is fine, works the same as a human
|
||||
/mob/living/carbon/alien/humanoid/Bump(atom/movable/AM as mob|obj, yes)
|
||||
spawn( 0 )
|
||||
if((!( yes ) || now_pushing))
|
||||
return
|
||||
now_pushing = 0
|
||||
..()
|
||||
if(!istype(AM, /atom/movable))
|
||||
return
|
||||
|
||||
if(ismob(AM))
|
||||
var/mob/tmob = AM
|
||||
tmob.LAssailant = src
|
||||
|
||||
if(!now_pushing)
|
||||
now_pushing = 1
|
||||
if(!AM.anchored)
|
||||
var/t = get_dir(src, AM)
|
||||
if(istype(AM, /obj/structure/window/full))
|
||||
for(var/obj/structure/window/win in get_step(AM,t))
|
||||
now_pushing = 0
|
||||
return
|
||||
step(AM, t)
|
||||
now_pushing = null
|
||||
return
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/humanoid/movement_delay()
|
||||
var/tally = 0
|
||||
|
||||
@@ -26,38 +26,6 @@
|
||||
|
||||
..()
|
||||
|
||||
//This is fine, works the same as a human
|
||||
/mob/living/carbon/alien/larva/Bump(atom/movable/AM as mob|obj, yes)
|
||||
|
||||
spawn( 0 )
|
||||
if((!( yes ) || now_pushing))
|
||||
return
|
||||
now_pushing = 1
|
||||
if(ismob(AM))
|
||||
var/mob/tmob = AM
|
||||
if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations))
|
||||
if(prob(70))
|
||||
to_chat(src, "<span class='danger'>You fail to push [tmob]'s fat ass out of the way.</span>")
|
||||
now_pushing = 0
|
||||
return
|
||||
if(!(tmob.status_flags & CANPUSH))
|
||||
now_pushing = 0
|
||||
return
|
||||
tmob.LAssailant = src
|
||||
|
||||
now_pushing = 0
|
||||
..()
|
||||
if(!( istype(AM, /atom/movable) ))
|
||||
return
|
||||
if(!( now_pushing ))
|
||||
now_pushing = 1
|
||||
if(!( AM.anchored ))
|
||||
var/t = get_dir(src, AM)
|
||||
step(AM, t)
|
||||
now_pushing = null
|
||||
return
|
||||
return
|
||||
|
||||
//This needs to be fixed
|
||||
/mob/living/carbon/alien/larva/Stat()
|
||||
..()
|
||||
|
||||
@@ -492,6 +492,29 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
|
||||
|
||||
//Throwing stuff
|
||||
|
||||
/mob/living/carbon/throw_impact(atom/hit_atom, throwingdatum)
|
||||
. = ..()
|
||||
var/hurt = TRUE
|
||||
/*if(istype(throwingdatum, /datum/thrownthing))
|
||||
var/datum/thrownthing/D = throwingdatum
|
||||
if(isrobot(D.thrower))
|
||||
var/mob/living/silicon/robot/R = D.thrower
|
||||
if(!R.emagged)
|
||||
hurt = FALSE*/
|
||||
if(hit_atom.density && isturf(hit_atom))
|
||||
if(hurt)
|
||||
Weaken(1)
|
||||
take_organ_damage(10)
|
||||
if(iscarbon(hit_atom) && hit_atom != src)
|
||||
var/mob/living/carbon/victim = hit_atom
|
||||
if(hurt)
|
||||
victim.take_organ_damage(10)
|
||||
take_organ_damage(10)
|
||||
victim.Weaken(1)
|
||||
Weaken(1)
|
||||
visible_message("<span class='danger'>[src] crashes into [victim], knocking them both over!</span>", "<span class='userdanger'>You violently crash into [victim]!</span>")
|
||||
playsound(src, 'sound/weapons/punch1.ogg', 50, 1)
|
||||
|
||||
/mob/living/carbon/proc/toggle_throw_mode()
|
||||
if(in_throw_mode)
|
||||
throw_mode_off()
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
/mob/living/carbon/hitby(atom/movable/AM)
|
||||
if(in_throw_mode && !get_active_hand()) //empty active hand and we're in throw mode
|
||||
if(canmove && !restrained())
|
||||
if(istype(AM, /obj/item))
|
||||
var/obj/item/I = AM
|
||||
if(isturf(I.loc))
|
||||
put_in_active_hand(I)
|
||||
visible_message("<span class='warning'>[src] catches [I]!</span>")
|
||||
throw_mode_off()
|
||||
return
|
||||
/mob/living/carbon/hitby(atom/movable/AM, skipcatch, hitpush = 1, blocked = 0)
|
||||
if(!skipcatch)
|
||||
if(in_throw_mode && !get_active_hand()) //empty active hand and we're in throw mode
|
||||
if(canmove && !restrained())
|
||||
if(istype(AM, /obj/item))
|
||||
var/obj/item/I = AM
|
||||
if(isturf(I.loc))
|
||||
put_in_active_hand(I)
|
||||
visible_message("<span class='warning'>[src] catches [I]!</span>")
|
||||
throw_mode_off()
|
||||
return 1
|
||||
..()
|
||||
|
||||
/mob/living/carbon/water_act(volume, temperature, source)
|
||||
|
||||
@@ -147,93 +147,6 @@
|
||||
/mob/living/carbon/human/stok/New(var/new_loc)
|
||||
..(new_loc, "Stok")
|
||||
|
||||
/mob/living/carbon/human/Bump(atom/movable/AM, yes)
|
||||
if(!(yes) || now_pushing || buckled)
|
||||
return 0
|
||||
now_pushing = 1
|
||||
if(ismob(AM))
|
||||
var/mob/tmob = AM
|
||||
|
||||
//BubbleWrap - Should stop you pushing a restrained person out of the way
|
||||
//i still don't get it, is this supposed to be 'bubblewrapping' or was it made by a guy named 'BubbleWrap'
|
||||
if(ishuman(tmob))
|
||||
for(var/mob/M in range(tmob, 1))
|
||||
|
||||
if(tmob.pinned.len || (M.pulling == tmob && (tmob.restrained() && !M.restrained()) && M.stat == CONSCIOUS))
|
||||
if(!(world.time % 5)) //tmob is pinned to wall, or is restrained and pulled by a concious unrestrained human
|
||||
to_chat(src, "<span class='danger'>[tmob] is restrained, you cannot push past.</span>")
|
||||
now_pushing = 0
|
||||
return 0
|
||||
|
||||
//I have to fucking document this somewhere- the above if(tmob.pinned.len || etc) check above had
|
||||
//locate(/obj/item/weapon/grab, tmob.grabbed_by.len)) at the end of it
|
||||
//FIRST OF ALL, THAT IS NOT HOW YOU FUCKING USE LOCATE()
|
||||
//SECOND OF ALL, OH GOD, WHY WOULD YOU EVER WANT GRABBED MOBS TO BE UNABLE TO BE PUSHED PAST GOD
|
||||
|
||||
if(tmob.pulling == M && (M.restrained() && !tmob.restrained()) && tmob.stat == CONSCIOUS)
|
||||
if(!(world.time % 5))
|
||||
to_chat(src, "<span class='danger'>[tmob] is restraining [M], you cannot push past.</span>")
|
||||
now_pushing = 0
|
||||
return 0
|
||||
|
||||
//Leaping mobs just land on the tile, no pushing, no anything.
|
||||
if(status_flags & LEAPING)
|
||||
loc = tmob.loc
|
||||
status_flags &= ~LEAPING
|
||||
now_pushing = 0
|
||||
return
|
||||
|
||||
//BubbleWrap: people in handcuffs are always switched around as if they were on 'help' intent to prevent a person being pulled from being seperated from their puller
|
||||
//it might be 'bubblewrapping' given that this rhymes with 'hugboxing'
|
||||
if((tmob.a_intent == I_HELP || tmob.restrained()) && (a_intent == I_HELP || restrained()))
|
||||
if((canmove && tmob.canmove) && (!tmob.buckled && !tmob.buckled_mob))
|
||||
var/turf/oldloc = loc
|
||||
loc = tmob.loc
|
||||
tmob.loc = oldloc
|
||||
now_pushing = 0
|
||||
for(var/mob/living/carbon/slime/slime in view(1,tmob))
|
||||
if(slime.Victim == tmob)
|
||||
slime.UpdateFeed()
|
||||
return
|
||||
|
||||
if(ishuman(tmob) && (FAT in tmob.mutations))
|
||||
if(prob(40) && !(FAT in src.mutations))
|
||||
to_chat(src, "<span class='danger'>You fail to push [tmob]'s fat ass out of the way.</span>")
|
||||
now_pushing = 0
|
||||
return
|
||||
|
||||
|
||||
//anti-riot equipment is also anti-push
|
||||
if(tmob.r_hand && (prob(tmob.r_hand.block_chance * 2)) && !istype(tmob.r_hand, /obj/item/clothing))
|
||||
now_pushing = 0
|
||||
return
|
||||
if(tmob.l_hand && (prob(tmob.l_hand.block_chance * 2)) && !istype(tmob.l_hand, /obj/item/clothing))
|
||||
now_pushing = 0
|
||||
return
|
||||
|
||||
if(!(tmob.status_flags & CANPUSH))
|
||||
now_pushing = 0
|
||||
return
|
||||
|
||||
tmob.LAssailant = src
|
||||
|
||||
now_pushing = 0
|
||||
spawn(0)
|
||||
..()
|
||||
if(!istype(AM, /atom/movable))
|
||||
return
|
||||
if(!now_pushing)
|
||||
now_pushing = 1
|
||||
|
||||
if(!AM.anchored)
|
||||
var/t = get_dir(src, AM)
|
||||
if(istype(AM, /obj/structure/window/full))
|
||||
for(var/obj/structure/window/win in get_step(AM, t))
|
||||
now_pushing = 0
|
||||
return
|
||||
step(AM, t)
|
||||
now_pushing = 0
|
||||
|
||||
/mob/living/carbon/human/Stat()
|
||||
..()
|
||||
statpanel("Status")
|
||||
|
||||
@@ -313,85 +313,37 @@ emp_act
|
||||
return 1*/
|
||||
|
||||
//this proc handles being hit by a thrown atom
|
||||
/mob/living/carbon/human/hitby(atom/movable/AM as mob|obj,var/speed = 5)
|
||||
/mob/living/carbon/human/hitby(atom/movable/AM, skipcatch = 0, hitpush = 1, blocked = 0)
|
||||
var/obj/item/I
|
||||
var/throwpower = 30
|
||||
if(istype(AM, /obj/item))
|
||||
var/obj/item/I = AM
|
||||
|
||||
if(in_throw_mode && !get_active_hand() && speed <= 5) //empty active hand and we're in throw mode
|
||||
if(canmove && !restrained())
|
||||
if(isturf(I.loc))
|
||||
put_in_active_hand(I)
|
||||
visible_message("<span class='warning'>[src] catches [I]!</span>")
|
||||
throw_mode_off()
|
||||
return
|
||||
|
||||
var/zone = ran_zone("chest", 65)
|
||||
var/dtype = BRUTE
|
||||
if(istype(I, /obj/item/weapon))
|
||||
var/obj/item/weapon/W = I
|
||||
dtype = W.damtype
|
||||
var/throw_damage = I.throwforce*(speed/5)
|
||||
|
||||
I.throwing = 0 //it hit, so stop moving
|
||||
|
||||
if((I.thrower != src) && check_shields(throw_damage, "\the [I.name]", I, THROWN_PROJECTILE_ATTACK))
|
||||
return
|
||||
|
||||
var/obj/item/organ/external/affecting = get_organ(zone)
|
||||
if(!affecting)
|
||||
var/missverb = (I.gender == PLURAL) ? "whizz" : "whizzes"
|
||||
visible_message("<span class='notice'>\The [I] [missverb] past [src]'s missing [parse_zone(zone)]!</span>",
|
||||
"<span class='notice'>\The [I] [missverb] past your missing [parse_zone(zone)]!</span>")
|
||||
return
|
||||
var/hit_area = affecting.name
|
||||
|
||||
src.visible_message("<span class='warning'>[src] has been hit in the [hit_area] by [I].</span>")
|
||||
var/armor = run_armor_check(affecting, "melee", "Your armor has protected your [hit_area].", "Your armor has softened hit to your [hit_area].", I.armour_penetration) //I guess "melee" is the best fit here
|
||||
|
||||
apply_damage(throw_damage, dtype, zone, armor, is_sharp(I), has_edge(I), I)
|
||||
|
||||
if(ismob(I.thrower))
|
||||
var/mob/M = I.thrower
|
||||
if(M)
|
||||
add_logs(M, src, "hit", I, " (thrown)", print_attack_log = I.throwforce)
|
||||
|
||||
//thrown weapon embedded object code.
|
||||
if(dtype == BRUTE && istype(I))
|
||||
if(!I.is_robot_module())
|
||||
I = AM
|
||||
throwpower = I.throwforce
|
||||
if(I.thrownby == src) //No throwing stuff at yourself to trigger reactions
|
||||
return ..()
|
||||
if(check_shields(throwpower, "\the [AM.name]", AM, THROWN_PROJECTILE_ATTACK))
|
||||
hitpush = 0
|
||||
skipcatch = 1
|
||||
blocked = 1
|
||||
/*else if(I)
|
||||
if(I.throw_speed >= EMBED_THROWSPEED_THRESHOLD)
|
||||
if(!I.is_robot_module())
|
||||
var/armor = run_armor_check(affecting, "melee", "Your armor has protected your [hit_area].", "Your armor has softened hit to your [hit_area].", I.armour_penetration) //I guess "melee" is the best fit here
|
||||
var/sharp = is_sharp(I)
|
||||
var/damage = throw_damage
|
||||
var/damage = throwpower * (I.throw_speed / 5)
|
||||
if(armor)
|
||||
damage /= armor+1
|
||||
damage /= armor + 1
|
||||
|
||||
//blunt objects should really not be embedding in things unless a huge amount of force is involved
|
||||
var/embed_chance = sharp? damage/I.w_class : damage/(I.w_class*3)
|
||||
var/embed_threshold = sharp? 5*I.w_class : 15*I.w_class
|
||||
var/embed_chance = sharp? damage / I.w_class : damage/(I.w_class * 3)
|
||||
var/embed_threshold = sharp? 5 * I.w_class : 15 * I.w_class
|
||||
|
||||
//Sharp objects will always embed if they do enough damage.
|
||||
//Thrown sharp objects have some momentum already and have a small chance to embed even if the damage is below the threshold
|
||||
if(((sharp && prob(damage/(10*I.w_class)*100)) || (damage > embed_threshold && prob(embed_chance))) && (I.no_embed == 0))
|
||||
affecting.embed(I)
|
||||
|
||||
// Begin BS12 momentum-transfer code.
|
||||
if(I.throw_source && speed >= 15)
|
||||
var/obj/item/weapon/W = I
|
||||
var/momentum = speed/2
|
||||
var/dir = get_dir(I.throw_source, src)
|
||||
|
||||
visible_message("<span class='warning'>[src] staggers under the impact!</span>","<span class='warning'>You stagger under the impact!</span>")
|
||||
src.throw_at(get_edge_target_turf(src,dir),1,momentum)
|
||||
|
||||
if(!W || !src) return
|
||||
|
||||
if(W.loc == src && W.sharp) //Projectile is embedded and suitable for pinning.
|
||||
var/turf/T = near_wall(dir,2)
|
||||
|
||||
if(T)
|
||||
src.loc = T
|
||||
visible_message("<span class='warning'>[src] is pinned to the wall by [I]!</span>","<span class='warning'>You are pinned to the wall by [I]!</span>")
|
||||
src.anchored = 1
|
||||
src.pinned += I
|
||||
|
||||
if(((sharp && prob(damage / (10 * I.w_class) * 100)) || (damage > embed_threshold && prob(embed_chance))) && (I.no_embed == 0))
|
||||
affecting.embed(I)*/
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/proc/bloody_hands(var/mob/living/source, var/amount = 2)
|
||||
|
||||
|
||||
@@ -1,67 +1,75 @@
|
||||
/mob/living/carbon/human/movement_delay()
|
||||
var/tally = 0
|
||||
. = 0
|
||||
. += ..()
|
||||
|
||||
if(species.slowdown)
|
||||
tally = species.slowdown
|
||||
var/gravity = 1
|
||||
|
||||
if(!has_gravity(src))
|
||||
return -1 // It's hard to be slowed down in space by... anything
|
||||
gravity = 0
|
||||
|
||||
if(flying) return -1
|
||||
if(flying)
|
||||
gravity = 0
|
||||
|
||||
if(embedded_flag)
|
||||
handle_embedded_objects() //Moving with objects stuck in you can cause bad times.
|
||||
|
||||
if(slowed)
|
||||
tally += 10
|
||||
. += 10
|
||||
|
||||
var/health_deficiency = (maxHealth - health + staminaloss)
|
||||
if(reagents)
|
||||
for(var/datum/reagent/R in reagents.reagent_list)
|
||||
if(R.shock_reduction)
|
||||
health_deficiency -= R.shock_reduction
|
||||
if(health_deficiency >= 40)
|
||||
tally += (health_deficiency / 25)
|
||||
if(gravity)
|
||||
if(species.slowdown)
|
||||
. = species.slowdown
|
||||
|
||||
var/hungry = (500 - nutrition)/5 // So overeat would be 100 and default level would be 80
|
||||
if(hungry >= 70)
|
||||
tally += hungry/50
|
||||
var/health_deficiency = (maxHealth - health + staminaloss)
|
||||
if(reagents)
|
||||
for(var/datum/reagent/R in reagents.reagent_list)
|
||||
if(R.shock_reduction)
|
||||
health_deficiency -= R.shock_reduction
|
||||
if(health_deficiency >= 40)
|
||||
. += (health_deficiency / 25)
|
||||
|
||||
if(wear_suit)
|
||||
tally += wear_suit.slowdown
|
||||
var/hungry = (500 - nutrition)/5 // So overeat would be 100 and default level would be 80
|
||||
if(hungry >= 70)
|
||||
. += hungry/50
|
||||
|
||||
if(!buckled)
|
||||
if(shoes)
|
||||
tally += shoes.slowdown
|
||||
if(wear_suit)
|
||||
. += wear_suit.slowdown
|
||||
|
||||
if(shock_stage >= 10) tally += 3
|
||||
if(!buckled)
|
||||
if(shoes)
|
||||
. += shoes.slowdown
|
||||
|
||||
if(back)
|
||||
tally += back.slowdown
|
||||
if(shock_stage >= 10)
|
||||
. += 3
|
||||
|
||||
if(l_hand && (l_hand.flags & HANDSLOW))
|
||||
tally += l_hand.slowdown
|
||||
if(r_hand && (r_hand.flags & HANDSLOW))
|
||||
tally += r_hand.slowdown
|
||||
if(back)
|
||||
. += back.slowdown
|
||||
|
||||
if(FAT in src.mutations)
|
||||
tally += 1.5
|
||||
if(bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT)
|
||||
tally += (BODYTEMP_COLD_DAMAGE_LIMIT - bodytemperature) / COLD_SLOWDOWN_FACTOR
|
||||
if(l_hand && (l_hand.flags & HANDSLOW))
|
||||
. += l_hand.slowdown
|
||||
if(r_hand && (r_hand.flags & HANDSLOW))
|
||||
. += r_hand.slowdown
|
||||
|
||||
tally += 2*stance_damage //damaged/missing feet or legs is slow
|
||||
if(FAT in src.mutations)
|
||||
. += 1.5
|
||||
|
||||
if(RUN in mutations)
|
||||
tally = -1
|
||||
if(status_flags & IGNORESLOWDOWN) // make sure this is always at the end so we don't have ignore slowdown getting ignored itself
|
||||
tally = -1
|
||||
if(bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT)
|
||||
. += (BODYTEMP_COLD_DAMAGE_LIMIT - bodytemperature) / COLD_SLOWDOWN_FACTOR
|
||||
|
||||
if(status_flags & GOTTAGOFAST)
|
||||
tally -= 1
|
||||
if(status_flags & GOTTAGOREALLYFAST)
|
||||
tally -= 2
|
||||
. += 2 * stance_damage //damaged/missing feet or legs is slow
|
||||
|
||||
return (tally + config.human_delay)
|
||||
if(RUN in mutations)
|
||||
. = -1
|
||||
|
||||
if(status_flags & IGNORESLOWDOWN) // make sure this is always at the end so we don't have ignore slowdown getting ignored itself
|
||||
. = -1
|
||||
|
||||
if(status_flags & GOTTAGOFAST)
|
||||
. -= 1
|
||||
if(status_flags & GOTTAGOREALLYFAST)
|
||||
. -= 2
|
||||
|
||||
. += config.human_delay
|
||||
|
||||
/mob/living/carbon/human/Process_Spacemove(movement_dir = 0)
|
||||
|
||||
|
||||
@@ -449,7 +449,7 @@
|
||||
..()
|
||||
retalTarget(user)
|
||||
|
||||
/mob/living/carbon/human/interactive/hitby(atom/movable/AM)
|
||||
/mob/living/carbon/human/interactive/hitby(atom/movable/AM, skipcatch, hitpush, blocked)
|
||||
..()
|
||||
var/mob/living/carbon/C = locate(/mob/living/carbon) in view(SNPC_MIN_RANGE_FIND, src)
|
||||
if(C)
|
||||
|
||||
@@ -103,59 +103,24 @@
|
||||
|
||||
return tally + config.slime_delay
|
||||
|
||||
/mob/living/carbon/slime/Bump(atom/movable/AM as mob|obj, yes)
|
||||
if((!(yes) || now_pushing))
|
||||
return
|
||||
now_pushing = 1
|
||||
|
||||
if(isobj(AM))
|
||||
if(!client && powerlevel > 0)
|
||||
var/probab = 10
|
||||
switch(powerlevel)
|
||||
if(1 to 2) probab = 20
|
||||
if(3 to 4) probab = 30
|
||||
if(5 to 6) probab = 40
|
||||
if(7 to 8) probab = 60
|
||||
if(9) probab = 70
|
||||
if(10) probab = 95
|
||||
if(prob(probab))
|
||||
if(istype(AM, /obj/structure/window) || istype(AM, /obj/structure/grille))
|
||||
if(nutrition <= get_hunger_nutrition() && !Atkcool)
|
||||
if(is_adult || prob(5))
|
||||
AM.attack_slime(src)
|
||||
spawn()
|
||||
Atkcool = 1
|
||||
sleep(45)
|
||||
Atkcool = 0
|
||||
|
||||
if(ismob(AM))
|
||||
var/mob/tmob = AM
|
||||
|
||||
if(is_adult)
|
||||
if(istype(tmob, /mob/living/carbon/human))
|
||||
if(prob(90))
|
||||
now_pushing = 0
|
||||
return
|
||||
else
|
||||
if(istype(tmob, /mob/living/carbon/human))
|
||||
now_pushing = 0
|
||||
return
|
||||
|
||||
now_pushing = 0
|
||||
..()
|
||||
if(!istype(AM, /atom/movable))
|
||||
return
|
||||
if(!( now_pushing ))
|
||||
now_pushing = 1
|
||||
if(!( AM.anchored ))
|
||||
var/t = get_dir(src, AM)
|
||||
if(istype(AM, /obj/structure/window))
|
||||
if(AM:ini_dir == NORTHWEST || AM:ini_dir == NORTHEAST || AM:ini_dir == SOUTHWEST || AM:ini_dir == SOUTHEAST)
|
||||
for(var/obj/structure/window/win in get_step(AM,t))
|
||||
now_pushing = 0
|
||||
return
|
||||
step(AM, t)
|
||||
now_pushing = null
|
||||
/mob/living/carbon/slime/ObjBump(obj/O)
|
||||
if(!client && powerlevel > 0)
|
||||
var/chance = 10
|
||||
switch(powerlevel)
|
||||
if(1 to 2) chance = 20
|
||||
if(3 to 4) chance = 30
|
||||
if(5 to 6) chance = 40
|
||||
if(7 to 8) chance = 60
|
||||
if(9) chance = 70
|
||||
if(10) chance = 95
|
||||
if(prob(chance))
|
||||
if(istype(O, /obj/structure/window) || istype(O, /obj/structure/grille))
|
||||
if(nutrition <= get_hunger_nutrition() && !Atkcool)
|
||||
if(is_adult || prob(5))
|
||||
O.attack_slime(src)
|
||||
Atkcool = 1
|
||||
spawn(45)
|
||||
Atkcool = 0
|
||||
|
||||
/mob/living/carbon/slime/Process_Spacemove(var/movement_dir = 0)
|
||||
return 2
|
||||
|
||||
@@ -14,6 +14,121 @@
|
||||
/mob/living/proc/OpenCraftingMenu()
|
||||
return
|
||||
|
||||
//Generic Bump(). Override MobBump() and ObjBump() instead of this.
|
||||
/mob/living/Bump(atom/A, yes)
|
||||
if(..()) //we are thrown onto something
|
||||
return
|
||||
if(buckled || !yes || now_pushing)
|
||||
return
|
||||
if(ismob(A))
|
||||
if(MobBump(A))
|
||||
return
|
||||
if(isobj(A))
|
||||
if(ObjBump(A))
|
||||
return
|
||||
if(istype(A, /atom/movable))
|
||||
if(PushAM(A))
|
||||
return
|
||||
|
||||
//Called when we bump into a mob
|
||||
/mob/living/proc/MobBump(mob/M)
|
||||
//Even if we don't push/swap places, we "touched" them, so spread fire
|
||||
spreadFire(M)
|
||||
|
||||
if(now_pushing)
|
||||
return 1
|
||||
|
||||
//Should stop you pushing a restrained person out of the way
|
||||
if(isliving(M))
|
||||
var/mob/living/L = M
|
||||
if(L.pulledby && L.pulledby != src && L.restrained())
|
||||
if(!(world.time % 5))
|
||||
to_chat(src, "<span class='warning'>[L] is restrained, you cannot push past.</span>")
|
||||
return 1
|
||||
|
||||
if(L.pulling)
|
||||
if(ismob(L.pulling))
|
||||
var/mob/P = L.pulling
|
||||
if(P.restrained())
|
||||
if(!(world.time % 5))
|
||||
to_chat(src, "<span class='warning'>[L] is restrained, you cannot push past.</span>")
|
||||
return 1
|
||||
|
||||
if(moving_diagonally) //no mob swap during diagonal moves.
|
||||
return 1
|
||||
|
||||
if(!M.buckled && !M.has_buckled_mobs())
|
||||
var/mob_swap
|
||||
//the puller can always swap with it's victim if on grab intent
|
||||
if(M.pulledby == src && a_intent == I_GRAB)
|
||||
mob_swap = 1
|
||||
//restrained people act if they were on 'help' intent to prevent a person being pulled from being seperated from their puller
|
||||
else if((M.restrained() || M.a_intent == I_HELP) && (restrained() || a_intent == I_HELP))
|
||||
mob_swap = 1
|
||||
if(mob_swap)
|
||||
//switch our position with M
|
||||
if(loc && !loc.Adjacent(M.loc))
|
||||
return 1
|
||||
now_pushing = 1
|
||||
var/oldloc = loc
|
||||
var/oldMloc = M.loc
|
||||
|
||||
var/M_passmob = (M.pass_flags & PASSMOB) // we give PASSMOB to both mobs to avoid bumping other mobs during swap.
|
||||
var/src_passmob = (pass_flags & PASSMOB)
|
||||
M.pass_flags |= PASSMOB
|
||||
pass_flags |= PASSMOB
|
||||
|
||||
M.Move(oldloc)
|
||||
Move(oldMloc)
|
||||
|
||||
if(!src_passmob)
|
||||
pass_flags &= ~PASSMOB
|
||||
if(!M_passmob)
|
||||
M.pass_flags &= ~PASSMOB
|
||||
|
||||
now_pushing = 0
|
||||
return 1
|
||||
|
||||
// okay, so we didn't switch. but should we push?
|
||||
// not if he's not CANPUSH of course
|
||||
if(!(M.status_flags & CANPUSH))
|
||||
return 1
|
||||
//anti-riot equipment is also anti-push
|
||||
if(M.r_hand && (prob(M.r_hand.block_chance * 2)) && !istype(M.r_hand, /obj/item/clothing))
|
||||
return 1
|
||||
if(M.l_hand && (prob(M.l_hand.block_chance * 2)) && !istype(M.l_hand, /obj/item/clothing))
|
||||
return 1
|
||||
|
||||
//Called when we bump into an obj
|
||||
/mob/living/proc/ObjBump(obj/O)
|
||||
return
|
||||
|
||||
//Called when we want to push an atom/movable
|
||||
/mob/living/proc/PushAM(atom/movable/AM)
|
||||
if(now_pushing)
|
||||
return 1
|
||||
if(moving_diagonally) // no pushing during diagonal moves
|
||||
return 1
|
||||
if(!client && (mob_size < MOB_SIZE_SMALL))
|
||||
return
|
||||
if(!AM.anchored)
|
||||
now_pushing = 1
|
||||
var/t = get_dir(src, AM)
|
||||
if(istype(AM, /obj/structure/window/full))
|
||||
for(var/obj/structure/window/win in get_step(AM, t))
|
||||
now_pushing = 0
|
||||
return
|
||||
if(pulling == AM)
|
||||
stop_pulling()
|
||||
var/current_dir
|
||||
if(isliving(AM))
|
||||
current_dir = AM.dir
|
||||
step(AM, t)
|
||||
if(current_dir)
|
||||
AM.setDir(current_dir)
|
||||
now_pushing = 0
|
||||
|
||||
|
||||
/mob/living/Stat()
|
||||
. = ..()
|
||||
if(. && get_rig_stats)
|
||||
@@ -430,83 +545,47 @@
|
||||
else
|
||||
return 0
|
||||
|
||||
var/atom/movable/pullee = pulling
|
||||
if(pullee && get_dist(src, pullee) > 1)
|
||||
stop_pulling()
|
||||
if(pullee && !isturf(pullee.loc) && pullee.loc != loc)
|
||||
log_game("DEBUG: [src]'s pull on [pullee] was broken despite [pullee] being in [pullee.loc]. Pull stopped manually.")
|
||||
stop_pulling()
|
||||
if(restrained())
|
||||
stop_pulling()
|
||||
|
||||
|
||||
var/t7 = 1
|
||||
if(restrained())
|
||||
for(var/mob/living/M in range(src, 1))
|
||||
if((M.pulling == src && M.stat == 0 && !( M.restrained() )))
|
||||
t7 = null
|
||||
if(t7 && pulling && (get_dist(src, pulling) <= 1 || pulling.loc == loc))
|
||||
var/turf/T = loc
|
||||
. = ..()
|
||||
|
||||
if(pulling && pulling.loc)
|
||||
if(!( isturf(pulling.loc) ))
|
||||
stop_pulling()
|
||||
return
|
||||
else
|
||||
if(Debug)
|
||||
diary <<"pulling disappeared? at [__LINE__] in mob.dm - pulling = [pulling]"
|
||||
diary <<"REPORT THIS"
|
||||
|
||||
/////
|
||||
if(pulling && pulling.anchored)
|
||||
stop_pulling()
|
||||
return
|
||||
|
||||
if(!restrained())
|
||||
var/diag = get_dir(src, pulling)
|
||||
if((diag - 1) & diag)
|
||||
else
|
||||
diag = null
|
||||
if((get_dist(src, pulling) > 1 || diag))
|
||||
if(isliving(pulling))
|
||||
var/mob/living/M = pulling
|
||||
var/ok = 1
|
||||
if(locate(/obj/item/weapon/grab, M.grabbed_by))
|
||||
if(prob(75))
|
||||
var/obj/item/weapon/grab/G = pick(M.grabbed_by)
|
||||
if(istype(G, /obj/item/weapon/grab))
|
||||
for(var/mob/O in viewers(M, null))
|
||||
O.show_message(text("<span class='warning'>[] has been pulled from []'s grip by []</span>", G.affecting, G.assailant, src), 1)
|
||||
//G = null
|
||||
qdel(G)
|
||||
else
|
||||
ok = 0
|
||||
if(locate(/obj/item/weapon/grab, M.grabbed_by.len))
|
||||
ok = 0
|
||||
if(ok)
|
||||
var/atom/movable/t = M.pulling
|
||||
M.stop_pulling()
|
||||
|
||||
if(M.lying && (prob(M.getBruteLoss() / 6)))
|
||||
var/turf/location = M.loc
|
||||
if(istype(location, /turf/simulated))
|
||||
location.add_blood(M)
|
||||
pulling.Move(T, get_dir(pulling, T))
|
||||
if(M)
|
||||
M.start_pulling(t)
|
||||
else
|
||||
if(pulling)
|
||||
pulling.Move(T, get_dir(pulling, T))
|
||||
else
|
||||
stop_pulling()
|
||||
. = ..()
|
||||
|
||||
if(s_active && !( s_active in contents ) && get_turf(s_active) != get_turf(src)) //check !( s_active in contents ) first so we hopefully don't have to call get_turf() so much.
|
||||
s_active.close(src)
|
||||
|
||||
if(.) // did we actually move?
|
||||
var/turf/T = loc
|
||||
. = ..()
|
||||
if(.)
|
||||
handle_footstep(loc)
|
||||
step_count++
|
||||
|
||||
if(pulling && pulling == pullee) // we were pulling a thing and didn't lose it during our move.
|
||||
if(pulling.anchored)
|
||||
stop_pulling()
|
||||
return
|
||||
|
||||
var/pull_dir = get_dir(src, pulling)
|
||||
if(get_dist(src, pulling) > 1 || ((pull_dir - 1) & pull_dir)) // puller and pullee more than one tile away or in diagonal position
|
||||
//if(isliving(pulling))
|
||||
//var/mob/living/M = pulling
|
||||
//if(M.lying && !M.buckled && (prob(M.getBruteLoss() * 200 / M.maxHealth)))
|
||||
//M.makeTrail(T)
|
||||
pulling.Move(T, get_dir(pulling, T)) // the pullee tries to reach our previous position
|
||||
if(pulling && get_dist(src, pulling) > 1) // the pullee couldn't keep up
|
||||
stop_pulling()
|
||||
|
||||
if(pulledby && moving_diagonally != FIRST_DIAG_STEP && get_dist(src, pulledby) > 1) //seperated from our puller and not in the middle of a diagonal move
|
||||
pulledby.stop_pulling()
|
||||
|
||||
if(s_active && !(s_active in contents) && get_turf(s_active) != get_turf(src)) //check !( s_active in contents ) first so we hopefully don't have to call get_turf() so much.
|
||||
s_active.close(src)
|
||||
|
||||
if(update_slimes)
|
||||
for(var/mob/living/carbon/slime/M in view(1,src))
|
||||
M.UpdateFeed(src)
|
||||
|
||||
|
||||
/mob/living/proc/handle_footstep(turf/T)
|
||||
if(istype(T))
|
||||
return 1
|
||||
@@ -838,13 +917,25 @@
|
||||
visible_message("<span class='notice'>[user] butchers [src].</span>")
|
||||
gib()
|
||||
|
||||
/mob/living/movement_delay()
|
||||
var/tally = 0
|
||||
/mob/living/movement_delay(ignorewalk = 0)
|
||||
. = ..()
|
||||
|
||||
if(isturf(loc))
|
||||
var/turf/T = loc
|
||||
. += T.slowdown
|
||||
if(slowed)
|
||||
tally += 10
|
||||
. += 10
|
||||
if(ignorewalk)
|
||||
. += config.run_speed
|
||||
else
|
||||
switch(m_intent)
|
||||
if("run")
|
||||
if(drowsyness > 0)
|
||||
. += 6
|
||||
. += config.run_speed
|
||||
if("walk")
|
||||
. += config.walk_speed
|
||||
|
||||
return tally
|
||||
|
||||
/mob/living/proc/can_use_guns(var/obj/item/weapon/gun/G)
|
||||
if(G.trigger_guard != TRIGGER_GUARD_ALLOW_ALL && !IsAdvancedToolUser() && !issmall(src))
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
if(P.dismemberment)
|
||||
check_projectile_dismemberment(P, def_zone)
|
||||
return P.on_hit(src, armor, def_zone)
|
||||
|
||||
|
||||
/mob/living/proc/check_projectile_dismemberment(obj/item/projectile/P, def_zone)
|
||||
return 0
|
||||
|
||||
@@ -65,60 +65,47 @@
|
||||
O.emp_act(severity)
|
||||
..()
|
||||
|
||||
/obj/item/proc/get_volume_by_throwforce_and_or_w_class()
|
||||
if(throwforce && w_class)
|
||||
return Clamp((throwforce + w_class) * 5, 30, 100)// Add the item's throwforce to its weight class and multiply by 5, then clamp the value between 30 and 100
|
||||
else if(w_class)
|
||||
return Clamp(w_class * 8, 20, 100) // Multiply the item's weight class by 8, then clamp the value between 20 and 100
|
||||
else
|
||||
return 0
|
||||
|
||||
//this proc handles being hit by a thrown atom
|
||||
/mob/living/hitby(atom/movable/AM as mob|obj,var/speed = 5)//Standardization and logging -Sieve
|
||||
/mob/living/hitby(atom/movable/AM, skipcatch, hitpush = 1, blocked = 0)//Standardization and logging -Sieve
|
||||
if(istype(AM, /obj/item))
|
||||
var/obj/item/I = AM
|
||||
var/zone = ran_zone("chest", 65)//Hits a random part of the body, geared towards the chest
|
||||
var/dtype = BRUTE
|
||||
var/dtype = BRUTE
|
||||
var/volume = I.get_volume_by_throwforce_and_or_w_class()
|
||||
if(istype(I, /obj/item/weapon))
|
||||
var/obj/item/weapon/W = I
|
||||
dtype = W.damtype
|
||||
if(W.hitsound && W.throwforce > 0)
|
||||
playsound(loc, W.hitsound, 30, 1, -1)
|
||||
if(W.throwforce > 0) //If the weapon's throwforce is greater than zero...
|
||||
if(W.hitsound) //...and hitsound is defined...
|
||||
playsound(loc, W.hitsound, volume, 1, -1) //...play the weapon's hitsound.
|
||||
else //Otherwise, if hitsound isn't defined...
|
||||
playsound(loc, 'sound/weapons/genhit1.ogg', volume, 1, -1) //...play genhit1.ogg.
|
||||
|
||||
//run to-hit check here
|
||||
else if(I.throwforce > 0) //Otherwise, if the item doesn't have a throwhitsound and has a throwforce greater than zero...
|
||||
playsound(loc, 'sound/weapons/genhit1.ogg', volume, 1, -1)//...play genhit1.ogg
|
||||
if(!I.throwforce)// Otherwise, if the item's throwforce is 0...
|
||||
playsound(loc, 'sound/weapons/throwtap.ogg', 1, volume, -1)//...play throwtap.ogg.
|
||||
if(!blocked)
|
||||
visible_message("<span class='danger'>[src] has been hit by [I].</span>",
|
||||
"<span class='userdanger'>[src] has been hit by [I].</span>")
|
||||
var/armor = run_armor_check(zone, "melee", "Your armor has protected your [parse_zone(zone)].", "Your armor has softened hit to your [parse_zone(zone)].", I.armour_penetration)
|
||||
apply_damage(I.throwforce, dtype, zone, armor, is_sharp(I), has_edge(I), I)
|
||||
if(I.thrownby)
|
||||
add_logs(I.thrownby, src, "hit", I)
|
||||
else
|
||||
return 1
|
||||
else
|
||||
playsound(loc, 'sound/weapons/genhit1.ogg', 50, 1, -1) //...play genhit1.ogg.)
|
||||
..()
|
||||
|
||||
var/throw_damage = I.throwforce*(speed/5)
|
||||
|
||||
src.visible_message("<span class='warning'>[src] has been hit by [I].</span>")
|
||||
var/armor = run_armor_check(zone, "melee", "Your armor has protected your [parse_zone(zone)].", "Your armor has softened hit to your [parse_zone(zone)].", I.armour_penetration)
|
||||
|
||||
apply_damage(throw_damage, dtype, zone, armor, is_sharp(I), has_edge(I), I)
|
||||
|
||||
I.throwing = 0 //it hit, so stop moving
|
||||
|
||||
if(ismob(I.thrower))
|
||||
var/mob/M = I.thrower
|
||||
if(M)
|
||||
create_attack_log("<font color='orange'>Has been hit with a [I], thrown by [key_name(M)]</font>")
|
||||
M.create_attack_log("<font color='red'>Hit [key_name(src)] with a thrown [I]</font>")
|
||||
if(!istype(src,/mob/living/simple_animal/mouse))
|
||||
msg_admin_attack("[key_name_admin(src)] was hit by a [I], thrown by [key_name_admin(M)]")
|
||||
|
||||
// Begin BS12 momentum-transfer code.
|
||||
if(I.throw_source && speed >= 15)
|
||||
var/obj/item/weapon/W = I
|
||||
var/momentum = speed/2
|
||||
var/dir = get_dir(I.throw_source, src)
|
||||
|
||||
visible_message("<span class='warning'>[src] staggers under the impact!</span>","<span class='warning'>You stagger under the impact!</span>")
|
||||
src.throw_at(get_edge_target_turf(src,dir),1,momentum)
|
||||
|
||||
if(!W || !src) return
|
||||
|
||||
if(W.sharp) //Projectile is suitable for pinning.
|
||||
//Handles embedding for non-humans and simple_animals.
|
||||
I.loc = src
|
||||
embedded += I
|
||||
|
||||
var/turf/T = near_wall(dir,2)
|
||||
|
||||
if(T)
|
||||
src.loc = T
|
||||
visible_message("<span class='warning'>[src] is pinned to the wall by [I]!</span>","<span class='warning'>You are pinned to the wall by [I]!</span>")
|
||||
src.anchored = 1
|
||||
src.pinned += I
|
||||
|
||||
/mob/living/mech_melee_attack(obj/mecha/M)
|
||||
if(M.occupant.a_intent == I_HARM)
|
||||
@@ -201,6 +188,24 @@
|
||||
adjust_fire_stacks(3)
|
||||
IgniteMob()
|
||||
|
||||
//Share fire evenly between the two mobs
|
||||
//Called in MobBump() and Crossed()
|
||||
/mob/living/proc/spreadFire(mob/living/L)
|
||||
if(!istype(L))
|
||||
return
|
||||
var/L_old_on_fire = L.on_fire
|
||||
|
||||
if(on_fire) //Only spread fire stacks if we're on fire
|
||||
fire_stacks /= 2
|
||||
L.fire_stacks += fire_stacks
|
||||
if(L.IgniteMob())
|
||||
log_game("[key_name(src)] bumped into [key_name(L)] and set them on fire")
|
||||
|
||||
if(L_old_on_fire) //Only ignite us and gain their stacks if they were onfire before we bumped them
|
||||
L.fire_stacks /= 2
|
||||
fire_stacks += L.fire_stacks
|
||||
IgniteMob()
|
||||
|
||||
//Mobs on Fire end
|
||||
|
||||
/mob/living/water_act(volume, temperature)
|
||||
|
||||
@@ -539,10 +539,10 @@
|
||||
card.forceMove(card.loc)
|
||||
icon_state = "[chassis]"
|
||||
|
||||
/mob/living/silicon/pai/Bump(atom/movable/AM as mob|obj, yes)
|
||||
/mob/living/silicon/pai/Bump()
|
||||
return
|
||||
|
||||
/mob/living/silicon/pai/Bumped(AM as mob|obj)
|
||||
/mob/living/silicon/pai/Bumped()
|
||||
return
|
||||
|
||||
/mob/living/silicon/pai/start_pulling(var/atom/movable/AM)
|
||||
|
||||
@@ -310,18 +310,15 @@
|
||||
*/
|
||||
|
||||
|
||||
/mob/living/silicon/robot/drone/Bump(atom/movable/AM as mob|obj, yes)
|
||||
if(!yes || ( \
|
||||
!istype(AM,/obj/machinery/door) && \
|
||||
!istype(AM,/obj/machinery/recharge_station) && \
|
||||
!istype(AM,/obj/machinery/disposal/deliveryChute) && \
|
||||
!istype(AM,/obj/machinery/teleport/hub) && \
|
||||
!istype(AM,/obj/effect/portal)
|
||||
)) return
|
||||
..()
|
||||
return
|
||||
/mob/living/silicon/robot/drone/Bump(atom/movable/AM, yes)
|
||||
if(istype(AM, /obj/machinery/door) \
|
||||
|| istype(AM, /obj/machinery/recharge_station) \
|
||||
|| istype(AM, /obj/machinery/disposal/deliveryChute) \
|
||||
|| istype(AM, /obj/machinery/teleport/hub) \
|
||||
|| istype(AM, /obj/effect/portal))
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/robot/drone/Bumped(AM as mob|obj)
|
||||
/mob/living/silicon/robot/drone/Bumped(atom/movable/AM)
|
||||
return
|
||||
|
||||
/mob/living/silicon/robot/drone/start_pulling(var/atom/movable/AM)
|
||||
|
||||
@@ -552,38 +552,6 @@ var/list/robot_verbs_default = list(
|
||||
return 2
|
||||
|
||||
|
||||
/mob/living/silicon/robot/Bump(atom/movable/AM as mob|obj, yes)
|
||||
spawn( 0 )
|
||||
if((!( yes ) || now_pushing))
|
||||
return
|
||||
now_pushing = 1
|
||||
if(ismob(AM))
|
||||
var/mob/tmob = AM
|
||||
if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations))
|
||||
if(prob(20))
|
||||
to_chat(usr, "<span class='danger'>You fail to push [tmob]'s fat ass out of the way.</span>")
|
||||
now_pushing = 0
|
||||
return
|
||||
if(!(tmob.status_flags & CANPUSH))
|
||||
now_pushing = 0
|
||||
return
|
||||
now_pushing = 0
|
||||
..()
|
||||
if(!istype(AM, /atom/movable))
|
||||
return
|
||||
if(!now_pushing)
|
||||
now_pushing = 1
|
||||
if(!AM.anchored)
|
||||
var/t = get_dir(src, AM)
|
||||
if(istype(AM, /obj/structure/window/full))
|
||||
for(var/obj/structure/window/win in get_step(AM,t))
|
||||
now_pushing = 0
|
||||
return
|
||||
step(AM, t)
|
||||
now_pushing = null
|
||||
return
|
||||
return
|
||||
|
||||
/mob/living/silicon/robot/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
|
||||
if(istype(W, /obj/item/weapon/restraints/handcuffs)) // fuck i don't even know why isrobot() in handcuff code isn't working so this will have to do
|
||||
return
|
||||
|
||||
@@ -195,31 +195,6 @@
|
||||
src << browse(dat, "window=airoster")
|
||||
onclose(src, "airoster")
|
||||
|
||||
/mob/living/silicon/Bump(atom/movable/AM as mob|obj, yes) //Allows the AI to bump into mobs if it's itself pushed
|
||||
if((!( yes ) || now_pushing))
|
||||
return
|
||||
now_pushing = 1
|
||||
if(ismob(AM))
|
||||
var/mob/tmob = AM
|
||||
if(!(tmob.status_flags & CANPUSH))
|
||||
now_pushing = 0
|
||||
return
|
||||
now_pushing = 0
|
||||
..()
|
||||
if(!istype(AM, /atom/movable))
|
||||
return
|
||||
if(!now_pushing)
|
||||
now_pushing = 1
|
||||
if(!AM.anchored)
|
||||
var/t = get_dir(src, AM)
|
||||
if(istype(AM, /obj/structure/window))
|
||||
if(AM:ini_dir == NORTHWEST || AM:ini_dir == NORTHEAST || AM:ini_dir == SOUTHWEST || AM:ini_dir == SOUTHEAST)
|
||||
for(var/obj/structure/window/win in get_step(AM,t))
|
||||
now_pushing = 0
|
||||
return
|
||||
step(AM, t)
|
||||
now_pushing = null
|
||||
|
||||
/mob/living/silicon/assess_threat() //Secbots won't hunt silicon units
|
||||
return -10
|
||||
|
||||
|
||||
@@ -218,8 +218,8 @@ Auto Patrol: []"},
|
||||
/mob/living/simple_animal/bot/secbot/hitby(atom/movable/AM, skipcatch = 0, hitpush = 1, blocked = 0)
|
||||
if(istype(AM, /obj/item))
|
||||
var/obj/item/I = AM
|
||||
if(I.throwforce < src.health && I.thrower && (istype(I.thrower, /mob/living/carbon/human)))
|
||||
var/mob/living/carbon/human/H = I.thrower
|
||||
if(I.throwforce < src.health && I.thrownby && ishuman(I.thrownby))
|
||||
var/mob/living/carbon/human/H = I.thrownby
|
||||
retaliate(H)
|
||||
..()
|
||||
|
||||
|
||||
@@ -470,41 +470,6 @@
|
||||
name = "Corgi meat"
|
||||
desc = "Tastes like... well you know..."
|
||||
|
||||
/mob/living/simple_animal/pet/corgi/Ian/Bump(atom/movable/AM as mob|obj, yes)
|
||||
|
||||
spawn( 0 )
|
||||
if((!( yes ) || now_pushing))
|
||||
return
|
||||
now_pushing = 1
|
||||
if(ismob(AM))
|
||||
var/mob/tmob = AM
|
||||
if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations))
|
||||
if(prob(70))
|
||||
to_chat(src, "<span class='danger'>You fail to push [tmob]'s fat ass out of the way.</span>")
|
||||
now_pushing = 0
|
||||
return
|
||||
if(!(tmob.status_flags & CANPUSH))
|
||||
now_pushing = 0
|
||||
return
|
||||
|
||||
tmob.LAssailant = src
|
||||
now_pushing = 0
|
||||
..()
|
||||
if(!( istype(AM, /atom/movable) ))
|
||||
return
|
||||
if(!( now_pushing ))
|
||||
now_pushing = 1
|
||||
if(!( AM.anchored ))
|
||||
var/t = get_dir(src, AM)
|
||||
if(istype(AM, /obj/structure/window/full))
|
||||
for(var/obj/structure/window/win in get_step(AM,t))
|
||||
now_pushing = 0
|
||||
return
|
||||
step(AM, t)
|
||||
now_pushing = null
|
||||
return
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/pet/corgi/regenerate_icons()
|
||||
overlays.Cut()
|
||||
if(inventory_head)
|
||||
|
||||
@@ -103,7 +103,7 @@ Difficulty: Hard
|
||||
triple_charge()
|
||||
else
|
||||
spawn(0)
|
||||
warp_charge()
|
||||
warp_charge()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/bubblegum/New()
|
||||
..()
|
||||
@@ -186,7 +186,7 @@ Difficulty: Hard
|
||||
shake_camera(L, 4, 3)
|
||||
shake_camera(src, 2, 3)
|
||||
var/throwtarget = get_edge_target_turf(src, get_dir(src, get_step_away(L, src)))
|
||||
L.throw_at_fast(throwtarget, 3)
|
||||
L.throw_at(throwtarget, 3)
|
||||
|
||||
charging = 0
|
||||
|
||||
|
||||
@@ -238,7 +238,7 @@ Difficulty: Medium
|
||||
if(L.loc == loc)
|
||||
throw_dir = pick(alldirs)
|
||||
var/throwtarget = get_edge_target_turf(src, throw_dir)
|
||||
L.throw_at_fast(throwtarget, 3)
|
||||
L.throw_at(throwtarget, 3)
|
||||
visible_message("<span class='warning'>[L] is thrown clear of [src]!</span>")
|
||||
|
||||
for(var/mob/M in range(7, src))
|
||||
|
||||
@@ -123,7 +123,6 @@
|
||||
|
||||
//Attempt to eat things we bump into, Mobs, Walls, Clowns
|
||||
/mob/living/simple_animal/hostile/spaceWorm/wormHead/Bump(atom/obstacle)
|
||||
|
||||
attemptToEat(obstacle)
|
||||
|
||||
//Attempt to eat things, only the head can eat
|
||||
|
||||
@@ -25,13 +25,12 @@
|
||||
ts_spiderling_list -= src
|
||||
return ..()
|
||||
|
||||
/obj/structure/spider/spiderling/terror_spiderling/Bump(atom/A)
|
||||
if(istype(A, /obj/structure/table))
|
||||
forceMove(A.loc)
|
||||
else if(istype(A, /obj/machinery/recharge_station))
|
||||
/obj/structure/spider/spiderling/terror_spiderling/Bump(obj/O)
|
||||
if(istype(O, /obj/structure/table))
|
||||
forceMove(O.loc)
|
||||
else if(istype(O, /obj/machinery/recharge_station))
|
||||
qdel(src)
|
||||
else
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
/obj/structure/spider/spiderling/terror_spiderling/process()
|
||||
if(travelling_in_vent)
|
||||
|
||||
@@ -329,16 +329,17 @@ var/global/list/ts_spiderling_list = list()
|
||||
/mob/living/simple_animal/hostile/poison/terror_spider/proc/spider_special_action()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/terror_spider/Bump(atom/A)
|
||||
if(istype(A, /obj/machinery/door/airlock))
|
||||
var/obj/machinery/door/airlock/L = A
|
||||
/mob/living/simple_animal/hostile/poison/terror_spider/ObjBump(obj/O)
|
||||
if(istype(O, /obj/machinery/door/airlock))
|
||||
var/obj/machinery/door/airlock/L = O
|
||||
if(L.density)
|
||||
try_open_airlock(L)
|
||||
if(istype(A, /obj/machinery/door/firedoor))
|
||||
var/obj/machinery/door/firedoor/F = A
|
||||
return try_open_airlock(L)
|
||||
if(istype(O, /obj/machinery/door/firedoor))
|
||||
var/obj/machinery/door/firedoor/F = O
|
||||
if(F.density && !F.welded)
|
||||
F.open()
|
||||
..()
|
||||
return 1
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/terror_spider/proc/msg_terrorspiders(msgtext)
|
||||
for(var/mob/living/simple_animal/hostile/poison/terror_spider/T in ts_spiderlist)
|
||||
@@ -362,6 +363,7 @@ var/global/list/ts_spiderling_list = list()
|
||||
to_chat(src, "<span class='warning'>The door is bolted shut.</span>")
|
||||
else if(D.allowed(src))
|
||||
D.open(1)
|
||||
return 1
|
||||
else if(D.arePowerSystemsOn() && (spider_opens_doors != 2))
|
||||
to_chat(src, "<span class='warning'>The door's motors resist your efforts to force it.</span>")
|
||||
else if(!spider_opens_doors)
|
||||
@@ -369,4 +371,5 @@ var/global/list/ts_spiderling_list = list()
|
||||
else
|
||||
visible_message("<span class='danger'>[src] pries open the door!</span>")
|
||||
playsound(src.loc, "sparks", 100, 1)
|
||||
D.open(1)
|
||||
D.open(1)
|
||||
return 1
|
||||
@@ -250,20 +250,6 @@
|
||||
else if(bodytemperature > maxbodytemp)
|
||||
adjustBruteLoss(heat_damage_per_tick)
|
||||
|
||||
/mob/living/simple_animal/Bumped(AM as mob|obj)
|
||||
if(!AM) return
|
||||
|
||||
if(resting || buckled)
|
||||
return
|
||||
|
||||
if(isturf(src.loc))
|
||||
if((status_flags & CANPUSH) && ismob(AM))
|
||||
var/newamloc = src.loc
|
||||
src.loc = AM:loc
|
||||
AM:loc = newamloc
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/gib()
|
||||
if(icon_gib)
|
||||
flick(icon_gib, src)
|
||||
|
||||
+124
-133
@@ -15,21 +15,27 @@
|
||||
return 1
|
||||
return (!mover.density || !density || lying)
|
||||
|
||||
//The byond version of these verbs wait for the next tick before acting.
|
||||
// instant verbs however can run mid tick or even during the time between ticks.
|
||||
/client/verb/moveup()
|
||||
set name = ".moveup"
|
||||
set instant = 1
|
||||
Move(get_step(mob, NORTH), NORTH)
|
||||
|
||||
/client/North()
|
||||
..()
|
||||
/client/verb/movedown()
|
||||
set name = ".movedown"
|
||||
set instant = 1
|
||||
Move(get_step(mob, SOUTH), SOUTH)
|
||||
|
||||
/client/verb/moveright()
|
||||
set name = ".moveright"
|
||||
set instant = 1
|
||||
Move(get_step(mob, EAST), EAST)
|
||||
|
||||
/client/South()
|
||||
..()
|
||||
|
||||
|
||||
/client/West()
|
||||
..()
|
||||
|
||||
|
||||
/client/East()
|
||||
..()
|
||||
/client/verb/moveleft()
|
||||
set name = ".moveleft"
|
||||
set instant = 1
|
||||
Move(get_step(mob, WEST), WEST)
|
||||
|
||||
|
||||
/client/Northeast()
|
||||
@@ -105,12 +111,11 @@
|
||||
|
||||
/client/verb/toggle_throw_mode()
|
||||
set hidden = 1
|
||||
if(!istype(mob, /mob/living/carbon))
|
||||
return
|
||||
if(!mob.stat && isturf(mob.loc) && !mob.restrained())
|
||||
mob:toggle_throw_mode()
|
||||
if(iscarbon(mob))
|
||||
var/mob/living/carbon/C = mob
|
||||
C.toggle_throw_mode()
|
||||
else
|
||||
return
|
||||
to_chat(usr, "<span class='danger'>This mob type cannot throw items.</span>")
|
||||
|
||||
|
||||
/client/verb/drop_item()
|
||||
@@ -134,16 +139,16 @@
|
||||
/client/proc/Move_object(direct)
|
||||
if(mob && mob.control_object)
|
||||
if(mob.control_object.density)
|
||||
step(mob.control_object,direct)
|
||||
if(!mob.control_object) return
|
||||
mob.control_object.dir = direct
|
||||
step(mob.control_object, direct)
|
||||
if(!mob.control_object)
|
||||
return
|
||||
mob.control_object.setDir(direct)
|
||||
else
|
||||
mob.control_object.forceMove(get_step(mob.control_object,direct))
|
||||
mob.control_object.forceMove(get_step(mob.control_object, direct))
|
||||
return
|
||||
|
||||
|
||||
/client/Move(n, direct)
|
||||
|
||||
if(viewingCanvas)
|
||||
view = world.view //Reset the view
|
||||
winset(src, "mapwindow.map", "icon-size=[src.reset_stretch]")
|
||||
@@ -152,19 +157,28 @@
|
||||
if(mob.hud_used)
|
||||
mob.hud_used.show_hud(HUD_STYLE_STANDARD)
|
||||
|
||||
if(mob.control_object) Move_object(direct)
|
||||
if(world.time < move_delay)
|
||||
return
|
||||
|
||||
if(world.time < move_delay) return
|
||||
move_delay = world.time + world.tick_lag //this is here because Move() can now be called multiple times per tick
|
||||
if(!mob || !mob.loc)
|
||||
return 0
|
||||
|
||||
if(!isliving(mob)) return mob.Move(n,direct)
|
||||
if(mob.notransform)
|
||||
return 0 //This is sota the goto stop mobs from moving var
|
||||
|
||||
if(moving) return 0
|
||||
if(mob.control_object)
|
||||
return Move_object(direct)
|
||||
|
||||
if(!mob) return
|
||||
if(!isliving(mob))
|
||||
return mob.Move(n, direct)
|
||||
|
||||
if(mob.stat==DEAD) return
|
||||
if(mob.stat == DEAD)
|
||||
mob.ghostize()
|
||||
return 0
|
||||
|
||||
if(mob.notransform) return//This is sota the goto stop mobs from moving var
|
||||
if(moving)
|
||||
return 0
|
||||
|
||||
if(isliving(mob))
|
||||
var/mob/living/L = mob
|
||||
@@ -172,126 +186,105 @@
|
||||
Process_Incorpmove(direct)
|
||||
return
|
||||
|
||||
if(Process_Grab()) return
|
||||
|
||||
if(mob.buckled) //if we're buckled to something, tell it we moved.
|
||||
return mob.buckled.relaymove(mob, direct)
|
||||
|
||||
if(mob.remote_control) //we're controlling something, our movement is relayed to it
|
||||
if(mob.remote_control) //we're controlling something, our movement is relayed to it
|
||||
return mob.remote_control.relaymove(mob, direct)
|
||||
|
||||
if(isAI(mob))
|
||||
if(istype(mob.loc, /obj/item/device/aicard))
|
||||
var/obj/O = mob.loc
|
||||
return O.relaymove(mob, direct) //aicards have special relaymove stuff
|
||||
return AIMove(n,direct,mob)
|
||||
return O.relaymove(mob, direct) // aicards have special relaymove stuff
|
||||
return AIMove(n, direct, mob)
|
||||
|
||||
|
||||
if(Process_Grab())
|
||||
return
|
||||
|
||||
if(mob.buckled) //if we're buckled to something, tell it we moved.
|
||||
return mob.buckled.relaymove(mob, direct)
|
||||
|
||||
if(!mob.canmove)
|
||||
return
|
||||
|
||||
//if(istype(mob.loc, /turf/space) || (mob.flags & NOGRAV))
|
||||
// if(!mob.Process_Spacemove(0)) return 0
|
||||
|
||||
if(!mob.lastarea)
|
||||
mob.lastarea = get_area(mob.loc)
|
||||
|
||||
if(isobj(mob.loc) || ismob(mob.loc))//Inside an object, tell it we moved
|
||||
if(isobj(mob.loc) || ismob(mob.loc)) //Inside an object, tell it we moved
|
||||
var/atom/O = mob.loc
|
||||
return O.relaymove(mob, direct)
|
||||
|
||||
if(istype(mob.get_active_hand(), /obj/item))
|
||||
var/obj/item/I = mob.get_active_hand()
|
||||
I.moved(mob, n, direct)
|
||||
|
||||
|
||||
if(!mob.Process_Spacemove(direct))
|
||||
return 0
|
||||
return 0
|
||||
|
||||
if(isturf(mob.loc))
|
||||
|
||||
if(mob.restrained())//Why being pulled while cuffed prevents you from moving
|
||||
for(var/mob/M in range(mob, 1))
|
||||
if(M.pulling == mob)
|
||||
if(!M.restrained() && M.stat == 0 && M.canmove && mob.Adjacent(M))
|
||||
to_chat(src, "<span class='notice'>You're restrained! You can't move!</span>")
|
||||
return 0
|
||||
else
|
||||
M.stop_pulling()
|
||||
|
||||
if(mob.pinned.len)
|
||||
to_chat(src, "<span class='notice'>You're pinned to a wall by [mob.pinned[1]]!</span>")
|
||||
return 0
|
||||
|
||||
var/turf/T = mob.loc
|
||||
move_delay = world.time//set move delay
|
||||
move_delay += T.slowdown
|
||||
mob.last_movement = world.time
|
||||
switch(mob.m_intent)
|
||||
if("run")
|
||||
if(mob.drowsyness > 0)
|
||||
move_delay += 6
|
||||
move_delay += 1+config.run_speed
|
||||
if("walk")
|
||||
move_delay += 1+config.walk_speed
|
||||
move_delay += mob.movement_delay()
|
||||
|
||||
if(config.Tickcomp)
|
||||
move_delay -= 1.3
|
||||
var/tickcomp = ((1/(world.tick_lag))*1.3)
|
||||
move_delay = move_delay + tickcomp
|
||||
|
||||
//We are now going to move
|
||||
moving = 1
|
||||
//Something with pulling things
|
||||
if(locate(/obj/item/weapon/grab, mob))
|
||||
move_delay = max(move_delay, world.time + 7)
|
||||
var/list/L = mob.ret_grab()
|
||||
if(istype(L, /list))
|
||||
if(L.len == 2)
|
||||
L -= mob
|
||||
var/mob/M = L[1]
|
||||
if(M)
|
||||
if((get_dist(mob, M) <= 1 || M.loc == mob.loc))
|
||||
. = ..()
|
||||
if(isturf(M.loc))
|
||||
var/diag = get_dir(mob, M)
|
||||
if((diag - 1) & diag)
|
||||
else
|
||||
diag = null
|
||||
if((get_dist(mob, M) > 1 || diag))
|
||||
step(M, get_dir(M.loc, T))
|
||||
if(mob.restrained()) // Why being pulled while cuffed prevents you from moving
|
||||
for(var/mob/M in orange(1, mob))
|
||||
if(M.pulling == mob)
|
||||
if(!M.incapacitated() && mob.Adjacent(M))
|
||||
to_chat(src, "<span class='warning'>You're restrained! You can't move!</span>")
|
||||
move_delay = world.time + 10
|
||||
return 0
|
||||
else
|
||||
for(var/mob/M in L)
|
||||
M.other_mobs = 1
|
||||
if(mob != M)
|
||||
M.animate_movement = 3
|
||||
for(var/mob/M in L)
|
||||
spawn( 0 )
|
||||
step(M, direct)
|
||||
return
|
||||
spawn( 1 )
|
||||
M.other_mobs = null
|
||||
M.animate_movement = 2
|
||||
return
|
||||
M.stop_pulling()
|
||||
|
||||
else if(mob.confused)
|
||||
step(mob, pick(cardinal))
|
||||
else
|
||||
. = ..()
|
||||
|
||||
for(var/obj/item/weapon/grab/G in mob)
|
||||
if(G.state == GRAB_NECK)
|
||||
mob.setDir(reverse_dir[direct])
|
||||
G.adjust_position()
|
||||
for(var/obj/item/weapon/grab/G in mob.grabbed_by)
|
||||
G.adjust_position()
|
||||
//We are now going to move
|
||||
moving = 1
|
||||
move_delay = mob.movement_delay() + world.time
|
||||
mob.last_movement = world.time
|
||||
|
||||
if(locate(/obj/item/weapon/grab, mob))
|
||||
move_delay = max(move_delay, world.time + 7)
|
||||
var/list/L = mob.ret_grab()
|
||||
if(istype(L, /list))
|
||||
if(L.len == 2)
|
||||
L -= mob
|
||||
var/mob/M = L[1]
|
||||
if(M)
|
||||
if((get_dist(mob, M) <= 1 || M.loc == mob.loc))
|
||||
var/turf/prev_loc = mob.loc
|
||||
. = ..()
|
||||
if(M && isturf(M.loc)) // Mob may get deleted during parent call
|
||||
var/diag = get_dir(mob, M)
|
||||
if((diag - 1) & diag)
|
||||
else
|
||||
diag = null
|
||||
if((get_dist(mob, M) > 1 || diag))
|
||||
step(M, get_dir(M.loc, prev_loc))
|
||||
else
|
||||
for(var/mob/M in L)
|
||||
M.other_mobs = 1
|
||||
if(mob != M)
|
||||
M.animate_movement = 3
|
||||
for(var/mob/M in L)
|
||||
spawn(0)
|
||||
step(M, direct)
|
||||
return
|
||||
spawn(1)
|
||||
M.other_mobs = null
|
||||
M.animate_movement = 2
|
||||
return
|
||||
|
||||
else if(mob.confused)
|
||||
step(mob, pick(cardinal))
|
||||
else
|
||||
. = ..()
|
||||
|
||||
for(var/obj/item/weapon/grab/G in mob)
|
||||
if(G.state == GRAB_NECK)
|
||||
mob.setDir(reverse_dir[direct])
|
||||
G.adjust_position()
|
||||
for(var/obj/item/weapon/grab/G in mob.grabbed_by)
|
||||
G.adjust_position()
|
||||
|
||||
moving = 0
|
||||
if(mob && .)
|
||||
if(mob.throwing)
|
||||
mob.throwing.finalize(FALSE)
|
||||
|
||||
for(var/obj/O in mob)
|
||||
O.on_mob_move(direct, mob)
|
||||
|
||||
moving = 0
|
||||
if(mob && .)
|
||||
mob.throwing = 0
|
||||
|
||||
return .
|
||||
|
||||
return
|
||||
|
||||
|
||||
///Process_Grab()
|
||||
@@ -408,13 +401,13 @@
|
||||
var/atom/movable/backup = get_spacemove_backup()
|
||||
if(backup)
|
||||
if(istype(backup) && movement_dir && !backup.anchored)
|
||||
if(backup.newtonian_move(turn(movement_dir, 180))) //You're pushing off something movable, so it moves
|
||||
src << "<span class='info'>You push off of [backup] to propel yourself.</span>"
|
||||
var/opposite_dir = turn(movement_dir, 180)
|
||||
if(backup.newtonian_move(opposite_dir)) //You're pushing off something movable, so it moves
|
||||
to_chat(src, "<span class='notice'>You push off of [backup] to propel yourself.</span>")
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/get_spacemove_backup()
|
||||
var/atom/movable/dense_object_backup
|
||||
for(var/A in orange(1, get_turf(src)))
|
||||
if(isarea(A))
|
||||
continue
|
||||
@@ -434,9 +427,7 @@
|
||||
return AM
|
||||
if(pulling == AM)
|
||||
continue
|
||||
dense_object_backup = AM
|
||||
break
|
||||
. = dense_object_backup
|
||||
. = AM
|
||||
|
||||
|
||||
/mob/proc/mob_has_gravity(turf/T)
|
||||
|
||||
@@ -15,7 +15,11 @@
|
||||
return
|
||||
stop_pulling()
|
||||
|
||||
src.pulling = AM
|
||||
if(AM.pulledby)
|
||||
visible_message("<span class='danger'>[src] has pulled [AM] from [AM.pulledby]'s grip.</span>")
|
||||
AM.pulledby.stop_pulling() //an object can't be pulled by two mobs at once.
|
||||
|
||||
pulling = AM
|
||||
AM.pulledby = src
|
||||
if(pullin)
|
||||
pullin.update_icon(src)
|
||||
|
||||
@@ -502,8 +502,3 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
||||
/obj/item/device/pda/process()
|
||||
if(current_app)
|
||||
current_app.program_process()
|
||||
|
||||
/obj/item/device/pda/hit_check(speed)
|
||||
if(current_app)
|
||||
current_app.program_hit_check()
|
||||
..()
|
||||
@@ -74,12 +74,6 @@
|
||||
return
|
||||
scan_nearby()
|
||||
|
||||
/datum/data/pda/app/mob_hunter_game/program_hit_check()
|
||||
if(!pda)
|
||||
return
|
||||
for(var/obj/effect/nanomob/hit_mob in get_turf(pda))
|
||||
hit_mob.hitby(pda)
|
||||
|
||||
/datum/data/pda/app/mob_hunter_game/proc/register_capture(datum/mob_hunt/captured, wild = 0)
|
||||
if(!captured)
|
||||
return 0
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/throw/proc/get_throwrange()
|
||||
return projectile_speed
|
||||
return projectile_range
|
||||
|
||||
/obj/item/weapon/gun/throw/proc/get_throwspeed()
|
||||
return projectile_range
|
||||
return projectile_speed
|
||||
|
||||
/obj/item/weapon/gun/throw/proc/modify_projectile(obj/item/I, on_chamber = 0)
|
||||
return
|
||||
@@ -80,7 +80,7 @@
|
||||
to_launch = null
|
||||
modify_projectile(I)
|
||||
playsound(user, fire_sound, 50, 1)
|
||||
I.throw_at(target, get_throwrange(), get_throwspeed(), user, 1)
|
||||
I.throw_at(target, get_throwrange(), get_throwspeed(), user, FALSE)
|
||||
message_admins("[key_name_admin(user)] fired \a [I] from a [src].")
|
||||
log_game("[key_name_admin(user)] used \a [src].")
|
||||
process_chamber()
|
||||
|
||||
@@ -206,9 +206,6 @@ ALLOW_HOLIDAYS
|
||||
##Defines the ticklag for the world. 0.9 is the normal one, 0.5 is smoother.
|
||||
TICKLAG 0.5
|
||||
|
||||
## Defines if Tick Compensation is used. It results in a minor slowdown of movement of all mobs, but attempts to result in a level movement speed across all ticks. Recommended if tickrate is lowered.
|
||||
TICKCOMP 1
|
||||
|
||||
## Whether the server will talk to other processes through socket_talk
|
||||
SOCKET_TALK 0
|
||||
|
||||
|
||||
@@ -38,17 +38,17 @@ REVIVAL_BRAIN_LIFE -1
|
||||
## We suggest editing these variabled in-game to find a good speed for your server. To do this you must be a high level admin. Open the 'debug' tab ingame. Select "Debug Controller" and then, in the popup, select "Configuration". These variables should have the same name.
|
||||
## These values get directly added to values and totals in-game. To speed things up make the number negative, to slow things down, make the number positive.
|
||||
|
||||
## These modify the run/walk speed of all mobs before the mob-specific modifiers are applied.
|
||||
## These modify the run/walk speed of all mobs before the mob-specific modifiers are applied.
|
||||
RUN_SPEED 1
|
||||
WALK_SPEED 4
|
||||
|
||||
## The variables below affect the movement of specific mob types.
|
||||
HUMAN_DELAY 0
|
||||
ROBOT_DELAY 0
|
||||
MONKEY_DELAY 0
|
||||
ALIEN_DELAY 0
|
||||
METROID_DELAY 0
|
||||
ANIMAL_DELAY 0
|
||||
HUMAN_DELAY 1.5
|
||||
ROBOT_DELAY 1.5
|
||||
MONKEY_DELAY 1.5
|
||||
ALIEN_DELAY 1.5
|
||||
METROID_DELAY 1.5
|
||||
ANIMAL_DELAY 1.5
|
||||
|
||||
## Comment for "normal" explosions, which ignore obstacles
|
||||
## Uncomment for explosions that react to doors and walls
|
||||
|
||||
+60
-60
@@ -29,7 +29,7 @@ macro "AZERTYoff"
|
||||
is-disabled = false
|
||||
elem "AZRFF-WEST+REP"
|
||||
name = "WEST+REP"
|
||||
command = ".west"
|
||||
command = ".moveleft"
|
||||
is-disabled = false
|
||||
elem "AZRFF-CTRL+NORTH"
|
||||
name = "CTRL+NORTH"
|
||||
@@ -37,7 +37,7 @@ macro "AZERTYoff"
|
||||
is-disabled = false
|
||||
elem "AZRFF-NORTH+REP"
|
||||
name = "NORTH+REP"
|
||||
command = ".north"
|
||||
command = ".moveup"
|
||||
is-disabled = false
|
||||
elem "AZRFF-CTRL+EAST"
|
||||
name = "CTRL+EAST"
|
||||
@@ -45,7 +45,7 @@ macro "AZERTYoff"
|
||||
is-disabled = false
|
||||
elem "AZRFF-EAST+REP"
|
||||
name = "EAST+REP"
|
||||
command = ".east"
|
||||
command = ".moveright"
|
||||
is-disabled = false
|
||||
elem "AZRFF-CTRL+SOUTH"
|
||||
name = "CTRL+SOUTH"
|
||||
@@ -53,7 +53,7 @@ macro "AZERTYoff"
|
||||
is-disabled = false
|
||||
elem "AZRFF-SOUTH+REP"
|
||||
name = "SOUTH+REP"
|
||||
command = ".south"
|
||||
command = ".movedown"
|
||||
is-disabled = false
|
||||
elem "AZRFF-INSERT"
|
||||
name = "INSERT"
|
||||
@@ -85,7 +85,7 @@ macro "AZERTYoff"
|
||||
is-disabled = false
|
||||
elem "AZRFF-CTRL+D+REP"
|
||||
name = "CTRL+D+REP"
|
||||
command = ".east"
|
||||
command = ".moveright"
|
||||
is-disabled = false
|
||||
elem "AZRFF-CTRL+B"
|
||||
name = "CTRL+B"
|
||||
@@ -105,7 +105,7 @@ macro "AZERTYoff"
|
||||
is-disabled = false
|
||||
elem "AZRFF-CTRL+Q+REP"
|
||||
name = "CTRL+Q+REP"
|
||||
command = ".west"
|
||||
command = ".moveleft"
|
||||
is-disabled = false
|
||||
elem "AZRFF-CTRL+R"
|
||||
name = "CTRL+R"
|
||||
@@ -113,7 +113,7 @@ macro "AZERTYoff"
|
||||
is-disabled = false
|
||||
elem "AZRFF-CTRL+S+REP"
|
||||
name = "CTRL+S+REP"
|
||||
command = ".south"
|
||||
command = ".movedown"
|
||||
is-disabled = false
|
||||
elem "AZRFF-CTRL+W"
|
||||
name = "CTRL+W"
|
||||
@@ -129,7 +129,7 @@ macro "AZERTYoff"
|
||||
is-disabled = false
|
||||
elem "AZRFF-CTRL+Z+REP"
|
||||
name = "CTRL+Z+REP"
|
||||
command = ".north"
|
||||
command = ".moveup"
|
||||
is-disabled = false
|
||||
elem "AZRFF-F1"
|
||||
name = "F1"
|
||||
@@ -215,7 +215,7 @@ macro "AZERTYon"
|
||||
is-disabled = false
|
||||
elem "AZRON-WEST+REP"
|
||||
name = "WEST+REP"
|
||||
command = ".west"
|
||||
command = ".moveleft"
|
||||
is-disabled = false
|
||||
elem "AZRON-CTRL+NORTH"
|
||||
name = "CTRL+NORTH"
|
||||
@@ -223,7 +223,7 @@ macro "AZERTYon"
|
||||
is-disabled = false
|
||||
elem "AZRON-NORTH+REP"
|
||||
name = "NORTH+REP"
|
||||
command = ".north"
|
||||
command = ".moveup"
|
||||
is-disabled = false
|
||||
elem "AZRON-CTRL+EAST"
|
||||
name = "CTRL+EAST"
|
||||
@@ -231,7 +231,7 @@ macro "AZERTYon"
|
||||
is-disabled = false
|
||||
elem "AZRON-EAST+REP"
|
||||
name = "EAST+REP"
|
||||
command = ".east"
|
||||
command = ".moveright"
|
||||
is-disabled = false
|
||||
elem "AZRON-CTRL+SOUTH"
|
||||
name = "CTRL+SOUTH"
|
||||
@@ -239,7 +239,7 @@ macro "AZERTYon"
|
||||
is-disabled = false
|
||||
elem "AZRON-SOUTH+REP"
|
||||
name = "SOUTH+REP"
|
||||
command = ".south"
|
||||
command = ".movedown"
|
||||
is-disabled = false
|
||||
elem "AZRON-INSERT"
|
||||
name = "INSERT"
|
||||
@@ -291,11 +291,11 @@ macro "AZERTYon"
|
||||
is-disabled = false
|
||||
elem "AZRON-D+REP"
|
||||
name = "D+REP"
|
||||
command = ".east"
|
||||
command = ".moveright"
|
||||
is-disabled = false
|
||||
elem "AZRON-CTRL+D+REP"
|
||||
name = "CTRL+D+REP"
|
||||
command = ".east"
|
||||
command = ".moveright"
|
||||
is-disabled = false
|
||||
elem "AZRON-CTRL+B"
|
||||
name = "CTRL+B"
|
||||
@@ -335,11 +335,11 @@ macro "AZERTYon"
|
||||
is-disabled = false
|
||||
elem "AZRON-Q+REP"
|
||||
name = "Q+REP"
|
||||
command = ".west"
|
||||
command = ".moveleft"
|
||||
is-disabled = false
|
||||
elem "AZRON-CTRL+Q+REP"
|
||||
name = "CTRL+Q+REP"
|
||||
command = ".west"
|
||||
command = ".moveleft"
|
||||
is-disabled = false
|
||||
elem "AZRON-R"
|
||||
name = "R"
|
||||
@@ -351,11 +351,11 @@ macro "AZERTYon"
|
||||
is-disabled = false
|
||||
elem "s_key"
|
||||
name = "S+REP"
|
||||
command = ".south"
|
||||
command = ".movedown"
|
||||
is-disabled = false
|
||||
elem "AZRON-CTRL+S+REP"
|
||||
name = "CTRL+S+REP"
|
||||
command = ".south"
|
||||
command = ".movedown"
|
||||
is-disabled = false
|
||||
elem "AZRON-T"
|
||||
name = "T"
|
||||
@@ -395,11 +395,11 @@ macro "AZERTYon"
|
||||
is-disabled = false
|
||||
elem "w_key"
|
||||
name = "Z+REP"
|
||||
command = ".north"
|
||||
command = ".moveup"
|
||||
is-disabled = false
|
||||
elem "AZRON-CTRL+Z+REP"
|
||||
name = "CTRL+Z+REP"
|
||||
command = ".north"
|
||||
command = ".moveup"
|
||||
is-disabled = false
|
||||
elem "AZRON-F1"
|
||||
name = "F1"
|
||||
@@ -481,7 +481,7 @@ macro "borghotkeymode"
|
||||
is-disabled = false
|
||||
elem "BRGHK-WEST+REP"
|
||||
name = "WEST+REP"
|
||||
command = ".west"
|
||||
command = ".moveleft"
|
||||
is-disabled = false
|
||||
elem "BRGHK-CTRL+NORTH"
|
||||
name = "CTRL+NORTH"
|
||||
@@ -489,7 +489,7 @@ macro "borghotkeymode"
|
||||
is-disabled = false
|
||||
elem "BRGHK-NORTH+REP"
|
||||
name = "NORTH+REP"
|
||||
command = ".north"
|
||||
command = ".moveup"
|
||||
is-disabled = false
|
||||
elem "BRGHK-CTRL+EAST"
|
||||
name = "CTRL+EAST"
|
||||
@@ -497,7 +497,7 @@ macro "borghotkeymode"
|
||||
is-disabled = false
|
||||
elem "BRGHK-EAST+REP"
|
||||
name = "EAST+REP"
|
||||
command = ".east"
|
||||
command = ".moveright"
|
||||
is-disabled = false
|
||||
elem "BRGHK-CTRL+SOUTH"
|
||||
name = "CTRL+SOUTH"
|
||||
@@ -505,7 +505,7 @@ macro "borghotkeymode"
|
||||
is-disabled = false
|
||||
elem "BRGHK-SOUTH+REP"
|
||||
name = "SOUTH+REP"
|
||||
command = ".south"
|
||||
command = ".movedown"
|
||||
is-disabled = false
|
||||
elem "BRGHK-INSERT"
|
||||
name = "INSERT"
|
||||
@@ -549,11 +549,11 @@ macro "borghotkeymode"
|
||||
is-disabled = false
|
||||
elem "BRGHK-A+REP"
|
||||
name = "A+REP"
|
||||
command = ".west"
|
||||
command = ".moveleft"
|
||||
is-disabled = false
|
||||
elem "BRGHK-CTRL+A+REP"
|
||||
name = "CTRL+A+REP"
|
||||
command = ".west"
|
||||
command = ".moveleft"
|
||||
is-disabled = false
|
||||
elem "BRGHK-B"
|
||||
name = "B"
|
||||
@@ -581,11 +581,11 @@ macro "borghotkeymode"
|
||||
is-disabled = false
|
||||
elem "BRGHK-D+REP"
|
||||
name = "D+REP"
|
||||
command = ".east"
|
||||
command = ".moveright"
|
||||
is-disabled = false
|
||||
elem "BRGHK-CTRL+D+REP"
|
||||
name = "CTRL+D+REP"
|
||||
command = ".east"
|
||||
command = ".moveright"
|
||||
is-disabled = false
|
||||
elem "BRGHK-F"
|
||||
name = "F"
|
||||
@@ -613,19 +613,19 @@ macro "borghotkeymode"
|
||||
is-disabled = false
|
||||
elem "s_key"
|
||||
name = "S+REP"
|
||||
command = ".south"
|
||||
command = ".movedown"
|
||||
is-disabled = false
|
||||
elem "BRGHK-CTRL+S+REP"
|
||||
name = "CTRL+S+REP"
|
||||
command = ".south"
|
||||
command = ".movedown"
|
||||
is-disabled = false
|
||||
elem "w_key"
|
||||
name = "W+REP"
|
||||
command = ".north"
|
||||
command = ".moveup"
|
||||
is-disabled = false
|
||||
elem "BRGHK-CTRL+W+REP"
|
||||
name = "CTRL+W+REP"
|
||||
command = ".north"
|
||||
command = ".moveup"
|
||||
is-disabled = false
|
||||
elem "BRGHK-X"
|
||||
name = "X"
|
||||
@@ -735,7 +735,7 @@ macro "macro"
|
||||
is-disabled = false
|
||||
elem "MACRO-WEST+REP"
|
||||
name = "WEST+REP"
|
||||
command = ".west"
|
||||
command = ".moveleft"
|
||||
is-disabled = false
|
||||
elem "MACRO-CTRL+NORTH"
|
||||
name = "CTRL+NORTH"
|
||||
@@ -743,7 +743,7 @@ macro "macro"
|
||||
is-disabled = false
|
||||
elem "MACRO-NORTH+REP"
|
||||
name = "NORTH+REP"
|
||||
command = ".north"
|
||||
command = ".moveup"
|
||||
is-disabled = false
|
||||
elem "MACRO-CTRL+EAST"
|
||||
name = "CTRL+EAST"
|
||||
@@ -751,7 +751,7 @@ macro "macro"
|
||||
is-disabled = false
|
||||
elem "MACRO-EAST+REP"
|
||||
name = "EAST+REP"
|
||||
command = ".east"
|
||||
command = ".moveright"
|
||||
is-disabled = false
|
||||
elem "MACRO-CTRL+SOUTH"
|
||||
name = "CTRL+SOUTH"
|
||||
@@ -759,7 +759,7 @@ macro "macro"
|
||||
is-disabled = false
|
||||
elem "MACRO-SOUTH+REP"
|
||||
name = "SOUTH+REP"
|
||||
command = ".south"
|
||||
command = ".movedown"
|
||||
is-disabled = false
|
||||
elem "MACRO-INSERT"
|
||||
name = "INSERT"
|
||||
@@ -787,11 +787,11 @@ macro "macro"
|
||||
is-disabled = false
|
||||
elem "MACRO-CTRL+A+REP"
|
||||
name = "CTRL+A+REP"
|
||||
command = ".west"
|
||||
command = ".moveleft"
|
||||
is-disabled = false
|
||||
elem "MACRO-CTRL+D+REP"
|
||||
name = "CTRL+D+REP"
|
||||
command = ".east"
|
||||
command = ".moveright"
|
||||
is-disabled = false
|
||||
elem "MACRO-CTRL+B"
|
||||
name = "CTRL+B"
|
||||
@@ -819,11 +819,11 @@ macro "macro"
|
||||
is-disabled = false
|
||||
elem "MACRO-CTRL+S+REP"
|
||||
name = "CTRL+S+REP"
|
||||
command = ".south"
|
||||
command = ".movedown"
|
||||
is-disabled = false
|
||||
elem "MACRO-CTRL+W+REP"
|
||||
name = "CTRL+W+REP"
|
||||
command = ".north"
|
||||
command = ".moveup"
|
||||
is-disabled = false
|
||||
elem "MACRO-CTRL+X"
|
||||
name = "CTRL+X"
|
||||
@@ -921,7 +921,7 @@ macro "hotkeymode"
|
||||
is-disabled = false
|
||||
elem "HKMODE-WEST+REP"
|
||||
name = "WEST+REP"
|
||||
command = ".west"
|
||||
command = ".moveleft"
|
||||
is-disabled = false
|
||||
elem "HKMODE-CTRL+NORTH"
|
||||
name = "CTRL+NORTH"
|
||||
@@ -929,7 +929,7 @@ macro "hotkeymode"
|
||||
is-disabled = false
|
||||
elem "HKMODE-NORTH+REP"
|
||||
name = "NORTH+REP"
|
||||
command = ".north"
|
||||
command = ".moveup"
|
||||
is-disabled = false
|
||||
elem "HKMODE-CTRL+EAST"
|
||||
name = "CTRL+EAST"
|
||||
@@ -937,7 +937,7 @@ macro "hotkeymode"
|
||||
is-disabled = false
|
||||
elem "HKMODE-EAST+REP"
|
||||
name = "EAST+REP"
|
||||
command = ".east"
|
||||
command = ".moveright"
|
||||
is-disabled = false
|
||||
elem "HKMODE-CTRL+SOUTH"
|
||||
name = "CTRL+SOUTH"
|
||||
@@ -945,7 +945,7 @@ macro "hotkeymode"
|
||||
is-disabled = false
|
||||
elem "HKMODE-SOUTH+REP"
|
||||
name = "SOUTH+REP"
|
||||
command = ".south"
|
||||
command = ".movedown"
|
||||
is-disabled = false
|
||||
elem "HKMODE-INSERT"
|
||||
name = "INSERT"
|
||||
@@ -1001,19 +1001,19 @@ macro "hotkeymode"
|
||||
is-disabled = false
|
||||
elem "HKMODE-A+REP"
|
||||
name = "A+REP"
|
||||
command = ".west"
|
||||
command = ".moveleft"
|
||||
is-disabled = false
|
||||
elem "HKMODE-CTRL+A+REP"
|
||||
name = "CTRL+A+REP"
|
||||
command = ".west"
|
||||
command = ".moveleft"
|
||||
is-disabled = false
|
||||
elem "HKMODE-D+REP"
|
||||
name = "D+REP"
|
||||
command = ".east"
|
||||
command = ".moveright"
|
||||
is-disabled = false
|
||||
elem "HKMODE-CTRL+D+REP"
|
||||
name = "CTRL+D+REP"
|
||||
command = ".east"
|
||||
command = ".moveright"
|
||||
is-disabled = false
|
||||
elem "HKMODE-B"
|
||||
name = "B"
|
||||
@@ -1073,11 +1073,11 @@ macro "hotkeymode"
|
||||
is-disabled = false
|
||||
elem "s_key"
|
||||
name = "S+REP"
|
||||
command = ".south"
|
||||
command = ".movedown"
|
||||
is-disabled = false
|
||||
elem "HKMODE-CTRL+S+REP"
|
||||
name = "CTRL+S+REP"
|
||||
command = ".south"
|
||||
command = ".movedown"
|
||||
is-disabled = false
|
||||
elem "HKMODE-T"
|
||||
name = "T"
|
||||
@@ -1085,11 +1085,11 @@ macro "hotkeymode"
|
||||
is-disabled = false
|
||||
elem "w_key"
|
||||
name = "W+REP"
|
||||
command = ".north"
|
||||
command = ".moveup"
|
||||
is-disabled = false
|
||||
elem "HKMODE-CTRL+W+REP"
|
||||
name = "CTRL+W+REP"
|
||||
command = ".north"
|
||||
command = ".moveup"
|
||||
is-disabled = false
|
||||
elem "HKMODE-X"
|
||||
name = "X"
|
||||
@@ -1195,7 +1195,7 @@ macro "borgmacro"
|
||||
is-disabled = false
|
||||
elem "BRGMACRO-WEST+REP"
|
||||
name = "WEST+REP"
|
||||
command = ".west"
|
||||
command = ".moveleft"
|
||||
is-disabled = false
|
||||
elem "BRGMACRO-CTRL+NORTH"
|
||||
name = "CTRL+NORTH"
|
||||
@@ -1203,7 +1203,7 @@ macro "borgmacro"
|
||||
is-disabled = false
|
||||
elem "BRGMACRO-NORTH+REP"
|
||||
name = "NORTH+REP"
|
||||
command = ".north"
|
||||
command = ".moveup"
|
||||
is-disabled = false
|
||||
elem "BRGMACRO-CTRL+EAST"
|
||||
name = "CTRL+EAST"
|
||||
@@ -1211,7 +1211,7 @@ macro "borgmacro"
|
||||
is-disabled = false
|
||||
elem "BRGMACRO-EAST+REP"
|
||||
name = "EAST+REP"
|
||||
command = ".east"
|
||||
command = ".moveright"
|
||||
is-disabled = false
|
||||
elem "BRGMACRO-CTRL+SOUTH"
|
||||
name = "CTRL+SOUTH"
|
||||
@@ -1219,7 +1219,7 @@ macro "borgmacro"
|
||||
is-disabled = false
|
||||
elem "BRGMACRO-SOUTH+REP"
|
||||
name = "SOUTH+REP"
|
||||
command = ".south"
|
||||
command = ".movedown"
|
||||
is-disabled = false
|
||||
elem "BRGMACRO-INSERT"
|
||||
name = "INSERT"
|
||||
@@ -1247,7 +1247,7 @@ macro "borgmacro"
|
||||
is-disabled = false
|
||||
elem "BRGMACRO-CTRL+A+REP"
|
||||
name = "CTRL+A+REP"
|
||||
command = ".west"
|
||||
command = ".moveleft"
|
||||
is-disabled = false
|
||||
elem "BRGMACRO-CTRL+B"
|
||||
name = "CTRL+B"
|
||||
@@ -1259,7 +1259,7 @@ macro "borgmacro"
|
||||
is-disabled = false
|
||||
elem "BRGMACRO-CTRL+D+REP"
|
||||
name = "CTRL+D+REP"
|
||||
command = ".east"
|
||||
command = ".moveright"
|
||||
is-disabled = false
|
||||
elem "BRGMACRO-CTRL+F"
|
||||
name = "CTRL+F"
|
||||
@@ -1275,11 +1275,11 @@ macro "borgmacro"
|
||||
is-disabled = false
|
||||
elem "BRGMACRO-CTRL+S+REP"
|
||||
name = "CTRL+S+REP"
|
||||
command = ".south"
|
||||
command = ".movedown"
|
||||
is-disabled = false
|
||||
elem "BRGMACRO-CTRL+W+REP"
|
||||
name = "CTRL+W+REP"
|
||||
command = ".north"
|
||||
command = ".moveup"
|
||||
is-disabled = false
|
||||
elem "BRGMACRO-CTRL+X"
|
||||
name = "CTRL+X"
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "code\__DEFINES\admin.dm"
|
||||
#include "code\__DEFINES\atmospherics.dm"
|
||||
#include "code\__DEFINES\bots.dm"
|
||||
#include "code\__DEFINES\callbacks.dm"
|
||||
#include "code\__DEFINES\clothing.dm"
|
||||
#include "code\__DEFINES\combat.dm"
|
||||
#include "code\__DEFINES\construction.dm"
|
||||
@@ -188,7 +189,9 @@
|
||||
#include "code\controllers\Processes\obj.dm"
|
||||
#include "code\controllers\Processes\pipenet.dm"
|
||||
#include "code\controllers\Processes\shuttles.dm"
|
||||
#include "code\controllers\Processes\spacedrift.dm"
|
||||
#include "code\controllers\Processes\sun.dm"
|
||||
#include "code\controllers\Processes\throwing.dm"
|
||||
#include "code\controllers\Processes\ticker.dm"
|
||||
#include "code\controllers\Processes\timer.dm"
|
||||
#include "code\controllers\Processes\weather.dm"
|
||||
@@ -199,6 +202,7 @@
|
||||
#include "code\datums\ai_laws.dm"
|
||||
#include "code\datums\beam.dm"
|
||||
#include "code\datums\browser.dm"
|
||||
#include "code\datums\callback.dm"
|
||||
#include "code\datums\cargoprofile.dm"
|
||||
#include "code\datums\computerfiles.dm"
|
||||
#include "code\datums\datacore.dm"
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user