Merge remote-tracking branch 'citadel/master' into mobility_flags

This commit is contained in:
kevinz000
2020-01-19 16:18:12 -07:00
320 changed files with 5694 additions and 2936 deletions

View File

@@ -14,7 +14,7 @@
/obj/effect/dummy/phased_mob/slaughter/ex_act()
return
/obj/effect/dummy/phased_mob/slaughter/bullet_act()
return
return BULLET_ACT_FORCE_PIERCE
/obj/effect/dummy/phased_mob/slaughter/singularity_act()
return

View File

@@ -5,7 +5,7 @@
/mob/living/carbon/alien/get_ear_protection()
return 2 //no ears
/mob/living/carbon/alien/hitby(atom/movable/AM, skipcatch, hitpush)
/mob/living/carbon/alien/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
return ..(AM, skipcatch = TRUE, hitpush = FALSE)
/mob/living/carbon/alien/can_embed(obj/item/I)

View File

@@ -54,15 +54,15 @@
weather_immunities -= "lava"
update_icons()
/mob/living/carbon/alien/humanoid/hunter/throw_impact(atom/A)
/mob/living/carbon/alien/humanoid/hunter/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(!leaping)
return ..()
pounce_cooldown = world.time + pounce_cooldown_time
if(A)
if(isliving(A))
var/mob/living/L = A
if(hit_atom)
if(isliving(hit_atom))
var/mob/living/L = hit_atom
if(!L.check_shields(src, 0, "the [name]", attack_type = LEAP_ATTACK))
L.visible_message("<span class ='danger'>[src] pounces on [L]!</span>", "<span class ='userdanger'>[src] pounces on you!</span>")
L.DefaultCombatKnockdown(100)
@@ -72,9 +72,9 @@
DefaultCombatKnockdown(40, 1, 1)
toggle_leap(0)
else if(A.density && !A.CanPass(src))
visible_message("<span class ='danger'>[src] smashes into [A]!</span>", "<span class ='alertalien'>[src] smashes into [A]!</span>")
DefaultCombatKnockdown(40, 1, 1)
else if(hit_atom.density && !hit_atom.CanPass(src))
visible_message("<span class ='danger'>[src] smashes into [hit_atom]!</span>", "<span class ='alertalien'>[src] smashes into [hit_atom]!</span>")
Paralyze(40, TRUE, TRUE)
if(leaping)
leaping = 0

View File

@@ -56,7 +56,7 @@
/mob/living/carbon/alien/larva/toggle_throw_mode()
return
/mob/living/carbon/alien/larva/start_pulling()
/mob/living/carbon/alien/larva/start_pulling(atom/movable/AM, state, force = move_force, supress_message = FALSE)
return
/mob/living/carbon/alien/larva/stripPanelUnequip(obj/item/what, mob/who)

View File

@@ -115,7 +115,7 @@
if(icon_state == "[initial(icon_state)]_thrown")
icon_state = "[initial(icon_state)]"
/obj/item/clothing/mask/facehugger/throw_impact(atom/hit_atom)
/obj/item/clothing/mask/facehugger/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
..()
if(stat == CONSCIOUS)
icon_state = "[initial(icon_state)]"

View File

@@ -94,15 +94,13 @@
return 1
return ..()
/mob/living/carbon/throw_impact(atom/hit_atom, throwingdatum)
/mob/living/carbon/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
. = ..()
var/hurt = TRUE
if(istype(throwingdatum, /datum/thrownthing))
var/datum/thrownthing/D = throwingdatum
if(iscyborg(D.thrower))
var/mob/living/silicon/robot/R = D.thrower
if(!R.emagged)
hurt = FALSE
if(throwingdatum?.thrower && iscyborg(throwingdatum.thrower))
var/mob/living/silicon/robot/R = throwingdatum.thrower
if(!R.emagged)
hurt = FALSE
if(hit_atom.density && isturf(hit_atom))
if(hurt)
DefaultCombatKnockdown(20)
@@ -160,7 +158,7 @@
var/random_turn = a_intent == INTENT_HARM
//END OF CIT CHANGES
var/obj/item/I = src.get_active_held_item()
var/obj/item/I = get_active_held_item()
var/atom/movable/thrown_thing
var/mob/living/throwable_mob
@@ -201,11 +199,11 @@
if(thrown_thing)
visible_message("<span class='danger'>[src] has thrown [thrown_thing].</span>")
src.log_message("has thrown [thrown_thing]", LOG_ATTACK)
log_message("has thrown [thrown_thing]", LOG_ATTACK)
do_attack_animation(target, no_effect = 1)
playsound(loc, 'sound/weapons/punchmiss.ogg', 50, 1, -1)
newtonian_move(get_dir(target, src))
thrown_thing.throw_at(target, thrown_thing.throw_range, thrown_thing.throw_speed, src, null, null, null, random_turn)
thrown_thing.safe_throw_at(target, thrown_thing.throw_range, thrown_thing.throw_speed, src, null, null, null, move_force, random_turn)
@@ -463,7 +461,7 @@
I.throw_at(target,I.throw_range,I.throw_speed,src)
if(61 to 90) //throw it down to the floor
var/turf/target = get_turf(loc)
I.throw_at(target,I.throw_range,I.throw_speed,src)
I.safe_throw_at(target,I.throw_range,I.throw_speed,src, force = move_force)
/mob/living/carbon/Stat()
..()

View File

