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()