mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-21 03:55:05 +01:00
Merge pull request #10185 from Mitchs98/moveresist
Ports Move Force from TG
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
//Defaults
|
||||
#define MOVE_FORCE_DEFAULT 1000
|
||||
#define MOVE_RESIST_DEFAULT 1000
|
||||
#define PULL_FORCE_DEFAULT 1000
|
||||
|
||||
//Factors/modifiers
|
||||
#define MOVE_FORCE_PULL_RATIO 1 //Same move force to pull objects
|
||||
#define MOVE_FORCE_PUSH_RATIO 1 //Same move force to normally push
|
||||
#define MOVE_FORCE_FORCEPUSH_RATIO 2 //2x move force to forcefully push
|
||||
#define MOVE_FORCE_CRUSH_RATIO 3 //3x move force to do things like crush objects
|
||||
#define MOVE_FORCE_THROW_RATIO 1 //Same force throw as resist to throw objects
|
||||
#define MOVE_FORCE_OVERPOWERING MOVE_FORCE_DEFAULT * MOVE_FORCE_CRUSH_RATIO * 10
|
||||
#define MOVE_FORCE_EXTREMELY_STRONG MOVE_FORCE_DEFAULT * MOVE_FORCE_CRUSH_RATIO * 3
|
||||
#define MOVE_FORCE_VERY_STRONG (MOVE_FORCE_DEFAULT * MOVE_FORCE_CRUSH_RATIO) - 1
|
||||
#define MOVE_FORCE_STRONG MOVE_FORCE_DEFAULT * 2
|
||||
#define MOVE_FORCE_NORMAL MOVE_FORCE_DEFAULT
|
||||
#define MOVE_FORCE_WEAK MOVE_FORCE_DEFAULT / 2
|
||||
#define MOVE_FORCE_VERY_WEAK (MOVE_FORCE_DEFAULT / MOVE_FORCE_CRUSH_RATIO) + 1
|
||||
#define MOVE_FORCE_EXTREMELY_WEAK MOVE_FORCE_DEFAULT / (MOVE_FORCE_CRUSH_RATIO * 3)
|
||||
@@ -1495,7 +1495,7 @@ var/mob/dview/dview_mob = new
|
||||
invisibility = 101
|
||||
density = 0
|
||||
|
||||
anchored = 1
|
||||
move_resist = INFINITY
|
||||
simulated = 0
|
||||
|
||||
see_in_dark = 1e6
|
||||
|
||||
@@ -285,12 +285,12 @@
|
||||
/mob/proc/CtrlClickOn(var/atom/A)
|
||||
A.CtrlClick(src)
|
||||
return
|
||||
/atom/proc/CtrlClick(var/mob/user)
|
||||
return
|
||||
|
||||
/atom/movable/CtrlClick(var/mob/user)
|
||||
if(Adjacent(user))
|
||||
user.start_pulling(src)
|
||||
/atom/proc/CtrlClick(mob/user)
|
||||
SEND_SIGNAL(src, COMSIG_CLICK_CTRL, user)
|
||||
var/mob/living/ML = user
|
||||
if(istype(ML))
|
||||
ML.pulled(src)
|
||||
|
||||
/*
|
||||
Alt click
|
||||
|
||||
@@ -53,6 +53,7 @@ SUBSYSTEM_DEF(throwing)
|
||||
var/dist_y
|
||||
var/dx
|
||||
var/dy
|
||||
var/force = MOVE_FORCE_DEFAULT
|
||||
var/pure_diagonal
|
||||
var/diagonal_error
|
||||
var/datum/callback/callback
|
||||
|
||||
+2
-2
@@ -86,7 +86,7 @@
|
||||
if(opacity && isturf(loc))
|
||||
var/turf/T = loc
|
||||
T.has_opaque_atom = TRUE // No need to recalculate it in this case, it's guranteed to be on afterwards anyways.
|
||||
|
||||
|
||||
if(loc)
|
||||
loc.InitializedOn(src) // Used for poolcontroller / pool to improve performance greatly. However it also open up path to other usage of observer pattern on turfs.
|
||||
|
||||
@@ -324,7 +324,7 @@
|
||||
// Atoms that return TRUE prevent RPDs placing any kind of pipes on their turf.
|
||||
return FALSE
|
||||
|
||||
/atom/proc/hitby(atom/movable/AM, skipcatch, hitpush, blocked)
|
||||
/atom/proc/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
|
||||
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(CALLBACK(src, .proc/hitby_react, AM), 2)
|
||||
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
appearance_flags = TILE_BOUND
|
||||
var/last_move = null
|
||||
var/anchored = 0
|
||||
var/move_resist = MOVE_RESIST_DEFAULT
|
||||
var/move_force = MOVE_FORCE_DEFAULT
|
||||
var/pull_force = PULL_FORCE_DEFAULT
|
||||
// var/elevation = 2 - not used anywhere
|
||||
var/move_speed = 10
|
||||
var/l_move_time = 1
|
||||
@@ -13,6 +16,8 @@
|
||||
var/no_spin_thrown = 0
|
||||
var/moved_recently = 0
|
||||
var/mob/pulledby = null
|
||||
var/atom/movable/pulling
|
||||
var/canmove = 1
|
||||
|
||||
var/inertia_dir = 0
|
||||
var/atom/inertia_last_loc
|
||||
@@ -55,6 +60,70 @@
|
||||
pulledby = null
|
||||
return ..()
|
||||
|
||||
/atom/movable/proc/start_pulling(atom/movable/AM, state, force = move_force, supress_message = FALSE)
|
||||
if(QDELETED(AM))
|
||||
return FALSE
|
||||
if(!(AM.can_be_pulled(src, state, force)))
|
||||
return FALSE
|
||||
|
||||
// If we're pulling something then drop what we're currently pulling and pull this instead.
|
||||
if(pulling)
|
||||
if(state == 0)
|
||||
stop_pulling()
|
||||
return FALSE
|
||||
// Are we trying to pull something we are already pulling? Then enter grab cycle and end.
|
||||
if(AM == pulling)
|
||||
if(isliving(AM))
|
||||
var/mob/living/AMob = AM
|
||||
AMob.grabbedby(src)
|
||||
return TRUE
|
||||
stop_pulling()
|
||||
if(AM.pulledby)
|
||||
add_attack_logs(AM, AM.pulledby, "pulled from", ATKLOG_ALMOSTALL)
|
||||
AM.pulledby.stop_pulling() //an object can't be pulled by two mobs at once.
|
||||
pulling = AM
|
||||
AM.pulledby = src
|
||||
if(ismob(AM))
|
||||
var/mob/M = AM
|
||||
add_attack_logs(src, M, "passively grabbed", ATKLOG_ALMOSTALL)
|
||||
if(!supress_message)
|
||||
visible_message("<span class='warning'>[src] has grabbed [M] passively!</span>")
|
||||
return TRUE
|
||||
|
||||
/atom/movable/proc/stop_pulling()
|
||||
if(pulling)
|
||||
pulling.pulledby = null
|
||||
var/mob/living/ex_pulled = pulling
|
||||
pulling = null
|
||||
if(isliving(ex_pulled))
|
||||
var/mob/living/L = ex_pulled
|
||||
L.update_canmove()// mob gets up if it was lyng down in a chokehold
|
||||
|
||||
/atom/movable/proc/check_pulling()
|
||||
if(pulling)
|
||||
var/atom/movable/pullee = pulling
|
||||
if(pullee && get_dist(src, pullee) > 1)
|
||||
stop_pulling()
|
||||
return
|
||||
if(!isturf(loc))
|
||||
stop_pulling()
|
||||
return
|
||||
if(pullee && !isturf(pullee.loc) && pullee.loc != loc) //to be removed once all code that changes an object's loc uses forceMove().
|
||||
log_game("DEBUG:[src]'s pull on [pullee] wasn't broken despite [pullee] being in [pullee.loc]. Pull stopped manually.")
|
||||
stop_pulling()
|
||||
return
|
||||
if(pulling.anchored)
|
||||
stop_pulling()
|
||||
return
|
||||
|
||||
/atom/movable/proc/can_be_pulled(user, grab_state, force)
|
||||
if(src == user || !isturf(loc))
|
||||
return FALSE
|
||||
if(anchored || throwing)
|
||||
return FALSE
|
||||
if(force < (move_resist * MOVE_FORCE_PULL_RATIO))
|
||||
return FALSE
|
||||
return TRUE
|
||||
// Used in shuttle movement and AI eye stuff.
|
||||
// Primarily used to notify objects being moved by a shuttle/bluespace fuckup.
|
||||
/atom/movable/proc/setLoc(var/T, var/teleported=0)
|
||||
@@ -218,12 +287,12 @@
|
||||
if(!QDELETED(hit_atom))
|
||||
return hit_atom.hitby(src)
|
||||
|
||||
/atom/movable/hitby(atom/movable/AM, skipcatch, hitpush = 1, blocked)
|
||||
if(!anchored && hitpush)
|
||||
/atom/movable/hitby(atom/movable/AM, skipcatch, hitpush = 1, blocked, datum/thrownthing/throwingdatum)
|
||||
if(!anchored && hitpush && (!throwingdatum || (throwingdatum.force >= (move_resist * MOVE_FORCE_PUSH_RATIO))))
|
||||
step(src, AM.dir)
|
||||
..()
|
||||
|
||||
/atom/movable/proc/throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, diagonals_first = FALSE, var/datum/callback/callback)
|
||||
/atom/movable/proc/throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, diagonals_first = FALSE, datum/callback/callback, force = INFINITY)
|
||||
if(!target || (flags & NODROP) || speed <= 0)
|
||||
return 0
|
||||
|
||||
@@ -330,6 +399,22 @@
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/atom/movable/proc/force_pushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction)
|
||||
return FALSE
|
||||
|
||||
/atom/movable/proc/force_push(atom/movable/AM, force = move_force, direction, silent = FALSE)
|
||||
. = AM.force_pushed(src, force, direction)
|
||||
if(!silent && .)
|
||||
visible_message("<span class='warning'>[src] forcefully pushes against [AM]!</span>", "<span class='warning'>You forcefully push against [AM]!</span>")
|
||||
|
||||
/atom/movable/proc/move_crush(atom/movable/AM, force = move_force, direction, silent = FALSE)
|
||||
. = AM.move_crushed(src, force, direction)
|
||||
if(!silent && .)
|
||||
visible_message("<span class='danger'>[src] crushes past [AM]!</span>", "<span class='danger'>You crush [AM]!</span>")
|
||||
|
||||
/atom/movable/proc/move_crushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction)
|
||||
return FALSE
|
||||
|
||||
/atom/movable/CanPass(atom/movable/mover, turf/target, height=1.5)
|
||||
if(buckled_mob == mover)
|
||||
return 1
|
||||
|
||||
@@ -311,7 +311,7 @@
|
||||
to_chat(S, "<span class='warning'>Destroying this machine while it is occupied would result in biological and sentient resources to be harmed. Aborting.</span>")
|
||||
return
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
|
||||
S.DisperseTarget(src)
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
wander = 0
|
||||
density = 0
|
||||
flying = 1
|
||||
anchored = 1
|
||||
move_resist = INFINITY
|
||||
mob_size = MOB_SIZE_TINY
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
|
||||
speed = 1
|
||||
@@ -130,7 +130,7 @@
|
||||
else
|
||||
message_admins("Revenant was created but has no mind. Put a ghost inside, or a poll will be made in one minute.")
|
||||
addtimer(CALLBACK(src, .proc/setupOrDelete), 1 MINUTES)
|
||||
|
||||
|
||||
/mob/living/simple_animal/revenant/proc/setupOrDelete()
|
||||
if(mind)
|
||||
giveObjectivesandGoals()
|
||||
|
||||
@@ -154,7 +154,6 @@
|
||||
name = "odd blood"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "nothing"
|
||||
var/canmove = 1
|
||||
density = 0
|
||||
anchored = 1
|
||||
invisibility = 60
|
||||
|
||||
@@ -43,6 +43,7 @@ var/list/airlock_overlays = list()
|
||||
name = "airlock"
|
||||
icon = 'icons/obj/doors/airlocks/station/public.dmi'
|
||||
icon_state = "closed"
|
||||
anchored = 1
|
||||
max_integrity = 300
|
||||
integrity_failure = 70
|
||||
damage_deflection = AIRLOCK_DAMAGE_DEFLECTION_N
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
var/code = 0 // frequency code, they should be different unless you have a group of magnets working together or something
|
||||
var/turf/center // the center of magnetic attraction
|
||||
var/on = 0
|
||||
var/pulling = 0
|
||||
var/magpulling = 0
|
||||
|
||||
// x, y modifiers to the center turf; (0, 0) is centered on the magnet, whereas (1, -1) is one tile right, one tile down
|
||||
var/center_x = 0
|
||||
@@ -154,10 +154,10 @@
|
||||
|
||||
|
||||
/obj/machinery/magnetic_module/proc/magnetic_process() // proc that actually does the pulling
|
||||
if(pulling) return
|
||||
if(magpulling) return
|
||||
while(on)
|
||||
|
||||
pulling = 1
|
||||
magpulling = 1
|
||||
center = locate(x+center_x, y+center_y, z)
|
||||
if(center)
|
||||
for(var/obj/M in orange(magnetic_field, center))
|
||||
@@ -171,7 +171,7 @@
|
||||
use_power(electricity_level * 5)
|
||||
sleep(13 - electricity_level)
|
||||
|
||||
pulling = 0
|
||||
magpulling = 0
|
||||
|
||||
/obj/machinery/magnetic_controller
|
||||
name = "Magnetic Control Console"
|
||||
|
||||
@@ -154,6 +154,7 @@
|
||||
|
||||
active = 1
|
||||
update_icon()
|
||||
anchored = 1
|
||||
|
||||
for(var/turf/target_tile in range(2, src))
|
||||
if(istype(target_tile,/turf/space) && !(locate(/obj/machinery/shield) in target_tile))
|
||||
@@ -166,6 +167,7 @@
|
||||
|
||||
active = 0
|
||||
update_icon()
|
||||
anchored = 0
|
||||
|
||||
for(var/obj/machinery/shield/shield_tile in deployed_shields)
|
||||
qdel(shield_tile)
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
burn_state = LAVA_PROOF | FIRE_PROOF
|
||||
resistance_flags = INDESTRUCTIBLE
|
||||
anchored = 1
|
||||
can_be_hit = FALSE
|
||||
|
||||
/obj/effect/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
|
||||
|
||||
@@ -532,10 +532,10 @@ var/global/image/fire_overlay = image("icon" = 'icons/goonstation/effects/fire.d
|
||||
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)
|
||||
/obj/item/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force)
|
||||
thrownby = thrower
|
||||
callback = CALLBACK(src, .proc/after_throw, callback) //replace their callback with our own
|
||||
. = ..(target, range, speed, thrower, spin, diagonals_first, callback)
|
||||
. = ..(target, range, speed, thrower, spin, diagonals_first, callback, force)
|
||||
|
||||
/obj/item/proc/after_throw(datum/callback/callback)
|
||||
if(callback) //call the original callback
|
||||
|
||||
@@ -87,6 +87,17 @@
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/force_pushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction)
|
||||
return TRUE
|
||||
|
||||
/obj/move_crushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction)
|
||||
collision_damage(pusher, force, direction)
|
||||
return TRUE
|
||||
|
||||
/obj/proc/collision_damage(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction)
|
||||
var/amt = max(0, ((force - (move_resist * MOVE_FORCE_CRUSH_RATIO)) / (move_resist * MOVE_FORCE_CRUSH_RATIO)) * 10)
|
||||
take_damage(amt, BRUTE)
|
||||
|
||||
/obj/blob_act(obj/structure/blob/B)
|
||||
if(isturf(loc))
|
||||
var/turf/T = loc
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/mob/camera
|
||||
name = "camera mob"
|
||||
density = 0
|
||||
anchored = 1
|
||||
move_force = INFINITY
|
||||
move_resist = INFINITY
|
||||
status_flags = GODMODE // You can't damage it.
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
see_in_dark = 7
|
||||
|
||||
@@ -3,3 +3,6 @@
|
||||
|
||||
/mob/dead/gib() //ghosts can't be gibbed.
|
||||
return
|
||||
|
||||
/mob/dead
|
||||
move_resist = INFINITY
|
||||
@@ -13,7 +13,7 @@ var/list/image/ghost_darkness_images = list() //this is a list of images for thi
|
||||
density = 0
|
||||
canmove = 0
|
||||
alpha = 127
|
||||
anchored = 1 // don't get pushed around
|
||||
move_resist = INFINITY // don't get pushed around
|
||||
invisibility = INVISIBILITY_OBSERVER
|
||||
var/can_reenter_corpse
|
||||
var/bootime = 0
|
||||
@@ -706,6 +706,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
set name = "Mob spawners menu"
|
||||
set desc = "See all currently available ghost spawners"
|
||||
set category = "Ghost"
|
||||
|
||||
|
||||
var/datum/spawners_menu/menu = new /datum/spawners_menu(src)
|
||||
menu.ui_interact(src)
|
||||
|
||||
@@ -574,7 +574,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
|
||||
if(thrown_thing)
|
||||
visible_message("<span class='danger'>[src] has thrown [thrown_thing].</span>")
|
||||
newtonian_move(get_dir(target, src))
|
||||
thrown_thing.throw_at(target, thrown_thing.throw_range, thrown_thing.throw_speed, src)
|
||||
thrown_thing.throw_at(target, thrown_thing.throw_range, thrown_thing.throw_speed, src, null, null, null, move_force)
|
||||
|
||||
/mob/living/carbon/can_use_hands()
|
||||
if(handcuffed)
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
if(ObjBump(A))
|
||||
return
|
||||
if(istype(A, /atom/movable))
|
||||
if(PushAM(A))
|
||||
if(PushAM(A, move_force))
|
||||
return
|
||||
|
||||
//Called when we bump into a mob
|
||||
@@ -127,32 +127,41 @@
|
||||
return
|
||||
|
||||
//Called when we want to push an atom/movable
|
||||
/mob/living/proc/PushAM(atom/movable/AM)
|
||||
/mob/living/proc/PushAM(atom/movable/AM, force = move_force)
|
||||
if(now_pushing)
|
||||
return 1
|
||||
return TRUE
|
||||
if(moving_diagonally) // no pushing during diagonal moves
|
||||
return 1
|
||||
return TRUE
|
||||
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))
|
||||
var/obj/structure/window/W = AM
|
||||
if(W.fulltile)
|
||||
for(var/obj/structure/window/win in get_step(W, 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
|
||||
|
||||
now_pushing = TRUE
|
||||
var/t = get_dir(src, AM)
|
||||
var/push_anchored = FALSE
|
||||
if((AM.move_resist * MOVE_FORCE_CRUSH_RATIO) <= force)
|
||||
if(move_crush(AM, move_force, t))
|
||||
push_anchored = TRUE
|
||||
if((AM.move_resist * MOVE_FORCE_FORCEPUSH_RATIO) <= force) //trigger move_crush and/or force_push regardless of if we can push it normally
|
||||
if(force_push(AM, move_force, t, push_anchored))
|
||||
push_anchored = TRUE
|
||||
if((AM.anchored && !push_anchored) || (force < (AM.move_resist * MOVE_FORCE_PUSH_RATIO)))
|
||||
now_pushing = FALSE
|
||||
return
|
||||
if(istype(AM, /obj/structure/window))
|
||||
var/obj/structure/window/W = AM
|
||||
if(W.fulltile)
|
||||
for(var/obj/structure/window/win in get_step(W,t))
|
||||
now_pushing = FALSE
|
||||
return
|
||||
if(pulling == AM)
|
||||
stop_pulling()
|
||||
var/current_dir
|
||||
if(isliving(AM))
|
||||
current_dir = AM.dir
|
||||
if(step(AM, t))
|
||||
step(src, t)
|
||||
if(current_dir)
|
||||
AM.setDir(current_dir)
|
||||
now_pushing = FALSE
|
||||
|
||||
/mob/living/Stat()
|
||||
. = ..()
|
||||
@@ -187,9 +196,20 @@
|
||||
set name = "Pull"
|
||||
set category = "Object"
|
||||
|
||||
if(AM.Adjacent(src))
|
||||
if(istype(AM) && Adjacent(AM))
|
||||
start_pulling(AM)
|
||||
return
|
||||
else
|
||||
stop_pulling()
|
||||
|
||||
/mob/living/stop_pulling()
|
||||
..()
|
||||
if(pullin)
|
||||
pullin.update_icon(src)
|
||||
|
||||
/mob/living/verb/stop_pulling1()
|
||||
set name = "Stop Pulling"
|
||||
set category = "IC"
|
||||
stop_pulling()
|
||||
|
||||
//same as above
|
||||
/mob/living/pointed(atom/A as mob|obj|turf in view())
|
||||
@@ -852,6 +872,37 @@
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/mob/living/start_pulling(atom/movable/AM, state, force = pull_force, supress_message = FALSE)
|
||||
if(!AM || !src)
|
||||
return FALSE
|
||||
if(!(AM.can_be_pulled(src, state, force)))
|
||||
return FALSE
|
||||
if(incapacitated())
|
||||
return
|
||||
// If we're pulling something then drop what we're currently pulling and pull this instead.
|
||||
AM.add_fingerprint(src)
|
||||
if(pulling)
|
||||
if(AM == pulling)// Are we trying to pull something we are already pulling? Then just stop here, no need to continue.
|
||||
return
|
||||
stop_pulling()
|
||||
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)
|
||||
if(ismob(AM))
|
||||
var/mob/M = AM
|
||||
if(!iscarbon(src))
|
||||
M.LAssailant = null
|
||||
else
|
||||
M.LAssailant = usr
|
||||
|
||||
/mob/living/proc/check_pull()
|
||||
if(pulling && !(pulling in orange(1)))
|
||||
stop_pulling()
|
||||
|
||||
/mob/living/proc/get_taste_sensitivity()
|
||||
return 1
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
return 0
|
||||
|
||||
//this proc handles being hit by a thrown atom
|
||||
/mob/living/hitby(atom/movable/AM, skipcatch, hitpush = 1, blocked = 0)//Standardization and logging -Sieve
|
||||
/mob/living/hitby(atom/movable/AM, skipcatch, hitpush = 1, blocked = 0, datum/thrownthing/throwingdatum)//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
|
||||
@@ -229,7 +229,7 @@
|
||||
|
||||
// End BS12 momentum-transfer code.
|
||||
|
||||
/mob/living/proc/grabbedby(mob/living/carbon/user, supress_message = 0)
|
||||
/mob/living/proc/grabbedby(mob/living/carbon/user, supress_message = FALSE)
|
||||
if(user == src || anchored)
|
||||
return 0
|
||||
if(!(status_flags & CANPUSH))
|
||||
|
||||
@@ -38,7 +38,7 @@ var/list/ai_verbs_default = list(
|
||||
name = "AI"
|
||||
icon = 'icons/mob/AI.dmi'//
|
||||
icon_state = "ai"
|
||||
anchored = 1 // -- TLE
|
||||
move_resist = MOVE_FORCE_VERY_STRONG
|
||||
density = 1
|
||||
status_flags = CANSTUN|CANPARALYSE|CANPUSH
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
@@ -533,9 +533,14 @@ var/list/ai_verbs_default = list(
|
||||
if(!isturf(loc)) // if their location isn't a turf
|
||||
return // stop
|
||||
|
||||
anchored = !anchored // Toggles the anchor
|
||||
var/is_anchored = FALSE
|
||||
if(move_resist == MOVE_FORCE_VERY_STRONG)
|
||||
move_resist = MOVE_FORCE_VERY_STRONG
|
||||
else
|
||||
is_anchored = TRUE
|
||||
move_resist = MOVE_FORCE_NORMAL
|
||||
|
||||
to_chat(src, "[anchored ? "<b>You are now anchored.</b>" : "<b>You are now unanchored.</b>"]")
|
||||
to_chat(src, "[is_anchored ? "<b>You are now anchored.</b>" : "<b>You are now unanchored.</b>"]")
|
||||
|
||||
/mob/living/silicon/ai/update_canmove()
|
||||
return FALSE
|
||||
|
||||
@@ -517,12 +517,8 @@
|
||||
/mob/living/silicon/pai/Bumped()
|
||||
return
|
||||
|
||||
/mob/living/silicon/pai/start_pulling(var/atom/movable/AM)
|
||||
if(stat || sleeping || paralysis || weakened)
|
||||
return
|
||||
if(istype(AM,/obj/item))
|
||||
to_chat(src, "<span class='warning'>You are far too small to pull anything!</span>")
|
||||
return
|
||||
/mob/living/silicon/pai/start_pulling(atom/movable/AM, state, force = move_force, supress_message = FALSE)
|
||||
return FALSE
|
||||
|
||||
/mob/living/silicon/pai/update_canmove(delay_action_updates = 0)
|
||||
. = ..()
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
desc = "A Multiple Utility Load Effector bot."
|
||||
icon_state = "mulebot0"
|
||||
density = 1
|
||||
anchored = 1
|
||||
animate_movement=1
|
||||
move_resist = MOVE_FORCE_STRONG
|
||||
animate_movement = 1
|
||||
health = 50
|
||||
maxHealth = 50
|
||||
damage_coeff = list(BRUTE = 0.5, BURN = 0.7, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
|
||||
|
||||
@@ -38,7 +38,9 @@
|
||||
var/elimination = 0
|
||||
var/anger_modifier = 0
|
||||
var/obj/item/gps/internal_gps
|
||||
anchored = TRUE
|
||||
move_force = MOVE_FORCE_OVERPOWERING
|
||||
move_resist = MOVE_FORCE_OVERPOWERING
|
||||
pull_force = MOVE_FORCE_OVERPOWERING
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
layer = MOB_LAYER + 0.5 //Looks weird with them slipping under mineral walls and cameras and shit otherwise
|
||||
mouse_opacity = MOUSE_OPACITY_OPAQUE // Easier to click on in melee, they're giant targets anyway
|
||||
|
||||
@@ -136,7 +136,9 @@
|
||||
throw_message = "does nothing to the rocky hide of the"
|
||||
aggro_vision_range = 9
|
||||
idle_vision_range = 5
|
||||
anchored = 1 //Stays anchored until death as to be unpullable
|
||||
move_force = MOVE_FORCE_VERY_STRONG
|
||||
move_resist = MOVE_FORCE_VERY_STRONG
|
||||
pull_force = MOVE_FORCE_VERY_STRONG
|
||||
var/pre_attack = 0
|
||||
loot = list(/obj/item/asteroid/goliath_hide{layer = 4.1})
|
||||
|
||||
@@ -152,7 +154,9 @@
|
||||
icon_state = "Goliath_preattack"
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/goliath/revive()
|
||||
anchored = 1
|
||||
move_force = MOVE_FORCE_VERY_STRONG
|
||||
move_resist = MOVE_FORCE_VERY_STRONG
|
||||
pull_force = MOVE_FORCE_VERY_STRONG
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/goliath/OpenFire()
|
||||
|
||||
@@ -42,7 +42,9 @@
|
||||
|
||||
see_invisible = SEE_INVISIBLE_OBSERVER_NOLIGHTING
|
||||
sight = SEE_SELF|SEE_MOBS|SEE_OBJS|SEE_TURFS
|
||||
anchored = 1
|
||||
move_force = MOVE_FORCE_EXTREMELY_STRONG
|
||||
move_resist = MOVE_FORCE_EXTREMELY_STRONG
|
||||
pull_force = MOVE_FORCE_EXTREMELY_STRONG
|
||||
status_flags = GODMODE // Cannot push also
|
||||
|
||||
var/cannot_be_seen = 1
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
var/mob_type = /mob/living/simple_animal/hostile/carp
|
||||
var/spawn_text = "emerges from"
|
||||
status_flags = 0
|
||||
anchored = 1
|
||||
move_resist = MOVE_FORCE_VERY_STRONG
|
||||
AIStatus = AI_OFF
|
||||
a_intent = INTENT_HARM
|
||||
stop_automated_movement = 1
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
var/obj/machinery/machine = null
|
||||
var/other_mobs = null
|
||||
var/memory = ""
|
||||
var/atom/movable/pulling = null
|
||||
var/next_move = null
|
||||
var/notransform = null //Carbon
|
||||
var/other = 0.0
|
||||
@@ -48,7 +47,6 @@
|
||||
var/bhunger = 0 //Carbon
|
||||
var/lying = 0
|
||||
var/lying_prev = 0
|
||||
var/canmove = 1
|
||||
var/lastpuke = 0
|
||||
var/unacidable = 0
|
||||
var/can_strip = 1
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
stat = 2
|
||||
canmove = 0
|
||||
|
||||
anchored = 1 // don't get pushed around
|
||||
|
||||
/mob/new_player/New()
|
||||
GLOB.mob_list += src
|
||||
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
//this and stop_pulling really ought to be /mob/living procs
|
||||
/mob/proc/start_pulling(atom/movable/AM)
|
||||
if(src == AM) // Trying to pull yourself is a shortcut to stop pulling
|
||||
stop_pulling()
|
||||
return
|
||||
if(!AM || !isturf(AM.loc)) //if there's no object or the object being pulled is inside something: abort!
|
||||
return
|
||||
if(incapacitated())
|
||||
return
|
||||
if(!(AM.anchored))
|
||||
AM.add_fingerprint(src)
|
||||
|
||||
// If we're pulling something then drop what we're currently pulling and pull this instead.
|
||||
if(pulling)
|
||||
// Are we trying to pull something we are already pulling? Then just stop here, no need to continue.
|
||||
if(AM == pulling)
|
||||
return
|
||||
stop_pulling()
|
||||
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)
|
||||
if(ismob(AM))
|
||||
var/mob/M = AM
|
||||
if(!iscarbon(src))
|
||||
M.LAssailant = null
|
||||
else
|
||||
M.LAssailant = usr
|
||||
|
||||
/mob/verb/stop_pulling()
|
||||
set name = "Stop Pulling"
|
||||
set category = "IC"
|
||||
|
||||
if(pulling)
|
||||
pulling.pulledby = null
|
||||
pulling = null
|
||||
if(pullin)
|
||||
pullin.update_icon(src)
|
||||
|
||||
/mob/living/proc/check_pull()
|
||||
if(pulling && !(pulling in orange(1)))
|
||||
stop_pulling()
|
||||
@@ -16,6 +16,7 @@ GLOBAL_LIST_INIT(conveyor_switches, list())
|
||||
desc = "It's a conveyor belt, commonly used to transport large numbers of items elsewhere quite quickly."
|
||||
layer = CONVEYOR_LAYER // so they appear under stuff but not below stuff like vents
|
||||
anchored = TRUE
|
||||
move_force = MOVE_FORCE_DEFAULT
|
||||
var/operating = FALSE //NB: this can be TRUE while the belt doesn't go
|
||||
var/forwards // The direction the conveyor sends you in
|
||||
var/backwards // hopefully self-explanatory
|
||||
@@ -183,9 +184,12 @@ GLOBAL_LIST_INIT(conveyor_switches, list())
|
||||
..()
|
||||
|
||||
/obj/machinery/conveyor/proc/move_thing(atom/movable/AM)
|
||||
if(move_force < (AM.move_resist))
|
||||
return FALSE
|
||||
if(!AM.anchored && AM.loc == loc)
|
||||
step(AM, forwards)
|
||||
|
||||
|
||||
/obj/machinery/conveyor/proc/can_conveyor_run()
|
||||
if(stat & BROKEN)
|
||||
return FALSE
|
||||
|
||||
Reference in New Issue
Block a user