@@ -51,7 +51,7 @@
if(prob(mind.martial_art.dodge_chance))
var/dodgemessage = pick("dodges under the projectile!","dodges to the right of the projectile!","jumps over the projectile!")
visible_message("<span class='danger'>[src] [dodgemessage]</span>", "<span class='userdanger'>You dodge the projectile!</span>")
return -1
return BULLET_ACT_BLOCK
if(mind.martial_art && !incapacitated(FALSE, TRUE) && mind.martial_art.can_use(src) && mind.martial_art.deflection_chance) //Some martial arts users can deflect projectiles!
if(prob(mind.martial_art.deflection_chance))
if(!lying && dna && !dna.check_mutation(HULK)) //But only if they're not lying down, and hulks can't do it
@@ -60,12 +60,10 @@
else
visible_message("<span class='danger'>[src] deflects the projectile!</span>", "<span class='userdanger'>You deflect the projectile!</span>")
playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, 1)
if(!mind.martial_art.reroute_deflection)
return FALSE
else
if(mind.martial_art.reroute_deflection)
P.firer = src
P.setAngle(rand(0, 360))//SHING
return FALSE
return BULLET_ACT_FORCE_PIERCE
return ..()
@@ -104,7 +102,7 @@
return TRUE
return FALSE
/mob/living/carbon/human/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE)
/mob/living/carbon/human/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)
return dna?.species?.spec_hitby(AM, src) || ..()
/mob/living/carbon/human/grabbedby(mob/living/carbon/user, supress_message = 0)

View File

@@ -1997,7 +1997,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
/datum/species/proc/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H)
// called before a projectile hit
return 0
return
/////////////
//BREATHING//

View File

@@ -360,8 +360,8 @@
playsound(H, 'sound/effects/shovel_dig.ogg', 70, 1)
H.visible_message("<span class='danger'>The [P.name] sinks harmlessly in [H]'s sandy body!</span>", \
"<span class='userdanger'>The [P.name] sinks harmlessly in [H]'s sandy body!</span>")
return 2
return 0
return BULLET_ACT_BLOCK
return ..()
//Reflects lasers and resistant to burn damage, but very vulnerable to brute damage. Shatters on death.
/datum/species/golem/glass
@@ -397,8 +397,8 @@
var/turf/target = get_turf(P.starting)
// redirect the projectile
P.preparePixelProjectile(locate(CLAMP(target.x + new_x, 1, world.maxx), CLAMP(target.y + new_y, 1, world.maxy), H.z), H)
return -1
return 0
return BULLET_ACT_FORCE_PIERCE
return ..()
//Teleports when hit or when it wants to
/datum/species/golem/bluespace

View File

@@ -60,8 +60,8 @@
if(light_amount < SHADOW_SPECIES_LIGHT_THRESHOLD)
H.visible_message("<span class='danger'>[H] dances in the shadows, evading [P]!</span>")
playsound(T, "bullet_miss", 75, 1)
return -1
return 0
return BULLET_ACT_FORCE_PIERCE
return ..()
/datum/species/shadow/nightmare/check_roundstart_eligible()
return FALSE

View File

@@ -397,9 +397,9 @@
if((Proj.damage_type == BURN) || (Proj.damage_type == BRUTE))
if(!Proj.nodamage && Proj.damage < src.health && isliving(Proj.firer))
retaliate(Proj.firer)
..()
return ..()
/mob/living/carbon/monkey/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE)
/mob/living/carbon/monkey/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)
if(istype(AM, /obj/item))
var/obj/item/I = AM
if(I.throwforce < src.health && I.thrownby && ishuman(I.thrownby))

View File

@@ -110,7 +110,7 @@
/mob/living/proc/apply_effects(stun = 0, knockdown = 0, unconscious = 0, irradiate = 0, slur = 0, stutter = 0, eyeblur = 0, drowsy = 0, blocked = FALSE, stamina = 0, jitter = 0, kd_stamoverride, kd_stammax)
if(blocked >= 100)
return 0
return BULLET_ACT_BLOCK
if(stun)
apply_effect(stun, EFFECT_STUN, blocked)
if(knockdown)
@@ -131,7 +131,7 @@
apply_damage(stamina, STAMINA, null, blocked)
if(jitter)
apply_effect(jitter, EFFECT_JITTER, blocked)
return 1
return BULLET_ACT_HIT
/mob/living/proc/getBruteLoss()

View File

@@ -75,7 +75,7 @@
return
if(ismovableatom(A))
var/atom/movable/AM = A
if(PushAM(AM))
if(PushAM(AM, move_force))
return
/mob/living/Bumped(atom/movable/AM)
@@ -218,36 +218,46 @@
return
//Called when we want to push an atom/movable
/mob/living/proc/PushAM(atom/movable/AM)
/mob/living/proc/PushAM(atom/movable/AM, force = move_force)
if(now_pushing)
return 1
return TRUE
if(moving_diagonally)// no pushing during diagonal moves.
return 1
return TRUE
if(!client && (mob_size < MOB_SIZE_SMALL))
return
if(!AM.anchored)
now_pushing = 1
var/t = get_dir(src, AM)
if (istype(AM, /obj/structure/window))
var/obj/structure/window/W = AM
if(W.fulltile)
for(var/obj/structure/window/win in get_step(W,t))
now_pushing = 0
return
if(pulling == AM)
stop_pulling()
var/current_dir
if(isliving(AM))
current_dir = AM.dir
step(AM, t)
if(current_dir)
AM.setDir(current_dir)
now_pushing = 0
now_pushing = TRUE
var/t = get_dir(src, AM)
var/push_anchored = FALSE
if((AM.move_resist * MOVE_FORCE_CRUSH_RATIO) <= force)
if(move_crush(AM, move_force, t))
push_anchored = TRUE
if((AM.move_resist * MOVE_FORCE_FORCEPUSH_RATIO) <= force) //trigger move_crush and/or force_push regardless of if we can push it normally
if(force_push(AM, move_force, t, push_anchored))
push_anchored = TRUE
if((AM.anchored && !push_anchored) || (force < (AM.move_resist * MOVE_FORCE_PUSH_RATIO)))
now_pushing = FALSE
return
if (istype(AM, /obj/structure/window))
var/obj/structure/window/W = AM
if(W.fulltile)
for(var/obj/structure/window/win in get_step(W,t))
now_pushing = FALSE
return
if(pulling == AM)
stop_pulling()
var/current_dir
if(isliving(AM))
current_dir = AM.dir
if(step(AM, t))
step(src, t)
if(current_dir)
AM.setDir(current_dir)
now_pushing = FALSE
/mob/living/start_pulling(atom/movable/AM, supress_message = 0)
/mob/living/start_pulling(atom/movable/AM, state, force = pull_force, supress_message = FALSE)
if(!AM || !src)
return FALSE
if(!(AM.can_be_pulled(src)))
if(!(AM.can_be_pulled(src, state, force)))
return FALSE
if(throwing || incapacitated())
return FALSE

