-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:
Tigercat2000
2017-05-16 21:30:38 -07:00
parent 9448a4d5b8
commit bbca8405ef
69 changed files with 1126 additions and 1191 deletions
-3
View File
@@ -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>")
+3 -3
View File
@@ -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)
+4 -5
View File
@@ -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.
+2 -45
View File
@@ -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()
..()
+23
View File
@@ -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)
+18 -53
View File
@@ -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
+162 -71
View File
@@ -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))
+51 -46
View File
@@ -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)
+2 -2
View File
@@ -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
View File
@@ -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)
+5 -1
View File
@@ -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)
-5
View File
@@ -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()
..()
-6
View File
@@ -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
+3 -3
View File
@@ -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()