From e884e7644566d99dc78429dd1997923b6f06f694 Mon Sep 17 00:00:00 2001 From: Fox McCloud Date: Tue, 8 Oct 2019 20:57:39 -0400 Subject: [PATCH] Updates Swarmers: Fixes Swarmer Megafauna (#12516) --- code/datums/helper_datums/teleport.dm | 51 ++- .../gamemodes/miniantags/bot_swarm/swarmer.dm | 343 +++++++++++------- .../mob/living/simple_animal/hostile/bees.dm | 11 + .../living/simple_animal/hostile/hostile.dm | 6 +- 4 files changed, 269 insertions(+), 142 deletions(-) diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm index bb424a9afdf..2170ad4196e 100644 --- a/code/datums/helper_datums/teleport.dm +++ b/code/datums/helper_datums/teleport.dm @@ -185,4 +185,53 @@ if(istype(teleatom, /mob/living)) var/mob/living/MM = teleatom to_chat(MM, "The bluespace interface on your bag of holding interferes with the teleport!") - return 1 \ No newline at end of file + return 1 + +// Safe location finder +/proc/find_safe_turf(zlevel, list/zlevels, extended_safety_checks = FALSE) + if(!zlevels) + if(zlevel) + zlevels = list(zlevel) + else + zlevels = levels_by_trait(STATION_LEVEL) + var/cycles = 1000 + for(var/cycle in 1 to cycles) + // DRUNK DIALLING WOOOOOOOOO + var/x = rand(1, world.maxx) + var/y = rand(1, world.maxy) + var/z = pick(zlevels) + var/random_location = locate(x,y,z) + + if(!isfloorturf(random_location)) + continue + var/turf/simulated/floor/F = random_location + if(!F.air) + continue + + var/datum/gas_mixture/A = F.air + + // Can most things breathe? + if(A.trace_gases.len) + continue + if(A.oxygen < 16) + continue + if(A.toxins) + continue + if(A.carbon_dioxide >= 10) + continue + + // Aim for goldilocks temperatures and pressure + if((A.temperature <= 270) || (A.temperature >= 360)) + continue + var/pressure = A.return_pressure() + if((pressure <= 20) || (pressure >= 550)) + continue + + if(extended_safety_checks) + if(islava(F)) //chasms aren't /floor, and so are pre-filtered + var/turf/simulated/floor/plating/lava/L = F + if(!L.is_safe()) + continue + + // DING! You have passed the gauntlet, and are "probably" safe. + return F \ No newline at end of file diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm index d87ba8c057f..63905bc3390 100644 --- a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm +++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm @@ -1,15 +1,15 @@ ////Deactivated swarmer shell//// /obj/item/deactivated_swarmer name = "unactivated swarmer" - desc = "A currently unactivated swarmer. Swarmers can self activate at any time, it would be wise to immediately dispose of this." + desc = "A shell of swarmer that was completely powered down. It can no longer activate itself." icon = 'icons/mob/swarmer.dmi' icon_state = "swarmer_unactivated" origin_tech = "bluespace=4;materials=4;programming=7" - materials = list(MAT_METAL=100, MAT_GLASS=400) + materials = list(MAT_METAL=10000, MAT_GLASS=4000) /obj/effect/mob_spawn/swarmer name = "unactivated swarmer" - desc = "A currently unactivated swarmer. Swarmers can self activate at any time, it would be wise to immediately dispose of this." + desc = "A currently unactivated swarmer. Swarmers can self activate at any time, so it would be wise to immediately dispose of this." icon = 'icons/mob/swarmer.dmi' icon_state = "swarmer_unactivated" density = FALSE @@ -41,8 +41,8 @@ return to_chat(user, "Picking up the swarmer may cause it to activate. You should be careful about this.") -/obj/effect/mob_spawn/swarmer/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/screwdriver) && user.a_intent != INTENT_HARM) +/obj/effect/mob_spawn/swarmer/attackby(obj/item/I, mob/user, params) + if(isscrewdriver(I) && user.a_intent != INTENT_HARM) user.visible_message("[usr.name] deactivates [src].", "After some fiddling, you find a way to disable [src]'s power source.", "You hear clicking.") @@ -57,7 +57,7 @@ name = "Swarmer" real_name = "Swarmer" icon = 'icons/mob/swarmer.dmi' - desc = "A robot of unknown design, they seek only to consume materials and replicate themselves indefinitely." + desc = "Robotic constructs of unknown design, swarmers seek only to consume materials and replicate themselves indefinitely." speak_emote = list("tones") health = 40 maxHealth = 40 @@ -65,6 +65,7 @@ icon_state = "swarmer" icon_living = "swarmer" icon_dead = "swarmer_unactivated" + icon_gib = null wander = 0 harm_intent_damage = 5 minbodytemp = 0 @@ -75,8 +76,9 @@ melee_damage_upper = 15 melee_damage_type = STAMINA damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0) + hud_possible = list(SPECIALROLE_HUD, DIAG_STAT_HUD, DIAG_HUD) obj_damage = 0 - environment_smash = 0 + environment_smash = ENVIRONMENT_SMASH_NONE attacktext = "shocks" attack_sound = 'sound/effects/empulse.ogg' friendly = "pinches" @@ -84,23 +86,22 @@ a_intent = INTENT_HARM can_change_intents = 0 faction = list("swarmer") - projectiletype = /obj/item/projectile/beam/disabler + AIStatus = AI_OFF pass_flags = PASSTABLE mob_size = MOB_SIZE_SMALL - ventcrawler = 2 + ventcrawler = VENTCRAWLER_ALWAYS ranged = 1 - light_color = LIGHT_COLOR_CYAN + projectiletype = /obj/item/projectile/beam/disabler ranged_cooldown_time = 20 + projectilesound = 'sound/weapons/taser2.ogg' + loot = list(/obj/effect/decal/cleanable/robot_debris, /obj/item/stack/ore/bluespace_crystal) + del_on_death = 1 + deathmessage = "explodes with a sharp pop!" + light_color = LIGHT_COLOR_CYAN universal_speak = 0 universal_understand = 0 - projectilesound = 'sound/weapons/taser2.ogg' - AIStatus = AI_OFF var/resources = 0 //Resource points, generated by consuming metal/glass var/max_resources = 100 - loot = list(/obj/effect/decal/cleanable/blood/gibs/robot, /obj/item/stack/ore/bluespace_crystal/artificial) - deathmessage = "The swarmer explodes with a sharp pop!" - del_on_death = 1 - hud_possible = list(SPECIALROLE_HUD, DIAG_STAT_HUD, DIAG_HUD) /mob/living/simple_animal/hostile/swarmer/Login() ..() @@ -120,6 +121,10 @@ diag_hud.add_to_hud(src) updatename() +/mob/living/simple_animal/hostile/swarmer/proc/updatename() + real_name = "Swarmer [rand(100,999)]-[pick("kappa","sigma","beta","omicron","iota","epsilon","omega","gamma","delta","tau","alpha")]" + name = real_name + /mob/living/simple_animal/hostile/swarmer/med_hud_set_health() var/image/holder = hud_list[DIAG_HUD] var/icon/I = icon(icon, icon_state, dir) @@ -150,11 +155,6 @@ return 1 ..() -/mob/living/simple_animal/hostile/swarmer/proc/updatename() - real_name = "Swarmer [rand(100,999)]-[pick("kappa","sigma","beta","omicron","iota","epsilon","omega","gamma","delta","tau","alpha")]" - name = real_name - - ////CTRL CLICK FOR SWARMERS AND SWARMER_ACT()'S//// /mob/living/simple_animal/hostile/swarmer/AttackingTarget() if(!isliving(target)) @@ -171,11 +171,25 @@ if(!A.Adjacent(src)) return A.swarmer_act(src) - return /atom/proc/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) S.DisIntegrate(src) - return TRUE + return TRUE //return TRUE/FALSE whether or not an AI swarmer should try this swarmer_act() again, NOT whether it succeeded. + +/atom/movable/swarmer_act() + if(!simulated) + return FALSE + return ..() + +/obj/effect/mob_spawn/swarmer/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) + S.Integrate(src) + return FALSE //would logically be TRUE, but we don't want AI swarmers eating player spawn chances. + +/obj/effect/mob_spawn/swarmer/IntegrateAmount() + return 50 + +/turf/simulated/wall/indestructible/swarmer_act() + return FALSE /obj/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) if(resistance_flags & INDESTRUCTIBLE) @@ -187,13 +201,31 @@ return ..() /obj/item/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) - S.Integrate(src) + return S.Integrate(src) + +/atom/movable/proc/IntegrateAmount() + return 0 + +/obj/item/IntegrateAmount() //returns the amount of resources gained when eating this item + if(materials[MAT_METAL] || materials[MAT_GLASS]) + return 1 + return ..() + +/obj/item/gun/swarmer_act() //Stops you from eating the entire armory return FALSE -/atom/movable/swarmer_act() - if(!simulated) +/turf/simulated/floor/swarmer_act() //ex_act() on turf calls it on its contents, this is to prevent attacking mobs by DisIntegrate()'ing the floor + return FALSE + +/obj/structure/lattice/catwalk/swarmer_catwalk/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) + to_chat(S, "We have created these for our own benefit. Aborting.") + return FALSE + +/obj/structure/swarmer/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) + if(S.AIStatus == AI_ON) return FALSE - return ..() + else + return ..() /obj/effect/swarmer_act() return FALSE @@ -203,10 +235,12 @@ qdel(src) return TRUE -/obj/item/gun/swarmer_act()//Stops you from eating the entire armory +/obj/structure/flora/swarmer_act() return FALSE -/turf/simulated/floor/swarmer_act()//ex_act() on turf calls it on its contents, this is to prevent attacking mobs by DisIntegrate()'ing the floor +/turf/simulated/floor/plating/lava/swarmer_act() + if(!is_safe()) + new /obj/structure/lattice/catwalk/swarmer_catwalk(src) return FALSE /obj/machinery/atmospherics/swarmer_act() @@ -224,6 +258,17 @@ return TRUE /obj/machinery/door/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) + var/isonshuttle = istype(get_area(src), /area/shuttle) + for(var/turf/T in range(1, src)) + var/area/A = get_area(T) + if(isspaceturf(T) || (!isonshuttle && (istype(A, /area/shuttle) || istype(A, /area/space))) || (isonshuttle && !istype(A, /area/shuttle))) + to_chat(S, "Destroying this object has the potential to cause a hull breach. Aborting.") + S.target = null + return FALSE + else if(istype(A, /area/engine/supermatter)) + to_chat(S, "Disrupting the containment of a supermatter crystal would not be to our benefit. Aborting.") + S.target = null + return FALSE S.DisIntegrate(src) return TRUE @@ -316,27 +361,37 @@ return FALSE /turf/simulated/wall/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) + var/isonshuttle = istype(loc, /area/shuttle) for(var/turf/T in range(1, src)) - if(istype(T, /turf/space) || istype(T.loc, /area/space) || istype(T, /turf/simulated/floor/plating/airless)) + var/area/A = get_area(T) + if(isspaceturf(T) || (!isonshuttle && (istype(A, /area/shuttle) || istype(A, /area/space))) || (isonshuttle && !istype(A, /area/shuttle))) to_chat(S, "Destroying this object has the potential to cause a hull breach. Aborting.") - return FALSE + S.target = null + return TRUE + else if(istype(A, /area/engine/supermatter)) + to_chat(S, "Disrupting the containment of a supermatter crystal would not be to our benefit. Aborting.") + S.target = null + return TRUE return ..() /obj/structure/window/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) + var/isonshuttle = istype(get_area(src), /area/shuttle) for(var/turf/T in range(1, src)) - if(istype(T, /turf/space) || istype(T.loc, /area/space)) + var/area/A = get_area(T) + if(isspaceturf(T) || (!isonshuttle && (istype(A, /area/shuttle) || istype(A, /area/space))) || (isonshuttle && !istype(A, /area/shuttle))) to_chat(S, "Destroying this object has the potential to cause a hull breach. Aborting.") - return FALSE + S.target = null + return TRUE + else if(istype(A, /area/engine/supermatter)) + to_chat(S, "Disrupting the containment of a supermatter crystal would not be to our benefit. Aborting.") + S.target = null + return TRUE return ..() /obj/item/stack/cable_coil/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)//Wiring would be too effective as a resource to_chat(S, "This object does not contain enough materials to work with.") return FALSE -/obj/item/circuitboard/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) - to_chat(S, "This object does not contain enough materials to work with.") - return FALSE - /obj/machinery/porta_turret/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) to_chat(S, "Attempting to dismantle this machine would result in an immediate counterattack. Aborting.") return FALSE @@ -359,17 +414,33 @@ to_chat(S, "This biological resource is somehow resisting our bluespace transceiver. Aborting.") return FALSE -/obj/structure/lattice/catwalk/swarmer_catwalk/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) - to_chat(S, "We have created these for our own benefit. Aborting.") - return FALSE - /obj/structure/shuttle/engine/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) to_chat(S, "This shuttle may be important to us later. Aborting.") return FALSE +/obj/structure/lattice/catwalk/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) + . = ..() + var/turf/here = get_turf(src) + for(var/A in here.contents) + var/obj/structure/cable/C = A + if(istype(C)) + to_chat(S, "Disrupting the power grid would bring no benefit to us. Aborting.") + return FALSE + +/obj/item/deactivated_swarmer/IntegrateAmount() + return 50 + +/obj/machinery/hydroponics/soil/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) + to_chat(S, "This object does not contain enough materials to work with.") + return FALSE + +/obj/machinery/field/containment/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) + to_chat(S, "This object does not contain solid matter. Aborting.") + return FALSE + ////END CTRL CLICK FOR SWARMERS//// -/mob/living/simple_animal/hostile/swarmer/proc/Fabricate(var/atom/fabrication_object,var/fabrication_cost = 0) +/mob/living/simple_animal/hostile/swarmer/proc/Fabricate(atom/fabrication_object, fabrication_cost = 0) if(!isturf(loc)) to_chat(src, "This is not a suitable location for fabrication. We need more space.") if(resources >= fabrication_cost) @@ -377,95 +448,117 @@ else to_chat(src, "You do not have the necessary resources to fabricate this object.") return 0 - new fabrication_object(loc) - return 1 + return new fabrication_object(loc) -/mob/living/simple_animal/hostile/swarmer/proc/Integrate(var/obj/item/target) - if(resources >= max_resources) +/mob/living/simple_animal/hostile/swarmer/proc/Integrate(atom/movable/target) + var/resource_gain = target.IntegrateAmount() + if(resources + resource_gain > max_resources) to_chat(src, "We cannot hold more materials!") - return - //Check if any entries are either MAT_METAL or MAT_GLASS - if((MAT_METAL in target.materials) || (MAT_GLASS in target.materials)) - resources++ + return TRUE + if(resource_gain) + resources += resource_gain do_attack_animation(target) changeNext_move(CLICK_CD_MELEE) - var/obj/structure/swarmer/integrate/I = new /obj/structure/swarmer/integrate(get_turf(target)) + var/obj/effect/temp_visual/swarmer/integrate/I = new /obj/effect/temp_visual/swarmer/integrate(get_turf(target)) I.pixel_x = target.pixel_x I.pixel_y = target.pixel_y + I.pixel_z = target.pixel_z if(istype(target, /obj/item/stack)) var/obj/item/stack/S = target S.use(1) if(S.amount) - return + return TRUE qdel(target) + return TRUE else - to_chat(src, "\the [target] is incompatible with our internal matter recycler.") - return + to_chat(src, "[target] is incompatible with our internal matter recycler.") + return FALSE -/mob/living/simple_animal/hostile/swarmer/proc/DisIntegrate(var/atom/movable/target) - new /obj/structure/swarmer/disintegration(get_turf(target)) +/mob/living/simple_animal/hostile/swarmer/proc/DisIntegrate(atom/movable/target) + new /obj/effect/temp_visual/swarmer/disintegration(get_turf(target)) do_attack_animation(target) changeNext_move(CLICK_CD_MELEE) - target.ex_act(3) + target.ex_act(EXPLODE_LIGHT) /mob/living/simple_animal/hostile/swarmer/proc/DisperseTarget(var/mob/living/target) - if(target != src) - to_chat(src, "Attempting to remove this being from our presence.") - if(!is_station_level(src.z)) - to_chat(src, "Our bluespace transceiver cannot locate a viable bluespace link, our teleportation abilities are useless in this area.") - return - if(do_mob(src, target, 30)) - var/cycle - for(cycle=0,cycle<100,cycle++) - var/random_location = locate(rand(37,202),rand(75,192),level_name_to_num(MAIN_STATION))//Drunk dial a turf in the general ballpark of the station - if(istype(random_location, /turf/simulated/floor)) - var/turf/simulated/floor/F = random_location - if(F.air) - var/datum/gas_mixture/A = F.air - if(A.oxygen >= 16 && !A.toxins && A.carbon_dioxide < 10 && !A.trace_gases.len)//Can most things breathe in this location? - if((A.temperature > 270) && (A.temperature < 360))//Not too hot, not too cold - var/pressure = A.return_pressure() - if((pressure > 20) && (pressure < 550))//Account for crushing pressure or vaccuums - if(ishuman(target))//If we're getting rid of a human, slap some zipties on them to keep them away from us a little longer - var/obj/item/restraints/handcuffs/energy/used/Z = new /obj/item/restraints/handcuffs/energy/used(src) - Z.apply_cuffs(target, src) - do_teleport(target, F, 0) - playsound(src,'sound/effects/sparks4.ogg',50,1) - break - return + if(target == src) + return + + if(!is_station_level(z) && !is_mining_level(z)) + to_chat(src, "Our bluespace transceiver cannot locate a viable bluespace link, our teleportation abilities are useless in this area.") + return + + to_chat(src, "Attempting to remove this being from our presence.") + + if(!do_mob(src, target, 30)) + return + + var/turf/simulated/floor/F + F = find_safe_turf(zlevels = z, extended_safety_checks = TRUE) + + if(!F) + return + // If we're getting rid of a human, slap some energy cuffs on + // them to keep them away from us a little longer + + var/mob/living/carbon/human/H = target + if(ishuman(target) && (!H.handcuffed)) + var/obj/item/restraints/handcuffs/energy/used/Z = new /obj/item/restraints/handcuffs/energy/used(src) + Z.apply_cuffs(target, src) + + do_sparks(4, 0, target) + playsound(src,'sound/effects/sparks4.ogg', 50, TRUE) + do_teleport(target, F, 0) /mob/living/simple_animal/hostile/swarmer/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = FALSE, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE) if(!tesla_shock) return FALSE return ..() -/mob/living/simple_animal/hostile/swarmer/proc/DismantleMachine(var/obj/machinery/target) +/mob/living/simple_animal/hostile/swarmer/proc/DismantleMachine(obj/machinery/target) do_attack_animation(target) to_chat(src, "We begin to dismantle this machine. We will need to be uninterrupted.") - var/obj/structure/swarmer/dismantle/D = new /obj/structure/swarmer/dismantle(get_turf(target)) + var/obj/effect/temp_visual/swarmer/dismantle/D = new /obj/effect/temp_visual/swarmer/dismantle(get_turf(target)) D.pixel_x = target.pixel_x D.pixel_y = target.pixel_y + D.pixel_z = target.pixel_z if(do_mob(src, target, 100)) - if(!src.Adjacent(target)) - to_chat(src, "Error:Dismantling aborted.") - else - to_chat(src, "Dismantling complete.") - var/obj/item/stack/sheet/metal/M = new /obj/item/stack/sheet/metal(target.loc) - M.amount = 5 - if(target.component_parts && target.component_parts.len) - for(var/obj/item/I in target.component_parts) - I.forceMove(M.loc) - var/obj/structure/swarmer/disintegration/N = new /obj/structure/swarmer/disintegration(get_turf(target)) - N.pixel_x = target.pixel_x - N.pixel_y = target.pixel_y - target.dropContents() - if(istype(target, /obj/machinery/computer)) - var/obj/machinery/computer/C = target - if(C.circuit) - new C.circuit(get_turf(M)) - qdel(target) + to_chat(src, "Dismantling complete.") + var/atom/Tsec = target.drop_location() + new /obj/item/stack/sheet/metal(Tsec, 5) + for(var/obj/item/I in target.component_parts) + I.forceMove(Tsec) + var/obj/effect/temp_visual/swarmer/disintegration/N = new /obj/effect/temp_visual/swarmer/disintegration(get_turf(target)) + N.pixel_x = target.pixel_x + N.pixel_y = target.pixel_y + N.pixel_z = target.pixel_z + target.dropContents() + if(istype(target, /obj/machinery/computer)) + var/obj/machinery/computer/C = target + if(C.circuit) + new C.circuit(Tsec) + qdel(target) +/obj/effect/temp_visual/swarmer //temporary swarmer visual feedback objects + icon = 'icons/mob/swarmer.dmi' + layer = BELOW_MOB_LAYER + +/obj/effect/temp_visual/swarmer/disintegration + icon_state = "disintegrate" + duration = 10 + +/obj/effect/temp_visual/swarmer/disintegration/Initialize(mapload) + . = ..() + playsound(loc, "sparks", 100, TRUE) + +/obj/effect/temp_visual/swarmer/dismantle + icon_state = "dismantle" + duration = 25 + +/obj/effect/temp_visual/swarmer/integrate + icon_state = "integrate" + duration = 5 /obj/structure/swarmer //Default swarmer effect object visual feedback name = "swarmer ui" @@ -474,15 +567,14 @@ icon = 'icons/mob/swarmer.dmi' icon_state = "ui_light" layer = MOB_LAYER - anchored = 1 - light_range = 1 - mouse_opacity = MOUSE_OPACITY_ICON - max_integrity = 30 + anchored = TRUE resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF light_color = LIGHT_COLOR_CYAN + max_integrity = 30 + anchored = TRUE var/lon_range = 1 -/obj/structure/swarmer/New() +/obj/structure/swarmer/Initialize(mapload) . = ..() set_light(lon_range) @@ -493,38 +585,16 @@ if(BURN) playsound(src, 'sound/items/welder.ogg', 100, TRUE) -/obj/structure/swarmer/disintegration - icon_state = "disintegrate" - -/obj/structure/swarmer/disintegration/New() - playsound(src.loc, "sparks", 100, 1) - spawn(10) - qdel(src) - -/obj/structure/swarmer/dismantle - icon_state = "dismantle" - -/obj/structure/swarmer/dismantle/New() - spawn(25) - qdel(src) - -/obj/structure/swarmer/integrate - icon_state = "integrate" - -/obj/structure/swarmer/integrate/New() - spawn(5) - qdel(src) - /obj/structure/swarmer/emp_act() + ..() qdel(src) /obj/structure/swarmer/trap name = "swarmer trap" desc = "A quickly assembled trap that electrifies living beings and overwhelms machine sensors. Will not retain its form if damaged enough." icon_state = "trap" - light_range = 1 - light_color = LIGHT_COLOR_CYAN max_integrity = 10 + density = FALSE /obj/structure/swarmer/trap/Crossed(var/atom/movable/AM, oldloc) if(isliving(AM)) @@ -546,6 +616,7 @@ return Fabricate(/obj/structure/swarmer/trap, 5) + /mob/living/simple_animal/hostile/swarmer/proc/CreateBarricade() set name = "Create barricade" set category = "Swarmer" @@ -559,15 +630,13 @@ if(do_mob(src, src, 10)) Fabricate(/obj/structure/swarmer/blockade, 5) + /obj/structure/swarmer/blockade name = "swarmer blockade" desc = "A quickly assembled energy blockade. Will not retain its form if damaged enough, but disabler beams and swarmers pass right through." icon_state = "barricade" - light_range = 1 - light_color = LIGHT_COLOR_CYAN + light_range = MINIMUM_USEFUL_LIGHT_RANGE max_integrity = 50 - density = 1 - anchored = 1 /obj/structure/swarmer/blockade/CanPass(atom/movable/O) if(isswarmer(O)) @@ -589,11 +658,13 @@ if(do_mob(src, src, 100)) var/createtype = SwarmerTypeToCreate() if(createtype && Fabricate(createtype, 50)) - playsound(loc,'sound/items/poster_being_created.ogg',50, 1, -1) + playsound(loc,'sound/items/poster_being_created.ogg',50, TRUE, -1) + /mob/living/simple_animal/hostile/swarmer/proc/SwarmerTypeToCreate() return /obj/effect/mob_spawn/swarmer + /mob/living/simple_animal/hostile/swarmer/proc/RepairSelf() set name = "Self Repair" set category = "Swarmer" @@ -616,4 +687,4 @@ if(message) for(var/mob/M in GLOB.mob_list) if(isswarmer(M) || (M in GLOB.dead_mob_list)) - to_chat(M, "Swarm communication - [src] states: [message]") + to_chat(M, "Swarm communication - [src] states: [message]") \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/bees.dm b/code/modules/mob/living/simple_animal/hostile/bees.dm index 6349c50851d..c6586fefa2f 100644 --- a/code/modules/mob/living/simple_animal/hostile/bees.dm +++ b/code/modules/mob/living/simple_animal/hostile/bees.dm @@ -83,6 +83,17 @@ if(!bee_syndicate && !beehome) . += "This bee is homeless!" +/mob/living/simple_animal/hostile/poison/bees/ListTargets() // Bee processing is expessive, so we override them finding targets here. + if(!search_objects) //In case we want to have purely hostile bees + return ..() + else + . = list() // The following code is only very slightly slower than just returning oview(vision_range, targets_from), but it saves us much more work down the line + var/list/searched_for = oview(vision_range, targets_from) + for(var/obj/A in searched_for) + . += A + for(var/mob/A in searched_for) + . += A + /mob/living/simple_animal/hostile/poison/bees/proc/generate_bee_visuals() overlays.Cut() diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 41ed10288c3..c5749e939c4 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -137,11 +137,7 @@ if(can_see(targets_from, HM, vision_range)) . += HM else - . = list() // The following code is only very slightly slower than just returning oview(vision_range, targets_from), but it saves us much more work down the line, particularly when bees are involved - for(var/obj/A in oview(vision_range, targets_from)) - . += A - for(var/mob/A in oview(vision_range, targets_from)) - . += A + . = oview(vision_range, targets_from) /mob/living/simple_animal/hostile/proc/FindTarget(var/list/possible_targets, var/HasTargetsList = 0)//Step 2, filter down possible targets to things we actually care about . = list()