View File

@@ -34,7 +34,7 @@
return FALSE
/mob/living/proc/on_hit(obj/item/projectile/P)
return
return BULLET_ACT_HIT
/mob/living/proc/check_shields(atom/AM, damage, attack_text = "the attack", attack_type = MELEE_ATTACK, armour_penetration = 0)
var/block_chance_modifier = round(damage / -3)
@@ -76,16 +76,16 @@
/mob/living/bullet_act(obj/item/projectile/P, def_zone)
if(P.original != src || P.firer != src) //try to block or reflect the bullet, can't do so when shooting oneself
if(reflect_bullet_check(P, def_zone))
return -1 // complete projectile permutation
return BULLET_ACT_FORCE_PIERCE // complete projectile permutation
if(check_shields(P, P.damage, "the [P.name]", PROJECTILE_ATTACK, P.armour_penetration))
P.on_hit(src, 100, def_zone)
return 2
return BULLET_ACT_BLOCK
var/armor = run_armor_check(def_zone, P.flag, null, null, P.armour_penetration, null)
if(!P.nodamage)
apply_damage(P.damage, P.damage_type, def_zone, armor)
if(P.dismemberment)
check_projectile_dismemberment(P, def_zone)
return P.on_hit(src, armor)
return P.on_hit(src, armor) ? BULLET_ACT_HIT : BULLET_ACT_BLOCK
/mob/living/proc/check_projectile_dismemberment(obj/item/projectile/P, def_zone)
return 0
@@ -107,7 +107,7 @@
/mob/living/proc/can_embed(obj/item/I)
return FALSE
/mob/living/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked = FALSE)
/mob/living/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)
var/obj/item/I
var/throwpower = 30
if(isitem(AM))
@@ -189,7 +189,7 @@
adjust_fire_stacks(3)
IgniteMob()
/mob/living/proc/grabbedby(mob/living/carbon/user, supress_message = 0)
/mob/living/proc/grabbedby(mob/living/carbon/user, supress_message = FALSE)
if(user == anchored || !isturf(user.loc))
return FALSE
@@ -215,7 +215,7 @@
return FALSE
if(!user.pulling || user.pulling != src)
user.start_pulling(src, supress_message)
user.start_pulling(src, supress_message = supress_message)
return
if(!(status_flags & CANPUSH) || HAS_TRAIT(src, TRAIT_PUSHIMMUNE))

View File

@@ -2,6 +2,21 @@
. = ..()
update_turf_movespeed(loc)
/mob/living/CanPass(atom/movable/mover, turf/target)
if((mover.pass_flags & PASSMOB))
return TRUE
if(istype(mover, /obj/item/projectile))
var/obj/item/projectile/P = mover
return !P.can_hit_target(src, P.permutated, src == P.original, TRUE)
if(mover.throwing)
return (!density || lying)
if(buckled == mover)
return TRUE
if(ismob(mover))
if (mover in buckled_mobs)
return TRUE
return (!mover.density || !density || lying || (mover.throwing && mover.throwing.thrower == src && !ismob(mover)))
/mob/living/toggle_move_intent()
. = ..()
update_move_intent_slowdown()

View File

@@ -16,7 +16,7 @@
name = "AI"
icon = 'icons/mob/ai.dmi'
icon_state = "ai"
anchored = TRUE
move_resist = MOVE_FORCE_OVERPOWERING
density = TRUE
mobility_flags = NONE
status_flags = CANSTUN|CANPUSH
@@ -101,6 +101,7 @@
new/obj/structure/AIcore/deactivated(loc) //New empty terminal.
return INITIALIZE_HINT_QDEL //Delete AI.
ADD_TRAIT(src, TRAIT_NO_TELEPORT, src)
if(L && istype(L, /datum/ai_laws))
laws = L
laws.associate(src)
@@ -311,9 +312,16 @@
return // stop
if(incapacitated())
return
anchored = !anchored // Toggles the anchor
var/is_anchored = FALSE
if(move_resist == MOVE_FORCE_OVERPOWERING)
move_resist = MOVE_FORCE_NORMAL
else
is_anchored = TRUE
move_resist = MOVE_FORCE_OVERPOWERING
REMOVE_TRAIT(src, TRAIT_NO_TELEPORT, src)
ADD_TRAIT(src, TRAIT_NO_TELEPORT, src)
to_chat(src, "<b>You are now [anchored ? "" : "un"]anchored.</b>")
to_chat(src, "<b>You are now [is_anchored ? "" : "un"]anchored.</b>")
// the message in the [] will change depending whether or not the AI is anchored
// AIs are immobile

View File

@@ -42,9 +42,8 @@
/mob/living/silicon/ai/bullet_act(obj/item/projectile/Proj)
..(Proj)
. = ..()
updatehealth()
return 2
/mob/living/silicon/ai/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0)
return // no eyes, no flashing

