diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm
index 1d5d419ba82..9e32705fc90 100644
--- a/code/_onclick/hud/alert.dm
+++ b/code/_onclick/hud/alert.dm
@@ -366,6 +366,25 @@ so as to remain in compliance with the most up-to-date laws."
desc = "Mech integrity is low."
icon_state = "low_mech_integrity"
+//GUARDIANS
+/obj/screen/alert/cancharge
+ name = "Charge Ready"
+ desc = "You are ready to charge at a location!"
+ icon_state = "guardian_charge"
+ alerttooltipstyle = "parasite"
+
+/obj/screen/alert/canstealth
+ name = "Stealth Ready"
+ desc = "You are ready to enter stealth!"
+ icon_state = "guardian_canstealth"
+ alerttooltipstyle = "parasite"
+
+/obj/screen/alert/instealth
+ name = "In Stealth"
+ desc = "You are in stealth and your next attack will do bonus damage!"
+ icon_state = "guardian_instealth"
+ alerttooltipstyle = "parasite"
+
//GHOSTS
//TODO: expand this system to replace the pollCandidates/CheckAntagonist/"choose quickly"/etc Yes/No messages
diff --git a/code/game/gamemodes/miniantags/guardian/guardian.dm b/code/game/gamemodes/miniantags/guardian/guardian.dm
index 4825dea6ebb..b6f240b8319 100644
--- a/code/game/gamemodes/miniantags/guardian/guardian.dm
+++ b/code/game/gamemodes/miniantags/guardian/guardian.dm
@@ -39,40 +39,43 @@
var/bio_fluff_string = "Your scarabs fail to mutate. This shouldn't happen! Submit a bug report!"
var/admin_fluff_string = "URK URF!"//the wheels on the bus...
var/adminseal = FALSE
+ var/name_color = "white"//only used with protector shields for the time being
/mob/living/simple_animal/hostile/guardian/Life() //Dies if the summoner dies
..()
if(summoner)
if(summoner.stat == DEAD)
to_chat(src, "Your summoner has died!")
- visible_message("The [src] dies along with its user!")
+ visible_message("The [src] dies along with its user!")
ghostize()
qdel(src)
- if(summoner)
- if(get_dist(get_turf(summoner),get_turf(src)) <= range)
- return
- else
- to_chat(src, "You moved out of range, and were pulled back! You can only move [range] meters from [summoner.real_name]")
- visible_message("The [src] jumps back to its user.")
- Recall()
+ snapback()
if(summoned && !summoner && !adminseal)
to_chat(src, "You somehow lack a summoner! As a result, you dispel!")
ghostize()
qdel()
-/mob/living/simple_animal/hostile/guardian/Move() //Returns to summoner if they move out of range
- ..()
+/mob/living/simple_animal/hostile/guardian/proc/snapback()
if(summoner)
if(get_dist(get_turf(summoner),get_turf(src)) <= range)
return
else
- to_chat(src, "You moved out of range, and were pulled back! You can only move [range] meters from [summoner.real_name]")
- visible_message("The [src] jumps back to its user.")
- Recall()
+ to_chat(src, "You moved out of range, and were pulled back! You can only move [range] meters from [summoner.real_name]!")
+ visible_message("\The [src] jumps back to its user.")
+ if(istype(summoner.loc, /obj/effect))
+ Recall(TRUE)
+ else
+ new /obj/effect/overlay/temp/guardian/phase/out(loc)
+ forceMove(summoner.loc) //move to summoner's tile, don't recall
+ new /obj/effect/overlay/temp/guardian/phase(loc)
+
+/mob/living/simple_animal/hostile/guardian/Move() //Returns to summoner if they move out of range
+ ..()
+ snapback()
/mob/living/simple_animal/hostile/guardian/death(gibbed)
..()
- to_chat(summoner, "Your [name] died somehow!")
+ to_chat(summoner, "Your [name] died somehow!")
summoner.death()
@@ -93,10 +96,10 @@
return
summoner.adjustBruteLoss(damage)
if(damage)
- to_chat(summoner, "Your [name] is under attack! You take damage!")
- summoner.visible_message("Blood sprays from [summoner] as [src] takes damage!")
+ to_chat(summoner, "Your [name] is under attack! You take damage!")
+ summoner.visible_message("Blood sprays from [summoner] as [src] takes damage!")
if(summoner.stat == UNCONSCIOUS)
- to_chat(summoner, "Your body can't take the strain of sustaining [src] in this condition, it begins to fall apart!")
+ to_chat(summoner, "Your body can't take the strain of sustaining [src] in this condition, it begins to fall apart!")
summoner.adjustCloneLoss(damage/2)
/mob/living/simple_animal/hostile/guardian/ex_act(severity, target)
@@ -112,7 +115,7 @@
/mob/living/simple_animal/hostile/guardian/gib()
if(summoner)
- to_chat(summoner, "Your [src] was blown up!")
+ to_chat(summoner, "Your [src] was blown up!")
summoner.Weaken(10)// your fermillier has died! ROLL FOR CON LOSS!
ghostize()
qdel(src)
@@ -128,8 +131,8 @@
src.client.eye = loc
cooldown = world.time + 30
-/mob/living/simple_animal/hostile/guardian/proc/Recall()
- if(cooldown > world.time)
+/mob/living/simple_animal/hostile/guardian/proc/Recall(forced = FALSE)
+ if(cooldown > world.time && !forced)
return
if(!summoner) return
new /obj/effect/overlay/temp/guardian/phase/out(get_turf(src))
@@ -141,7 +144,6 @@
var/input = stripped_input(src, "Please enter a message to tell your summoner.", "Guardian", "")
if(!input) return
-
for(var/mob/M in mob_list)
if(M == summoner)
to_chat(M, "[src]: [input]")
@@ -151,7 +153,7 @@
to_chat(src, "[src]: [input]")
/mob/living/simple_animal/hostile/guardian/proc/ToggleMode()
- to_chat(src, "You dont have another mode!")
+ to_chat(src, "You dont have another mode!")
/mob/living/proc/guardian_comm()
@@ -212,456 +214,6 @@
to_chat(src, "You deactivate your light.")
light_on = !light_on
-//////////////////////////TYPES OF GUARDIANS
-
-
-//Fire. Low damage, low resistance, sets mobs on fire when bumping
-
-/mob/living/simple_animal/hostile/guardian/fire
- a_intent = INTENT_HELP
- melee_damage_lower = 10
- melee_damage_upper = 10
- attack_sound = 'sound/items/Welder.ogg'
- attacktext = "sears"
- damage_transfer = 0.8
- range = 10
- playstyle_string = "As a Chaos type, you have only light damage resistance, but will ignite any enemy you bump into. In addition, your melee attacks will randomly teleport enemies."
- environment_smash = 1
- magic_fluff_string = "..And draw the Wizard, bringer of endless chaos!"
- tech_fluff_string = "Boot sequence complete. Crowd control modules activated. Holoparasite swarm online."
- bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, ready to sow havoc at random."
- var/toggle = FALSE
-
-/mob/living/simple_animal/hostile/guardian/fire/Life() //Dies if the summoner dies
- ..()
- if(summoner)
- summoner.ExtinguishMob()
- summoner.adjust_fire_stacks(-20)
-
-/mob/living/simple_animal/hostile/guardian/fire/ToggleMode()
- if(src.loc == summoner)
- if(toggle)
- to_chat(src, "You switch to dispersion mode, and will teleport victims away from your master.")
- toggle = FALSE
- else
- to_chat(src, "You switch to deception mode, and will turn your victims against their allies.")
- toggle = TRUE
-
-/mob/living/simple_animal/hostile/guardian/fire/AttackingTarget()
- if(..())
- if(toggle)
- if(ishuman(target) && !summoner)
- spawn(0)
- new /obj/effect/hallucination/delusion(target.loc, target, force_kind="custom", duration=200, skip_nearby=0, custom_icon = src.icon_state, custom_icon_file = src.icon)
- else
- if(prob(45))
- if(istype(target, /atom/movable))
- var/atom/movable/M = target
- if(!M.anchored && M != summoner)
- new /obj/effect/overlay/temp/guardian/phase/out(get_turf(M))
- do_teleport(M, M, 10)
- new /obj/effect/overlay/temp/guardian/phase/out(get_turf(M))
-
-/mob/living/simple_animal/hostile/guardian/fire/Crossed(AM as mob|obj)
- ..()
- collision_ignite(AM)
-
-/mob/living/simple_animal/hostile/guardian/fire/Bumped(AM as mob|obj)
- ..()
- collision_ignite(AM)
-
-/mob/living/simple_animal/hostile/guardian/fire/Bump(AM as mob|obj)
- ..()
- collision_ignite(AM)
-
-/mob/living/simple_animal/hostile/guardian/fire/proc/collision_ignite(AM as mob|obj)
- if(istype(AM, /mob/living/))
- var/mob/living/M = AM
- if(AM != summoner && M.fire_stacks < 7)
- M.fire_stacks = 7
- M.IgniteMob()
-
-/mob/living/simple_animal/hostile/guardian/fire/Bump(AM as mob|obj)
- ..()
- collision_ignite(AM)
-//Standard
-
-/mob/living/simple_animal/hostile/guardian/punch
- melee_damage_lower = 20
- melee_damage_upper = 20
- damage_transfer = 0.5
- playstyle_string = "As a standard type you have no special abilities, but have a high damage resistance and a powerful attack capable of smashing through walls."
- environment_smash = 2
- magic_fluff_string = "..And draw the Assistant, faceless and generic, but never to be underestimated."
- tech_fluff_string = "Boot sequence complete. Standard combat modules loaded. Holoparasite swarm online."
- bio_fluff_string = "Your scarab swarm stirs to life, ready to tear apart your enemies."
- var/battlecry = "AT"
-
-
-/mob/living/simple_animal/hostile/guardian/punch/sealpunch
- name = "Seal Sprit"
- real_name = "Seal Sprit"
- icon = 'icons/mob/animal.dmi'
- icon_living = "seal"
- icon_state = "seal"
- attacktext = "slaps"
- speak_emote = list("barks")
- melee_damage_lower = 0
- melee_damage_upper = 0
- melee_damage_type = STAMINA
- damage_transfer = 0
- playstyle_string = "As a standard type you have no special abilities, but have a high damage resistance and a powerful attack capable of smashing through walls."
- environment_smash = 2
- battlecry = "URK"
- adminseal = TRUE
-
-/mob/living/simple_animal/hostile/guardian/punch/verb/Battlecry()
- set name = "Set Battlecry"
- set category = "Guardian"
- set desc = "Choose what you shout as you punch"
- var/input = stripped_input(src,"What do you want your battlecry to be? Max length of 5 characters.", ,"", 6)
- if(input)
- battlecry = input
-
-
-
-/mob/living/simple_animal/hostile/guardian/punch/AttackingTarget()
- ..()
- if(iscarbon(target) && target != summoner)
- if(length(battlecry) > 11)//no more then 11 letters in a battle cry.
- src.visible_message("[src] punches [target]!")
- else
- src.say("[src.battlecry][src.battlecry][src.battlecry][src.battlecry][src.battlecry]")
- playsound(loc, src.attack_sound, 50, 1, 1)
- playsound(loc, src.attack_sound, 50, 1, 1)
- playsound(loc, src.attack_sound, 50, 1, 1)
- playsound(loc, src.attack_sound, 50, 1, 1)
-
-//Healer
-
-/mob/living/simple_animal/hostile/guardian/healer
- a_intent = INTENT_HARM
- friendly = "heals"
- speed = 0
- melee_damage_lower = 15
- melee_damage_upper = 15
- playstyle_string = "As a Support type, you may toggle your basic attacks to a healing mode. In addition, Alt-Clicking on an adjacent mob will warp them to your bluespace beacon after a short delay."
- magic_fluff_string = "..And draw the CMO, a potent force of life...and death."
- tech_fluff_string = "Boot sequence complete. Medical modules active. Bluespace modules activated. Holoparasite swarm online."
- bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, capable of mending wounds and travelling via bluespace."
- var/turf/simulated/floor/beacon
- var/beacon_cooldown = 0
- var/toggle = FALSE
- var/heal_cooldown = 0
-
-/mob/living/simple_animal/hostile/guardian/healer/sealhealer
- name = "Seal Sprit"
- real_name = "Seal Sprit"
- icon = 'icons/mob/animal.dmi'
- icon_living = "seal"
- icon_state = "seal"
- attacktext = "slaps"
- speak_emote = list("barks")
- a_intent = INTENT_HARM
- friendly = "heals"
- speed = 0
- melee_damage_lower = 0
- melee_damage_upper = 0
- melee_damage_type = STAMINA
- adminseal = TRUE
-
-
-/mob/living/simple_animal/hostile/guardian/healer/New()
- ..()
-
-/mob/living/simple_animal/hostile/guardian/healer/Life()
- ..()
- var/datum/atom_hud/medsensor = huds[DATA_HUD_MEDICAL_ADVANCED]
- medsensor.add_hud_to(src)
-
-/mob/living/simple_animal/hostile/guardian/healer/AttackingTarget()
- ..()
- if(toggle == TRUE)
- if(src.loc == summoner)
- to_chat(src, "You must be manifested to heal!")
- return
- if(iscarbon(target))
- src.changeNext_move(CLICK_CD_MELEE)
- if(heal_cooldown <= world.time && !stat)
- var/mob/living/carbon/C = target
- C.adjustBruteLoss(-5)
- C.adjustFireLoss(-5)
- C.adjustOxyLoss(-5)
- C.adjustToxLoss(-5)
- heal_cooldown = world.time + 20
-
-/mob/living/simple_animal/hostile/guardian/healer/ToggleMode()
- if(src.loc == summoner)
- if(toggle)
- a_intent = INTENT_HARM
- speed = 0
- damage_transfer = 0.7
- if(src.adminseal)
- damage_transfer = 0
- melee_damage_lower = 15
- melee_damage_upper = 15
- to_chat(src, "You switch to combat mode.")
- toggle = FALSE
- else
- a_intent = INTENT_HELP
- speed = 1
- damage_transfer = 1
- if(src.adminseal)
- damage_transfer = 0
- melee_damage_lower = 0
- melee_damage_upper = 0
- to_chat(src, "You switch to healing mode.")
- toggle = TRUE
- else
- to_chat(src, "You have to be recalled to toggle modes!")
-
-
-/mob/living/simple_animal/hostile/guardian/healer/verb/Beacon()
- set name = "Place Bluespsace Beacon"
- set category = "Guardian"
- set desc = "Mark a floor as your beacon point, allowing you to warp targets to it. Your beacon will not work in unfavorable atmospheric conditions."
- if(beacon_cooldownBeacon placed! You may now warp targets to it, including your user, via Alt+Click. ")
- if(beacon)
- beacon.ChangeTurf(/turf/simulated/floor/plating)
- beacon = F
- beacon_cooldown = world.time+3000
-
- else
- to_chat(src, "Your power is on cooldown. You must wait five minutes between placing beacons.")
-
-/mob/living/simple_animal/hostile/guardian/healer/AltClickOn(atom/movable/A)
- if(!istype(A))
- return
- if(src.loc == summoner)
- to_chat(src, "You must be manifested to warp a target!")
- return
- if(!beacon)
- to_chat(src, "You need a beacon placed to warp things!")
- return
- if(!Adjacent(A))
- to_chat(src, "You must be adjacent to your target!")
- return
- if((A.anchored))
- to_chat(src, "Your target can not be anchored!")
- return
- to_chat(src, "You begin to warp [A]")
- if(do_mob(src, A, 50))
- if(!A.anchored)
- if(src.beacon) //Check that the beacon still exists and is in a safe place. No instant kills.
- if(beacon.air)
- var/datum/gas_mixture/Z = beacon.air
- if(Z.oxygen >= 16 && !Z.toxins && Z.carbon_dioxide < 10 && !Z.trace_gases.len)
- if((Z.temperature > 270) && (Z.temperature < 360))
- var/pressure = Z.return_pressure()
- if((pressure > 20) && (pressure < 550))
- new /obj/effect/overlay/temp/guardian/phase/out(get_turf(A))
- do_teleport(A, beacon, 0)
- new /obj/effect/overlay/temp/guardian/phase(get_turf(A))
- else
- to_chat(src, "The beacon isn't in a safe location!")
- else
- to_chat(src, "The beacon isn't in a safe location!")
- else
- to_chat(src, "You need a beacon to warp things!")
- else
- to_chat(src, "You need to hold still!")
-
-
-///////////////////Ranged
-
-/obj/item/projectile/guardian
- name = "crystal spray"
- icon_state = "guardian"
- damage = 5
- damage_type = BRUTE
- armour_penetration = 100
-
-/mob/living/simple_animal/hostile/guardian/ranged
- a_intent = INTENT_HELP
- friendly = "quietly assesses"
- melee_damage_lower = 10
- melee_damage_upper = 10
- damage_transfer = 0.9
- projectiletype = /obj/item/projectile/guardian
- ranged_cooldown_time = 10
- projectilesound = 'sound/effects/hit_on_shattered_glass.ogg'
- ranged = 1
- rapid = 1
- range = 13
- see_invisible = SEE_INVISIBLE_MINIMUM
- see_in_dark = 8
- playstyle_string = "As a ranged type, you have only light damage resistance, but are capable of spraying shards of crystal at incredibly high speed. You can also deploy surveillance snares to monitor enemy movement. Finally, you can switch to scout mode, in which you can't attack, but can move without limit."
- magic_fluff_string = "..And draw the Sentinel, an alien master of ranged combat."
- tech_fluff_string = "Boot sequence complete. Ranged combat modules active. Holoparasite swarm online."
- bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, capable of spraying shards of crystal."
- var/list/snares = list()
- var/toggle = FALSE
-
-/mob/living/simple_animal/hostile/guardian/ranged/ToggleMode()
- if(src.loc == summoner)
- if(toggle)
- ranged = 1
- melee_damage_lower = 10
- melee_damage_upper = 10
- alpha = 255
- range = 13
- incorporeal_move = 0
- to_chat(src, "You switch to combat mode.")
- toggle = FALSE
- else
- ranged = 0
- melee_damage_lower = 0
- melee_damage_upper = 0
- alpha = 60
- range = 255
- incorporeal_move = 1
- to_chat(src, "You switch to scout mode.")
- toggle = TRUE
- else
- to_chat(src, "You have to be recalled to toggle modes!")
-
-/mob/living/simple_animal/hostile/guardian/ranged/ToggleLight()
- if(see_invisible == SEE_INVISIBLE_MINIMUM)
- to_chat(src, "You deactivate your night vision.")
- see_invisible = SEE_INVISIBLE_LIVING
- else
- to_chat(src, "You activate your night vision.")
- see_invisible = SEE_INVISIBLE_MINIMUM
-
-/mob/living/simple_animal/hostile/guardian/ranged/verb/Snare()
- set name = "Set Surveillance Trap"
- set category = "Guardian"
- set desc = "Set an invisible trap that will alert you when living creatures walk over it. Max of 5"
- if(src.snares.len <6)
- var/turf/snare_loc = get_turf(src.loc)
- var/obj/item/effect/snare/S = new /obj/item/effect/snare(snare_loc)
- S.spawner = src
- S.name = "[get_area(snare_loc)] trap ([rand(1, 1000)])"
- src.snares |= S
- to_chat(src, "Surveillance trap deployed!")
- else
- to_chat(src, "You have too many traps deployed. Delete some first.")
-
-/mob/living/simple_animal/hostile/guardian/ranged/verb/DisarmSnare()
- set name = "Remove Surveillance Trap"
- set category = "Guardian"
- set desc = "Disarm unwanted surveillance traps."
- var/picked_snare = input(src, "Pick which trap to disarm", "Disarm Trap") as null|anything in src.snares
- if(picked_snare)
- src.snares -= picked_snare
- qdel(picked_snare)
- to_chat(src, "Snare disarmed.")
-
-/obj/item/effect/snare
- name = "snare"
- desc = "You shouldn't be seeing this!"
- var/mob/living/spawner
- invisibility = 1
-
-
-/obj/item/effect/snare/Crossed(AM as mob|obj)
- if(istype(AM, /mob/living/))
- var/turf/snare_loc = get_turf(src.loc)
- if(spawner)
- to_chat(spawner, "[AM] has crossed your surveillance trap at [get_area(snare_loc)].")
- if(istype(spawner, /mob/living/simple_animal/hostile/guardian))
- var/mob/living/simple_animal/hostile/guardian/G = spawner
- if(G.summoner)
- to_chat(G.summoner, "[AM] has crossed your surveillance trap at [get_area(snare_loc)].")
-
-////Bomb
-
-/mob/living/simple_animal/hostile/guardian/bomb
- melee_damage_lower = 15
- melee_damage_upper = 15
- damage_transfer = 0.6
- range = 13
- playstyle_string = "As an explosive type, you have only moderate close combat abilities, but are capable of converting any adjacent item into a disguised bomb via alt click."
- magic_fluff_string = "..And draw the Scientist, master of explosive death."
- tech_fluff_string = "Boot sequence complete. Explosive modules active. Holoparasite swarm online."
- bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, capable of stealthily booby trapping items."
- var/bomb_cooldown = 0
-
-/mob/living/simple_animal/hostile/guardian/bomb/AltClickOn(atom/movable/A)
- if(!istype(A))
- return
- if(src.loc == summoner)
- to_chat(src, "You must be manifested to create bombs!")
- return
- if(istype(A, /obj/))
- if(bomb_cooldown <= world.time && !stat)
- var/obj/item/weapon/guardian_bomb/B = new /obj/item/weapon/guardian_bomb(get_turf(A))
- to_chat(src, "Success! Bomb on \the [A] armed!")
- if(summoner)
- to_chat(summoner, "Your guardian has primed \the [A] to explode!")
- bomb_cooldown = world.time + 200
- B.spawner = src
- B.disguise (A)
- else
- to_chat(src, "Your powers are on cooldown! You must wait 20 seconds between bombs.")
-
-/obj/item/weapon/guardian_bomb
- name = "bomb"
- desc = "You shouldn't be seeing this!"
- var/obj/stored_obj
- var/mob/living/spawner
-
-
-/obj/item/weapon/guardian_bomb/proc/disguise(var/obj/A)
- A.loc = src
- stored_obj = A
- anchored = A.anchored
- density = A.density
- appearance = A.appearance
- spawn(600)
- if(src)
- stored_obj.loc = get_turf(src.loc)
- if(spawner)
- to_chat(spawner, "Failure! Your trap on \the [stored_obj] didn't catch anyone this time.")
- qdel(src)
-
-/obj/item/weapon/guardian_bomb/proc/detonate(var/mob/living/user)
- to_chat(user, "The [src] was boobytrapped!")
- if(istype(spawner, /mob/living/simple_animal/hostile/guardian))
- var/mob/living/simple_animal/hostile/guardian/G = spawner
- if(user == G.summoner)
- to_chat(user, "You knew this because of your link with your guardian, so you smartly defuse the bomb.")
- stored_obj.loc = get_turf(src.loc)
- qdel(src)
- return
- to_chat(spawner, "Success! Your trap on \the [src] caught [user]!")
- stored_obj.loc = get_turf(src.loc)
- playsound(get_turf(src),'sound/effects/Explosion2.ogg', 200, 1)
- user.ex_act(2)
- qdel(src)
-
-/obj/item/weapon/guardian_bomb/attackby(mob/living/user)
- detonate(user)
- return
-
-/obj/item/weapon/guardian_bomb/pickup(mob/living/user)
- detonate(user)
- return
-
-/obj/item/weapon/guardian_bomb/examine(mob/user)
- stored_obj.examine(user)
- if(get_dist(user,src)<=2)
- to_chat(user, "Looks odd!")
-
-
////////Creation
/obj/item/weapon/guardiancreator
@@ -676,7 +228,7 @@
var/used_message = "All the cards seem to be blank now."
var/failure_message = "..And draw a card! It's...blank? Maybe you should try again later."
var/ling_failure = "The deck refuses to respond to a souless creature such as you."
- var/list/possible_guardians = list("Chaos", "Standard", "Ranged", "Support", "Explosive")
+ var/list/possible_guardians = list("Chaos", "Standard", "Ranged", "Support", "Explosive", "Assassin", "Lightning", "Charger", "Protector")
var/random = TRUE
/obj/item/weapon/guardiancreator/attack_self(mob/living/user)
@@ -727,6 +279,18 @@
if("Explosive")
pickedtype = /mob/living/simple_animal/hostile/guardian/bomb
+ if("Assassin")
+ pickedtype = /mob/living/simple_animal/hostile/guardian/assassin
+
+ if("Lightning")
+ pickedtype = /mob/living/simple_animal/hostile/guardian/beam
+
+ if("Charger")
+ pickedtype = /mob/living/simple_animal/hostile/guardian/charger
+
+ if("Protector")
+ pickedtype = /mob/living/simple_animal/hostile/guardian/protector
+
var/mob/living/simple_animal/hostile/guardian/G = new pickedtype(user)
G.summoner = user
G.summoned = TRUE
@@ -741,12 +305,33 @@
user.verbs += /mob/living/proc/guardian_reset
var/color
+
+ //names and their RGB
+ var/magic_list = list("Pink" = "#FFC0CB", \
+ "Red" = "#FF0000", \
+ "Orange" = "#FFA500", \
+ "Green" = "#008000", \
+ "Blue" = "#0000FF")
+
+ var/tech_list = list("Rose" = "#F62C6B", \
+ "Peony" = "#E54750", \
+ "Lily" = "#F6562C", \
+ "Daisy" = "#ECCD39", \
+ "Zinnia" = "#89F62C", \
+ "Ivy" = "#5DF62C", \
+ "Iris" = "#2CF6B8", \
+ "Petunia" = "#51A9D4", \
+ "Violet" = "#8A347C", \
+ "Lilac" = "#C7A0F6", \
+ "Orchid" = "#F62CF5")
+
var/picked_name
var/picked_color = pick("#FFFFFF","#000000","#808080","#A52A2A","#FF0000","#8B0000","#DC143C","#FFA500","#FFFF00","#008000","#00FF00","#006400","#00FFFF","#0000FF","#000080","#008080","#800080","#4B0082")
switch(theme)
if("magic")
- color = pick("Pink", "Red", "Orange", "Green", "Blue")
+ color = pick(magic_list)
+ G.name_color = magic_list[color]
picked_name = pick("Aries", "Leo", "Sagittarius", "Taurus", "Virgo", "Capricorn", "Gemini", "Libra", "Aquarius", "Cancer", "Scorpio", "Pisces")
G.name = "[picked_name] [color]"
@@ -757,7 +342,8 @@
to_chat(user, "[G.magic_fluff_string].")
if("tech")
- color = pick("Rose", "Peony", "Lily", "Daisy", "Zinnia", "Ivy", "Iris", "Petunia", "Violet", "Lilac", "Orchid") //technically not colors, just flowers that can be specific colors
+ color = pick(tech_list) //technically not colors, just flowers that can be specific colors
+ G.name_color = tech_list[color]
picked_name = pick("Gallium", "Indium", "Thallium", "Bismuth", "Aluminium", "Mercury", "Iron", "Silver", "Zinc", "Titanium", "Chromium", "Nickel", "Platinum", "Tellurium", "Palladium", "Rhodium", "Cobalt", "Osmium", "Tungsten", "Iridium")
G.name = "[picked_name] [color]"
@@ -769,6 +355,7 @@
to_chat(user, "[G.tech_fluff_string].")
G.speak_emote = list("states")
if("bio")
+ G.name_color = picked_color
G.icon = 'icons/mob/mob.dmi'
picked_name = pick("brood", "hive", "nest")
to_chat(user, "[G.bio_fluff_string].")
diff --git a/code/game/gamemodes/miniantags/guardian/types/assassin.dm b/code/game/gamemodes/miniantags/guardian/types/assassin.dm
new file mode 100644
index 00000000000..39ea9992308
--- /dev/null
+++ b/code/game/gamemodes/miniantags/guardian/types/assassin.dm
@@ -0,0 +1,89 @@
+/mob/living/simple_animal/hostile/guardian/assassin
+ melee_damage_lower = 15
+ melee_damage_upper = 15
+ armour_penetration = 0
+ damage_transfer = 0.6
+ playstyle_string = "As an Assassin type you do medium damage and have no damage resistance, but can enter stealth, massively increasing the damage of your next attack and causing it to ignore armor. Stealth is broken when you attack or take damage."
+ magic_fluff_string = "..And draw the Space Ninja, a lethal, invisible assassin."
+ tech_fluff_string = "Boot sequence complete. Assassin modules loaded. Holoparasite swarm online."
+ bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, capable of sneaking and stealthy attacks."
+ var/toggle = FALSE
+ var/stealthcooldown = 0
+ var/default_stealth_cooldown = 16 SECONDS
+ var/obj/screen/alert/canstealthalert
+ var/obj/screen/alert/instealthalert
+
+/mob/living/simple_animal/hostile/guardian/assassin/Life()
+ . = ..()
+ updatestealthalert()
+ if(loc == summoner && toggle)
+ ToggleMode(0)
+
+/mob/living/simple_animal/hostile/guardian/assassin/Stat()
+ ..()
+ if(statpanel("Status"))
+ if(stealthcooldown >= world.time)
+ stat(null, "Stealth Cooldown Remaining: [max(round((stealthcooldown - world.time)*0.1, 0.1), 0)] seconds")
+
+/mob/living/simple_animal/hostile/guardian/assassin/AttackingTarget()
+ ..()
+ if(toggle && (isliving(target) || istype(target, /obj/structure/window) || istype(target, /obj/structure/grille)))
+ ToggleMode(1)
+
+/mob/living/simple_animal/hostile/guardian/assassin/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
+ . = ..()
+ if(. > 0 && toggle)
+ ToggleMode(1)
+
+/mob/living/simple_animal/hostile/guardian/assassin/Recall()
+ ..()
+ if(toggle)
+ ToggleMode(0)
+
+/mob/living/simple_animal/hostile/guardian/assassin/ToggleMode(forced = 0)
+ if(toggle)
+ melee_damage_lower = initial(melee_damage_lower)
+ melee_damage_upper = initial(melee_damage_upper)
+ armour_penetration = initial(armour_penetration)
+ alpha = initial(alpha)
+ if(!forced)
+ to_chat(src, "You exit stealth.")
+ else
+ visible_message("[src] suddenly appears!")
+ stealthcooldown = world.time + default_stealth_cooldown //we were forced out of stealth and go on cooldown
+ cooldown = world.time + 40 //can't recall for 4 seconds
+ updatestealthalert()
+ toggle = FALSE
+ else if(stealthcooldown <= world.time)
+ if(loc == summoner)
+ to_chat(src, "You have to be manifested to enter stealth!")
+ return
+ melee_damage_lower = 50
+ melee_damage_upper = 50
+ armour_penetration = 100
+ new /obj/effect/overlay/temp/guardian/phase(get_turf(src))
+ alpha = 15
+ if(!forced)
+ to_chat(src, "You enter stealth, empowering your next attack.")
+ updatestealthalert()
+ toggle = TRUE
+ else if(!forced)
+ to_chat(src, "You cannot yet enter stealth, wait another [max(round((stealthcooldown - world.time)*0.1, 0.1), 0)] seconds!")
+
+/mob/living/simple_animal/hostile/guardian/assassin/proc/updatestealthalert()
+ if(stealthcooldown <= world.time)
+ if(toggle)
+ if(!instealthalert)
+ instealthalert = throw_alert("instealth", /obj/screen/alert/instealth)
+ clear_alert("canstealth")
+ canstealthalert = null
+ else
+ if(!canstealthalert)
+ canstealthalert = throw_alert("canstealth", /obj/screen/alert/canstealth)
+ clear_alert("instealth")
+ instealthalert = null
+ else
+ clear_alert("instealth")
+ instealthalert = null
+ clear_alert("canstealth")
+ canstealthalert = null
\ No newline at end of file
diff --git a/code/game/gamemodes/miniantags/guardian/types/bomb.dm b/code/game/gamemodes/miniantags/guardian/types/bomb.dm
new file mode 100644
index 00000000000..6a4c74ff1a3
--- /dev/null
+++ b/code/game/gamemodes/miniantags/guardian/types/bomb.dm
@@ -0,0 +1,76 @@
+/mob/living/simple_animal/hostile/guardian/bomb
+ melee_damage_lower = 15
+ melee_damage_upper = 15
+ damage_transfer = 0.6
+ range = 13
+ playstyle_string = "As an Explosive type, you have only moderate close combat abilities, but are capable of converting any adjacent item into a disguised bomb via alt click."
+ magic_fluff_string = "..And draw the Scientist, master of explosive death."
+ tech_fluff_string = "Boot sequence complete. Explosive modules active. Holoparasite swarm online."
+ bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, capable of stealthily booby trapping items."
+ var/bomb_cooldown = 0
+
+/mob/living/simple_animal/hostile/guardian/bomb/AltClickOn(atom/movable/A)
+ if(!istype(A))
+ return
+ if(get_dist(get_turf(src), get_turf(A)) > 1)
+ to_chat(src, "You're too far from [A] to disguise it as a bomb.")
+ return
+ if(istype(A, /obj/))
+ if(bomb_cooldown <= world.time && !stat)
+ var/obj/item/weapon/guardian_bomb/B = new /obj/item/weapon/guardian_bomb(get_turf(A))
+ to_chat(src, "Success! Bomb on [A] armed!")
+ if(summoner)
+ to_chat(summoner, "Your guardian has primed [A] to explode!")
+ bomb_cooldown = world.time + 200
+ B.spawner = src
+ B.disguise (A)
+ else
+ to_chat(src, "Your powers are on cooldown! You must wait 20 seconds between bombs.")
+
+/obj/item/weapon/guardian_bomb
+ name = "bomb"
+ desc = "You shouldn't be seeing this!"
+ var/obj/stored_obj
+ var/mob/living/spawner
+
+
+/obj/item/weapon/guardian_bomb/proc/disguise(var/obj/A)
+ A.forceMove(src)
+ stored_obj = A
+ anchored = A.anchored
+ density = A.density
+ appearance = A.appearance
+ spawn(600)
+ if(src)
+ stored_obj.loc = get_turf(loc)
+ if(spawner)
+ to_chat(spawner, "Failure! Your trap on [stored_obj] didn't catch anyone this time.")
+ qdel(src)
+
+/obj/item/weapon/guardian_bomb/proc/detonate(var/mob/living/user)
+ to_chat(user, "The [src] was boobytrapped!")
+ if(istype(spawner, /mob/living/simple_animal/hostile/guardian))
+ var/mob/living/simple_animal/hostile/guardian/G = spawner
+ if(user == G.summoner)
+ to_chat(user, "You knew this because of your link with your guardian, so you smartly defuse the bomb.")
+ stored_obj.loc = get_turf(loc)
+ qdel(src)
+ return
+ to_chat(spawner, "Success! Your trap on [src] caught [user]!")
+ stored_obj.loc = get_turf(loc)
+ playsound(get_turf(src),'sound/effects/Explosion2.ogg', 200, 1)
+ user.ex_act(2)
+ qdel(src)
+
+/obj/item/weapon/guardian_bomb/attackby(mob/living/user)
+ detonate(user)
+ return
+
+/obj/item/weapon/guardian_bomb/pickup(mob/living/user)
+ detonate(user)
+ return
+
+/obj/item/weapon/guardian_bomb/examine(mob/user)
+ stored_obj.examine(user)
+ if(get_dist(user,src) <= 2)
+ to_chat(user, "Looks odd!")
diff --git a/code/game/gamemodes/miniantags/guardian/types/charger.dm b/code/game/gamemodes/miniantags/guardian/types/charger.dm
new file mode 100644
index 00000000000..39bf995967e
--- /dev/null
+++ b/code/game/gamemodes/miniantags/guardian/types/charger.dm
@@ -0,0 +1,72 @@
+/mob/living/simple_animal/hostile/guardian/charger
+ melee_damage_lower = 15
+ melee_damage_upper = 15
+ ranged = 1 //technically
+ ranged_message = "charges"
+ ranged_cooldown_time = 40
+ speed = -1
+ damage_transfer = 0.6
+ playstyle_string = "As a Charger type you do medium damage, have medium damage resistance, move very fast, and can charge at a location, damaging any target hit and forcing them to drop any items they are holding."
+ magic_fluff_string = "..And draw the Hunter, an alien master of rapid assault."
+ tech_fluff_string = "Boot sequence complete. Charge modules loaded. Holoparasite swarm online."
+ bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, ready to deal damage."
+ var/charging = 0
+ var/obj/screen/alert/chargealert
+
+/mob/living/simple_animal/hostile/guardian/charger/Life()
+ . = ..()
+ if(ranged_cooldown <= world.time)
+ if(!chargealert)
+ chargealert = throw_alert("charge", /obj/screen/alert/cancharge)
+ else
+ clear_alert("charge")
+ chargealert = null
+
+/mob/living/simple_animal/hostile/guardian/charger/OpenFire(atom/A)
+ if(!charging)
+ visible_message("[src] [ranged_message] at [A]!")
+ ranged_cooldown = world.time + ranged_cooldown_time
+ clear_alert("charge")
+ chargealert = null
+ Shoot(A)
+
+/mob/living/simple_animal/hostile/guardian/charger/Shoot(atom/targeted_atom)
+ charging = 1
+ throw_at(targeted_atom, range, 1, src, 0, callback = CALLBACK(src, .proc/charging_end))
+
+/mob/living/simple_animal/hostile/guardian/charger/proc/charging_end()
+ charging = 0
+
+/mob/living/simple_animal/hostile/guardian/charger/Move()
+ if(charging)
+ new /obj/effect/overlay/temp/decoy/fading(loc,src)
+ . = ..()
+
+/mob/living/simple_animal/hostile/guardian/charger/snapback()
+ if(!charging)
+ ..()
+
+/mob/living/simple_animal/hostile/guardian/charger/throw_impact(atom/A)
+ if(!charging)
+ return ..()
+
+ else if(A)
+ if(isliving(A) && A != summoner)
+ var/mob/living/L = A
+ var/blocked = FALSE
+ var/mob/living/simple_animal/hostile/guardian/G = A
+ if(istype(G) && G.summoner == summoner) //if the summoner matches don't hurt them
+ blocked = TRUE
+ if(ishuman(A))
+ var/mob/living/carbon/human/H = A
+ if(H.check_shields(src, 90, "[name]", attack_type = THROWN_PROJECTILE_ATTACK))
+ blocked = TRUE
+ if(!blocked)
+ L.Stun(1)
+ L.visible_message("[src] slams into [L]!", "[src] slams into you!")
+ L.apply_damage(20, BRUTE)
+ playsound(get_turf(L), 'sound/effects/meteorimpact.ogg', 100, 1)
+ shake_camera(L, 4, 3)
+ shake_camera(src, 2, 3)
+
+ charging = 0
\ No newline at end of file
diff --git a/code/game/gamemodes/miniantags/guardian/types/fire.dm b/code/game/gamemodes/miniantags/guardian/types/fire.dm
new file mode 100644
index 00000000000..1447f36e739
--- /dev/null
+++ b/code/game/gamemodes/miniantags/guardian/types/fire.dm
@@ -0,0 +1,67 @@
+/mob/living/simple_animal/hostile/guardian/fire
+ a_intent = INTENT_HELP
+ melee_damage_lower = 10
+ melee_damage_upper = 10
+ attack_sound = 'sound/items/Welder.ogg'
+ attacktext = "sears"
+ damage_transfer = 0.8
+ range = 10
+ playstyle_string = "As a Chaos type, you have only light damage resistance, but will ignite any enemy you bump into. In addition, your melee attacks will randomly teleport enemies."
+ environment_smash = 1
+ magic_fluff_string = "..And draw the Wizard, bringer of endless chaos!"
+ tech_fluff_string = "Boot sequence complete. Crowd control modules activated. Holoparasite swarm online."
+ bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, ready to sow havoc at random."
+ var/toggle = FALSE
+
+/mob/living/simple_animal/hostile/guardian/fire/Life() //Dies if the summoner dies
+ ..()
+ if(summoner)
+ summoner.ExtinguishMob()
+ summoner.adjust_fire_stacks(-20)
+
+/mob/living/simple_animal/hostile/guardian/fire/ToggleMode()
+ if(loc == summoner)
+ if(toggle)
+ to_chat(src, "You switch to dispersion mode, and will teleport victims away from your master.")
+ toggle = FALSE
+ else
+ to_chat(src, "You switch to deception mode, and will turn your victims against their allies.")
+ toggle = TRUE
+
+/mob/living/simple_animal/hostile/guardian/fire/AttackingTarget()
+ if(..())
+ if(toggle)
+ if(ishuman(target) && !summoner)
+ spawn(0)
+ new /obj/effect/hallucination/delusion(target.loc, target, force_kind = "custom", duration = 200, skip_nearby = 0, custom_icon = icon_state, custom_icon_file = icon)
+ else
+ if(prob(45))
+ if(ismovableatom(target))
+ var/atom/movable/M = target
+ if(!M.anchored && M != summoner)
+ new /obj/effect/overlay/temp/guardian/phase/out(get_turf(M))
+ do_teleport(M, M, 10)
+ new /obj/effect/overlay/temp/guardian/phase/out(get_turf(M))
+
+/mob/living/simple_animal/hostile/guardian/fire/Crossed(AM as mob|obj)
+ ..()
+ collision_ignite(AM)
+
+/mob/living/simple_animal/hostile/guardian/fire/Bumped(AM as mob|obj)
+ ..()
+ collision_ignite(AM)
+
+/mob/living/simple_animal/hostile/guardian/fire/Bump(AM as mob|obj)
+ ..()
+ collision_ignite(AM)
+
+/mob/living/simple_animal/hostile/guardian/fire/proc/collision_ignite(AM as mob|obj)
+ if(isliving(AM))
+ var/mob/living/M = AM
+ if(AM != summoner && M.fire_stacks < 7)
+ M.fire_stacks = 7
+ M.IgniteMob()
+
+/mob/living/simple_animal/hostile/guardian/fire/Bump(AM as mob|obj)
+ ..()
+ collision_ignite(AM)
diff --git a/code/game/gamemodes/miniantags/guardian/types/healer.dm b/code/game/gamemodes/miniantags/guardian/types/healer.dm
new file mode 100644
index 00000000000..0a6efb45d06
--- /dev/null
+++ b/code/game/gamemodes/miniantags/guardian/types/healer.dm
@@ -0,0 +1,138 @@
+/mob/living/simple_animal/hostile/guardian/healer
+ a_intent = INTENT_HARM
+ friendly = "heals"
+ speed = 0
+ melee_damage_lower = 15
+ melee_damage_upper = 15
+ playstyle_string = "As a Support type, you may toggle your basic attacks to a healing mode. In addition, Alt-Clicking on an adjacent mob will warp them to your bluespace beacon after a short delay."
+ magic_fluff_string = "..And draw the CMO, a potent force of life...and death."
+ tech_fluff_string = "Boot sequence complete. Medical modules active. Bluespace modules activated. Holoparasite swarm online."
+ bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, capable of mending wounds and travelling via bluespace."
+ var/turf/simulated/floor/beacon
+ var/beacon_cooldown = 0
+ var/toggle = FALSE
+ var/heal_cooldown = 0
+
+/mob/living/simple_animal/hostile/guardian/healer/sealhealer
+ name = "Seal Sprit"
+ real_name = "Seal Sprit"
+ icon = 'icons/mob/animal.dmi'
+ icon_living = "seal"
+ icon_state = "seal"
+ attacktext = "slaps"
+ speak_emote = list("barks")
+ a_intent = INTENT_HARM
+ friendly = "heals"
+ speed = 0
+ melee_damage_lower = 0
+ melee_damage_upper = 0
+ melee_damage_type = STAMINA
+ adminseal = TRUE
+
+/mob/living/simple_animal/hostile/guardian/healer/New()
+ ..()
+
+/mob/living/simple_animal/hostile/guardian/healer/Life()
+ ..()
+ var/datum/atom_hud/medsensor = huds[DATA_HUD_MEDICAL_ADVANCED]
+ medsensor.add_hud_to(src)
+
+/mob/living/simple_animal/hostile/guardian/healer/AttackingTarget()
+ ..()
+ if(toggle == TRUE)
+ if(loc == summoner)
+ to_chat(src, "You must be manifested to heal!")
+ return
+ if(iscarbon(target))
+ changeNext_move(CLICK_CD_MELEE)
+ if(heal_cooldown <= world.time && !stat)
+ var/mob/living/carbon/C = target
+ C.adjustBruteLoss(-5)
+ C.adjustFireLoss(-5)
+ C.adjustOxyLoss(-5)
+ C.adjustToxLoss(-5)
+ heal_cooldown = world.time + 20
+
+/mob/living/simple_animal/hostile/guardian/healer/ToggleMode()
+ if(loc == summoner)
+ if(toggle)
+ a_intent = INTENT_HARM
+ speed = 0
+ damage_transfer = 0.7
+ if(adminseal)
+ damage_transfer = 0
+ melee_damage_lower = 15
+ melee_damage_upper = 15
+ to_chat(src, "You switch to combat mode.")
+ toggle = FALSE
+ else
+ a_intent = INTENT_HELP
+ speed = 1
+ damage_transfer = 1
+ if(adminseal)
+ damage_transfer = 0
+ melee_damage_lower = 0
+ melee_damage_upper = 0
+ to_chat(src, "You switch to healing mode.")
+ toggle = TRUE
+ else
+ to_chat(src, "You have to be recalled to toggle modes!")
+
+
+/mob/living/simple_animal/hostile/guardian/healer/verb/Beacon()
+ set name = "Place Bluespsace Beacon"
+ set category = "Guardian"
+ set desc = "Mark a floor as your beacon point, allowing you to warp targets to it. Your beacon will not work in unfavorable atmospheric conditions."
+ if(beacon_cooldown < world.time)
+ var/turf/beacon_loc = get_turf(loc)
+ if(istype(beacon_loc, /turf/simulated/floor))
+ var/turf/simulated/floor/F = beacon_loc
+ F.icon = 'icons/turf/floors.dmi'
+ F.name = "bluespace recieving pad"
+ F.desc = "A recieving zone for bluespace teleportations. Building a wall over it should disable it."
+ F.icon_state = "light_on-w"
+ to_chat(src, "Beacon placed! You may now warp targets to it, including your user, via Alt+Click. ")
+ if(beacon)
+ beacon.ChangeTurf(/turf/simulated/floor/plating)
+ beacon = F
+ beacon_cooldown = world.time+3000
+
+ else
+ to_chat(src, "Your power is on cooldown. You must wait five minutes between placing beacons.")
+
+/mob/living/simple_animal/hostile/guardian/healer/AltClickOn(atom/movable/A)
+ if(!istype(A))
+ return
+ if(loc == summoner)
+ to_chat(src, "You must be manifested to warp a target!")
+ return
+ if(!beacon)
+ to_chat(src, "You need a beacon placed to warp things!")
+ return
+ if(!Adjacent(A))
+ to_chat(src, "You must be adjacent to your target!")
+ return
+ if((A.anchored))
+ to_chat(src, "Your target can not be anchored!")
+ return
+ to_chat(src, "You begin to warp [A]")
+ if(do_mob(src, A, 50))
+ if(!A.anchored)
+ if(beacon) //Check that the beacon still exists and is in a safe place. No instant kills.
+ if(beacon.air)
+ var/datum/gas_mixture/Z = beacon.air
+ if(Z.oxygen >= 16 && !Z.toxins && Z.carbon_dioxide < 10 && !Z.trace_gases.len)
+ if((Z.temperature > 270) && (Z.temperature < 360))
+ var/pressure = Z.return_pressure()
+ if((pressure > 20) && (pressure < 550))
+ new /obj/effect/overlay/temp/guardian/phase/out(get_turf(A))
+ do_teleport(A, beacon, 0)
+ new /obj/effect/overlay/temp/guardian/phase(get_turf(A))
+ else
+ to_chat(src, "The beacon isn't in a safe location!")
+ else
+ to_chat(src, "The beacon isn't in a safe location!")
+ else
+ to_chat(src, "You need a beacon to warp things!")
+ else
+ to_chat(src, "You need to hold still!")
diff --git a/code/game/gamemodes/miniantags/guardian/types/lightning.dm b/code/game/gamemodes/miniantags/guardian/types/lightning.dm
new file mode 100644
index 00000000000..ea11fc5cfdd
--- /dev/null
+++ b/code/game/gamemodes/miniantags/guardian/types/lightning.dm
@@ -0,0 +1,109 @@
+/obj/effect/ebeam/chain
+ name = "lightning chain"
+ layer = LYING_MOB_LAYER
+
+/mob/living/simple_animal/hostile/guardian/beam
+ melee_damage_lower = 7
+ melee_damage_upper = 7
+ attacktext = "shocks"
+ melee_damage_type = BURN
+ attack_sound = 'sound/machines/defib_zap.ogg'
+ damage_transfer = 0.7
+ range = 7
+ playstyle_string = "As a Lightning type, you will apply lightning chains to targets on attack and have a lightning chain to your summoner. Lightning chains will shock anyone near them."
+ magic_fluff_string = "..And draw the Tesla, a shocking, lethal source of power."
+ tech_fluff_string = "Boot sequence complete. Lightning modules active. Holoparasite swarm online."
+ bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, ready to electrify your enemies."
+ var/datum/beam/summonerchain
+ var/list/enemychains = list()
+ var/successfulshocks = 0
+
+/mob/living/simple_animal/hostile/guardian/beam/AttackingTarget()
+ ..()
+ if(isliving(target) && target != src && target != summoner)
+ cleardeletedchains()
+ for(var/chain in enemychains)
+ var/datum/beam/B = chain
+ if(B.target == target)
+ return //oh this guy already HAS a chain, let's not chain again
+ if(enemychains.len > 2)
+ var/datum/beam/C = pick(enemychains)
+ qdel(C)
+ enemychains -= C
+ enemychains += Beam(target, "lightning[rand(1,12)]", 'icons/effects/effects.dmi', time=70, maxdistance=7, beam_type=/obj/effect/ebeam/chain)
+
+/mob/living/simple_animal/hostile/guardian/beam/Destroy()
+ removechains()
+ return ..()
+
+/mob/living/simple_animal/hostile/guardian/beam/Manifest()
+ ..()
+ if(summoner)
+ summonerchain = Beam(summoner, "lightning[rand(1,12)]", 'icons/effects/effects.dmi', time=INFINITY, maxdistance=INFINITY, beam_type=/obj/effect/ebeam/chain)
+ while(loc != summoner)
+ if(successfulshocks > 5)
+ successfulshocks = 0
+ if(shockallchains())
+ successfulshocks++
+ sleep(3)
+
+/mob/living/simple_animal/hostile/guardian/beam/Recall()
+ . = ..()
+ if(.)
+ removechains()
+
+/mob/living/simple_animal/hostile/guardian/beam/proc/cleardeletedchains()
+ if(summonerchain && qdeleted(summonerchain))
+ summonerchain = null
+ if(enemychains.len)
+ for(var/chain in enemychains)
+ var/datum/cd = chain
+ if(!chain || qdeleted(cd))
+ enemychains -= chain
+
+/mob/living/simple_animal/hostile/guardian/beam/proc/shockallchains()
+ . = 0
+ cleardeletedchains()
+ if(summoner)
+ if(!summonerchain)
+ summonerchain = Beam(summoner, "lightning[rand(1,12)]", 'icons/effects/effects.dmi', time=INFINITY, maxdistance=INFINITY, beam_type=/obj/effect/ebeam/chain)
+ . += chainshock(summonerchain)
+ if(enemychains.len)
+ for(var/chain in enemychains)
+ . += chainshock(chain)
+
+/mob/living/simple_animal/hostile/guardian/beam/proc/removechains()
+ if(summonerchain)
+ QDEL_NULL(summonerchain)
+ if(enemychains.len)
+ for(var/chain in enemychains)
+ qdel(chain)
+ enemychains = list()
+
+/mob/living/simple_animal/hostile/guardian/beam/proc/chainshock(datum/beam/B)
+ . = 0
+ var/list/turfs = list()
+ for(var/E in B.elements)
+ var/obj/effect/ebeam/chainpart = E
+ if(chainpart && chainpart.x && chainpart.y && chainpart.z)
+ var/turf/T = get_turf_pixel(chainpart)
+ turfs |= T
+ if(T != get_turf(B.origin) && T != get_turf(B.target))
+ for(var/turf/TU in circlerange(T, 1))
+ turfs |= TU
+ for(var/turf in turfs)
+ var/turf/T = turf
+ for(var/mob/living/L in T)
+ if(L.stat != DEAD && L != src && L != summoner)
+ var/mob/living/simple_animal/hostile/guardian/G = L
+ if(istype(G) && G.summoner == summoner)
+ continue
+ if(successfulshocks > 4)
+ //L.electrocute_act(30, src) //shocks for 30 burn damage
+ L.visible_message(
+ "[L] was shocked by the lightning chain!", \
+ "You are shocked by the lightning chain!", \
+ "You hear a heavy electrical crack." \
+ )
+ L.adjustFireLoss(1.2) //adds up very rapidly
+ . = 1
\ No newline at end of file
diff --git a/code/game/gamemodes/miniantags/guardian/types/protector.dm b/code/game/gamemodes/miniantags/guardian/types/protector.dm
new file mode 100644
index 00000000000..aa8bcaf09dc
--- /dev/null
+++ b/code/game/gamemodes/miniantags/guardian/types/protector.dm
@@ -0,0 +1,57 @@
+/mob/living/simple_animal/hostile/guardian/protector
+ melee_damage_lower = 15
+ melee_damage_upper = 15
+ range = 15 //worse for it due to how it leashes
+ damage_transfer = 0.4
+ playstyle_string = "As a Protector type you cause your summoner to leash to you instead of you leashing to them and have two modes; Combat Mode, where you do and take medium damage, and Protection Mode, where you do and take almost no damage, but move slightly slower."
+ magic_fluff_string = "..And draw the Guardian, a stalwart protector that never leaves the side of its charge."
+ tech_fluff_string = "Boot sequence complete. Protector modules loaded. Holoparasite swarm online."
+ bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, ready to defend you."
+ var/toggle = FALSE
+
+/mob/living/simple_animal/hostile/guardian/protector/ex_act(severity)
+ if(severity == 1)
+ adjustBruteLoss(400) //if in protector mode, will do 20 damage and not actually necessarily kill the summoner
+ else
+ ..()
+ if(toggle)
+ visible_message("The explosion glances off [src]'s energy shielding!")
+
+/mob/living/simple_animal/hostile/guardian/protector/ToggleMode()
+ if(cooldown > world.time)
+ return 0
+ cooldown = world.time + 10
+ if(toggle)
+ overlays.Cut()
+ melee_damage_lower = initial(melee_damage_lower)
+ melee_damage_upper = initial(melee_damage_upper)
+ speed = initial(speed)
+ damage_transfer = 0.4
+ to_chat(src, "You switch to combat mode.")
+ toggle = FALSE
+ else
+ var/icon/shield_overlay = icon('icons/effects/effects.dmi', "shield-grey")
+ shield_overlay *= name_color
+ overlays.Add(shield_overlay)
+ melee_damage_lower = 2
+ melee_damage_upper = 2
+ speed = 1
+ damage_transfer = 0.05 //damage? what's damage?
+ to_chat(src, "You switch to protection mode.")
+ toggle = TRUE
+
+/mob/living/simple_animal/hostile/guardian/protector/snapback() //snap to what? snap to the guardian!
+ if(summoner)
+ if(get_dist(get_turf(summoner),get_turf(src)) <= range)
+ return
+ else
+ if(istype(summoner.loc, /obj/effect))
+ to_chat(src, "You moved out of range, and were pulled back! You can only move [range] meters from [summoner.real_name]!")
+ visible_message("[src] jumps back to its user.")
+ Recall(TRUE)
+ else
+ to_chat(summoner, "You moved out of range, and were pulled back! You can only move [range] meters from [src]!")
+ summoner.visible_message("[summoner] jumps back to their protector.")
+ new /obj/effect/overlay/temp/guardian/phase/out(get_turf(summoner))
+ summoner.forceMove(get_turf(src))
+ new /obj/effect/overlay/temp/guardian/phase(get_turf(summoner))//Protector
\ No newline at end of file
diff --git a/code/game/gamemodes/miniantags/guardian/types/ranged.dm b/code/game/gamemodes/miniantags/guardian/types/ranged.dm
new file mode 100644
index 00000000000..648339743fd
--- /dev/null
+++ b/code/game/gamemodes/miniantags/guardian/types/ranged.dm
@@ -0,0 +1,99 @@
+/obj/item/projectile/guardian
+ name = "crystal spray"
+ icon_state = "guardian"
+ damage = 5
+ damage_type = BRUTE
+ armour_penetration = 100
+
+/mob/living/simple_animal/hostile/guardian/ranged
+ a_intent = INTENT_HELP
+ friendly = "quietly assesses"
+ melee_damage_lower = 10
+ melee_damage_upper = 10
+ damage_transfer = 0.9
+ projectiletype = /obj/item/projectile/guardian
+ ranged_cooldown_time = 10
+ projectilesound = 'sound/effects/hit_on_shattered_glass.ogg'
+ ranged = 1
+ rapid = 1
+ range = 13
+ see_invisible = SEE_INVISIBLE_MINIMUM
+ see_in_dark = 8
+ playstyle_string = "As a Ranged type, you have only light damage resistance, but are capable of spraying shards of crystal at incredibly high speed. You can also deploy surveillance snares to monitor enemy movement. Finally, you can switch to scout mode, in which you can't attack, but can move without limit."
+ magic_fluff_string = "..And draw the Sentinel, an alien master of ranged combat."
+ tech_fluff_string = "Boot sequence complete. Ranged combat modules active. Holoparasite swarm online."
+ bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, capable of spraying shards of crystal."
+ var/list/snares = list()
+ var/toggle = FALSE
+
+/mob/living/simple_animal/hostile/guardian/ranged/ToggleMode()
+ if(loc == summoner)
+ if(toggle)
+ ranged = 1
+ melee_damage_lower = 10
+ melee_damage_upper = 10
+ alpha = 255
+ range = 13
+ incorporeal_move = 0
+ to_chat(src, "You switch to combat mode.")
+ toggle = FALSE
+ else
+ ranged = 0
+ melee_damage_lower = 0
+ melee_damage_upper = 0
+ alpha = 60
+ range = 255
+ incorporeal_move = 1
+ to_chat(src, "You switch to scout mode.")
+ toggle = TRUE
+ else
+ to_chat(src, "You have to be recalled to toggle modes!")
+
+/mob/living/simple_animal/hostile/guardian/ranged/ToggleLight()
+ if(see_invisible == SEE_INVISIBLE_MINIMUM)
+ to_chat(src, "You deactivate your night vision.")
+ see_invisible = SEE_INVISIBLE_LIVING
+ else
+ to_chat(src, "You activate your night vision.")
+ see_invisible = SEE_INVISIBLE_MINIMUM
+
+/mob/living/simple_animal/hostile/guardian/ranged/verb/Snare()
+ set name = "Set Surveillance Trap"
+ set category = "Guardian"
+ set desc = "Set an invisible trap that will alert you when living creatures walk over it. Max of 5"
+ if(snares.len <6)
+ var/turf/snare_loc = get_turf(loc)
+ var/obj/item/effect/snare/S = new /obj/item/effect/snare(snare_loc)
+ S.spawner = src
+ S.name = "[get_area(snare_loc)] trap ([rand(1, 1000)])"
+ snares |= S
+ to_chat(src, "Surveillance trap deployed!")
+ else
+ to_chat(src, "You have too many traps deployed. Delete some first.")
+
+/mob/living/simple_animal/hostile/guardian/ranged/verb/DisarmSnare()
+ set name = "Remove Surveillance Trap"
+ set category = "Guardian"
+ set desc = "Disarm unwanted surveillance traps."
+ var/picked_snare = input(src, "Pick which trap to disarm", "Disarm Trap") as null|anything in snares
+ if(picked_snare)
+ snares -= picked_snare
+ qdel(picked_snare)
+ to_chat(src, "Snare disarmed.")
+
+/obj/item/effect/snare
+ name = "snare"
+ desc = "You shouldn't be seeing this!"
+ var/mob/living/spawner
+ invisibility = 1
+
+
+/obj/item/effect/snare/Crossed(AM as mob|obj)
+ if(isliving(AM))
+ var/turf/snare_loc = get_turf(loc)
+ if(spawner)
+ to_chat(spawner, "[AM] has crossed your surveillance trap at [get_area(snare_loc)].")
+ if(istype(spawner, /mob/living/simple_animal/hostile/guardian))
+ var/mob/living/simple_animal/hostile/guardian/G = spawner
+ if(G.summoner)
+ to_chat(G.summoner, "[AM] has crossed your surveillance trap at [get_area(snare_loc)].")
diff --git a/code/game/gamemodes/miniantags/guardian/types/standard.dm b/code/game/gamemodes/miniantags/guardian/types/standard.dm
new file mode 100644
index 00000000000..10327778a65
--- /dev/null
+++ b/code/game/gamemodes/miniantags/guardian/types/standard.dm
@@ -0,0 +1,47 @@
+/mob/living/simple_animal/hostile/guardian/punch
+ melee_damage_lower = 20
+ melee_damage_upper = 20
+ damage_transfer = 0.4
+ playstyle_string = "As a Standard type you have no special abilities, but have a high damage resistance and a powerful attack capable of smashing through walls."
+ environment_smash = 2
+ magic_fluff_string = "..And draw the Assistant, faceless and generic, but never to be underestimated."
+ tech_fluff_string = "Boot sequence complete. Standard combat modules loaded. Holoparasite swarm online."
+ bio_fluff_string = "Your scarab swarm stirs to life, ready to tear apart your enemies."
+ var/battlecry = "AT"
+
+/mob/living/simple_animal/hostile/guardian/punch/verb/Battlecry()
+ set name = "Set Battlecry"
+ set category = "Guardian"
+ set desc = "Choose what you shout as you punch"
+ var/input = stripped_input(src,"What do you want your battlecry to be? Max length of 5 characters.", ,"", 6)
+ if(input)
+ battlecry = input
+
+/mob/living/simple_animal/hostile/guardian/punch/AttackingTarget()
+ ..()
+ if(iscarbon(target) && target != summoner)
+ if(length(battlecry) > 11)//no more then 11 letters in a battle cry.
+ visible_message("[src] punches [target]!")
+ else
+ say("[battlecry][battlecry][battlecry][battlecry][battlecry]")
+ playsound(loc, attack_sound, 50, 1, 1)
+ playsound(loc, attack_sound, 50, 1, 1)
+ playsound(loc, attack_sound, 50, 1, 1)
+ playsound(loc, attack_sound, 50, 1, 1)
+
+/mob/living/simple_animal/hostile/guardian/punch/sealpunch
+ name = "Seal Sprit"
+ real_name = "Seal Sprit"
+ icon = 'icons/mob/animal.dmi'
+ icon_living = "seal"
+ icon_state = "seal"
+ attacktext = "slaps"
+ speak_emote = list("barks")
+ melee_damage_lower = 0
+ melee_damage_upper = 0
+ melee_damage_type = STAMINA
+ damage_transfer = 0
+ playstyle_string = "As a standard type you have no special abilities, but have a high damage resistance and a powerful attack capable of smashing through walls."
+ environment_smash = 2
+ battlecry = "URK"
+ adminseal = TRUE
\ No newline at end of file
diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm
index 2dd8502d662..96f52929da6 100644
--- a/code/game/objects/effects/overlays.dm
+++ b/code/game/objects/effects/overlays.dm
@@ -277,4 +277,11 @@
/obj/effect/overlay/temp/cult/turf/open/floor
icon_state = "floorglow"
- duration = 5
\ No newline at end of file
+ duration = 5
+
+/obj/effect/overlay/temp/shieldflash
+ icon_state = "shield-flash"
+ duration = 3
+
+/obj/effect/overlay/temp/shieldflash/New(var/flash_color)
+
diff --git a/code/modules/mob/living/carbon/human/species/apollo.dm b/code/modules/mob/living/carbon/human/species/apollo.dm
index 989fe9ba62a..4c1d8e9aa2e 100644
--- a/code/modules/mob/living/carbon/human/species/apollo.dm
+++ b/code/modules/mob/living/carbon/human/species/apollo.dm
@@ -73,7 +73,7 @@
node.remove(H)
node.loc = M.loc
to_chat(M, "You hear a loud crunch as you mercilessly pull off [H]'s antennae.")
- to_chat(H, "You hear a loud crunch as your antennae is ripped off your head by [M].")
+ to_chat(H, "You hear a loud crunch as your antennae is ripped off your head by [M].")
to_chat(H, "It's so quiet...")
head_organ.h_style = "Bald"
H.update_hair()
diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi
index e0bc6105f06..118b04af87a 100644
Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ
diff --git a/paradise.dme b/paradise.dme
index 96e55cfe1cd..4cc5aa5bd3b 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -459,6 +459,15 @@
#include "code\game\gamemodes\miniantags\bot_swarm\swarmer.dm"
#include "code\game\gamemodes\miniantags\bot_swarm\swarmer_event.dm"
#include "code\game\gamemodes\miniantags\guardian\guardian.dm"
+#include "code\game\gamemodes\miniantags\guardian\types\assassin.dm"
+#include "code\game\gamemodes\miniantags\guardian\types\bomb.dm"
+#include "code\game\gamemodes\miniantags\guardian\types\charger.dm"
+#include "code\game\gamemodes\miniantags\guardian\types\fire.dm"
+#include "code\game\gamemodes\miniantags\guardian\types\healer.dm"
+#include "code\game\gamemodes\miniantags\guardian\types\lightning.dm"
+#include "code\game\gamemodes\miniantags\guardian\types\protector.dm"
+#include "code\game\gamemodes\miniantags\guardian\types\ranged.dm"
+#include "code\game\gamemodes\miniantags\guardian\types\standard.dm"
#include "code\game\gamemodes\miniantags\morph\morph.dm"
#include "code\game\gamemodes\miniantags\morph\morph_event.dm"
#include "code\game\gamemodes\miniantags\revenant\revenant.dm"