Ports move force and move resist, movement/pushing/pulling tweaks & co.

This commit is contained in:
Ghommie
2019-10-24 18:01:46 +02:00
parent 432a7dba5d
commit 2c578ca683
121 changed files with 553 additions and 437 deletions
@@ -45,10 +45,10 @@
bonus_damage *= 3 //total 30 damage on cultists, 50 with ratvar
GLOB.clockwork_vitality += target.adjustFireLoss(bonus_damage) //adds the damage done to existing vitality
/obj/item/clockwork/weapon/ratvarian_spear/throw_impact(atom/target)
var/turf/T = get_turf(target)
if(isliving(target))
var/mob/living/L = target
/obj/item/clockwork/weapon/ratvarian_spear/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
var/turf/T = get_turf(hit_atom)
if(isliving(hit_atom))
var/mob/living/L = hit_atom
if(is_servant_of_ratvar(L))
if(L.put_in_active_hand(src))
L.visible_message("<span class='warning'>[L] catches [src] out of the air!</span>")
+9 -9
View File
@@ -264,7 +264,7 @@
to_chat(user, "<span class='warning'>The bola seems to take on a life of its own!</span>")
throw_impact(user)
/obj/item/restraints/legcuffs/bola/cult/throw_impact(atom/hit_atom)
/obj/item/restraints/legcuffs/bola/cult/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(iscultist(hit_atom))
return
. = ..()
@@ -689,10 +689,10 @@
/obj/item/twohanded/cult_spear/update_icon()
icon_state = "bloodspear[wielded]"
/obj/item/twohanded/cult_spear/throw_impact(atom/target)
var/turf/T = get_turf(target)
if(isliving(target))
var/mob/living/L = target
/obj/item/twohanded/cult_spear/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
var/turf/T = get_turf(hit_atom)
if(isliving(hit_atom))
var/mob/living/L = hit_atom
if(iscultist(L))
playsound(src, 'sound/weapons/throwtap.ogg', 50)
if(L.put_in_active_hand(src))
@@ -983,11 +983,11 @@
return TRUE
return FALSE
/obj/item/shield/mirror/throw_impact(atom/target, throwingdatum)
var/turf/T = get_turf(target)
/obj/item/shield/mirror/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
var/turf/T = get_turf(hit_atom)
var/datum/thrownthing/D = throwingdatum
if(isliving(target))
var/mob/living/L = target
if(isliving(hit_atom))
var/mob/living/L = hit_atom
if(iscultist(L))
playsound(src, 'sound/weapons/throwtap.ogg', 50)
if(L.put_in_active_hand(src))
@@ -43,7 +43,7 @@
wander = FALSE
density = FALSE
movement_type = FLYING
anchored = TRUE
move_resist = MOVE_FORCE_OVERPOWERING
mob_size = MOB_SIZE_TINY
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
speed = 1
@@ -360,7 +360,7 @@
user.dropItemToGround(src)
scatter()
/obj/item/ectoplasm/revenant/throw_impact(atom/hit_atom)
/obj/item/ectoplasm/revenant/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
..()
if(inert)
return
+1 -1
View File
@@ -142,7 +142,7 @@
. = ..()
olddir = dir
/obj/item/assembly/infra/throw_impact()
/obj/item/assembly/infra/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
. = ..()
if(!olddir)
return
+2 -2
View File
@@ -130,10 +130,10 @@
return FALSE
/obj/item/assembly/mousetrap/hitby(A as mob|obj)
/obj/item/assembly/mousetrap/hitby(atom/hit_atom, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)
if(!armed)
return ..()
visible_message("<span class='warning'>[src] is triggered by [A].</span>")
visible_message("<span class='warning'>[src] is triggered by [hit_atom].</span>")
triggered(null)
@@ -266,12 +266,13 @@
/atom/movable/proc/experience_pressure_difference(pressure_difference, direction, pressure_resistance_prob_delta = 0)
var/const/PROBABILITY_OFFSET = 25
var/const/PROBABILITY_BASE_PRECENT = 75
var/max_force = sqrt(pressure_difference)*(MOVE_FORCE_DEFAULT / 5)
set waitfor = 0
var/move_prob = 100
if (pressure_resistance > 0)
move_prob = (pressure_difference/pressure_resistance*PROBABILITY_BASE_PRECENT)-PROBABILITY_OFFSET
move_prob += pressure_resistance_prob_delta
if (move_prob > PROBABILITY_OFFSET && prob(move_prob))
if (move_prob > PROBABILITY_OFFSET && prob(move_prob) && (move_resist != INFINITY) && (!anchored && (max_force >= (move_resist * MOVE_FORCE_PUSH_RATIO))) || (anchored && (max_force >= (move_resist * MOVE_FORCE_FORCEPUSH_RATIO))))
step(src, direction)
last_high_pressure_movement_air_cycle = SSair.times_fired
@@ -14,6 +14,7 @@ Pipelines + Other Objects -> Pipe network
/obj/machinery/atmospherics
anchored = TRUE
move_resist = INFINITY //Moving a connected machine without actually doing the normal (dis)connection things will probably cause a LOT of issues.
idle_power_usage = 0
active_power_usage = 0
power_channel = ENVIRON
+3
View File
@@ -43,6 +43,9 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
icon = 'icons/obj/objects.dmi'
icon_state = "immrod"
throwforce = 100
move_force = INFINITY
move_resist = INFINITY
pull_force = INFINITY
density = TRUE
anchored = TRUE
var/mob/living/wizard
+2 -2
View File
@@ -213,9 +213,9 @@ GLOBAL_LIST_INIT(hallucination_list, list(
. = ..()
name = "alien hunter ([rand(1, 1000)])"
/obj/effect/hallucination/simple/xeno/throw_impact(A)
/obj/effect/hallucination/simple/xeno/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
update_icon("alienh_pounce")
if(A == target && target.stat!=DEAD)
if(hit_atom == target && target.stat!=DEAD)
target.Knockdown(100)
target.visible_message("<span class='danger'>[target] flails around wildly.</span>","<span class ='userdanger'>[name] pounces on you!</span>")
@@ -101,10 +101,10 @@
to_chat(user, "<span class='notice'>You heat [name] with [I]!</span>")
..()
/obj/item/reagent_containers/food/drinks/throw_impact(atom/target, datum/thrownthing/throwinfo)
/obj/item/reagent_containers/food/drinks/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
. = ..()
if(!.) //if the bottle wasn't caught
smash(target, throwinfo.thrower, TRUE)
smash(hit_atom, throwingdatum?.thrower, TRUE)
/obj/item/reagent_containers/food/drinks/proc/smash(atom/target, mob/thrower, ranged = FALSE)
if(!isGlass)
@@ -442,7 +442,7 @@
isGlass = FALSE
return
/obj/item/reagent_containers/food/drinks/bottle/molotov/throw_impact(atom/target,datum/thrownthing/throwdata)
/obj/item/reagent_containers/food/drinks/bottle/molotov/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
var/firestarter = 0
for(var/datum/reagent/R in reagents.reagent_list)
for(var/A in accelerants)
@@ -450,8 +450,8 @@
firestarter = 1
break
if(firestarter && active)
target.fire_act()
new /obj/effect/hotspot(get_turf(target))
hit_atom.fire_act()
new /obj/effect/hotspot(get_turf(hit_atom))
..()
/obj/item/reagent_containers/food/drinks/bottle/molotov/attackby(obj/item/I, mob/user, params)
@@ -31,7 +31,7 @@
var/color = mix_color_from_reagents(reagents.reagent_list)
add_atom_colour(color, FIXED_COLOUR_PRIORITY)
/obj/item/reagent_containers/food/snacks/egg/throw_impact(atom/hit_atom)
/obj/item/reagent_containers/food/snacks/egg/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(!..()) //was it caught by a mob?
var/turf/T = get_turf(hit_atom)
new/obj/effect/decal/cleanable/egg_smudge(T)
@@ -439,8 +439,8 @@
head.color = C
add_overlay(head)
/obj/item/reagent_containers/food/snacks/lollipop/throw_impact(atom/A)
..(A)
/obj/item/reagent_containers/food/snacks/lollipop/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
..(hit_atom)
throw_speed = 1
throwforce = 0
@@ -29,7 +29,7 @@
foodtype = GRAIN | DAIRY | SUGAR
var/stunning = TRUE
/obj/item/reagent_containers/food/snacks/pie/cream/throw_impact(atom/hit_atom)
/obj/item/reagent_containers/food/snacks/pie/cream/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
. = ..()
if(!.) //if we're not being caught
splat(hit_atom)
+1 -1
View File
@@ -231,7 +231,7 @@
if(boxes.len >= 3 && prob(25 * boxes.len))
disperse_pizzas()
/obj/item/pizzabox/throw_impact(atom/movable/AM)
/obj/item/pizzabox/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(boxes.len >= 2 && prob(20 * boxes.len))
disperse_pizzas()
+1 -1
View File
@@ -422,7 +422,7 @@
reagents.add_reagent(R, 30)
name = "[R] Potion"
/obj/item/reagent_containers/potion_container/throw_impact(atom/target)
/obj/item/reagent_containers/potion_container/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
..()
sleep(20)
var/datum/effect_system/smoke_spread/chem/s = new()
+2 -2
View File
@@ -80,7 +80,7 @@
item_state = "dodgeball"
desc = "Used for playing the most violent and degrading of childhood games."
/obj/item/toy/beach_ball/holoball/dodgeball/throw_impact(atom/hit_atom)
/obj/item/toy/beach_ball/holoball/dodgeball/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
..()
if((ishuman(hit_atom)))
var/mob/living/carbon/M = hit_atom
@@ -123,7 +123,7 @@
else
..()
/obj/structure/holohoop/hitby(atom/movable/AM)
/obj/structure/holohoop/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
if (isitem(AM) && !istype(AM,/obj/item/projectile))
if(prob(50))
AM.forceMove(get_turf(src))
+1 -1
View File
@@ -91,7 +91,7 @@
squash(user)
..()
/obj/item/reagent_containers/food/snacks/grown/throw_impact(atom/hit_atom)
/obj/item/reagent_containers/food/snacks/grown/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(!..()) //was it caught by a mob?
if(seed)
for(var/datum/plant_gene/trait/T in seed.genes)
+1 -1
View File
@@ -48,7 +48,7 @@
return 1
return 0
/obj/item/grown/throw_impact(atom/hit_atom)
/obj/item/grown/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(!..()) //was it caught by a mob?
if(seed)
for(var/datum/plant_gene/trait/T in seed.genes)
+2 -1
View File
@@ -11,6 +11,7 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons)
var/uses_left = 3
var/can_use_indoors
var/safe_for_living_creatures = 1
var/max_force_fulton = MOVE_FORCE_STRONG
/obj/item/extraction_pack/examine()
. = ..()
@@ -57,7 +58,7 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons)
return
if(!isturf(A.loc)) // no extracting stuff inside other stuff
return
if(A.anchored)
if(A.anchored || (A.move_resist > max_force_fulton))
return
to_chat(user, "<span class='notice'>You start attaching the pack to [A]...</span>")
if(do_after(user,50,target=A))
+1 -1
View File
@@ -99,7 +99,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
recipes = GLOB.sand_recipes
. = ..()
/obj/item/stack/ore/glass/throw_impact(atom/hit_atom)
/obj/item/stack/ore/glass/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(..() || !ishuman(hit_atom))
return
var/mob/living/carbon/human/C = hit_atom
+2 -1
View File
@@ -3,7 +3,8 @@
/mob/camera
name = "camera mob"
density = FALSE
anchored = TRUE
move_force = INFINITY
move_resist = INFINITY
status_flags = GODMODE // You can't damage it.
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
see_in_dark = 7
+1
View File
@@ -4,6 +4,7 @@ INITIALIZE_IMMEDIATE(/mob/dead)
/mob/dead
sight = SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF
move_resist = INFINITY
throwforce = 0
/mob/dead/Initialize()
@@ -12,8 +12,6 @@
stat = DEAD
canmove = FALSE
anchored = TRUE // don't get pushed around
var/mob/living/new_character //for instant transfer once the round is set up
//Used to make sure someone doesn't get spammed with messages if they're ineligible for roles
@@ -151,7 +149,7 @@
message_admins(msg)
to_chat(usr, "<span class='danger'>The round is either not ready, or has already finished...</span>")
return
if(!GLOB.enter_allowed)
to_chat(usr, "<span class='notice'>There is an administrative lock on entering the game!</span>")
return
@@ -12,7 +12,6 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
stat = DEAD
density = FALSE
canmove = 0
anchored = TRUE // don't get pushed around
see_invisible = SEE_INVISIBLE_OBSERVER
see_in_dark = 100
invisibility = INVISIBILITY_OBSERVER
@@ -619,10 +618,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
to_chat(src, "<span class='warning'>This creature is too powerful for you to possess!</span>")
return 0
if(istype (target, /mob/living/simple_animal/hostile/spawner))
to_chat(src, "<span class='warning'>This isn't really a creature, now is it!</span>")
return 0
if(!can_reenter_round)
to_chat(src, "<span class='warning'>You are unable to re-enter the round.</span>")
return FALSE
@@ -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)
..(AM, skipcatch = TRUE, hitpush = FALSE)
@@ -54,18 +54,18 @@
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
var/blocked = FALSE
if(ishuman(A))
var/mob/living/carbon/human/H = A
if(ishuman(hit_atom))
var/mob/living/carbon/human/H = hit_atom
if(H.check_shields(src, 0, "the [name]", attack_type = LEAP_ATTACK))
blocked = TRUE
if(!blocked)
@@ -77,8 +77,8 @@
Knockdown(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>")
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>")
Knockdown(40, 1, 1)
if(leaping)
@@ -57,7 +57,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)
@@ -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)]"
+9 -11
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)
Knockdown(20)
@@ -160,7 +158,7 @@
//END OF CIT CHANGES
var/atom/movable/thrown_thing
var/obj/item/I = src.get_active_held_item()
var/obj/item/I = get_active_held_item()
if(!I)
if(pulling && isliving(pulling) && grab_state >= GRAB_AGGRESSIVE)
@@ -188,11 +186,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)
thrown_thing.safe_throw_at(target, thrown_thing.throw_range, thrown_thing.throw_speed, src, null, null, null, move_force)
/mob/living/carbon/restrained(ignore_grab)
. = (handcuffed || (!ignore_grab && pulledby && pulledby.grab_state >= GRAB_AGGRESSIVE))
@@ -448,7 +446,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()
..()
@@ -58,7 +58,7 @@
return
return TRUE
/mob/living/carbon/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked = FALSE)
/mob/living/carbon/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)
if(!skipcatch) //ugly, but easy
if(can_catch_item())
if(istype(AM, /obj/item))
@@ -124,7 +124,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)
if(dna && dna.species)
var/spec_return = dna.species.spec_hitby(AM, src)
if(spec_return)
@@ -384,7 +384,7 @@
retaliate(Proj.firer)
..()
/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))
+33 -23
View File
@@ -59,7 +59,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)
@@ -202,33 +202,43 @@
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)))
+3 -3
View File
@@ -55,7 +55,7 @@
else
return 0
/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)
if(istype(AM, /obj/item))
var/obj/item/I = AM
var/zone = ran_zone(BODY_ZONE_CHEST, 65)//Hits a random part of the body, geared towards the chest
@@ -120,7 +120,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
@@ -146,7 +146,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))
+8 -3
View File
@@ -16,7 +16,7 @@
name = "AI"
icon = 'icons/mob/ai.dmi'
icon_state = "ai"
anchored = TRUE
move_resist = MOVE_FORCE_VERY_STRONG
density = TRUE
canmove = FALSE
status_flags = CANSTUN|CANPUSH
@@ -318,9 +318,14 @@
return // stop
if(incapacitated())
return
anchored = !anchored // Toggles the anchor
var/is_anchored = FALSE
if(move_resist == MOVE_FORCE_VERY_STRONG)
move_resist = MOVE_FORCE_VERY_STRONG
else
is_anchored = TRUE
move_resist = MOVE_FORCE_NORMAL
to_chat(src, "<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
/mob/living/silicon/ai/update_canmove() //If the AI dies, mobs won't go through it anymore
+1 -1
View File
@@ -14,7 +14,7 @@
cameraFollow = null
anchored = FALSE //unbolt floorbolts
move_resist = MOVE_FORCE_NORMAL
update_canmove()
if(eyeobj)
eyeobj.setLoc(get_turf(src))
@@ -99,7 +99,7 @@
if(loc != card)
visible_message("<span class='notice'>[src] [rest? "lays down for a moment..." : "perks up from the ground"]</span>")
/mob/living/silicon/pai/start_pulling(atom/movable/AM)
/mob/living/silicon/pai/start_pulling(atom/movable/AM, state, force = move_force, supress_message = FALSE)
return FALSE
/mob/living/silicon/pai/proc/toggle_integrated_light()
@@ -155,7 +155,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
@@ -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)
@@ -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))
@@ -338,7 +338,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))
@@ -44,18 +44,18 @@
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(ishuman(A))
var/mob/living/carbon/human/H = A
if(ishuman(hit_atom))
var/mob/living/carbon/human/H = hit_atom
if(H.check_shields(src, 90, "[name]", attack_type = THROWN_PROJECTILE_ATTACK))
blocked = TRUE
if(!blocked)
@@ -249,7 +249,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()
@@ -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
@@ -29,7 +29,7 @@
projectilesound = 'sound/weapons/pierce.ogg'
robust_searching = TRUE
stat_attack = UNCONSCIOUS
anchored = TRUE
move_resist = MOVE_FORCE_EXTREMELY_STRONG
var/combatant_state = SEEDLING_STATE_NEUTRAL
var/obj/seedling_weakpoint/weak_point
var/mob/living/beam_debuff_target
@@ -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)
@@ -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
@@ -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
@@ -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()
@@ -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"
@@ -45,7 +45,7 @@
visible_message("<span class='danger'>[P] has a reduced effect on [src]!</span>")
..()
/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)
@@ -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)
qdel(src)
@@ -170,7 +170,7 @@
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
@@ -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)
@@ -43,7 +43,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
@@ -65,7 +65,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
@@ -61,7 +61,7 @@
var/mood = "" // To show its face
var/mutator_used = FALSE //So you can't shove a dozen mutators into a single slime
var/force_stasis = FALSE
do_footstep = TRUE
var/static/regex/slime_name_regex = new("\\w+ (baby|adult) slime \\(\\d+\\)")
@@ -245,7 +245,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)
@@ -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)
+1 -2
View File
@@ -108,8 +108,7 @@
if((direct & (direct - 1)) && mob.loc == n) //moved diagonally successfully
add_delay *= 2
if(mob.loc != oldloc)
move_delay += add_delay
move_delay += add_delay
if(.) // If mob is null here, we deserve the runtime
if(mob.throwing)
mob.throwing.finalize(FALSE)
+1 -1
View File
@@ -56,7 +56,7 @@
//If we hit the Ninja who owns this Katana, they catch it.
//Works for if the Ninja throws it or it throws itself or someone tries
//To throw it at the ninja
/obj/item/energy_katana/throw_impact(atom/hit_atom)
/obj/item/energy_katana/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(ishuman(hit_atom))
var/mob/living/carbon/human/H = hit_atom
if(istype(H.wear_suit, /obj/item/clothing/suit/space/space_ninja))
+1 -1
View File
@@ -97,7 +97,7 @@
/obj/item/paperplane/throw_at(atom/target, range, speed, mob/thrower, spin=FALSE, diagonals_first = FALSE, datum/callback/callback)
. = ..(target, range, speed, thrower, FALSE, diagonals_first, callback)
/obj/item/paperplane/throw_impact(atom/hit_atom)
/obj/item/paperplane/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(iscarbon(hit_atom))
var/mob/living/carbon/C = hit_atom
if(C.can_catch_item(TRUE))
+1
View File
@@ -23,6 +23,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
desc = "A device which produces a graviton field when set up."
icon = 'icons/obj/machines/gravity_generator.dmi'
density = TRUE
move_resist = INFINITY
use_power = NO_POWER_USE
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
var/sprite_number = 0
+1 -1
View File
@@ -758,7 +758,7 @@
/obj/item/light/bulb/broken
status = LIGHT_BROKEN
/obj/item/light/throw_impact(atom/hit_atom)
/obj/item/light/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(!..()) //not caught by a mob
shatter()
@@ -6,6 +6,7 @@
icon = 'icons/obj/singularity.dmi'
icon_state = "Contain_F"
density = FALSE
move_resist = INFINITY
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
use_power = NO_POWER_USE
interaction_flags_atom = NONE
@@ -245,6 +245,7 @@ field_generator power level display
if(state != FG_WELDED || !anchored)
turn_off()
return
move_resist = INFINITY
spawn(1)
setup_field(1)
spawn(2)
@@ -335,6 +336,7 @@ field_generator power level display
message_admins("A singulo exists and a containment field has failed at [ADMIN_VERBOSEJMP(T)].")
investigate_log("has <font color='red'>failed</font> whilst a singulo exists at [AREACOORD(T)].", INVESTIGATE_SINGULO)
O.last_warning = world.time
move_resist = initial(move_resist)
/obj/machinery/field/generator/shock(mob/living/user)
if(fields.len)
@@ -7,6 +7,7 @@
icon_state = "singularity_s1"
anchored = TRUE
density = TRUE
move_resist = INFINITY
layer = MASSIVE_OBJ_LAYER
light_range = 6
appearance_flags = 0
@@ -16,9 +16,9 @@
/datum/mapGeneratorModule/splatterLayer/lavalandTendrils
spawnableTurfs = list()
spawnableAtoms = list(/mob/living/simple_animal/hostile/spawner/lavaland = 5,
/mob/living/simple_animal/hostile/spawner/lavaland/legion = 5,
/mob/living/simple_animal/hostile/spawner/lavaland/goliath = 5)
spawnableAtoms = list(/obj/structure/spawner/lavaland = 5,
/obj/structure/spawner/lavaland/legion = 5,
/obj/structure/spawner/lavaland/goliath = 5)
/datum/mapGenerator/lavaland/ground_only
modules = list(/datum/mapGeneratorModule/bottomLayer/lavaland_default)
@@ -65,7 +65,7 @@
else
return ..()
/obj/item/ammo_casing/throw_impact(atom/A)
/obj/item/ammo_casing/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(heavy_metal)
bounce_away(FALSE, NONE)
. = ..()
+2 -2
View File
@@ -78,9 +78,9 @@
reagents.expose_temperature(exposed_temperature)
..()
/obj/item/reagent_containers/throw_impact(atom/target)
/obj/item/reagent_containers/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
. = ..()
SplashReagents(target, TRUE)
SplashReagents(hit_atom, TRUE)
/obj/item/reagent_containers/proc/bartender_check(atom/target)
. = FALSE
+1 -1
View File
@@ -355,7 +355,7 @@
ui.soft_update_fields()
/obj/machinery/disposal/bin/hitby(atom/movable/AM)
/obj/machinery/disposal/bin/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)
if(isitem(AM) && AM.CanEnterDisposals())
if(prob(75))
AM.forceMove(src)
@@ -1,26 +1,31 @@
#define ASH_WALKER_SPAWN_THRESHOLD 2
//The ash walker den consumes corpses or unconscious mobs to create ash walker eggs. For more info on those, check ghost_role_spawners.dm
/mob/living/simple_animal/hostile/spawner/lavaland/ash_walker
/obj/structure/lavaland/ash_walker
name = "necropolis tendril nest"
desc = "A vile tendril of corruption. It's surrounded by a nest of rapidly growing eggs..."
icon = 'icons/mob/nest.dmi'
icon_state = "ash_walker_nest"
icon_living = "ash_walker_nest"
icon_dead = "ash_walker_nest"
faction = list("ashwalker")
health = 200
maxHealth = 200
loot = list(/obj/effect/collapse)
move_resist=INFINITY // just killing it tears a massive hole in the ground, let's not move it
anchored = TRUE
density = TRUE
resistance_flags = FIRE_PROOF | LAVA_PROOF
max_integrity = 200
var/faction = list("ashwalker")
var/meat_counter = 6
/mob/living/simple_animal/hostile/spawner/lavaland/ash_walker/death()
/obj/structure/lavaland/ash_walker/Initialize()
.=..()
START_PROCESSING(SSprocessing, src)
/obj/structure/lavaland/ash_walker/deconstruct(disassembled)
new /obj/item/assembly/signaler/anomaly (get_step(loc, pick(GLOB.alldirs)))
return ..()
new /obj/effect/collapse(loc)
/mob/living/simple_animal/hostile/spawner/lavaland/ash_walker/Life()
/obj/structure/lavaland/ash_walker/process()
consume()
return ..()
spawn_mob()
/mob/living/simple_animal/hostile/spawner/lavaland/ash_walker/proc/consume()
/obj/structure/lavaland/ash_walker/proc/consume()
for(var/mob/living/H in view(src, 1)) //Only for corpse right next to/on same tile
if(H.stat)
visible_message("<span class='warning'>Serrated tendrils eagerly pull [H] to [src], tearing the body apart as its blood seeps over the eggs.</span>")
@@ -33,9 +38,9 @@
else
meat_counter++
H.gib()
adjustHealth(-maxHealth * 0.05)//restores 5% hp of tendril
obj_integrity = min(obj_integrity + max_integrity*0.05,max_integrity)//restores 5% hp of tendril
/mob/living/simple_animal/hostile/spawner/lavaland/ash_walker/spawn_mob()
/obj/structure/lavaland/ash_walker/proc/spawn_mob()
if(meat_counter >= ASH_WALKER_SPAWN_THRESHOLD)
new /obj/effect/mob_spawn/human/ash_walker(get_step(loc, pick(GLOB.alldirs)))
visible_message("<span class='danger'>One of the eggs swells to an unnatural size and tumbles free. It's ready to hatch!</span>")
+1 -1
View File
@@ -131,7 +131,7 @@ All ShuttleMove procs go here
var/range = throw_force * 10
range = CEILING(rand(range-(range*0.1), range+(range*0.1)), 10)/10
var/speed = range/5
throw_at(target, range, speed)
safe_throw_at(target, range, speed)
/////////////////////////////////////////////////////////////////////////////////////
+1 -1
View File
@@ -63,7 +63,7 @@
clothes_req = FALSE
charge_max = 600
cooldown_min = 200
summon_type = list(/mob/living/simple_animal/hostile/spawner/nether)
summon_type = list(/obj/structure/spawner/nether)
summon_amt = 1
range = 1
cast_sound = 'sound/weapons/marauder.ogg'
+1 -1
View File
@@ -363,7 +363,7 @@
icon_state = "snappop"
w_class = WEIGHT_CLASS_TINY
/obj/item/spellpacket/lightningbolt/throw_impact(atom/hit_atom)
/obj/item/spellpacket/lightningbolt/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(!..())
if(isliving(hit_atom))
var/mob/living/M = hit_atom
+1 -1
View File
@@ -116,7 +116,7 @@
else
return ..()
/obj/item/bodypart/throw_impact(atom/hit_atom)
/obj/item/bodypart/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
..()
if(status != BODYPART_ROBOTIC)
playsound(get_turf(src), 'sound/misc/splort.ogg', 50, 1, -1)
+1
View File
@@ -2,6 +2,7 @@
//Keep this sorted alphabetically
#ifdef UNIT_TESTS
#include "anchored_mobs.dm"
#include "reagent_id_typos.dm"
#include "reagent_recipe_collisions.dm"
#include "spawn_humans.dm"
+9
View File
@@ -0,0 +1,9 @@
/datum/unit_test/anchored_mobs/Run()
var/list/L = list()
for(var/i in typesof(/mob))
var/mob/M = i
if(initial(M.anchored))
L += "[i]"
if(!L.len)
return //passed!
Fail("The following mobs are defined as anchored. This is incompatible with the new move force/resist system and needs to be revised.: [L.Join(" ")]")