View File

@@ -14,7 +14,7 @@
cameraFollow = null
anchored = FALSE //unbolt floorbolts
move_resist = MOVE_FORCE_NORMAL
update_mobility()
if(eyeobj)
eyeobj.setLoc(get_turf(src))

View File

@@ -55,7 +55,7 @@
if(P.stun)
fold_in(force = TRUE)
visible_message("<span class='warning'>The electrically-charged projectile disrupts [src]'s holomatrix, forcing [src] to fold in!</span>")
. = ..()
return ..()
/mob/living/silicon/pai/stripPanelUnequip(obj/item/what, mob/who, where) //prevents stripping
to_chat(src, "<span class='warning'>Your holochassis stutters and warps intensely as you attempt to interact with the object, forcing you to cease lest the field fail.</span>")

View File

@@ -103,7 +103,7 @@
visible_message("<span class='notice'>[src] [resting? "lays down for a moment..." : "perks up from the ground"]</span>")
update_icon()
/mob/living/silicon/pai/start_pulling(atom/movable/AM, gs)
/mob/living/silicon/pai/start_pulling(atom/movable/AM, state, force = move_force, supress_message = FALSE)
if(ispAI(AM))
return ..()
return FALSE

View File

@@ -184,8 +184,7 @@
adjustBruteLoss(30)
/mob/living/silicon/robot/bullet_act(obj/item/projectile/P, def_zone)
..()
. = ..()
updatehealth()
if(prob(75) && P.damage > 0)
spark_system.start()
return 2

View File

@@ -129,7 +129,7 @@
unbuckle_mob(M)
M.visible_message("<span class='boldwarning'>[M] is knocked off of [src] by the [P]!</span>")
P.on_hit(src)
return 2
return BULLET_ACT_HIT
/mob/living/silicon/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /obj/screen/fullscreen/flash/static)
if(affect_silicon)

View File

@@ -114,7 +114,7 @@
return
apply_damage(Proj.damage, Proj.damage_type)
Proj.on_hit(src)
return 0
return BULLET_ACT_HIT
/mob/living/simple_animal/ex_act(severity, target, origin)
if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src))

View File

@@ -21,7 +21,7 @@
/mob/living/simple_animal/bot/secbot/grievous/bullet_act(obj/item/projectile/P)
visible_message("[src] deflects [P] with its energy swords!")
playsound(src, 'sound/weapons/blade1.ogg', 50, TRUE)
return FALSE
return BULLET_ACT_BLOCK
/mob/living/simple_animal/bot/secbot/grievous/Crossed(atom/movable/AM)
..()

View File

@@ -210,7 +210,7 @@ Auto Patrol[]"},
if((Proj.damage_type == BURN) || (Proj.damage_type == BRUTE))
if(!Proj.nodamage && Proj.damage < src.health && ishuman(Proj.firer))
retaliate(Proj.firer)
..()
return ..()
/mob/living/simple_animal/bot/ed209/handle_automated_action()
if(!..())
@@ -510,11 +510,9 @@ Auto Patrol[]"},
spawn(100)
disabled = 0
icon_state = "[lasercolor]ed2091"
return 1
else
..(Proj)
else
..(Proj)
return BULLET_ACT_HIT
return ..()
return ..()
/mob/living/simple_animal/bot/ed209/bluetag
lasercolor = "b"

View File

@@ -139,7 +139,7 @@ Maintenance panel panel is [open ? "opened" : "closed"]"},
/mob/living/simple_animal/bot/honkbot/bullet_act(obj/item/projectile/Proj)
if((istype(Proj,/obj/item/projectile/beam)) || (istype(Proj,/obj/item/projectile/bullet) && (Proj.damage_type == BURN))||(Proj.damage_type == BRUTE) && (!Proj.nodamage && Proj.damage < health && ishuman(Proj.firer)))
retaliate(Proj.firer)
..()
return ..()
/mob/living/simple_animal/bot/honkbot/UnarmedAttack(atom/A)
if(!on)
@@ -156,7 +156,7 @@ Maintenance panel panel is [open ? "opened" : "closed"]"},
bike_horn(A)
/mob/living/simple_animal/bot/honkbot/hitby(atom/movable/AM, skipcatch = 0, hitpush = 1, blocked = 0)
/mob/living/simple_animal/bot/honkbot/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)
if(istype(AM, /obj/item))
playsound(src, honksound, 50, TRUE, -1)
var/obj/item/I = AM

View File

@@ -13,8 +13,8 @@
desc = "A Multiple Utility Load Effector bot."
icon_state = "mulebot0"
density = TRUE
anchored = TRUE
animate_movement=1
move_resist = MOVE_FORCE_STRONG
animate_movement = 1
health = 50
maxHealth = 50
damage_coeff = list(BRUTE = 0.5, BURN = 0.7, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
@@ -152,7 +152,7 @@
/mob/living/simple_animal/bot/mulebot/bullet_act(obj/item/projectile/Proj)
. = ..()
if(. && !QDELETED(src)) //Got hit and not blown up yet.
if(. == BULLET_ACT_HIT && !QDELETED(src)) //Got hit and not blown up yet.)
if(prob(50) && !isnull(load))
unload(0)
if(prob(25))

View File

@@ -205,7 +205,7 @@ Auto Patrol: []"},
if((Proj.damage_type == BURN) || (Proj.damage_type == BRUTE))
if(!Proj.nodamage && Proj.damage < src.health && ishuman(Proj.firer))
retaliate(Proj.firer)
..()
return ..()
/mob/living/simple_animal/bot/secbot/UnarmedAttack(atom/A)
@@ -221,7 +221,7 @@ Auto Patrol: []"},
..()
/mob/living/simple_animal/bot/secbot/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE)
/mob/living/simple_animal/bot/secbot/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)
if(istype(AM, /obj/item))
var/obj/item/I = AM
if(I.throwforce < src.health && I.thrownby && ishuman(I.thrownby))

