mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-06 06:52:39 +00:00
Fixes a fuck ton more harddels (#58779)
Redoes how geese handle eating shit, it was fucking stupid and caused harddels, and while this method is technically slower in the best case, it's a fucking goose Fixes action related harddels, I hate how they work but at least this way they won't hold refs. Fixes the hierophont causing its beacon to harddel Removes the M variable from megafauna actions, it was used like a typed owner and caused harddels, so I burned it Fixes target and targets_from harddels, replaces all setters of target with LoseTarget and GiveTarget, which should help maintain behavior. I'm not sure if this breaks anything, but if it does we should fix the assumptions that code makes instead of reverting this change Fixes more area_senstive_contents related harddels, we need to allow the mob to move before clearing out its list. Fixes marked object harddels (I'm coming for you admin team) Fixes a language based human harddel Fixes managed overlay related harddels (This was just emissive blockers, but I think this is a good safety net to have. If we clear the overlay list we should clear this one as well) Fixes bot core harddels, I hate the fact that this exists but it has no reason to know who its owner is Adds a walk(src, 0) to simple_animal destroy, it's the best bang for the buck in terms of stopping spurious harddels. Walk related harddels aren't that expensive in the first place, since byond does the same thing I'm doing here, but this makes finding mob harddels easier, so let's go with it I fixed another source of part harddels, I hate fullupgrade so much Fixes all the sound loop harddels
This commit is contained in:
@@ -230,7 +230,7 @@
|
||||
/mob/living/simple_animal/hostile/UnarmedAttack(atom/attack_target, proximity_flag, list/modifiers)
|
||||
if(LIVING_UNARMED_ATTACK_BLOCKED(attack_target))
|
||||
return
|
||||
target = attack_target
|
||||
GiveTarget(attack_target)
|
||||
if(dextrous && (isitem(attack_target) || !combat_mode))
|
||||
..()
|
||||
else
|
||||
|
||||
@@ -64,6 +64,9 @@ SUBSYSTEM_DEF(atoms)
|
||||
if(late_loaders.len)
|
||||
for(var/I in 1 to late_loaders.len)
|
||||
var/atom/A = late_loaders[I]
|
||||
//I hate that we need this
|
||||
if(QDELETED(A))
|
||||
continue
|
||||
A.LateInitialize()
|
||||
testing("Late initialized [late_loaders.len] atoms")
|
||||
late_loaders.Cut()
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
return
|
||||
Remove(owner)
|
||||
owner = M
|
||||
RegisterSignal(owner, COMSIG_PARENT_QDELETING, .proc/owner_deleted)
|
||||
|
||||
//button id generation
|
||||
var/counter = 0
|
||||
@@ -72,13 +73,19 @@
|
||||
else
|
||||
Remove(owner)
|
||||
|
||||
/datum/action/proc/owner_deleted(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
Remove(owner)
|
||||
|
||||
/datum/action/proc/Remove(mob/M)
|
||||
if(M)
|
||||
if(M.client)
|
||||
M.client.screen -= button
|
||||
LAZYREMOVE(M.actions, src)
|
||||
M.update_action_buttons()
|
||||
owner = null
|
||||
if(owner)
|
||||
UnregisterSignal(owner, COMSIG_PARENT_QDELETING)
|
||||
owner = null
|
||||
button.moved = FALSE //so the button appears in its normal position when given to another owner.
|
||||
button.locked = FALSE
|
||||
button.id = null
|
||||
|
||||
@@ -55,8 +55,7 @@
|
||||
|
||||
/datum/component/acid/Destroy(force, silent)
|
||||
STOP_PROCESSING(SSacid, src)
|
||||
if(sizzle)
|
||||
QDEL_NULL(sizzle)
|
||||
QDEL_NULL(sizzle)
|
||||
if(process_effect)
|
||||
QDEL_NULL(process_effect)
|
||||
UnregisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS)
|
||||
|
||||
@@ -245,7 +245,6 @@
|
||||
/// Toggle our machinery on or off. This is called by a hook from default_unfasten_wrench with anchored as only param, so we dont have to copypaste this on every object that can move
|
||||
/datum/component/plumbing/proc/toggle_active(obj/O, new_state)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(new_state)
|
||||
enable()
|
||||
else
|
||||
@@ -314,12 +313,18 @@
|
||||
|
||||
/datum/component/plumbing/proc/set_recipient_reagents_holder(datum/reagents/receiver)
|
||||
if(recipient_reagents_holder)
|
||||
UnregisterSignal(recipient_reagents_holder, list(COMSIG_PARENT_QDELETING)) //stop tracking whoever we were tracking
|
||||
UnregisterSignal(recipient_reagents_holder, COMSIG_PARENT_QDELETING) //stop tracking whoever we were tracking
|
||||
if(receiver)
|
||||
RegisterSignal(receiver, list(COMSIG_PARENT_QDELETING), .proc/set_recipient_reagents_holder) //so on deletion it calls this proc again, but with no value to set
|
||||
RegisterSignal(receiver, COMSIG_PARENT_QDELETING, .proc/handle_reagent_del) //on deletion call a wrapper proc that clears us, and maybe reagents too
|
||||
|
||||
recipient_reagents_holder = receiver
|
||||
|
||||
/datum/component/plumbing/proc/handle_reagent_del(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
if(source == reagents)
|
||||
reagents = null
|
||||
if(source == recipient_reagents_holder)
|
||||
set_recipient_reagents_holder(null)
|
||||
|
||||
///has one pipe input that only takes, example is manual output pipe
|
||||
/datum/component/plumbing/simple_demand
|
||||
|
||||
@@ -284,11 +284,12 @@
|
||||
AA.remove_from_hud(src)
|
||||
|
||||
if(reagents)
|
||||
qdel(reagents)
|
||||
QDEL_NULL(reagents)
|
||||
|
||||
orbiters = null // The component is attached to us normaly and will be deleted elsewhere
|
||||
|
||||
LAZYCLEARLIST(overlays)
|
||||
LAZYCLEARLIST(managed_overlays)
|
||||
|
||||
QDEL_NULL(light)
|
||||
QDEL_NULL(ai_controller)
|
||||
|
||||
@@ -123,9 +123,6 @@
|
||||
|
||||
. = ..()
|
||||
|
||||
//We add ourselves to this list, best to clear it out
|
||||
LAZYCLEARLIST(area_sensitive_contents)
|
||||
|
||||
for(var/movable_content in contents)
|
||||
qdel(movable_content)
|
||||
|
||||
@@ -133,6 +130,10 @@
|
||||
|
||||
moveToNullspace()
|
||||
|
||||
//We add ourselves to this list, best to clear it out
|
||||
//DO it after moveToNullspace so memes can be had
|
||||
LAZYCLEARLIST(area_sensitive_contents)
|
||||
|
||||
vis_contents.Cut()
|
||||
|
||||
/atom/movable/proc/update_emissive_block()
|
||||
|
||||
@@ -269,21 +269,8 @@
|
||||
base_icon_state = "sleeper_s"
|
||||
controls_inside = TRUE
|
||||
|
||||
/obj/machinery/sleeper/syndie/fullupgrade/Initialize()
|
||||
. = ..()
|
||||
|
||||
// Cache the old_parts first, we'll delete it after we've changed component_parts to a new list.
|
||||
// This stops handle_atom_del being called on every part when not necessary.
|
||||
var/list/old_parts = component_parts.Copy()
|
||||
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/stock_parts/matter_bin/bluespace(src)
|
||||
component_parts += new /obj/item/stock_parts/manipulator/femto(src)
|
||||
component_parts += new /obj/item/stack/sheet/glass(src, 2)
|
||||
component_parts += new /obj/item/stack/cable_coil(src, 1)
|
||||
|
||||
QDEL_LIST(old_parts)
|
||||
RefreshParts()
|
||||
/obj/machinery/sleeper/syndie/fullupgrade
|
||||
circuit = /obj/item/circuitboard/machine/sleeper/fullupgrade
|
||||
|
||||
/obj/machinery/sleeper/old
|
||||
icon_state = "oldpod"
|
||||
|
||||
@@ -526,7 +526,7 @@
|
||||
playsound(game, 'sound/items/weeoo1.ogg', 100, FALSE)
|
||||
for(var/i, i<=3, i++)
|
||||
var/mob/living/simple_animal/hostile/syndicate/ranged/smg/orion/spaceport_security = new(get_turf(src))
|
||||
spaceport_security.target = usr
|
||||
spaceport_security.GiveTarget(usr)
|
||||
game.fuel += fuel
|
||||
game.food += food
|
||||
|
||||
|
||||
@@ -32,6 +32,10 @@
|
||||
soundloop = new(list(src), FALSE)
|
||||
update_appearance()
|
||||
|
||||
/obj/machinery/fat_sucker/Destroy()
|
||||
QDEL_NULL(soundloop)
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/fat_sucker/RefreshParts()
|
||||
..()
|
||||
var/rating = 0
|
||||
|
||||
@@ -54,6 +54,10 @@
|
||||
jackpot_loop = new(list(src), FALSE)
|
||||
wires = new /datum/wires/roulette(src)
|
||||
|
||||
/obj/machinery/roulette/Destroy()
|
||||
QDEL_NULL(jackpot_loop)
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/roulette/obj_break(damage_flag)
|
||||
prize_theft(0.05)
|
||||
. = ..()
|
||||
|
||||
@@ -776,6 +776,16 @@
|
||||
/obj/item/stack/cable_coil = 1,
|
||||
/obj/item/stack/sheet/glass = 2)
|
||||
|
||||
/obj/item/circuitboard/machine/sleeper/fullupgrade
|
||||
name = "Sleeper (Machine Board)"
|
||||
icon_state = "medical"
|
||||
build_path = /obj/machinery/sleeper/syndie/fullupgrade
|
||||
req_components = list(
|
||||
/obj/item/stock_parts/matter_bin/bluespace = 1,
|
||||
/obj/item/stock_parts/manipulator/femto = 1,
|
||||
/obj/item/stack/cable_coil = 1,
|
||||
/obj/item/stack/sheet/glass = 2)
|
||||
|
||||
/obj/item/circuitboard/machine/sleeper/party
|
||||
name = "Party Pod (Machine Board)"
|
||||
build_path = /obj/machinery/sleeper/party
|
||||
|
||||
@@ -2,11 +2,18 @@
|
||||
if(!holder)
|
||||
return
|
||||
if(holder.marked_datum)
|
||||
holder.UnregisterSignal(holder.marked_datum, COMSIG_PARENT_QDELETING)
|
||||
vv_update_display(holder.marked_datum, "marked", "")
|
||||
holder.marked_datum = D
|
||||
holder.RegisterSignal(holder.marked_datum, COMSIG_PARENT_QDELETING, /datum/admins/proc/handle_marked_del)
|
||||
vv_update_display(D, "marked", VV_MSG_MARKED)
|
||||
|
||||
/client/proc/mark_datum_mapview(datum/D as mob|obj|turf|area in view(view))
|
||||
set category = "Debug"
|
||||
set name = "Mark Object"
|
||||
mark_datum(D)
|
||||
|
||||
/datum/admins/proc/handle_marked_del(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
UnregisterSignal(marked_datum, COMSIG_PARENT_QDELETING)
|
||||
marked_datum = null
|
||||
|
||||
@@ -459,12 +459,18 @@
|
||||
glow_effect.icon_state = "pod_glow_" + GLOB.podstyles[style][POD_GLOW]
|
||||
vis_contents += glow_effect
|
||||
glow_effect.layer = GASFIRE_LAYER
|
||||
RegisterSignal(glow_effect, COMSIG_PARENT_QDELETING, .proc/remove_glow)
|
||||
|
||||
/obj/structure/closet/supplypod/proc/endGlow()
|
||||
if(!glow_effect)
|
||||
return
|
||||
glow_effect.layer = LOW_ITEM_LAYER
|
||||
glow_effect.fadeAway(delays[POD_OPENING])
|
||||
remove_glow()
|
||||
|
||||
/obj/structure/closet/supplypod/proc/remove_glow()
|
||||
SIGNAL_HANDLER
|
||||
UnregisterSignal(glow_effect, COMSIG_PARENT_QDELETING)
|
||||
glow_effect = null
|
||||
|
||||
/obj/structure/closet/supplypod/Destroy()
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
var/wait_how_many_bees_did_that_guy_pull_out_of_his_hat = rand(4, 8)
|
||||
for(var/b in 1 to wait_how_many_bees_did_that_guy_pull_out_of_his_hat)
|
||||
var/mob/living/simple_animal/hostile/poison/bees/barry = new(get_turf(magician))
|
||||
barry.target = magician
|
||||
barry.GiveTarget(magician)
|
||||
if(prob(20))
|
||||
barry.say(pick("BUZZ BUZZ", "PULLING A RABBIT OUT OF A HAT IS A TIRED TROPE", "I DIDN'T ASK TO BEE HERE"), forced = "bee hat")
|
||||
else
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/Destroy()
|
||||
. = ..()
|
||||
QDEL_NULL(soundloop)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/attack_self(mob/user)
|
||||
|
||||
@@ -29,6 +29,10 @@
|
||||
variant = rand(1,3)
|
||||
RegisterSignal(src, COMSIG_ATOM_EXPOSE_REAGENT, .proc/on_expose_reagent)
|
||||
|
||||
/obj/machinery/griddle/Destroy()
|
||||
QDEL_NULL(grill_loop)
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/griddle/crowbar_act(mob/living/user, obj/item/I)
|
||||
. = ..()
|
||||
if(flags_1 & NODECONSTRUCT_1)
|
||||
|
||||
@@ -206,7 +206,7 @@
|
||||
continue
|
||||
if(B.loc == src)
|
||||
B.forceMove(drop_location())
|
||||
B.target = user
|
||||
B.GiveTarget(user)
|
||||
bees = TRUE
|
||||
if(bees)
|
||||
visible_message("<span class='danger'>[user] disturbs the bees!</span>")
|
||||
|
||||
@@ -50,7 +50,7 @@ Key procs
|
||||
/// Currently spoken language
|
||||
var/selected_language
|
||||
/// Tracks the entity that owns the holder.
|
||||
var/owner
|
||||
var/atom/owner
|
||||
|
||||
/// Initializes, and copies in the languages from the current atom if available.
|
||||
/datum/language_holder/New(_owner)
|
||||
@@ -63,6 +63,7 @@ Key procs
|
||||
|
||||
/datum/language_holder/Destroy()
|
||||
QDEL_NULL(language_menu)
|
||||
owner = null
|
||||
return ..()
|
||||
|
||||
/// Grants the supplied language.
|
||||
|
||||
@@ -897,12 +897,10 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
/obj/machinery/bot_core
|
||||
use_power = NO_POWER_USE
|
||||
anchored = FALSE
|
||||
var/mob/living/simple_animal/bot/owner = null
|
||||
|
||||
/obj/machinery/bot_core/Initialize()
|
||||
. = ..()
|
||||
owner = loc
|
||||
if(!istype(owner))
|
||||
if(!isbot(loc))
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
/mob/living/simple_animal/bot/proc/topic_denied(mob/user) //Access check proc for bot topics! Remember to place in a bot's individual Topic if desired.
|
||||
|
||||
@@ -250,7 +250,7 @@
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/eldritch/armsy/Shoot(atom/targeted_atom)
|
||||
target = targeted_atom
|
||||
GiveTarget(targeted_atom)
|
||||
AttackingTarget()
|
||||
|
||||
/mob/living/simple_animal/hostile/eldritch/armsy/AttackingTarget()
|
||||
@@ -261,7 +261,7 @@
|
||||
if(target == back || target == front)
|
||||
return
|
||||
if(back)
|
||||
back.target = target
|
||||
back.GiveTarget(target)
|
||||
back.AttackingTarget()
|
||||
if(!Adjacent(target))
|
||||
return
|
||||
|
||||
@@ -166,7 +166,7 @@
|
||||
var/obj/structure/beebox/BB = target
|
||||
forceMove(BB)
|
||||
toggle_ai(AI_IDLE)
|
||||
target = null
|
||||
LoseTarget()
|
||||
wanted_objects -= beehometypecache //so we don't attack beeboxes when not going home
|
||||
return //no don't attack the goddamm box
|
||||
else
|
||||
@@ -193,10 +193,10 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/proc/pollinate(obj/machinery/hydroponics/Hydro)
|
||||
if(!istype(Hydro) || !Hydro.myseed || Hydro.dead || Hydro.recent_bee_visit)
|
||||
target = null
|
||||
LoseTarget()
|
||||
return
|
||||
|
||||
target = null //so we pick a new hydro tray next FindTarget(), instead of loving the same plant for eternity
|
||||
LoseTarget() //so we pick a new hydro tray next FindTarget(), instead of loving the same plant for eternity
|
||||
wanted_objects -= hydroponicstypecache //so we only hunt them while they're alive/seeded/not visisted
|
||||
Hydro.recent_bee_visit = TRUE
|
||||
addtimer(VARSET_CALLBACK(Hydro, recent_bee_visit, FALSE), BEE_TRAY_RECENT_VISIT)
|
||||
@@ -232,7 +232,7 @@
|
||||
if(idle <= BEE_IDLE_GOHOME && prob(BEE_PROB_GOHOME))
|
||||
if(!FindTarget())
|
||||
wanted_objects |= beehometypecache //so we don't attack beeboxes when not going home
|
||||
target = beehome
|
||||
GiveTarget(beehome)
|
||||
if(!beehome) //add outselves to a beebox (of the same reagent) if we have no home
|
||||
for(var/obj/structure/beebox/BB in view(vision_range, src))
|
||||
if(reagent_incompatible(BB.queen_bee) || BB.bees.len >= BB.get_max_bees())
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
var/icon_vomit = "vomit"
|
||||
var/icon_vomit_end = "vomit_end"
|
||||
var/message_cooldown = 0
|
||||
var/list/nummies = list()
|
||||
var/choking = FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/goose/Initialize()
|
||||
@@ -46,27 +45,21 @@
|
||||
/mob/living/simple_animal/hostile/retaliate/goose/proc/goosement(atom/movable/AM, OldLoc, Dir, Forced)
|
||||
if(stat == DEAD)
|
||||
return
|
||||
nummies.Cut()
|
||||
nummies += loc.contents
|
||||
if(prob(5) && random_retaliate)
|
||||
Retaliate()
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/goose/handle_automated_action()
|
||||
if(length(nummies))
|
||||
var/obj/item/E = locate() in nummies
|
||||
if(E && E.loc == loc)
|
||||
feed(E)
|
||||
nummies -= E
|
||||
var/obj/item/eat_it_motherfucker = pick(locate(/obj/item) in loc)
|
||||
if(!eat_it_motherfucker)
|
||||
return
|
||||
feed(eat_it_motherfucker)
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/goose/vomit/handle_automated_action()
|
||||
if(length(nummies))
|
||||
var/obj/item/E = pick(nummies)
|
||||
if(!E.has_material_type(/datum/material/plastic))
|
||||
nummies -= E // remove non-plastic item from queue
|
||||
E = locate(/obj/item/reagent_containers/food) in nummies // find food
|
||||
if(E && E.loc == loc)
|
||||
feed(E)
|
||||
nummies -= E
|
||||
for(var/obj/item/eat_it_motherfucker in loc)
|
||||
if(!eat_it_motherfucker.has_material_type(/datum/material/plastic))
|
||||
continue
|
||||
feed(eat_it_motherfucker)
|
||||
break
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/goose/proc/feed(obj/item/suffocator)
|
||||
if(stat == DEAD || choking) // plapatin I swear to god
|
||||
@@ -174,7 +167,7 @@
|
||||
if (stat == DEAD)
|
||||
return
|
||||
var/turf/T = get_turf(src)
|
||||
var/obj/item/reagent_containers/food/consumed = locate() in contents //Barf out a single food item from our guts
|
||||
var/obj/item/consumed = locate() in contents //Barf out a single food item from our guts
|
||||
choking = FALSE // assume birdboat is vomiting out whatever he was choking on
|
||||
if (prob(50) && consumed)
|
||||
barf_food(consumed)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
stop_automated_movement_when_pulled = 0
|
||||
obj_damage = 40
|
||||
environment_smash = ENVIRONMENT_SMASH_STRUCTURES //Bitflags. Set to ENVIRONMENT_SMASH_STRUCTURES to break closets,tables,racks, etc; ENVIRONMENT_SMASH_WALLS for walls; ENVIRONMENT_SMASH_RWALLS for rwalls
|
||||
///The current target of our attacks, use GiveTarget and LoseTarget to set this var
|
||||
var/atom/target
|
||||
var/ranged = FALSE
|
||||
var/rapid = 0 //How many shots per volley.
|
||||
@@ -46,6 +47,7 @@
|
||||
var/stat_attack = CONSCIOUS
|
||||
var/stat_exclusive = FALSE //Mobs with this set to TRUE will exclusively attack things defined by stat_attack, stat_attack DEAD means they will only attack corpses
|
||||
var/attack_same = 0 //Set us to 1 to allow us to attack our own faction
|
||||
//Use set_targets_from to modify this var
|
||||
var/atom/targets_from = null //all range/attack/etc. calculations should be done from this atom, defaults to the mob itself, useful for Vehicles and such
|
||||
var/attack_all_objects = FALSE //if true, equivalent to having a wanted_objects list containing ALL objects.
|
||||
var/lose_patience_timer_id //id for a timer to call LoseTarget(), used to stop mobs fixating on a target they can't reach
|
||||
@@ -68,12 +70,14 @@
|
||||
. = ..()
|
||||
|
||||
if(!targets_from)
|
||||
targets_from = src
|
||||
set_targets_from(src)
|
||||
wanted_objects = typecacheof(wanted_objects)
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/Destroy()
|
||||
targets_from = null
|
||||
set_targets_from(null)
|
||||
//We can't use losetarget here because fucking cursed blobs override it to do nothing the motherfuckers
|
||||
GiveTarget(null)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/Life(delta_time = SSMOBS_DT, times_fired)
|
||||
@@ -253,12 +257,12 @@
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/GiveTarget(new_target)//Step 4, give us our selected target
|
||||
target = new_target
|
||||
add_target(new_target)
|
||||
LosePatience()
|
||||
if(target != null)
|
||||
GainPatience()
|
||||
Aggro()
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
//What we do after closing in
|
||||
/mob/living/simple_animal/hostile/proc/MeleeAction(patience = TRUE)
|
||||
@@ -337,7 +341,7 @@
|
||||
. = ..()
|
||||
if(!ckey && !stat && search_objects < 3 && . > 0)//Not unconscious, and we don't ignore mobs
|
||||
if(search_objects)//Turn off item searching and ignore whatever item we were looking at, we're more concerned with fight or flight
|
||||
target = null
|
||||
LoseTarget()
|
||||
LoseSearchObjects()
|
||||
if(AIStatus != AI_ON && AIStatus != AI_OFF)
|
||||
toggle_ai(AI_ON)
|
||||
@@ -364,7 +368,7 @@
|
||||
taunt_chance = initial(taunt_chance)
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/LoseTarget()
|
||||
target = null
|
||||
GiveTarget(null)
|
||||
approaching_target = FALSE
|
||||
in_melee = FALSE
|
||||
walk(src, 0)
|
||||
@@ -511,7 +515,7 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/RangedAttack(atom/A, modifiers) //Player firing
|
||||
if(ranged && ranged_cooldown <= world.time)
|
||||
target = A
|
||||
GiveTarget(A)
|
||||
OpenFire(A)
|
||||
return ..()
|
||||
|
||||
@@ -652,3 +656,28 @@
|
||||
if(charge_state)
|
||||
charge_state = FALSE
|
||||
update_icons()
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/set_targets_from(atom/target_from)
|
||||
if(targets_from)
|
||||
UnregisterSignal(targets_from, COMSIG_PARENT_QDELETING)
|
||||
targets_from = target_from
|
||||
if(targets_from)
|
||||
RegisterSignal(targets_from, COMSIG_PARENT_QDELETING, .proc/handle_targets_from_del)
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/handle_targets_from_del(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
if(targets_from != src)
|
||||
set_targets_from(src)
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/handle_target_del(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
UnregisterSignal(target, COMSIG_PARENT_QDELETING)
|
||||
target = null
|
||||
LoseTarget()
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/add_target(new_target)
|
||||
if(target)
|
||||
UnregisterSignal(target, COMSIG_PARENT_QDELETING)
|
||||
target = new_target
|
||||
if(target)
|
||||
RegisterSignal(target, COMSIG_PARENT_QDELETING, .proc/handle_target_del)
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/jungle/leaper/CtrlClickOn(atom/A)
|
||||
face_atom(A)
|
||||
target = A
|
||||
GiveTarget(A)
|
||||
if(!isturf(loc))
|
||||
return
|
||||
if(next_move > world.time)
|
||||
|
||||
@@ -69,9 +69,9 @@
|
||||
/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/enter_mecha(obj/vehicle/sealed/mecha/M)
|
||||
if(!M)
|
||||
return 0
|
||||
target = null //Target was our mecha, so null it out
|
||||
LoseTarget() //Target was our mecha, so null it out
|
||||
M.aimob_enter_mech(src)
|
||||
targets_from = M
|
||||
set_targets_from(M)
|
||||
allow_movement_on_non_turfs = TRUE //duh
|
||||
var/do_ranged = 0
|
||||
for(var/equip in mecha.equipment)
|
||||
@@ -97,14 +97,14 @@
|
||||
|
||||
mecha.aimob_exit_mech(src)
|
||||
allow_movement_on_non_turfs = FALSE
|
||||
targets_from = src
|
||||
set_targets_from(src)
|
||||
|
||||
//Find a new mecha
|
||||
wanted_objects = typecacheof(/obj/vehicle/sealed/mecha/combat, TRUE)
|
||||
var/search_aggressiveness = 2
|
||||
for(var/obj/vehicle/sealed/mecha/combat/C in range(vision_range,src))
|
||||
if(is_valid_mecha(C))
|
||||
target = C
|
||||
GiveTarget(C)
|
||||
search_aggressiveness = 3 //We can see a mech? RUN FOR IT, IGNORE MOBS!
|
||||
break
|
||||
search_objects = search_aggressiveness
|
||||
@@ -188,7 +188,7 @@
|
||||
return
|
||||
else
|
||||
if(!CanAttack(M))
|
||||
target = null
|
||||
LoseTarget()
|
||||
return
|
||||
|
||||
return target.attack_animal(src)
|
||||
@@ -201,7 +201,7 @@
|
||||
if(!mecha)
|
||||
for(var/obj/vehicle/sealed/mecha/combat/mecha_in_range in range(src,vision_range))
|
||||
if(is_valid_mecha(mecha_in_range))
|
||||
target = mecha_in_range //Let's nab it!
|
||||
GiveTarget(mecha_in_range) //Let's nab it!
|
||||
minimum_distance = 1
|
||||
ranged = 0
|
||||
break
|
||||
|
||||
@@ -311,7 +311,7 @@
|
||||
if(stat || swooping)
|
||||
return
|
||||
if(manual_target)
|
||||
target = manual_target
|
||||
GiveTarget(manual_target)
|
||||
if(!target)
|
||||
return
|
||||
stop_automated_movement = TRUE
|
||||
|
||||
@@ -90,6 +90,10 @@ Difficulty: Hard
|
||||
. = ..()
|
||||
spawned_beacon = new(loc)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/hierophant/Destroy()
|
||||
QDEL_NULL(spawned_beacon)
|
||||
. = ..()
|
||||
|
||||
/datum/action/innate/megafauna_attack/blink
|
||||
name = "Blink To Target"
|
||||
icon_icon = 'icons/mob/actions/actions_items.dmi'
|
||||
@@ -412,10 +416,6 @@ Difficulty: Hard
|
||||
set_stat(CONSCIOUS) // deathgasp won't run if dead, stupid
|
||||
..(force_grant = stored_nearby)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/hierophant/Destroy()
|
||||
qdel(spawned_beacon)
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/hierophant/devour(mob/living/L)
|
||||
for(var/obj/item/W in L)
|
||||
if(!L.dropItemToGround(W))
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
for(var/i = 1 to nest_range)
|
||||
closest = get_step(closest, get_dir(closest, src))
|
||||
forceMove(closest) // someone teleported out probably and the megafauna kept chasing them
|
||||
target = null
|
||||
LoseTarget()
|
||||
return
|
||||
return ..()
|
||||
|
||||
@@ -179,16 +179,15 @@
|
||||
name = "Megafauna Attack"
|
||||
icon_icon = 'icons/mob/actions/actions_animal.dmi'
|
||||
button_icon_state = ""
|
||||
var/mob/living/simple_animal/hostile/megafauna/M
|
||||
var/chosen_message
|
||||
var/chosen_attack_num = 0
|
||||
|
||||
/datum/action/innate/megafauna_attack/Grant(mob/living/L)
|
||||
if(istype(L, /mob/living/simple_animal/hostile/megafauna))
|
||||
M = L
|
||||
return ..()
|
||||
return FALSE
|
||||
if(!ismegafauna(L))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/action/innate/megafauna_attack/Activate()
|
||||
M.chosen_attack = chosen_attack_num
|
||||
to_chat(M, chosen_message)
|
||||
var/mob/living/simple_animal/hostile/megafauna/fauna = owner
|
||||
fauna.chosen_attack = chosen_attack_num
|
||||
to_chat(fauna, chosen_message)
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
G.is_burrowed = TRUE
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/goldgrub/GiveTarget(new_target)
|
||||
target = new_target
|
||||
add_target(new_target)
|
||||
if(target != null)
|
||||
if(istype(target, /obj/item/stack/ore))
|
||||
visible_message("<span class='notice'>The [name] looks at [target.name] with hungry eyes.</span>")
|
||||
|
||||
@@ -230,6 +230,8 @@
|
||||
if (T && AIStatus == AI_Z_OFF)
|
||||
SSidlenpcpool.idle_mobs_by_zlevel[T.z] -= src
|
||||
|
||||
//Walking counts as a reference, putting this here because most things don't walk, clean this up once walk() procs are dead
|
||||
walk(src, 0)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/vv_edit_var(var_name, var_value)
|
||||
|
||||
@@ -34,6 +34,10 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
|
||||
. = ..()
|
||||
soundloop = new(list(src), TRUE)
|
||||
|
||||
/obj/machinery/gravity_generator/main/Destroy()
|
||||
. = ..()
|
||||
QDEL_NULL(soundloop)
|
||||
|
||||
/obj/machinery/gravity_generator/safe_throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, diagonals_first = FALSE, datum/callback/callback, force = MOVE_FORCE_STRONG, gentle = FALSE)
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -114,17 +114,17 @@
|
||||
//Check for dangerous pressure differences
|
||||
if (turf_in_range.return_turf_delta_p() > DANGEROUS_DELTA_P)
|
||||
to_chat(actor, "<span class='warning'>Destroying this object has the potential to cause an explosive pressure release. Aborting.</span>")
|
||||
actor.target = null
|
||||
actor.LoseTarget()
|
||||
return TRUE
|
||||
//Check if breaking this door will expose the station to space/planetary atmos
|
||||
else if(turf_in_range.is_nearby_planetary_atmos() || isspaceturf(turf_in_range) || (!isonshuttle && (istype(turf_area, /area/shuttle) || istype(turf_area, /area/space))) || (isonshuttle && !istype(turf_area, /area/shuttle)))
|
||||
to_chat(actor, "<span class='warning'>Destroying this object has the potential to cause a hull breach. Aborting.</span>")
|
||||
actor.target = null
|
||||
actor.LoseTarget()
|
||||
return FALSE
|
||||
//Check if this door is important in supermatter containment
|
||||
else if(istype(turf_area, /area/engineering/supermatter))
|
||||
to_chat(actor, "<span class='warning'>Disrupting the containment of a supermatter crystal would not be to our benefit. Aborting.</span>")
|
||||
actor.target = null
|
||||
actor.LoseTarget()
|
||||
return FALSE
|
||||
actor.dis_integrate(src)
|
||||
return TRUE
|
||||
@@ -201,15 +201,15 @@
|
||||
var/area/turf_area = get_area(turf_in_range)
|
||||
if (turf_in_range.return_turf_delta_p() > DANGEROUS_DELTA_P)
|
||||
to_chat(actor, "<span class='warning'>Destroying this object has the potential to cause an explosive pressure release. Aborting.</span>")
|
||||
actor.target = null
|
||||
actor.LoseTarget()
|
||||
return TRUE
|
||||
else if(turf_in_range.is_nearby_planetary_atmos() || isspaceturf(turf_area) || (!isonshuttle && (istype(turf_area, /area/shuttle) || istype(turf_area, /area/space))) || (isonshuttle && !istype(turf_area, /area/shuttle) ))
|
||||
to_chat(actor, "<span class='warning'>Destroying this object has the potential to cause a hull breach. Aborting.</span>")
|
||||
actor.target = null
|
||||
actor.LoseTarget()
|
||||
return TRUE
|
||||
else if(istype(turf_area, /area/engineering/supermatter))
|
||||
to_chat(actor, "<span class='warning'>Disrupting the containment of a supermatter crystal would not be to our benefit. Aborting.</span>")
|
||||
actor.target = null
|
||||
actor.LoseTarget()
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
@@ -220,15 +220,15 @@
|
||||
var/area/turf_area = get_area(turf_in_range)
|
||||
if (turf_in_range.return_turf_delta_p() > DANGEROUS_DELTA_P)
|
||||
to_chat(actor, "<span class='warning'>Destroying this object has the potential to cause an explosive pressure release. Aborting.</span>")
|
||||
actor.target = null
|
||||
actor.LoseTarget()
|
||||
return TRUE
|
||||
else if(turf_in_range.is_nearby_planetary_atmos() || isspaceturf(turf_in_range) || (!is_on_shuttle && (istype(turf_area, /area/shuttle) || istype(turf_area, /area/space))) || (is_on_shuttle && !istype(turf_area, /area/shuttle)))
|
||||
to_chat(actor, "<span class='warning'>Destroying this object has the potential to cause a hull breach. Aborting.</span>")
|
||||
actor.target = null
|
||||
actor.LoseTarget()
|
||||
return TRUE
|
||||
else if(istype(turf_area, /area/engineering/supermatter))
|
||||
to_chat(actor, "<span class='warning'>Disrupting the containment of a supermatter crystal would not be to our benefit. Aborting.</span>")
|
||||
actor.target = null
|
||||
actor.LoseTarget()
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user