mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-12 07:33:34 +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:
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user