View File

@@ -167,9 +167,9 @@
new_angle_s -= 360
P.setAngle(new_angle_s)
return -1 // complete projectile permutation
return BULLET_ACT_FORCE_PIERCE // complete projectile permutation
return (..(P))
return ..()
@@ -334,7 +334,7 @@
stored_pulling.forceMove(loc)
forceMove(AM)
if(stored_pulling)
start_pulling(stored_pulling, TRUE) //drag anything we're pulling through the wall with us by magic
start_pulling(stored_pulling, supress_message = TRUE) //drag anything we're pulling through the wall with us by magic
/mob/living/simple_animal/hostile/construct/harvester/AttackingTarget()
if(iscarbon(target))

View File

@@ -44,15 +44,15 @@
if(!charging)
..()
/mob/living/simple_animal/hostile/guardian/charger/throw_impact(atom/A)
/mob/living/simple_animal/hostile/guardian/charger/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(!charging)
return ..()
else if(A)
if(isliving(A) && A != summoner)
var/mob/living/L = A
else if(hit_atom)
if(isliving(hit_atom) && hit_atom != summoner)
var/mob/living/L = hit_atom
var/blocked = FALSE
if(hasmatchingsummoner(A)) //if the summoner matches don't hurt them
if(hasmatchingsummoner(hit_atom)) //if the summoner matches don't hurt them
blocked = TRUE
if(L.check_shields(src, 90, "[name]", attack_type = THROWN_PROJECTILE_ATTACK))
blocked = TRUE

View File

@@ -248,7 +248,7 @@
/mob/living/simple_animal/hostile/jungle/leaper/Goto()
return
/mob/living/simple_animal/hostile/jungle/leaper/throw_impact()
/mob/living/simple_animal/hostile/jungle/leaper/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
return
/mob/living/simple_animal/hostile/jungle/leaper/update_icons()

View File

@@ -147,7 +147,7 @@
update_icons()
Goto(target, move_to_delay, minimum_distance)
/mob/living/simple_animal/hostile/jungle/mook/throw_impact(atom/hit_atom, throwingdatum)
/mob/living/simple_animal/hostile/jungle/mook/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
. = ..()
if(isliving(hit_atom) && attack_state == MOOK_ATTACK_ACTIVE)
var/mob/living/L = hit_atom

View File

@@ -29,7 +29,7 @@
projectilesound = 'sound/weapons/pierce.ogg'
robust_searching = TRUE
stat_attack = UNCONSCIOUS
anchored = TRUE
move_resist = MOVE_FORCE_EXTREMELY_STRONG
blood_volume = 0
var/combatant_state = SEEDLING_STATE_NEUTRAL
var/obj/seedling_weakpoint/weak_point

View File

@@ -158,12 +158,12 @@ Difficulty: Hard
DestroySurroundings()
..()
/mob/living/simple_animal/hostile/megafauna/bubblegum/throw_impact(atom/A)
/mob/living/simple_animal/hostile/megafauna/bubblegum/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(!charging)
return ..()
else if(isliving(A))
var/mob/living/L = A
else if(isliving(hit_atom))
var/mob/living/L = hit_atom
L.visible_message("<span class='danger'>[src] slams into [L]!</span>", "<span class='userdanger'>[src] slams into you!</span>")
L.apply_damage(40, BRUTE)
playsound(get_turf(L), 'sound/effects/meteorimpact.ogg', 100, 1)

View File

@@ -117,7 +117,7 @@ Difficulty: Very Hard
var/random_y = rand(0, 72)
AT.pixel_y += random_y
..()
return ..()
/mob/living/simple_animal/hostile/megafauna/colossus/proc/enrage(mob/living/L)
if(ishuman(L))
@@ -395,7 +395,7 @@ Difficulty: Very Hard
..()
/obj/machinery/anomalous_crystal/bullet_act(obj/item/projectile/P, def_zone)
..()
. = ..()
if(istype(P, /obj/item/projectile/magic))
ActivationReaction(P.firer, ACTIVATE_MAGIC, P.damage_type)
return

View File

@@ -21,7 +21,9 @@
maxbodytemp = INFINITY
vision_range = 4
aggro_vision_range = 15
anchored = TRUE
move_force = MOVE_FORCE_OVERPOWERING
move_resist = MOVE_FORCE_OVERPOWERING
pull_force = MOVE_FORCE_OVERPOWERING
mob_size = MOB_SIZE_LARGE
layer = LARGE_MOB_LAYER //Looks weird with them slipping under mineral walls and cameras and shit otherwise
mouse_opacity = MOUSE_OPACITY_OPAQUE // Easier to click on in melee, they're giant targets anyway
@@ -37,6 +39,7 @@
/mob/living/simple_animal/hostile/megafauna/Initialize(mapload)
. = ..()
apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
ADD_TRAIT(src, TRAIT_NO_TELEPORT, MEGAFAUNA_TRAIT)
/mob/living/simple_animal/hostile/megafauna/Destroy()
QDEL_NULL(internal)

View File

