diff --git a/code/game/objects/effects/projectile/projectile_impact.dm b/code/game/objects/effects/projectile/projectile_impact.dm
index ef6ac8659ed..125f4c8b4fe 100644
--- a/code/game/objects/effects/projectile/projectile_impact.dm
+++ b/code/game/objects/effects/projectile/projectile_impact.dm
@@ -71,3 +71,7 @@
name = "xray impact"
icon_state = "impact_tachyon"
light_color = LIGHT_COLOR_RED
+
+/obj/effect/projectile/impact/bfg
+ icon_state = "impact_bfg"
+ light_color = LIGHT_COLOR_GREEN
diff --git a/code/game/objects/effects/projectile/projectile_muzzle.dm b/code/game/objects/effects/projectile/projectile_muzzle.dm
index a7c479095fa..702f4643204 100644
--- a/code/game/objects/effects/projectile/projectile_muzzle.dm
+++ b/code/game/objects/effects/projectile/projectile_muzzle.dm
@@ -7,7 +7,7 @@
light_color = LIGHT_COLOR_RED
/obj/effect/projectile/muzzle/laser/blue
- icon_state = "muzzle_laser_blue"
+ icon_state = "muzzle_blue"
light_color = LIGHT_COLOR_BLUE
/obj/effect/projectile/muzzle/disabler
@@ -70,4 +70,8 @@
light_color = LIGHT_COLOR_FIRE
/obj/effect/projectile/muzzle/gauss
- icon_state = "muzzle_gauss"
\ No newline at end of file
+ icon_state = "muzzle_gauss"
+
+/obj/effect/projectile/muzzle/bfg
+ icon_state = "muzzle_bfg"
+ light_color = LIGHT_COLOR_GREEN
diff --git a/code/game/objects/effects/projectile/projectile_tracer.dm b/code/game/objects/effects/projectile/projectile_tracer.dm
index 62776d7fcc1..d36fde88a50 100644
--- a/code/game/objects/effects/projectile/projectile_tracer.dm
+++ b/code/game/objects/effects/projectile/projectile_tracer.dm
@@ -82,3 +82,7 @@
name = "particle beam"
icon_state = "invisible"
light_color = LIGHT_COLOR_VIOLET
+
+/obj/effect/projectile/tracer/bfg
+ icon_state = "bfg"
+ light_color = LIGHT_COLOR_GREEN
diff --git a/code/modules/events/infestation.dm b/code/modules/events/infestation.dm
index 287c53c013b..a611d4389c1 100644
--- a/code/modules/events/infestation.dm
+++ b/code/modules/events/infestation.dm
@@ -48,9 +48,15 @@
switch(chosen_mob)
if(INFESTATION_HIVEBOTS)
- event_name = "Minor Hivebot Invasion"
+ event_name = "Hivebot Invasion"
chosen_verb = "have invaded"
- chosen_mob_types += /mob/living/simple_animal/hostile/hivebot/tele
+ var/list/beacon_types = list(
+ /mob/living/simple_animal/hostile/hivebotbeacon = 1,
+ /mob/living/simple_animal/hostile/hivebotbeacon/toxic = 1,
+ /mob/living/simple_animal/hostile/hivebotbeacon/incendiary = 1
+ )
+ chosen_mob_types += pickweight(beacon_types)
+
if(INFESTATION_SPACE_BATS)
event_name = "Space Bat Nest"
chosen_verb = "have been breeding in"
diff --git a/code/modules/mob/living/simple_animal/hostile/hivebot.dm b/code/modules/mob/living/simple_animal/hostile/hivebot.dm
index a5946f70a8c..18122684e70 100644
--- a/code/modules/mob/living/simple_animal/hostile/hivebot.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hivebot.dm
@@ -2,24 +2,61 @@
#define RANGED 2
#define RAPID 3
-/obj/item/projectile/hivebotbullet
+/obj/item/projectile/bullet/pistol/hivebotspike
+ name = "spike"
damage = 10
- damage_type = BRUTE
+ sharp = 1
+ embed = 0
+
+/obj/item/projectile/bullet/pistol/hivebotspike/needle
+ name = "needle"
+ damage = 5
+
+/obj/item/projectile/beam/hivebotdischarge
+ name = "electrical discharge"
+ damage = 3
+ damage_type = HALLOSS
+ taser_effect = 1
+ agony = 20
+ nodamage = 1
+ armor_penetration = 30
+ muzzle_type = /obj/effect/projectile/muzzle/stun
+ tracer_type = /obj/effect/projectile/tracer/stun
+ impact_type = /obj/effect/projectile/impact/stun
+
+/obj/item/projectile/beam/hivebotbeam
+ name = "concentrated gamma burst"
+ damage = 12
+ damage_type = TOX
+ irradiate = 30
+ agony = 30
+ armor_penetration = 30
+ muzzle_type = /obj/effect/projectile/muzzle/bfg
+ tracer_type = /obj/effect/projectile/tracer/bfg
+ impact_type = /obj/effect/projectile/impact/bfg
+
+/obj/item/projectile/beam/hivebotincendiary
+ name = "archaic energy welder"
+ damage = 10
+ incinerate = 3
+ muzzle_type = /obj/effect/projectile/muzzle/laser/blue
+ tracer_type = /obj/effect/projectile/tracer/laser/blue
+ impact_type = /obj/effect/projectile/impact/laser/blue
/mob/living/simple_animal/hostile/hivebot
name = "Hivebot"
- desc = "A small robot"
+ desc = "A primitive in design, hovering robot, with some menacing looking blades jutting out from it. It bears no manufacturer markings of any kind."
icon = 'icons/mob/npc/hivebot.dmi'
- icon_state = "basic"
- icon_living = "basic"
- icon_dead = "basic"
- health = 15
- maxHealth = 15
- melee_damage_lower = 2
- melee_damage_upper = 3
- attacktext = "clawed"
- projectilesound = 'sound/weapons/gunshot/gunshot1.ogg'
- projectiletype = /obj/item/projectile/hivebotbullet
+ icon_state = "hivebot"
+ health = 10
+ maxHealth = 10
+ harm_intent_damage = 3
+ melee_damage_lower = 10
+ melee_damage_upper = 10
+ break_stuff_probability = 25
+ attacktext = "slashed"
+ projectilesound = 'sound/weapons/bladeslice.ogg'
+ projectiletype = /obj/item/projectile/bullet/pistol/hivebotspike
faction = "hivebot"
min_oxy = 0
max_oxy = 0
@@ -31,85 +68,210 @@
max_n2 = 0
minbodytemp = 0
speed = 4
-
tameable = FALSE
+ flying = 1
+ see_in_dark = 8
+ pass_flags = PASSTABLE
+ attack_emote = "focuses on"
+ var/mob/living/simple_animal/hostile/hivebotbeacon/linked_parent = null
/mob/living/simple_animal/hostile/hivebot/range
name = "Hivebot"
- desc = "A smallish robot, this one is armed!"
+ desc = "A primitive in design, hovering robot, with a simple looking launcher sticking out of it. It bears no manufacturer markings of any kind."
+ icon_state = "hivebotranged"
ranged = 1
smart = TRUE
/mob/living/simple_animal/hostile/hivebot/range/rapid
+ projectiletype = /obj/item/projectile/bullet/pistol/hivebotspike/needle
rapid = 1
-/mob/living/simple_animal/hostile/hivebot/range/strong
- name = "Strong Hivebot"
- desc = "A robot, this one is armed and looks tough!"
- health = 80
+//Creates a reference to its parent beacon on init.
+/mob/living/simple_animal/hostile/hivebot/Initialize(mapload,mob/living/simple_animal/hostile/hivebot/hivebotbeacon)
+ if(hivebotbeacon)
+ linked_parent = hivebotbeacon
+ .=..()
/mob/living/simple_animal/hostile/hivebot/death()
- ..()
- visible_message("[src] blows apart!")
- new /obj/effect/decal/cleanable/blood/gibs/robot(src.loc)
- spark(src, 3, alldirs)
+ ..(null,"blows apart!")
+ var/T = get_turf(src)
+ new /obj/effect/gibspawner/robot(T)
+ spark(T, 1, alldirs)
+ qdel(src)
+
+/mob/living/simple_animal/hostile/hivebot/Destroy()
+ . = ..()
+ if(linked_parent)
+ linked_parent.linked_bots -= src
+
+/mob/living/simple_animal/hostile/hivebot/think()
+ . =..()
+ if(stance == HOSTILE_STANCE_IDLE)
+ icon_state = "[initial(icon_state)]"
+ else
+ icon_state = "[initial(icon_state)]_armed"
+
+/mob/living/simple_animal/hostile/hivebot/proc/wakeup()
+ stance = HOSTILE_STANCE_IDLE
+
+/mob/living/simple_animal/hostile/hivebot/emp_act(severity)
+ LoseTarget()
+ stance = HOSTILE_STANCE_TIRED
+ addtimer(CALLBACK(src, .proc/wakeup), 150)
+ if(severity == 1.0)
+ apply_damage(10)
+
+/mob/living/simple_animal/hostile/hivebotbeacon
+ name = "Hivebot beacon"
+ desc = "An odd and primitive looking machine. It emanates of strange and powerful energies. It bears no manufacturer markings of any kind."
+ icon = 'icons/mob/npc/hivebot.dmi'
+ icon_state = "hivebotbeacon_active"
+ icon_living = "hivebotbeacon_active"
+ health = 200
+ maxHealth = 200
+ projectilesound = 'sound/weapons/taser2.ogg'
+ projectiletype = /obj/item/projectile/beam/hivebotdischarge
+ wander = 0
+ status_flags = 0
+ faction = "hivebot"
+ ranged = 1
+ rapid = 1
+ min_oxy = 0
+ max_oxy = 0
+ min_tox = 0
+ max_tox = 0
+ min_co2 = 0
+ max_co2 = 0
+ min_n2 = 0
+ max_n2 = 0
+ minbodytemp = 0
+ speed = -10
+ see_in_dark = 8
+ smart = 1
+ destroy_surroundings = 0
+ var/bot_type = NORMAL // type of bot, 1 is normal, 2 is ranged, 3 is rapid ranged
+ var/bot_amt = 48 //Number of total bots that are spawned before the beacon disappears completely.
+ var/max_bots = 16 //Number of bots linked to this beacon specifically that can exist, before spawning more is halted.
+ var/list/linked_bots = list()
+ var/spawn_delay = 300
+ var/activated = 0
+ var/snoozing = 0 //If set to 1, it will be prevented from spawning bots, unless it spots an enemy.
+ attack_emote = "focuses on"
+
+/mob/living/simple_animal/hostile/hivebotbeacon/toxic
+ projectiletype = /obj/item/projectile/beam/hivebotbeam
+ projectilesound = 'sound/weapons/laser3.ogg'
+ rapid = 0
+
+/mob/living/simple_animal/hostile/hivebotbeacon/incendiary
+ projectiletype = /obj/item/projectile/beam/hivebotincendiary
+ projectilesound = 'sound/weapons/plasma_cutter.ogg'
+ rapid = 0
+
+/mob/living/simple_animal/hostile/hivebotbeacon/Initialize(mapload)
+ .=..()
+ if(!mapload)
+ var/datum/effect/effect/system/smoke_spread/S = new /datum/effect/effect/system/smoke_spread()
+ S.set_up(5, 0, src.loc)
+ S.start()
+
+ icon_state = "hivebotbeacon_off"
+ visible_message("[src] warps in!")
+ playsound(src.loc, 'sound/effects/EMPulse.ogg', 25, 1)
+
+/mob/living/simple_animal/hostile/hivebotbeacon/death()
+ ..(null,"blows apart and erupts in a cloud of noxious smoke!")
+ new /obj/effect/decal/cleanable/greenglow(src.loc)
+ var/T = get_turf(src)
+ new /obj/effect/gibspawner/robot(T)
+ spark(T, 3, alldirs)
qdel(src)
return
-/mob/living/simple_animal/hostile/hivebot/tele//this still needs work
- name = "Beacon"
- desc = "Some odd beacon thing"
- icon_state = "def_radar-off"
- icon_living = "def_radar-off"
- health = 200
- maxHealth = 200
- status_flags = 0
- anchored = 1
- stop_automated_movement = 1
- var/bot_type = NORMAL // type of bot, 1 is normal, 2 is ranged, 3 is rapid rnaged.
- var/bot_amt = 10
- var/spawn_delay = 600
+/mob/living/simple_animal/hostile/hivebotbeacon/Destroy()
+ for (var/mob/living/simple_animal/hostile/hivebot/latest_child in linked_bots)
+ latest_child.linked_parent = null
+ linked_bots.Cut()
+ var/datum/effect/effect/system/smoke_spread/S = new /datum/effect/effect/system/smoke_spread()
+ S.set_up(5, 0, src.loc)
+ S.start()
+ .=..()
-/mob/living/simple_animal/hostile/hivebot/tele/New()
- ..()
- var/datum/effect/effect/system/smoke_spread/smoke = new /datum/effect/effect/system/smoke_spread()
- smoke.set_up(5, 0, src.loc)
- smoke.start()
- visible_message("\The [src] warps in!")
- playsound(src.loc, 'sound/effects/EMPulse.ogg', 25, 1)
+/mob/living/simple_animal/hostile/hivebotbeacon/think()
+ . =..()
+ if(stance != HOSTILE_STANCE_IDLE && activated == 0)
+ visible_message("[src] suddenly activates!")
+ icon_state = "hivebotbeacon_raising"
+ addtimer(CALLBACK(src, .proc/reset_activation), 16)
+ else if(activated == 1)
+ icon_state = "hivebotbeacon_active"
-/mob/living/simple_animal/hostile/hivebot/tele/proc/warpbots()
+/mob/living/simple_animal/hostile/hivebotbeacon/MoveToTarget()
+ ..()
+ walk(src, 0)
+/mob/living/simple_animal/hostile/hivebotbeacon/proc/reset_activation()
+ icon_state = "hivebotbeacon_active"
+ activated = 1
+ snoozing = 0
+
+/mob/living/simple_animal/hostile/hivebotbeacon/emp_act(severity)
+ LoseTarget()
+ stance = HOSTILE_STANCE_TIRED
+ addtimer(CALLBACK(src, .proc/wakeup), 200)
+ if(severity == 1.0)
+ apply_damage(80)
+ icon_state = "hivebotbeacon_off"
+ activated = -1
+
+/mob/living/simple_animal/hostile/hivebotbeacon/proc/wakeup()
+ stance = HOSTILE_STANCE_IDLE
+ activated = 0
+
+/mob/living/simple_animal/hostile/hivebotbeacon/proc/warpbots()
if(!bot_amt)
+ visible_message("[src] disappears in a cloud of smoke!")
+ playsound(src.loc, 'sound/effects/teleport.ogg', 25, 1)
+ new /obj/effect/decal/cleanable/greenglow(src.loc)
qdel(src)
return
- icon_state = "def_radar"
- visible_message("\The [src] turns on!")
-
- switch(bot_type)
- if(NORMAL)
- new /mob/living/simple_animal/hostile/hivebot(get_turf(src))
- if(RANGED)
- new /mob/living/simple_animal/hostile/hivebot/range(get_turf(src))
- if(RAPID)
- new /mob/living/simple_animal/hostile/hivebot/range/rapid(get_turf(src))
-
- if(prob(30))
- if(prob(20))
- bot_type = RAPID
+ if(activated != 1)
+ if(activated == -1)
+ return
else
- bot_type = RANGED
- else
- bot_type = NORMAL
- bot_amt--
- addtimer(CALLBACK(src, .proc/warpbots, spawn_delay))
+ icon_state = "hivebotbeacon_raising"
+ sleep(16)
+ icon_state = "hivebotbeacon_active"
+ sleep(4)
+ activated = 1
+ if(linked_bots.len < max_bots)
+ visible_message("[src] radiates with energy!")
+ var/mob/living/simple_animal/hostile/hivebot/latest_child
+ switch(bot_type)
+ if(NORMAL)
+ latest_child = new /mob/living/simple_animal/hostile/hivebot(get_turf(src), src)
+ if(RANGED)
+ latest_child = new /mob/living/simple_animal/hostile/hivebot/range(get_turf(src), src)
+ if(RAPID)
+ latest_child = new /mob/living/simple_animal/hostile/hivebot/range/rapid(get_turf(src), src)
+ linked_bots += latest_child //Adds the spawned hivebot to the list of the beacon's children.
+ if(prob(30))
+ if(prob(65))
+ bot_type = RANGED
+ else
+ bot_type = RAPID
+ else
+ bot_type = NORMAL
+ bot_amt--
+ if(bot_amt>0 && linked_bots.len < max_bots)
+ addtimer(CALLBACK(src, .proc/warpbots), spawn_delay)
-/mob/living/simple_animal/hostile/hivebot/tele/Life()
+/mob/living/simple_animal/hostile/hivebotbeacon/Life()
..()
if(stat == 0)
- if(prob(2))//Might be a bit low, will mess with it likely
+ if((!snoozing) && (prob(2)))
warpbots()
#undef NORMAL
diff --git a/code/modules/research/xenoarchaeology/artifact/artifact_unknown.dm b/code/modules/research/xenoarchaeology/artifact/artifact_unknown.dm
index aaa162e1bb0..94e24e258da 100644
--- a/code/modules/research/xenoarchaeology/artifact/artifact_unknown.dm
+++ b/code/modules/research/xenoarchaeology/artifact/artifact_unknown.dm
@@ -285,7 +285,7 @@
/obj/machinery/artifact/bullet_act(var/obj/item/projectile/P)
if(istype(P,/obj/item/projectile/bullet) ||\
- istype(P,/obj/item/projectile/hivebotbullet))
+ istype(P,/obj/item/projectile/bullet/pistol/hivebotspike))
if(my_effect.trigger == TRIGGER_FORCE)
my_effect.ToggleActivate()
if(secondary_effect && secondary_effect.trigger == TRIGGER_FORCE && prob(25))
diff --git a/html/changelogs/[Ferner]-[060419-sprites_hivebots].yml b/html/changelogs/[Ferner]-[060419-sprites_hivebots].yml
new file mode 100644
index 00000000000..307b2e58266
--- /dev/null
+++ b/html/changelogs/[Ferner]-[060419-sprites_hivebots].yml
@@ -0,0 +1,42 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+# balance
+# admin
+# backend
+# security
+# refactor
+#################################
+
+# Your name.
+author: Ferner, Kyres1
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - imageadd: "Replaced the sprites of hivebots with new versions by Kyres1."
+ - tweak: "Tweaked, fixed and enhanced the behaviour of hivebot beacons."
diff --git a/icons/mob/npc/hivebot.dmi b/icons/mob/npc/hivebot.dmi
index cb13996361c..2b84314d8c8 100644
Binary files a/icons/mob/npc/hivebot.dmi and b/icons/mob/npc/hivebot.dmi differ