Merge pull request #2612 from Aurorablade/Guardingthings

Fethas Carnival of Horrors part 4: I am in your greytide guarding ur newbs
This commit is contained in:
TheDZD
2015-12-02 21:21:22 -05:00
11 changed files with 943 additions and 17 deletions
+2
View File
@@ -201,6 +201,8 @@ datum/hud/New(mob/owner)
human_hud('icons/mob/screen1_Vampire.dmi')
else if(isswarmer(mymob))
swarmer_hud()
else if(isguardian(mymob))
guardian_hud()
//Triggered when F12 is pressed (Unless someone changed something in the DMF)
/mob/verb/button_pressed_F12(var/full = 0 as null)
+5
View File
@@ -45,6 +45,11 @@
*/
/mob/living/UnarmedAttack(var/atom/A)
A.attack_animal(src)
/mob/living/simple_animal/hostile/UnarmedAttack(var/atom/A)
target = A
AttackingTarget()
/atom/proc/attack_animal(mob/user as mob)
return
/mob/living/RestrainedClickOn(var/atom/A)
+7
View File
@@ -412,6 +412,13 @@ var/list/uplink_items = list()
if(istype(T))
T.TC_cost = cost
/datum/uplink_item/dangerous/guardian
name = "Holoparasites"
desc = "Though capable of near sorcerous feats via use of hardlight holograms and nanomachines, they require an organic host as a home base and source of fuel."
item = /obj/item/weapon/storage/box/syndie_kit/guardian
excludefrom = list("nuclear emergency")
cost = 12
// Ammunition
/datum/uplink_item/ammo
+1 -1
View File
@@ -97,7 +97,7 @@ var/global/max_secret_rooms = 6
theme = "xenoden"
walltypes = list(/turf/simulated/mineral/random/high_chance=1)
floortypes = list(/turf/simulated/floor/plating/airless/asteroid, /turf/simulated/floor/beach/sand)
treasureitems = list(/obj/item/clothing/mask/facehugger=1,/obj/item/stack/sheet/animalhide/xeno=2,/obj/item/clothing/suit/xenos=2,/obj/item/clothing/head/xenos=2)
treasureitems = list(/obj/item/clothing/mask/facehugger=1,/obj/item/stack/sheet/animalhide/xeno=2,/obj/item/clothing/suit/xenos=2,/obj/item/clothing/head/xenos=2,/obj/item/weapon/guardiancreator/biological=1)
fluffitems = list(/obj/effect/decal/remains/human=1,/obj/effect/decal/cleanable/blood/xeno=5)
if("hitech")
+7
View File
@@ -258,6 +258,13 @@
log_name = "BB"
limit = 3
/datum/spellbook_entry/item/tarotdeck
name = "Tarot Deck"
desc = "A deck of tarot cards that can be used to summon a spirit companion for the wizard."
item_path = /obj/item/weapon/guardiancreator
log_name = "TD"
limit = 1
/datum/spellbook_entry/item/scryingorb/Buy(var/mob/living/carbon/human/user,var/obj/item/weapon/spellbook/book)
if(..())
if (!(XRAY in user.mutations))
@@ -315,21 +315,25 @@
D.pixel_x = target.pixel_x
D.pixel_y = target.pixel_y
if(do_mob(src, target, 100))
src << "<span class='info'>Dismantling complete.</span>"
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/effect/swarmer/disintegration/N = new /obj/effect/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)
if(!src.Adjacent(target))
src << "<span class='info'>Error:Dismantleing aborted.</span>"
else
src << "<span class='info'>Dismantling complete.</span>"
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/effect/swarmer/disintegration/N = new /obj/effect/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)
/obj/effect/swarmer //Default swarmer effect object visual feedback
@@ -0,0 +1,895 @@
/mob/living/simple_animal/hostile/guardian
name = "Guardian Spirit"
real_name = "Guardian Spirit"
desc = "A mysterious being that stands by it's charge, ever vigilant."
speak_emote = list("intones")
response_help = "passes through"
response_disarm = "flails at"
response_harm = "punches"
icon = 'icons/mob/mob.dmi'
icon_state = "stand"
icon_living = "stand"
speed = 0
a_intent = I_HARM
stop_automated_movement = 1
floating = 1
attack_sound = 'sound/weapons/punch1.ogg'
minbodytemp = 0
maxbodytemp = 10000000
min_oxy = 0
max_oxy = INFINITY
min_tox = 0
max_tox = INFINITY
min_co2 = 0
max_co2 = INFINITY
min_n2 = 0
max_n2 = INFINITY
attacktext = "punches"
maxHealth = 100000 //The spirit itself is invincible
health = 100000
environment_smash = 0
melee_damage_lower = 15
melee_damage_upper = 15
AIStatus = AI_OFF
var/animated_manifest = FALSE
var/cooldown = 0
var/damage_transfer = 1 //how much damage from each attack we transfer to the owner
var/mob/living/summoner
var/range = 10 //how far from the user the spirit can be
var/playstyle_string = "You are a standard Guardian. You shouldn't exist!"
var/magic_fluff_string = " You draw the Coder, symbolizing bugs and errors. This shouldn't happen! Submit a bug report!"
var/tech_fluff_string = "BOOT SEQUENCE COMPLETE. ERROR MODULE LOADED. THIS SHOULDN'T HAPPEN. Submit a bug report!"
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...
/mob/living/simple_animal/hostile/guardian/Life() //Dies if the summoner dies
..()
if(summoner)
if(summoner.stat == DEAD)
// src << "<span class='danger'>Your summoner has died!</span>"
// visible_message("<span class='danger'><B>The [src] dies along with its user!</B></span>")
// summoner.visible_message("<span class='danger'><B>[summoner]'s body is completely consumed by the strain of sustaining [src]!</B></span>")
// for(var/obj/item/W in summoner)
// if(!summoner.unEquip(W))
// qdel(W)
//summoner.dust()
//ghostize()
//qdel(src)
//else
src << "<span class='danger'>Your summoner has died!</span>"
visible_message("<span class='danger'><B>The [src] dies along with its user!</B></span>")
ghostize()
qdel(src)
if(summoner)
if (get_dist(get_turf(summoner),get_turf(src)) <= range)
return
else
src << "You moved out of range, and were pulled back! You can only move [range] meters from [summoner.real_name]"
visible_message("<span class='danger'>The [src] jumps back to its user.</span>")
Recall()
/mob/living/simple_animal/hostile/guardian/Move() //Returns to summoner if they move out of range
..()
if(summoner)
if (get_dist(get_turf(summoner),get_turf(src)) <= range)
return
else
src << "You moved out of range, and were pulled back! You can only move [range] meters from [summoner.real_name]"
visible_message("<span class='danger'>The [src] jumps back to its user.</span>")
Recall()
/mob/living/simple_animal/hostile/guardian/adjustBruteLoss(amount) //The spirit is invincible, but passes on damage to the summoner
var/damage = amount * damage_transfer
if (summoner)
if(loc == summoner)
return
summoner.adjustBruteLoss(damage)
if(damage)
summoner << "<span class='danger'><B>Your [name] is under attack! You take damage!</span></B>"
summoner.visible_message("<span class='danger'><B>Blood sprays from [summoner] as [src] takes damage!</B></span>")
if(summoner.stat == UNCONSCIOUS)
summoner << "<span class='danger'><B>Your body can't take the strain of sustaining [src] in this condition, it begins to fall apart!</span></B>"
summoner.adjustCloneLoss(damage/2)
/mob/living/simple_animal/hostile/guardian/ex_act(severity, target)
switch (severity)
if (1)
gib()
return
if (2)
adjustBruteLoss(60)
if(3)
adjustBruteLoss(30)
/mob/living/simple_animal/hostile/guardian/gib()
if(summoner)
summoner << "<span class='danger'><B>Your [src] was blown up!</span></B>"
summoner.gib()
ghostize()
qdel(src)
/mob/living/simple_animal/hostile/guardian/start_pulling(var/atom/movable/AM)
return //no pulling things fo you!
//Manifest, Recall, Communicate
/mob/living/simple_animal/hostile/guardian/proc/Manifest()
if(cooldown > world.time)
return
if(loc == summoner)
loc = get_turf(summoner)
src.client.eye = loc
cooldown = world.time + 30
if(animated_manifest)
var/end_icon = icon_state
icon_state = "parasite_forming"
spawn(6)
icon_state = end_icon
/mob/living/simple_animal/hostile/guardian/proc/Recall()
if(cooldown > world.time)
return
loc = summoner
buckled = null
cooldown = world.time + 30
/mob/living/simple_animal/hostile/guardian/proc/Communicate()
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 || (M in dead_mob_list))
M << "<span class='boldannounce'><i>[src]:</i> [input]</span>"
src << "<span class='boldannounce'><i>[src]:</i> [input]</span>"
log_say("[src.real_name]/[src.key] : [input]")
/mob/living/simple_animal/hostile/guardian/proc/ToggleMode()
src << "<span class='danger'><B>You dont have another mode!</span></B>"
/mob/living/proc/guardian_comm()
set name = "Communicate"
set category = "Guardian"
set desc = "Communicate telepathically with your guardian."
var/input = stripped_input(src, "Please enter a message to tell your guardian.", "Message", "")
if(!input) return
for(var/mob/M in mob_list)
if(istype (M, /mob/living/simple_animal/hostile/guardian))
var/mob/living/simple_animal/hostile/guardian/G = M
if(G.summoner == src)
G << "<span class='boldannounce'><i>[src]:</i> [input]</span>"
else if (M in dead_mob_list)
M << "<span class='boldannounce'><i>[src]:</i> [input]</span>"
src << "<span class='boldannounce'><i>[src]:</i> [input]</span>"
log_say("[src.real_name]/[src.key] : [text]")
/mob/living/proc/guardian_recall()
set name = "Recall Guardian"
set category = "Guardian"
set desc = "Forcibly recall your guardian."
for(var/mob/living/simple_animal/hostile/guardian/G in mob_list)
if(G.summoner == src)
G.Recall()
/mob/living/proc/guardian_reset()
set name = "Reset Guardian Player (One Use)"
set category = "Guardian"
set desc = "Re-rolls which ghost will control your Guardian. One use."
for(var/mob/living/simple_animal/hostile/guardian/G in mob_list)
if(G.summoner == src)
var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as [G.real_name]?", "pAI", null, FALSE, 100)
var/mob/dead/observer/new_stand = null
if(candidates.len)
new_stand = pick(candidates)
G << "Your user reset you, and your body was taken over by a ghost. Looks like they weren't happy with your performance."
src << "Your guardian has been successfully reset."
message_admins("[key_name_admin(new_stand)] has taken control of ([key_name_admin(G)])")
G.ghostize()
G.key = new_stand.key
src.verbs -= /mob/living/proc/guardian_reset
else
src << "There were no ghosts willing to take control. Looks like you're stuck with your Guardian for now."
/mob/living/simple_animal/hostile/guardian/proc/ToggleLight()
if(!luminosity)
set_light(3)
else
set_light(0)
//////////////////////////TYPES OF GUARDIANS
//Fire. Low damage, low resistance, sets mobs on fire when bumping
/mob/living/simple_animal/hostile/guardian/fire
a_intent = I_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."
/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/AttackingTarget()
..()
if(prob(45))
if(istype(target, /atom/movable))
var/atom/movable/M = target
if(!M.anchored && M != summoner)
do_teleport(M, M, 10)
/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
melee_damage_lower = 0
melee_damage_upper = 0
melee_damage_type = STAMINA
damage_transfer = 0.2
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"
/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("<span class='danger'><B>[src] punches [target]!</B></span>")
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 = I_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
/mob/living/simple_animal/hostile/guardian/healer/sealhealer
a_intent = I_HARM
friendly = "heals"
speed = 0
melee_damage_lower = 0
melee_damage_upper = 0
melee_damage_type = STAMINA
/mob/living/simple_animal/hostile/guardian/healer/New()
..()
/mob/living/simple_animal/hostile/guardian/healer/Life()
..()
regular_hud_updates()
process_med_hud(src, 1)
/mob/living/simple_animal/hostile/guardian/healer/AttackingTarget()
..()
if(toggle == TRUE)
if(src.loc == summoner)
src << "<span class='danger'><B>You must be manifested to heal!</span></B>"
return
if(iscarbon(target))
var/mob/living/carbon/C = target
C.adjustBruteLoss(-5)
C.adjustFireLoss(-5)
C.adjustOxyLoss(-5)
C.adjustToxLoss(-5)
/mob/living/simple_animal/hostile/guardian/healer/ToggleMode()
if(src.loc == summoner)
if(toggle)
a_intent = I_HARM
speed = 0
damage_transfer = 0.7
melee_damage_lower = 15
melee_damage_upper = 15
src << "<span class='danger'><B>You switch to combat mode.</span></B>"
toggle = FALSE
else
a_intent = I_HELP
speed = 1
damage_transfer = 1
melee_damage_lower = 0
melee_damage_upper = 0
src << "<span class='danger'><B>You switch to healing mode.</span></B>"
toggle = TRUE
else
src << "<span class='danger'><B>You have to be recalled to toggle modes!</span></B>"
/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(src.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"
src << "<span class='danger'><B>Beacon placed! You may now warp targets to it, including your user, via Alt+Click. </span></B>"
if(beacon)
beacon.ChangeTurf(/turf/simulated/floor/plating)
beacon = F
beacon_cooldown = world.time+3000
else
src << "<span class='danger'><B>Your power is on cooldown. You must wait five minutes between placing beacons.</span></B>"
/mob/living/simple_animal/hostile/guardian/healer/AltClickOn(atom/movable/A)
if(!istype(A))
return
if(src.loc == summoner)
src << "<span class='danger'><B>You must be manifested to warp a target!</span></B>"
return
if(!beacon)
src << "<span class='danger'><B>You need a beacon placed to warp things!</span></B>"
return
if(!Adjacent(A))
src << "<span class='danger'><B>You must be adjacent to your target!</span></B>"
return
if((A.anchored))
src << "<span class='danger'><B>Your target can not be anchored!</span></B>"
return
src << "<span class='danger'><B>You begin to warp [A]</span></B>"
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))
do_teleport(A, beacon, 0)
else
src << "<span class='danger'><B>The beacon isn't in a safe location!</span></B>"
else
src << "<span class='danger'><B>The beacon isn't in a safe location!</span></B>"
else
src << "<span class='danger'><B>You need a beacon to warp things!</span></B>"
else
src << "<span class='danger'><B>You need to hold still!</span></B>"
///////////////////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 = I_HELP
friendly = "quietly assesses"
melee_damage_lower = 10
melee_damage_upper = 10
damage_transfer = 0.9
projectiletype = /obj/item/projectile/guardian
ranged_cooldown_cap = 0
projectilesound = 'sound/effects/hit_on_shattered_glass.ogg'
ranged = 1
range = 13
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
src << "<span class='danger'><B>You switch to combat mode.</span></B>"
toggle = FALSE
else
ranged = 0
melee_damage_lower = 0
melee_damage_upper = 0
alpha = 60
range = 255
incorporeal_move = 1
src << "<span class='danger'><B>You switch to scout mode.</span></B>"
toggle = TRUE
else
src << "<span class='danger'><B>You have to be recalled to toggle modes!</span></B>"
/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
src << "<span class='danger'><B>Surveillance trap deployed!</span></B>"
else
src << "<span class='danger'><B>You have too many traps deployed. Delete some first.</span></B>"
/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)
src << "<span class='danger'><B>Snare disarmed.</span></B>"
/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)
spawner << "<span class='danger'><B>[AM] has crossed your surveillance trap at [get_area(snare_loc)].</span></B>"
if(istype(spawner, /mob/living/simple_animal/hostile/guardian))
var/mob/living/simple_animal/hostile/guardian/G = spawner
if(G.summoner)
G.summoner << "<span class='danger'><B>[AM] has crossed your surveillance trap at [get_area(snare_loc)].</span></B>"
////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)
src << "<span class='danger'><B>You must be manifested to create bombs!</span></B>"
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))
src << "<span class='danger'><B>Success! Bomb armed!</span></B>"
bomb_cooldown = world.time + 200
B.spawner = src
B.disguise (A)
else
src << "<span class='danger'><B>Your powers are on cooldown! You must wait 20 seconds between bombs.</span></B>"
/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)
stored_obj.loc = get_turf(src.loc)
spawner << "<span class='danger'><B>Failure! Your trap didn't catch anyone this time.</span></B>"
qdel(src)
/obj/item/weapon/guardian_bomb/proc/detonate(var/mob/living/user)
user << "<span class='danger'><B>The [src] was boobytrapped!</span></B>"
spawner << "<span class='danger'><B>Success! Your trap caught [user]</span></B>"
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)
user << "<span class='notice'>Looks odd!</span>"
////////Creation
/obj/item/weapon/guardiancreator
name = "deck of tarot cards"
desc = "An enchanted deck of tarot cards, rumored to be a source of unimaginable power. "
icon = 'icons/obj/toy.dmi'
icon_state = "deck_syndicate_full"
var/used = FALSE
var/theme = "magic"
var/mob_name = "Guardian Spirit"
var/use_message = "You shuffle the deck..."
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/random = TRUE
var/adminseal = FALSE
/obj/item/weapon/guardiancreator/attack_self(mob/living/user)
for(var/mob/living/simple_animal/hostile/guardian/G in living_mob_list)
if (G.summoner == user)
user << "You already have a [mob_name]!"
return
if(user.mind && user.mind.changeling)
user << "[ling_failure]"
return
if(used == TRUE)
user << "[used_message]"
return
used = TRUE
user << "[use_message]"
var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as the [mob_name] of [user.real_name]?",BE_PAI, null, FALSE, 100)
var/mob/dead/observer/theghost = null
if(candidates.len)
theghost = pick(candidates)
spawn_guardian(user, theghost.key)
else
user << "[failure_message]"
used = FALSE
/obj/item/weapon/guardiancreator/proc/spawn_guardian(var/mob/living/user, var/key)
var/gaurdiantype = "Standard"
if(random)
gaurdiantype = pick(possible_guardians)
if(adminseal)
gaurdiantype = pick("StandardSeal","SupportSeal")
else
gaurdiantype = input(user, "Pick the type of [mob_name]", "[mob_name] Creation") as null|anything in possible_guardians
var/pickedtype = /mob/living/simple_animal/hostile/guardian/punch
var/picked_color = pick("#FFFFFF","#000000","#808080","#A52A2A","#FF0000","#8B0000","#DC143C","#FFA500","#FFFF00","#008000","#00FF00","#006400","#00FFFF","#0000FF","#000080","#008080","#800080","#4B0082")
switch(gaurdiantype)
if("Chaos")
pickedtype = /mob/living/simple_animal/hostile/guardian/fire
if("Standard")
pickedtype = /mob/living/simple_animal/hostile/guardian/punch
if("StandardSeal")
pickedtype = /mob/living/simple_animal/hostile/guardian/punch/sealpunch
if("Ranged")
pickedtype = /mob/living/simple_animal/hostile/guardian/ranged
if("Support")
pickedtype = /mob/living/simple_animal/hostile/guardian/healer
if("SupportSeal")
pickedtype = /mob/living/simple_animal/hostile/guardian/healer/sealhealer
if("Explosive")
pickedtype = /mob/living/simple_animal/hostile/guardian/bomb
var/mob/living/simple_animal/hostile/guardian/G = new pickedtype(user)
G.summoner = user
G.key = key
G << "You are a [mob_name] bound to serve [user.real_name]."
G << "You are capable of manifesting or recalling to your master with verbs in the Guardian tab. You will also find a verb to communicate with them privately there."
G << "While personally invincible, you will die if [user.real_name] does, and any damage dealt to you will have a portion passed on to them as you feed upon them to sustain yourself."
G << "[G.playstyle_string]"
user.verbs += /mob/living/proc/guardian_comm
if(!adminseal)
user.verbs += /mob/living/proc/guardian_recall
user.verbs += /mob/living/proc/guardian_reset
switch (theme)
if("magic")
G.name = "[mob_name]"
G.color = picked_color
G.real_name = "[mob_name]"
user << "[G.magic_fluff_string]."
if("tech")
var/colour = pick("orange", "neon", "pink", "red", "blue", "green")
G.name = "[mob_name] [capitalize(colour)]"
G.real_name = "[mob_name] [capitalize(colour)]"
G.icon_living = "parasite[colour]"
G.icon_state = "parasite[colour]"
G.animated_manifest = TRUE
user << "[G.tech_fluff_string]."
G.speak_emote = list("states")
if("bio")
user << "[G.bio_fluff_string]."
G.name = "[mob_name]"
G.color = picked_color
G.real_name = "[mob_name]"
G.icon_living = "headcrab"
G.icon_state = "headcrab"
G.attacktext = "swarms"
G.speak_emote = list("chitters")
if("seal")
user << "[G.admin_fluff_string]."
G.name = "[mob_name]"
G.color = picked_color
G.real_name = "[mob_name]"
G.icon = 'icons/mob/animal.dmi'
G.icon_living = "seal"
G.icon_state = "seal"
G.attacktext = "slaps"
G.speak_emote = list("barks")
/obj/item/weapon/guardiancreator/choose
random = FALSE
/obj/item/weapon/guardiancreator/tech
name = "holoparasite injector"
desc = "It contains alien nanoswarm of unknown origin. Though capable of near sorcerous feats via use of hardlight holograms and nanomachines, it requires an organic host as a home base and source of fuel."
icon = 'icons/obj/syringe.dmi'
icon_state = "combat_hypo"
theme = "tech"
mob_name = "Holoparasite"
use_message = "You start to power on the injector..."
used_message = "The injector has already been used."
failure_message = "<B>...ERROR. BOOT SEQUENCE ABORTED. AI FAILED TO INTIALIZE. PLEASE CONTACT SUPPORT OR TRY AGAIN LATER.</B>"
ling_failure = "The holoparasites recoil in horror. They want nothing to do with a creature like you."
/obj/item/weapon/guardiancreator/tech/choose
random = FALSE
/obj/item/weapon/guardiancreator/biological
name = "scarab egg cluster"
desc = "A parasitic species that will nest in the closest living creature upon birth. While not great for your health, they'll defend their new 'hive' to the death."
icon = 'icons/obj/fish_items.dmi'
icon_state = "eggs"
theme = "bio"
mob_name = "Scarab Swarm"
use_message = "The eggs begin to twitch..."
used_message = "The cluster already hatched."
failure_message = "<B>...but soon settles again. Guess they weren't ready to hatch after all.</B>"
/obj/item/weapon/guardiancreator/biological/choose
random = FALSE
/obj/item/weapon/guardiancreator/adminbus
name = "Avatar deck"
desc = "A mystical deck..oddly all the cards have a form of Bus on them."
icon = 'icons/obj/toy.dmi'
icon_state = "deck_syndicate_full"
theme = "seal"
mob_name = "Avatar"
use_message = "URK!"
used_message = "arf?"
failure_message = "<B>...</B>"
adminseal = TRUE
/obj/item/weapon/guardiancreator/adminbus/attack_self(mob/living/user)
var/list/targets = list()
var/target = null
targets += getmobs() //Fill list, prompt user with list
target = input("Select a Player to guard!", "Player list", null, null) as null|anything in targets
if(!target) return
var/mob/living/carbon/human/H = target
if(H.mind )
spawn_guardian(H,user.key)
else
user << "Target has no mind. Aborting."
/obj/item/weapon/paper/guardian
name = "Holoparasite Guide"
icon_state = "paper"
info = {"<b>A list of Holoparasite Types</b><br>
<br>
<b>Chaos</b>: Ignites mobs on touch. teleports them at random on attack. Automatically extinguishes the user if they catch fire.<br>
<br>
<b>Standard</b>:Devestating close combat attacks and high damage resist. No special powers.<br>
<br>
<b>Ranged</b>: Has two modes. Ranged: Extremely weak, highly spammable projectile attack. Scout: Can not attack, but can move through walls. Can lay surveillance snares in either mode.<br>
<br>
<b>Support</b>:Has two modes. Combat: Medium power attacks and damage resist. Healer: Attacks heal damage, but low damage resist and slow movemen. Can deploy a bluespace beacon and warp targets to it (including you) in either mode.<br>
<br>
<b>Explosive</b>: High damage resist and medium power attack. Can turn any object into a bomb, dealing explosive damage to the next person to touch it. The object will return to normal after the trap is triggered.<br>
"}
/obj/item/weapon/paper/guardian/update_icon()
return
/obj/item/weapon/storage/box/syndie_kit/guardian
name = "holoparasite injector kit"
/obj/item/weapon/storage/box/syndie_kit/guardian/New()
..()
new /obj/item/weapon/guardiancreator/tech/choose(src)
new /obj/item/weapon/paper/guardian(src)
return
///HUD
/datum/hud/proc/guardian_hud(ui_style = 'icons/mob/screen1_midnight.dmi')
adding = list()
var/obj/screen/using
using = new /obj/screen/guardian/Manifest()
using.screen_loc = ui_rhand
adding += using
using = new /obj/screen/guardian/Recall()
using.screen_loc = ui_lhand
adding += using
using = new /obj/screen/guardian/ToggleMode()
using.screen_loc = ui_storage1
adding += using
using = new /obj/screen/guardian/ToggleLight()
using.screen_loc = ui_inventory
adding += using
using = new /obj/screen/guardian/Communicate()
using.screen_loc = ui_back
adding += using
mymob.client.screen = list()
mymob.client.screen += mymob.client.void
mymob.client.screen += adding
//HUD BUTTONS
/obj/screen/guardian
icon = 'icons/mob/guardian.dmi'
/obj/screen/guardian/Manifest
icon_state = "manifest"
name = "Manifest"
desc = "Spring forth into battle!"
/obj/screen/guardian/Manifest/Click()
if(isguardian(usr))
var/mob/living/simple_animal/hostile/guardian/G = usr
G.Manifest()
/obj/screen/guardian/Recall
icon_state = "recall"
name = "Recall"
desc = "Return to your user."
/obj/screen/guardian/Recall/Click()
if(isguardian(usr))
var/mob/living/simple_animal/hostile/guardian/G = usr
G.Recall()
/obj/screen/guardian/ToggleMode
icon_state = "toggle"
name = "Toggle Mode"
desc = "Switch between ability modes."
/obj/screen/guardian/ToggleMode/Click()
if(isguardian(usr))
var/mob/living/simple_animal/hostile/guardian/G = usr
G.ToggleMode()
/obj/screen/guardian/Communicate
icon_state = "communicate"
name = "Communicate"
desc = "Communicate telepathically with your user."
/obj/screen/guardian/Communicate/Click()
if(isguardian(usr))
var/mob/living/simple_animal/hostile/guardian/G = usr
G.Communicate()
/obj/screen/guardian/ToggleLight
icon_state = "light"
name = "Toggle Light"
desc = "Glow like star dust."
/obj/screen/guardian/ToggleLight/Click()
if(isguardian(usr))
var/mob/living/simple_animal/hostile/guardian/G = usr
G.ToggleLight()
+6 -1
View File
@@ -142,7 +142,12 @@ proc/isembryo(A)
return 1
return 0
proc/isobserver(A)
/proc/isguardian(A)
if(istype(A, /mob/living/simple_animal/hostile/guardian))
return 1
return 0
/proc/isobserver(A)
if(istype(A, /mob/dead/observer))
return 1
return 0
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 224 KiB

After

Width:  |  Height:  |  Size: 244 KiB

+1
View File
@@ -1473,6 +1473,7 @@
#include "code\modules\mob\living\simple_animal\friendly\slime.dm"
#include "code\modules\mob\living\simple_animal\friendly\spiderbot.dm"
#include "code\modules\mob\living\simple_animal\friendly\tomato.dm"
#include "code\modules\mob\living\simple_animal\guardian\guardian.dm"
#include "code\modules\mob\living\simple_animal\hostile\alien.dm"
#include "code\modules\mob\living\simple_animal\hostile\bat.dm"
#include "code\modules\mob\living\simple_animal\hostile\bear.dm"