@@ -54,7 +54,6 @@ GLOBAL_LIST_INIT(AISwarmerCapsByType, list(/mob/living/simple_animal/hostile/swa
weather_immunities = list("lava","ash")
stop_automated_movement = TRUE
wander = FALSE
anchored = TRUE
layer = BELOW_MOB_LAYER
AIStatus = AI_OFF
var/swarmer_spawn_cooldown = 0

View File

@@ -98,7 +98,7 @@ IGNORE_PROC_IF_NOT_TARGET(attack_slime)
/mob/living/simple_animal/hostile/asteroid/curseblob/bullet_act(obj/item/projectile/Proj)
if(Proj.firer != set_target)
return
return BULLET_ACT_FORCE_PIERCE
return ..()
/mob/living/simple_animal/hostile/asteroid/curseblob/attacked_by(obj/item/I, mob/living/L)

View File

@@ -75,7 +75,7 @@
/mob/living/simple_animal/hostile/asteroid/goldgrub/bullet_act(obj/item/projectile/P)
visible_message("<span class='danger'>The [P.name] was repelled by [name]'s girth!</span>")
return
return BULLET_ACT_BLOCK
/mob/living/simple_animal/hostile/asteroid/goldgrub/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
vision_range = 9

View File

@@ -27,7 +27,9 @@
throw_message = "does nothing to the rocky hide of the"
vision_range = 4
aggro_vision_range = 7
anchored = TRUE //Stays anchored until death as to be unpullable
move_force = MOVE_FORCE_VERY_STRONG
move_resist = MOVE_FORCE_VERY_STRONG
pull_force = MOVE_FORCE_VERY_STRONG
var/pre_attack = 0
var/pre_attack_icon = "Goliath_preattack"
loot = list(/obj/item/stack/sheet/animalhide/goliath_hide)
@@ -51,7 +53,9 @@
. = 1
/mob/living/simple_animal/hostile/asteroid/goliath/death(gibbed)
anchored = FALSE
move_force = MOVE_FORCE_DEFAULT
move_resist = MOVE_RESIST_DEFAULT
pull_force = PULL_FORCE_DEFAULT
..(gibbed)
/mob/living/simple_animal/hostile/asteroid/goliath/OpenFire()

View File

@@ -217,7 +217,7 @@
can_infest_dead = TRUE
//Legion that spawns Legions
/mob/living/simple_animal/hostile/spawner/legion
/mob/living/simple_animal/hostile/big_legion
name = "legion"
desc = "One of many."
icon = 'icons/mob/lavaland/64x64megafauna.dmi'
@@ -226,10 +226,6 @@
icon_dead = "legion"
health = 450
maxHealth = 450
max_mobs = 3
spawn_time = 200
spawn_text = "peels itself off from"
mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion)
melee_damage_lower = 20
melee_damage_upper = 20
anchored = FALSE
@@ -252,6 +248,10 @@
see_in_dark = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
/mob/living/simple_animal/hostile/big_legion/Initialize()
.=..()
AddComponent(/datum/component/spawner, list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion), 200, faction, "peels itself off from", 3)
//Tendril-spawned Legion remains, the charred skeletons of those whose bodies sank into laval or fell into chasms.
/obj/effect/mob_spawn/human/corpse/charredskeleton
name = "charred skeletal remains"

View File

@@ -43,9 +43,9 @@
if(P.damage < 30 && P.damage_type != BRUTE)
P.damage = (P.damage / 3)
visible_message("<span class='danger'>[P] has a reduced effect on [src]!</span>")
..()
return ..()
/mob/living/simple_animal/hostile/asteroid/hitby(atom/movable/AM)//No floor tiling them to death, wiseguy
/mob/living/simple_animal/hostile/asteroid/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)//No floor tiling them to death, wiseguy
if(istype(AM, /obj/item))
var/obj/item/T = AM
if(!stat)

View File

@@ -1,95 +0,0 @@
//Necropolis Tendrils, which spawn lavaland monsters and break into a chasm when killed
/obj/effect/light_emitter/tendril
set_luminosity = 4
set_cap = 2.5
light_color = LIGHT_COLOR_LAVA
/mob/living/simple_animal/hostile/spawner/lavaland
name = "necropolis tendril"
desc = "A vile tendril of corruption, originating deep underground. Terrible monsters are pouring out of it."
icon = 'icons/mob/nest.dmi'
icon_state = "tendril"
icon_living = "tendril"
icon_dead = "tendril"
faction = list("mining")
weather_immunities = list("lava","ash")
health = 250
maxHealth = 250
max_mobs = 3
spawn_time = 300 //30 seconds default
mob_types = list(/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/tendril)
spawn_text = "emerges from"
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
maxbodytemp = INFINITY
loot = list(/obj/effect/collapse, /obj/structure/closet/crate/necropolis/tendril)
del_on_death = 1
var/gps = null
var/obj/effect/light_emitter/tendril/emitted_light
/mob/living/simple_animal/hostile/spawner/lavaland/goliath
mob_types = list(/mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril)
/mob/living/simple_animal/hostile/spawner/lavaland/legion
mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril)
/mob/living/simple_animal/hostile/spawner/lavaland/Initialize()
. = ..()
emitted_light = new(loc)
for(var/F in RANGE_TURFS(1, src))
if(ismineralturf(F))
var/turf/closed/mineral/M = F
M.ScrapeAway(null, CHANGETURF_IGNORE_AIR)
gps = new /obj/item/gps/internal(src)
/mob/living/simple_animal/hostile/spawner/lavaland/Destroy()
QDEL_NULL(emitted_light)
QDEL_NULL(gps)
return ..()
/mob/living/simple_animal/hostile/spawner/lavaland/death()
var/last_tendril = TRUE
for(var/mob/living/simple_animal/hostile/spawner/lavaland/other in GLOB.mob_living_list)
if(other != src)
last_tendril = FALSE
break
if(last_tendril && !(flags_1 & ADMIN_SPAWNED_1))
if(SSmedals.hub_enabled)
for(var/mob/living/L in view(7,src))
if(L.stat || !L.client)
continue
SSmedals.UnlockMedal("[BOSS_MEDAL_TENDRIL] [ALL_KILL_MEDAL]", L.client)
SSmedals.SetScore(TENDRIL_CLEAR_SCORE, L.client, 1)
..()
/obj/effect/collapse
name = "collapsing necropolis tendril"
desc = "Get clear!"
layer = TABLE_LAYER
icon = 'icons/mob/nest.dmi'
icon_state = "tendril"
anchored = TRUE
density = TRUE
var/obj/effect/light_emitter/tendril/emitted_light
/obj/effect/collapse/Initialize()
. = ..()
emitted_light = new(loc)
visible_message("<span class='boldannounce'>The tendril writhes in fury as the earth around it begins to crack and break apart! Get back!</span>")
visible_message("<span class='warning'>Something falls free of the tendril!</span>")
playsound(loc,'sound/effects/tendril_destroyed.ogg', 200, 0, 50, 1, 1)
addtimer(CALLBACK(src, .proc/collapse), 50)
/obj/effect/collapse/Destroy()
QDEL_NULL(emitted_light)
return ..()
/obj/effect/collapse/proc/collapse()
for(var/mob/M in range(7,src))
shake_camera(M, 15, 1)
playsound(get_turf(src),'sound/effects/explosionfar.ogg', 200, 1)
visible_message("<span class='boldannounce'>The tendril falls inward, the ground around it widening into a yawning chasm!</span>")
for(var/turf/T in range(2,src))
if(!T.density)
T.TerraformTurf(/turf/open/chasm/lavaland, /turf/open/chasm/lavaland, flags = CHANGETURF_INHERIT_AIR)
qdel(src)

View File

@@ -172,16 +172,17 @@
if(M.a_intent == INTENT_HARM)
Bruise()
/mob/living/simple_animal/hostile/mushroom/hitby(atom/movable/AM)
/mob/living/simple_animal/hostile/mushroom/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)
..()
if(istype(AM, /obj/item))
var/obj/item/T = AM
if(T.throwforce)
Bruise()
/mob/living/simple_animal/hostile/mushroom/bullet_act()
..()
Bruise()
/mob/living/simple_animal/hostile/mushroom/bullet_act(obj/item/projectile/P)
. = ..()
if(!P.nodamage)
Bruise()
/mob/living/simple_animal/hostile/mushroom/harvest()
var/counter

View File

@@ -65,33 +65,30 @@
attacktext = "punches"
deathmessage = "falls apart into a fine dust."
/mob/living/simple_animal/hostile/spawner/nether
/obj/structure/spawner/nether
name = "netherworld link"
desc = "A direct link to another dimension full of creatures not very happy to see you. <span class='warning'>Entering the link would be a very bad idea.</span>"
icon_state = "nether"
icon_living = "nether"
health = 50
maxHealth = 50
max_integrity = 50
spawn_time = 600 //1 minute
max_mobs = 15
mob_biotypes = list(MOB_INORGANIC)
icon = 'icons/mob/nest.dmi'
spawn_text = "crawls through"
mob_types = list(/mob/living/simple_animal/hostile/netherworld/migo, /mob/living/simple_animal/hostile/netherworld, /mob/living/simple_animal/hostile/netherworld/blankbody)
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
faction = list("nether")
deathmessage = "shatters into oblivion."
del_on_death = TRUE
/mob/living/simple_animal/hostile/spawner/nether/attack_hand(mob/user)
/obj/structure/spawner/nether/Initialize()
.=..()
START_PROCESSING(SSprocessing, src)
/obj/structure/spawner/nether/attack_hand(mob/user)
user.visible_message("<span class='warning'>[user] is violently pulled into the link!</span>", \
"<span class='userdanger'>Touching the portal, you are quickly pulled through into a world of unimaginable horror!</span>")
contents.Add(user)
/mob/living/simple_animal/hostile/spawner/nether/Life()
..()
var/list/C = src.get_contents()
for(var/mob/living/M in C)
/obj/structure/spawner/nether/process()
for(var/mob/living/M in contents)
if(M)
playsound(src, 'sound/magic/demon_consume.ogg', 50, 1)
M.adjustBruteLoss(60)

View File

@@ -44,7 +44,10 @@
search_objects = 1 // So that it can see through walls
sight = SEE_SELF|SEE_MOBS|SEE_OBJS|SEE_TURFS
anchored = TRUE
move_force = MOVE_FORCE_EXTREMELY_STRONG
move_resist = MOVE_FORCE_EXTREMELY_STRONG
pull_force = MOVE_FORCE_EXTREMELY_STRONG
var/cannot_be_seen = 1
var/mob/living/creator = null

View File

@@ -128,13 +128,10 @@
return ..()
/mob/living/simple_animal/hostile/syndicate/melee/bullet_act(obj/item/projectile/Proj)
if(!Proj)
return
if(prob(25))
return ..()
else
visible_message("<span class='danger'>[src] blocks [Proj] with its shield!</span>")
return 0
visible_message("<span class='danger'>[src] blocks [Proj] with its shield!</span>")
return BULLET_ACT_BLOCK
/mob/living/simple_animal/hostile/syndicate/melee/sword/space
icon_state = "syndicate_space_sword"

View File

@@ -337,7 +337,7 @@
//Bullets
/mob/living/simple_animal/parrot/bullet_act(obj/item/projectile/Proj)
..()
. = ..()
if(!stat && !client)
if(parrot_state == PARROT_PERCH)
parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched
@@ -347,7 +347,6 @@
//parrot_been_shot += 5
icon_state = icon_living
drop_held_item(0)
return
/*

View File

@@ -66,7 +66,7 @@
var/buffed = 0 //In the event that you want to have a buffing effect on the mob, but don't want it to stack with other effects, any outside force that applies a buff to a simple mob should at least set this to 1, so we have something to check against
var/gold_core_spawnable = NO_SPAWN //If the mob can be spawned with a gold slime core. HOSTILE_SPAWN are spawned with plasma, FRIENDLY_SPAWN are spawned with blood
var/mob/living/simple_animal/hostile/spawner/nest
var/datum/component/spawner/nest
var/sentience_type = SENTIENCE_ORGANIC // Sentience type, for slime potions

View File

@@ -220,15 +220,12 @@
return ..() //Heals them
/mob/living/simple_animal/slime/bullet_act(obj/item/projectile/Proj)
if(!Proj)
return
attacked += 10
if((Proj.damage_type == BURN))
adjustBruteLoss(-abs(Proj.damage)) //fire projectiles heals slimes.
Proj.on_hit(src)
else
..(Proj)
return 0
return BULLET_ACT_BLOCK
return ..()
/mob/living/simple_animal/slime/emp_act(severity)
. = ..()
@@ -246,7 +243,7 @@
/mob/living/simple_animal/slime/doUnEquip(obj/item/W)
return
/mob/living/simple_animal/slime/start_pulling(atom/movable/AM)
/mob/living/simple_animal/slime/start_pulling(atom/movable/AM, state, force = move_force, supress_message = FALSE)
return
/mob/living/simple_animal/slime/attack_ui(slot)

View File

@@ -1,113 +0,0 @@
/mob/living/simple_animal/hostile/spawner
name = "monster nest"
icon = 'icons/mob/animal.dmi'
health = 100
maxHealth = 100
gender = NEUTER
var/list/spawned_mobs = list()
var/max_mobs = 5
var/spawn_delay = 0
var/spawn_time = 300 //30 seconds default
var/mob_types = list(/mob/living/simple_animal/hostile/carp)
var/spawn_text = "emerges from"
status_flags = 0
anchored = TRUE
AIStatus = AI_OFF
a_intent = INTENT_HARM
stop_automated_movement = 1
wander = 0
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
maxbodytemp = 350
layer = BELOW_MOB_LAYER
sentience_type = SENTIENCE_BOSS
/mob/living/simple_animal/hostile/spawner/Destroy()
for(var/mob/living/simple_animal/L in spawned_mobs)
if(L.nest == src)
L.nest = null
spawned_mobs = null
return ..()
/mob/living/simple_animal/hostile/spawner/Life()
. = ..()
if(!.) // dead
return
spawn_mob()
/mob/living/simple_animal/hostile/spawner/proc/spawn_mob()
if(spawned_mobs.len >= max_mobs)
return 0
if(spawn_delay > world.time)
return 0
spawn_delay = world.time + spawn_time
var/chosen_mob_type = pick(mob_types)
var/mob/living/simple_animal/L = new chosen_mob_type(src.loc)
L.flags_1 |= (flags_1 & ADMIN_SPAWNED_1) //If we were admin spawned, lets have our children count as that as well.
spawned_mobs += L
L.nest = src
L.faction = src.faction
visible_message("<span class='danger'>[L] [spawn_text] [src].</span>")
/mob/living/simple_animal/hostile/spawner/syndicate
name = "warp beacon"
icon = 'icons/obj/device.dmi'
icon_state = "syndbeacon"
spawn_text = "warps in from"
mob_types = list(/mob/living/simple_animal/hostile/syndicate/ranged)
faction = list(ROLE_SYNDICATE)
/mob/living/simple_animal/hostile/spawner/skeleton
name = "bone pit"
desc = "A pit full of bones, and some still seem to be moving..."
icon_state = "hole"
icon_living = "hole"
icon = 'icons/mob/nest.dmi'
health = 150
maxHealth = 150
max_mobs = 15
spawn_time = 150
mob_types = list(/mob/living/simple_animal/hostile/skeleton)
spawn_text = "climbs out of"
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
faction = list("skeleton")
/mob/living/simple_animal/hostile/spawner/mining
name = "monster den"
desc = "A hole dug into the ground, harboring all kinds of monsters found within most caves or mining asteroids."
icon_state = "hole"
icon_living = "hole"
health = 200
maxHealth = 200
max_mobs = 3
icon = 'icons/mob/nest.dmi'
spawn_text = "crawls out of"
mob_types = list(/mob/living/simple_animal/hostile/asteroid/goldgrub, /mob/living/simple_animal/hostile/asteroid/goliath, /mob/living/simple_animal/hostile/asteroid/hivelord, /mob/living/simple_animal/hostile/asteroid/basilisk, /mob/living/simple_animal/hostile/asteroid/fugu)
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
faction = list("mining")
/mob/living/simple_animal/hostile/spawner/mining/goldgrub
name = "goldgrub den"
desc = "A den housing a nest of goldgrubs, annoying but arguably much better than anything else you'll find in a nest."
mob_types = list(/mob/living/simple_animal/hostile/asteroid/goldgrub)
/mob/living/simple_animal/hostile/spawner/mining/goliath
name = "goliath den"
desc = "A den housing a nest of goliaths, oh god why?"
mob_types = list(/mob/living/simple_animal/hostile/asteroid/goliath)
/mob/living/simple_animal/hostile/spawner/mining/hivelord
name = "hivelord den"
desc = "A den housing a nest of hivelords."
mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord)
/mob/living/simple_animal/hostile/spawner/mining/basilisk
name = "basilisk den"
desc = "A den housing a nest of basilisks, bring a coat."
mob_types = list(/mob/living/simple_animal/hostile/asteroid/basilisk)
/mob/living/simple_animal/hostile/spawner/mining/wumborian
name = "wumborian fugu den"
desc = "A den housing a nest of wumborian fugus, how do they all even fit in there?"
mob_types = list(/mob/living/simple_animal/hostile/asteroid/fugu)