Merge branch 'master' of https://github.com/tgstation/-tg-station into bring_colossus_back_2016

This commit is contained in:
Ergovisavi
2016-09-07 01:08:58 -07:00
138 changed files with 1794 additions and 584 deletions
@@ -45,7 +45,7 @@
if(leaping || stat || buckled || lying)
return
if(!has_gravity(src) || !has_gravity(A))
if(!has_gravity() || !A.has_gravity())
src << "<span class='alertalien'>It is unsafe to leap without gravity!</span>"
//It's also extremely buggy visually, so it's balance+bugfix
return
@@ -15,7 +15,7 @@
return 0
return ..()
/mob/living/carbon/human/mob_has_gravity()
/mob/living/carbon/human/has_gravity()
. = ..()
if(!.)
if(mob_negates_gravity())
@@ -849,7 +849,7 @@
. -= 2
if(!(H.status_flags & IGNORESLOWDOWN))
if(!has_gravity(H))
if(!H.has_gravity())
if(FLYING in specflags)
. += speedmod
return
@@ -1416,7 +1416,6 @@
if(-INFINITY to 120)
H.throw_alert("temp", /obj/screen/alert/cold, 3)
H.apply_damage(COLD_DAMAGE_LEVEL_3*coldmod, BURN)
H.apply_status_effect(/datum/status_effect/freon)
else
H.clear_alert("temp")
+1 -1
View File
@@ -43,7 +43,7 @@
//stuff in the stomach
handle_stomach()
update_gravity(mob_has_gravity())
update_gravity(has_gravity())
if(machine)
machine.check_eye(src)
+3 -3
View File
@@ -602,7 +602,7 @@
. += config.walk_speed
/mob/living/proc/makeTrail(turf/T)
if(!has_gravity(src))
if(!has_gravity())
return
var/blood_exists = 0
@@ -666,8 +666,8 @@
if (AM.density && AM.anchored)
pressure_resistance_prob_delta -= 20
break
..(pressure_difference, direction, pressure_resistance_prob_delta)
if(!slipping)
..(pressure_difference, direction, pressure_resistance_prob_delta)
/mob/living/verb/resist()
set name = "Resist"
@@ -71,3 +71,5 @@
var/blood_volume = 0 //how much blood the mob has
var/obj/effect/proc_holder/ranged_ability //Any ranged ability the mob has, as a click override
var/slipping = FALSE
+1 -1
View File
@@ -144,7 +144,7 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
/mob/living/send_speech(message, message_range = 7, obj/source = src, bubble_type = bubble_icon, list/spans)
var/list/listening = get_hearers_in_view(message_range, source)
for(var/mob/M in player_list)
if(M.stat == DEAD && M.client && ((M.client.prefs.chat_toggles & CHAT_GHOSTEARS) || (get_dist(M, src) <= 7)) && client) // client is so that ghosts don't have to listen to mice
if(M.stat == DEAD && M.client && ((M.client.prefs.chat_toggles & CHAT_GHOSTEARS) || (get_dist(M, src) <= 7 && M.z == z)) && client) // client is so that ghosts don't have to listen to mice
listening |= M
var/rendered = compose_message(src, languages_spoken, message, , spans)
@@ -19,4 +19,6 @@
msg += "[src]Core.exe has stopped responding! NTOS is searching for a solution to the problem...\n"
msg += "*---------*</span>"
user << msg
user << msg
..()
+1 -1
View File
@@ -9,7 +9,7 @@
else //I'm not removing that shitton of tabs, unneeded as they are. -- Urist
//Being dead doesn't mean your temperature never changes
update_gravity(mob_has_gravity())
update_gravity(has_gravity())
if(malfhack && malfhack.aidisabled)
deltimer(malfhacking)
@@ -0,0 +1,4 @@
/mob/living/silicon/examine(mob/user) //Displays a silicon's laws to ghosts
if(laws && isobserver(user))
user << "<b>[src] has the following laws:</b>"
laws.show_laws(user)
@@ -236,7 +236,7 @@
else
src << "<span class='notice'>Unusable emote '[act]'. Say *help for a list.</span>"
if (message && src.stat == CONSCIOUS)
if (message && stat == CONSCIOUS)
log_emote("[name]/[key] : [message]")
if (m_type & 1)
visible_message(message)
@@ -248,9 +248,10 @@
set category = "Robot Commands"
set name = "Power Warning"
if(!cell || !cell.charge)
visible_message("The power warning light on <span class='name'>[src]</span> flashes urgently.",\
"You announce you are operating in low power mode.")
playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0)
else
src << "<span class='warning'>You can only use this emote when you're out of charge.</span>"
if(stat == CONSCIOUS)
if(!cell || !cell.charge)
visible_message("The power warning light on <span class='name'>[src]</span> flashes urgently.",\
"You announce you are operating in low power mode.")
playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0)
else
src << "<span class='warning'>You can only use this emote when you're out of charge.</span>"
@@ -47,3 +47,5 @@
msg += "*---------*</span>"
user << msg
..()
@@ -11,7 +11,7 @@
/mob/living/silicon/robot/mob_negates_gravity()
return magpulse
/mob/living/silicon/robot/mob_has_gravity()
/mob/living/silicon/robot/has_gravity()
return ..() || mob_negates_gravity()
/mob/living/silicon/robot/experience_pressure_difference(pressure_difference, direction)
@@ -859,7 +859,7 @@ Pass a positive integer as an argument to override a bot's default speed.
src << "<span class='notice'>You sense your form change as you are uploaded into [src].</span>"
bot_name = name
name = paicard.pai.name
faction = user.faction
faction = user.faction.Copy()
add_logs(user, paicard.pai, "uploaded to [bot_name],")
return 1
else
@@ -251,7 +251,7 @@
/mob/living/simple_animal/drone/mob_negates_gravity()
return 1
/mob/living/simple_animal/drone/mob_has_gravity()
/mob/living/simple_animal/drone/has_gravity()
return ..() || mob_negates_gravity()
/mob/living/simple_animal/drone/experience_pressure_difference(pressure_difference, direction)
@@ -38,7 +38,7 @@
/mob/living/simple_animal/hostile/guardian/charger/Move()
if(charging)
PoolOrNew(/obj/effect/overlay/temp/decoy, list(loc,src))
PoolOrNew(/obj/effect/overlay/temp/decoy/fading, list(loc,src))
. = ..()
/mob/living/simple_animal/hostile/guardian/charger/snapback()
@@ -20,6 +20,7 @@
response_harm = "hits"
maxHealth = 60
health = 60
var/armored = FALSE
melee_damage_lower = 20
melee_damage_upper = 30
@@ -46,11 +47,56 @@
icon_state = "snowbear"
icon_living = "snowbear"
icon_dead = "snowbear_dead"
desc = "It's a polar bear, in space, but not actually in space. "
desc = "It's a polar bear, in space, but not actually in space."
/mob/living/simple_animal/hostile/bear/russian
name = "combat bear"
desc = "A ferocious brown bear decked out in armor plating, a red star with yellow outlining details the shoulder plating."
icon_state = "combatbear"
icon_living = "combatbear"
icon_dead = "combatbear_dead"
faction = list("russian")
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/bear = 5, /obj/item/clothing/head/bearpelt = 1, /obj/item/bear_armor = 1)
melee_damage_lower = 25
melee_damage_upper = 35
armour_penetration = 20
health = 120
maxHealth = 120
armored = TRUE
/mob/living/simple_animal/hostile/bear/Process_Spacemove(movement_dir = 0)
return 1 //No drifting in space for space bears!
/mob/living/simple_animal/hostile/bear/update_icons()
..()
if(armored)
var/image/B = image(icon = 'icons/mob/animal.dmi', icon_state = "armor_bear")
if(B)
add_overlay(B)
/obj/item/bear_armor
name = "pile of bear armor"
desc = "A scattered pile of various shaped armor pieces fitted for a bear, some duct tape, and a nail filer. Crude instructions \
are written on the back of one of the plates in russian. This seems like an awful idea."
icon = 'icons/obj/items.dmi'
icon_state = "bear_armor_upgrade"
/obj/item/bear_armor/afterattack(atom/target, mob/user, proximity_flag)
if(istype(target, /mob/living/simple_animal/hostile/bear) && proximity_flag)
var/mob/living/simple_animal/hostile/bear/A = target
if(A.armored)
user << "<span class='warning'>[A] has already been armored up!</span>"
return
A.armored = TRUE
A.maxHealth += 60
A.health += 60
A.armour_penetration += 20
A.melee_damage_lower += 5
A.melee_damage_upper += 5
A.update_icons()
user << "<span class='info'>You strap the armor plating to [A] and sharpen their claws with the nail filer. This was a great idea.</span>"
qdel(src)
@@ -74,6 +74,11 @@
AIStatus = AI_IDLE // otherwise we go idle
return 1
/mob/living/simple_animal/hostile/attacked_by(obj/item/I, mob/living/user)
if(stat == CONSCIOUS && !target && AIStatus != AI_OFF && !client && user)
FindTarget(list(user), 1)
return ..()
/mob/living/simple_animal/hostile/bullet_act(obj/item/projectile/P)
if(stat == CONSCIOUS && !target && AIStatus != AI_OFF && !client)
if(P.firer && get_dist(src, P.firer) <= aggro_vision_range)
@@ -110,9 +110,9 @@ Difficulty: Hard
/mob/living/simple_animal/hostile/megafauna/bubblegum/Move()
if(!stat)
playsound(src.loc, 'sound/effects/meteorimpact.ogg', 200, 1)
playsound(src.loc, 'sound/effects/meteorimpact.ogg', 200, 1, 2, 1)
if(charging)
PoolOrNew(/obj/effect/overlay/temp/decoy, list(loc,src))
PoolOrNew(/obj/effect/overlay/temp/decoy/fading, list(loc,src))
DestroySurroundings()
. = ..()
if(charging)
@@ -126,15 +126,21 @@ Difficulty: Hard
charge()
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/charge()
var/turf/T = get_step_away(target, src)
var/turf/T = get_turf(target)
if(!T || T == loc)
return
PoolOrNew(/obj/effect/overlay/temp/dragon_swoop, T)
charging = 1
DestroySurroundings()
PoolOrNew(/obj/effect/overlay/temp/dragon_swoop, T)
walk(src, 0)
setDir(get_dir(src, T))
var/obj/effect/overlay/temp/decoy/D = PoolOrNew(/obj/effect/overlay/temp/decoy, list(loc,src))
D.color = "#FF0000"
animate(D, alpha = 0, color = initial(D.color), transform = matrix()*2, time = 5)
sleep(5)
walk(src,0)
throw_at(T, 7, 1, src, 0)
throw_at(T, get_dist(src, T), 1, src, 0)
charging = 0
Goto(target,move_to_delay,minimum_distance)
Goto(target, move_to_delay, minimum_distance)
/mob/living/simple_animal/hostile/megafauna/bubblegum/Bump(atom/A)
@@ -148,16 +154,15 @@ Difficulty: Hard
if(!charging)
return ..()
else if(A)
if(isliving(A))
var/mob/living/L = A
L.visible_message("<span class='danger'>[src] slams into [L]!</span>", "<span class='userdanger'>[src] slams into you!</span>")
L.apply_damage(40, BRUTE)
playsound(get_turf(L), 'sound/effects/meteorimpact.ogg', 100, 1)
shake_camera(L, 4, 3)
shake_camera(src, 2, 3)
var/throwtarget = get_edge_target_turf(src, get_dir(src, get_step_away(L, src)))
L.throw_at_fast(throwtarget)
else if(isliving(A))
var/mob/living/L = A
L.visible_message("<span class='danger'>[src] slams into [L]!</span>", "<span class='userdanger'>[src] slams into you!</span>")
L.apply_damage(40, BRUTE)
playsound(get_turf(L), 'sound/effects/meteorimpact.ogg', 100, 1)
shake_camera(L, 4, 3)
shake_camera(src, 2, 3)
var/throwtarget = get_edge_target_turf(src, get_dir(src, get_step_away(L, src)))
L.throw_at_fast(throwtarget, 3)
charging = 0
@@ -191,7 +191,7 @@ Difficulty: Medium
if(stat || swooping)
return
swoop_cooldown = world.time + 200
var/swoop_target
var/atom/swoop_target
if(manual_target)
swoop_target = manual_target
else
@@ -212,7 +212,7 @@ Difficulty: Medium
fire_rain()
icon_state = "dragon"
if(swoop_target && !qdeleted(swoop_target))
if(swoop_target && !qdeleted(swoop_target) && swoop_target.z == src.z)
tturf = get_turf(swoop_target)
else
tturf = get_turf(src)
@@ -0,0 +1,584 @@
#define MEDAL_PREFIX "Hierophant"
/*
The Hierophant
The Hierophant spawns in its arena, an area designed to make it harder to fight than it would otherwise be.
The text this boss speaks is ROT4, use ROT22 to decode
The Hierophant's attacks are as follows, and INTENSIFY at a random chance based on Hierophant's health;
- Creates a cardinal or diagonal blast(Cross Blast) under its target, exploding after a short time.
INTENSITY EFFECT: Creates one of the cross blast types under itself instead of under the target.
INTENSITY EFFECT: The created Cross Blast fires in all directions if below half health.
- If no chasers exist, creates a chaser that will seek its target, leaving a trail of blasts.
INTENSITY EFFECT: Creates a second, slower chaser.
- Creates an expanding AoE burst.
- INTENSE ATTACKS:
If target is at least 2 tiles away; Blinks to the target after a very brief delay, damaging everything near the start and end points.
As above, but does so multiple times if below half health.
Rapidly creates Cross Blasts under a target.
If chasers are off cooldown, creates four high-speed chasers.
- IF TARGET WAS STRUCK IN MELEE: Creates a 3x3 square of blasts under the target.
Cross Blasts and the AoE burst gain additional range as the Hierophant loses health, while Chasers gain additional speed.
When The Hierophant dies, it leaves behind its staff, which, while much weaker than when wielded by The Hierophant itself, is still quite effective.
- The staff can place a teleport rune, allowing the user to teleport themself and their allies to the rune.
Difficulty: Hard
*/
/mob/living/simple_animal/hostile/megafauna/hierophant
name = "Hierophant"
desc = "Stolen from Hyper Light Drifter."
health = 2500
maxHealth = 2500
attacktext = "clubs"
//attack_sound = 'sound/weapons/sonic_jackhammer.ogg'
attack_sound = "swing_hit"
icon_state = "hierophant"
icon_living = "hierophant"
friendly = "stares down"
icon = 'icons/mob/lavaland/hierophant.dmi'
faction = list("boss") //asteroid mobs? get that shit out of my beautiful square house
speak_emote = list("preaches")
armour_penetration = 50
melee_damage_lower = 10
melee_damage_upper = 10
speed = 1
move_to_delay = 10
ranged = 1
pixel_x = -16
ranged_cooldown_time = 40
aggro_vision_range = 23
loot = list(/obj/item/weapon/hierophant_staff)
wander = FALSE
var/burst_range = 3 //range on burst aoe
var/beam_range = 5 //range on cross blast beams
var/chaser_speed = 3 //how fast chasers are currently
var/chaser_cooldown = 101 //base cooldown/cooldown var between spawning chasers
var/major_attack_cooldown = 60 //base cooldown for major attacks
var/blinking = FALSE //if we're doing something that requires us to stand still and not attack
var/obj/effect/hierophant/spawned_rune //the rune we teleport back to
var/timeout_time = 15 //after this many Life() ticks with no target, we return to our rune
var/did_reset = TRUE //if we timed out, returned to our rune, and healed some
//var/list/kill_phrases = list("Wsyvgi sj irivkc xettih. Vitemvmrk...", "Irivkc wsyvgi jsyrh. Vitemvmrk...", "Jyip jsyrh. Egxmzexmrk vitemv gcgpiw...")
//var/list/target_phrases = list("Xevkix psgexih.", "Iriqc jsyrh.", "Eguymvih xevkix.")
medal_type = MEDAL_PREFIX
score_type = BIRD_SCORE
del_on_death = TRUE
death_sound = 'sound/magic/Repulse.ogg'
/mob/living/simple_animal/hostile/megafauna/hierophant/New()
..()
internal = new/obj/item/device/gps/internal/hierophant(src)
spawned_rune = new(loc)
/mob/living/simple_animal/hostile/megafauna/hierophant/Life()
. = ..()
if(. && spawned_rune && !client)
if(target || loc == spawned_rune.loc)
timeout_time = initial(timeout_time)
else
timeout_time--
if(timeout_time <= 0 && !did_reset)
did_reset = TRUE
//visible_message("<span class='hierophant'>\"Vixyvrmrk xs fewi...\"</span>")
blink(spawned_rune)
adjustHealth(max((health - maxHealth) * 0.5, 25)) //heal for 50% of our missing health
wander = FALSE
/*if(health > maxHealth * 0.9)
visible_message("<span class='hierophant'>\"Vitemvw gsqtpixi. Stivexmrk ex qebmqyq ijjmgmirgc.\"</span>")
else
visible_message("<span class='hierophant'>\"Vitemvw gsqtpixi. Stivexmsrep ijjmgmirgc gsqtvsqmwih.\"</span>")*/
/mob/living/simple_animal/hostile/megafauna/hierophant/death()
if(health > 0 || stat == DEAD)
return
else
stat = DEAD
blinking = TRUE //we do a fancy animation, release a huge burst(), and leave our staff.
animate(src, alpha = 0, color = "660099", time = 20, easing = EASE_OUT)
burst_range = 10
//visible_message("<span class='hierophant'>\"Mrmxmexmrk wipj-hiwxvygx wiuyirgi...\"</span>")
visible_message("<span class='hierophant_warning'>[src] disappears in a massive burst of magic, leaving only its staff.</span>")
burst(get_turf(src))
..()
/mob/living/simple_animal/hostile/megafauna/hierophant/Destroy()
qdel(spawned_rune)
. = ..()
/mob/living/simple_animal/hostile/megafauna/hierophant/devour(mob/living/L)
for(var/obj/item/W in L)
if(!L.unEquip(W))
qdel(W)
/*visible_message(
"<span class='hierophant'>\"[pick(kill_phrases)]\"</span>\n<span class='hierophant_warning'>[src] annihilates [L]!</span>",
"<span class='userdanger'>You annihilate [L], restoring your health!</span>")*/
visible_message(
"<span class='hierophant'>\"Caw.\"</span>\n<span class='hierophant_warning'>[src] annihilates [L]!</span>",
"<span class='userdanger'>You annihilate [L], restoring your health!</span>")
adjustHealth(-L.maxHealth*0.5)
L.dust()
/*/mob/living/simple_animal/hostile/megafauna/hierophant/GiveTarget(new_target)
var/targets_the_same = (new_target == target)
. = ..()
if(. && target && !targets_the_same)
visible_message("<span class='hierophant'>\"[pick(target_phrases)]\"</span>")*/
/mob/living/simple_animal/hostile/megafauna/hierophant/adjustHealth(amount)
. = ..()
if(src && amount > 0 && !blinking)
wander = TRUE
did_reset = FALSE
/mob/living/simple_animal/hostile/megafauna/hierophant/AttackingTarget()
if(!blinking)
if(target && isliving(target))
addtimer(src, "melee_blast", 0, FALSE, get_turf(target)) //melee attacks on living mobs produce a 3x3 blast
..()
/mob/living/simple_animal/hostile/megafauna/hierophant/DestroySurroundings()
if(!blinking)
..()
/mob/living/simple_animal/hostile/megafauna/hierophant/Move()
if(!blinking)
/*if(!stat)
playsound(loc, 'sound/mecha/mechmove04.ogg', 150, 1, -4)*/
..()
/mob/living/simple_animal/hostile/megafauna/hierophant/Goto(target, delay, minimum_distance)
wander = TRUE
if(!blinking)
..()
/mob/living/simple_animal/hostile/megafauna/hierophant/proc/calculate_rage() //how angry we are overall
did_reset = FALSE //oh hey we're doing SOMETHING, clearly we might need to heal if we recall
anger_modifier = Clamp(((maxHealth - health) / 42),0,50)
burst_range = initial(burst_range) + round(anger_modifier * 0.08)
beam_range = initial(beam_range) + round(anger_modifier * 0.12)
/mob/living/simple_animal/hostile/megafauna/hierophant/OpenFire()
calculate_rage()
var/target_is_slow = FALSE
if(isliving(target))
var/mob/living/L = target
if(!blinking && L.stat == DEAD && get_dist(src, L) > 2)
blink(L)
return
if(L.movement_delay() > 1.5)
target_is_slow = TRUE
chaser_speed = max(1, (3 - anger_modifier * 0.04) + target_is_slow * 0.5)
if(blinking)
return
ranged_cooldown = world.time + max(5, ranged_cooldown_time - anger_modifier * 0.75) //scale cooldown lower with high anger.
if(prob(anger_modifier * 0.75)) //major ranged attack
var/list/possibilities = list()
var/cross_counter = 1 + round(anger_modifier * 0.12)
if(cross_counter > 1)
possibilities += "cross_blast_spam"
if(get_dist(src, target) > 2)
possibilities += "blink_spam"
if(chaser_cooldown < world.time)
if(prob(anger_modifier * 2))
possibilities = list("chaser_swarm")
else
possibilities += "chaser_swarm"
if(possibilities.len)
ranged_cooldown = world.time + max(5, major_attack_cooldown - anger_modifier * 0.75) //we didn't cancel out of an attack, use the higher cooldown
var/blink_counter = 1 + round(anger_modifier * 0.08)
switch(pick(possibilities))
if("blink_spam") //blink either once or multiple times.
if(health < maxHealth * 0.5 && !target_is_slow && blink_counter > 1)
//visible_message("<span class='hierophant'>\"Mx ampp rsx iwgeti.\"</span>")
animate(src, color = "#660099", time = 6)
while(health && target && blink_counter)
if(loc == target.loc || loc == target) //we're on the same tile as them after about a second we can stop now
break
blink_counter--
blinking = FALSE
blink(target)
blinking = TRUE
sleep(5)
animate(src, color = initial(color), time = 8)
sleep(8)
blinking = FALSE
else
blink(target)
if("cross_blast_spam") //fire a lot of cross blasts at a target.
//visible_message("<span class='hierophant'>\"Piezi mx rsalivi xs vyr.\"</span>")
blinking = TRUE
animate(src, color = "#660099", time = 6)
while(health && target && cross_counter)
cross_counter--
var/delay = 6
if(prob(60))
addtimer(src, "cardinal_blasts", 0, FALSE, target)
else
addtimer(src, "diagonal_blasts", 0, FALSE, target)
delay = 5 //this one isn't so mean, so do the next one faster(if there is one)
sleep(delay)
animate(src, color = initial(color), time = 8)
sleep(8)
blinking = FALSE
if("chaser_swarm") //fire four fucking chasers at a target and their friends.
//visible_message("<span class='hierophant'>\"Mx gerrsx lmhi.\"</span>")
blinking = TRUE
animate(src, color = "#660099", time = 10)
var/list/targets = ListTargets()
var/list/cardinal_copy = cardinal.Copy()
while(health && targets.len && cardinal_copy.len)
var/mob/living/pickedtarget = pick(targets)
if(targets.len > 4)
pickedtarget = pick_n_take(targets)
if(pickedtarget.stat == DEAD)
pickedtarget = target
var/obj/effect/overlay/temp/hierophant/chaser/C = PoolOrNew(/obj/effect/overlay/temp/hierophant/chaser, list(loc, src, pickedtarget, chaser_speed, FALSE))
C.moving = 3
C.moving_dir = pick_n_take(cardinal_copy)
sleep(10)
chaser_cooldown = world.time + initial(chaser_cooldown)
animate(src, color = initial(color), time = 8)
sleep(8)
blinking = FALSE
return
if(prob(10 + (anger_modifier * 0.5)) && get_dist(src, target) > 2)
blink(target)
else if(prob(70 - anger_modifier)) //a cross blast of some type
if(prob(anger_modifier)) //at us?
if(prob(anger_modifier * 2) && health < maxHealth * 0.5) //we're super angry do it at all dirs
addtimer(src, "alldir_blasts", 0, FALSE, src)
else if(prob(60))
addtimer(src, "cardinal_blasts", 0, FALSE, src)
else
addtimer(src, "diagonal_blasts", 0, FALSE, src)
else //at them?
if(prob(anger_modifier * 2) && health < maxHealth * 0.5 && !target_is_slow) //we're super angry do it at all dirs
addtimer(src, "alldir_blasts", 0, FALSE, target)
else if(prob(60))
addtimer(src, "cardinal_blasts", 0, FALSE, target)
else
addtimer(src, "diagonal_blasts", 0, FALSE, target)
else if(chaser_cooldown < world.time) //if chasers are off cooldown, fire some!
var/obj/effect/overlay/temp/hierophant/chaser/C = PoolOrNew(/obj/effect/overlay/temp/hierophant/chaser, list(loc, src, target, chaser_speed, FALSE))
chaser_cooldown = world.time + initial(chaser_cooldown)
if((prob(anger_modifier) || target.Adjacent(src)) && target != src)
var/obj/effect/overlay/temp/hierophant/chaser/OC = PoolOrNew(/obj/effect/overlay/temp/hierophant/chaser, list(loc, src, target, max(1.5, 5 - anger_modifier * 0.07), FALSE))
OC.moving = 4
OC.moving_dir = pick(cardinal - C.moving_dir)
else //just release a burst of power
addtimer(src, "burst", 0, FALSE, get_turf(src))
/mob/living/simple_animal/hostile/megafauna/hierophant/proc/diagonal_blasts(mob/victim) //fire diagonal cross blasts with a delay
var/turf/T = get_turf(victim)
PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/diagonal, list(T, src))
playsound(T,'sound/magic/blink.ogg', 200, 1)
//playsound(T,'sound/effects/bin_close.ogg', 200, 1)
sleep(2)
PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(T, src, FALSE))
for(var/d in diagonals)
addtimer(src, "blast_wall", 0, FALSE, T, d)
/mob/living/simple_animal/hostile/megafauna/hierophant/proc/cardinal_blasts(mob/victim) //fire cardinal cross blasts with a delay
var/turf/T = get_turf(victim)
PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/cardinal, list(T, src))
playsound(T,'sound/magic/blink.ogg', 200, 1)
//playsound(T,'sound/effects/bin_close.ogg', 200, 1)
sleep(2)
PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(T, src, FALSE))
for(var/d in cardinal)
addtimer(src, "blast_wall", 0, FALSE, T, d)
/mob/living/simple_animal/hostile/megafauna/hierophant/proc/alldir_blasts(mob/victim) //fire alldir cross blasts with a delay
var/turf/T = get_turf(victim)
PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph, list(T, src))
playsound(T,'sound/magic/blink.ogg', 200, 1)
//playsound(T,'sound/effects/bin_close.ogg', 200, 1)
sleep(2)
PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(T, src, FALSE))
for(var/d in alldirs)
addtimer(src, "blast_wall", 0, FALSE, T, d)
/mob/living/simple_animal/hostile/megafauna/hierophant/proc/blast_wall(turf/T, dir) //make a wall of blasts beam_range tiles long
var/range = beam_range
var/turf/previousturf = T
var/turf/J = get_step(previousturf, dir)
for(var/i in 1 to range)
PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(J, src, FALSE))
previousturf = J
J = get_step(previousturf, dir)
/mob/living/simple_animal/hostile/megafauna/hierophant/proc/blink(mob/victim) //blink to a target
if(blinking || !victim)
return
var/turf/T = get_turf(victim)
var/turf/source = get_turf(src)
PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph, list(T, src))
PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph, list(source, src))
playsound(T,'sound/magic/blink.ogg', 200, 1)
//playsound(T,'sound/magic/Wand_Teleport.ogg', 200, 1)
playsound(source,'sound/magic/blink.ogg', 200, 1)
//playsound(source,'sound/machines/AirlockOpen.ogg', 200, 1)
blinking = TRUE
sleep(2) //short delay before we start...
PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/teleport, list(T, src))
PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/teleport, list(source, src))
for(var/t in RANGE_TURFS(1, T))
var/obj/effect/overlay/temp/hierophant/blast/B = PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(t, src, FALSE))
B.damage = 30
for(var/t in RANGE_TURFS(1, source))
var/obj/effect/overlay/temp/hierophant/blast/B = PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(t, src, FALSE))
B.damage = 30
animate(src, alpha = 0, time = 2, easing = EASE_OUT) //fade out
sleep(1)
visible_message("<span class='hierophant_warning'>[src] fades out!</span>")
density = FALSE
sleep(2)
forceMove(T)
sleep(1)
animate(src, alpha = 255, time = 2, easing = EASE_IN) //fade IN
sleep(1)
density = TRUE
visible_message("<span class='hierophant_warning'>[src] fades in!</span>")
sleep(1) //at this point the blasts we made detonate
blinking = FALSE
/mob/living/simple_animal/hostile/megafauna/hierophant/proc/melee_blast(mob/victim) //make a 3x3 blast around a target
if(!victim)
return
var/turf/T = get_turf(victim)
if(!T)
return
PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph, list(T, src))
playsound(T,'sound/magic/blink.ogg', 200, 1)
//playsound(T,'sound/effects/bin_close.ogg', 200, 1)
sleep(2)
for(var/t in RANGE_TURFS(1, T))
PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(t, src, FALSE))
/mob/living/simple_animal/hostile/megafauna/hierophant/proc/burst(turf/original) //release a wave of blasts
playsound(original,'sound/magic/blink.ogg', 200, 1)
//playsound(original,'sound/machines/AirlockOpen.ogg', 200, 1)
var/last_dist = 0
for(var/t in spiral_range_turfs(burst_range, original))
var/turf/T = t
if(!T)
continue
var/dist = get_dist(original, T)
if(dist > last_dist)
last_dist = dist
sleep(1 + (burst_range - last_dist) * 0.5) //gets faster as it gets further out
PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(T, src, FALSE))
/mob/living/simple_animal/hostile/megafauna/hierophant/AltClickOn(atom/A) //player control handler(don't give this to a player holy fuck)
if(!istype(A) || get_dist(A, src) <= 2)
return
blink(A)
//Hierophant overlays
/obj/effect/overlay/temp/hierophant
layer = BELOW_MOB_LAYER
var/mob/living/caster //who made this, anyway
/obj/effect/overlay/temp/hierophant/New(loc, new_caster)
..()
if(new_caster)
caster = new_caster
/obj/effect/overlay/temp/hierophant/chaser //a hierophant's chaser. follows target around, moving and producing a blast every speed deciseconds.
duration = 98
var/mob/living/target //what it's following
var/moving_dir //what dir it's moving in
var/previous_moving_dir //what dir it was moving in before that
var/more_previouser_moving_dir //what dir it was moving in before THAT
var/moving = 0 //how many steps to move before recalculating
var/standard_moving_before_recalc = 4 //how many times we step before recalculating normally
var/tiles_per_step = 1 //how many tiles we move each step
var/speed = 3 //how many deciseconds between each step
var/currently_seeking = FALSE
var/friendly_fire_check = FALSE //if blasts produced apply friendly fire
/obj/effect/overlay/temp/hierophant/chaser/New(loc, new_caster, new_target, new_speed, is_friendly_fire)
..()
target = new_target
friendly_fire_check = is_friendly_fire
if(new_speed)
speed = new_speed
addtimer(src, "seek_target", 1)
/obj/effect/overlay/temp/hierophant/chaser/proc/get_target_dir()
. = get_cardinal_dir(src, target)
if((. != previous_moving_dir && . == more_previouser_moving_dir) || . == 0) //we're alternating, recalculate
var/list/cardinal_copy = cardinal.Copy()
cardinal_copy -= more_previouser_moving_dir
. = pick(cardinal_copy)
/obj/effect/overlay/temp/hierophant/chaser/proc/seek_target()
if(!currently_seeking)
currently_seeking = TRUE
while(target && src && !qdeleted(src) && currently_seeking && x && y && target.x && target.y) //can this target actually be sook out
if(!moving) //we're out of tiles to move, find more and where the target is!
more_previouser_moving_dir = previous_moving_dir
previous_moving_dir = moving_dir
moving_dir = get_target_dir()
var/standard_target_dir = get_cardinal_dir(src, target)
if((standard_target_dir != previous_moving_dir && standard_target_dir == more_previouser_moving_dir) || standard_target_dir == 0)
moving = 1 //we would be repeating, only move a tile before checking
else
moving = standard_moving_before_recalc
if(moving) //move in the dir we're moving in right now
var/turf/T = get_turf(src)
for(var/i in 1 to tiles_per_step)
var/maybe_new_turf = get_step(T, moving_dir)
if(maybe_new_turf)
T = maybe_new_turf
else
break
forceMove(T)
make_blast() //make a blast, too
moving--
sleep(speed)
/obj/effect/overlay/temp/hierophant/chaser/proc/make_blast()
PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(loc, caster, friendly_fire_check))
/obj/effect/overlay/temp/hierophant/telegraph
icon = 'icons/effects/96x96.dmi'
icon_state = "hierophant_telegraph"
pixel_x = -32
pixel_y = -32
duration = 3
/obj/effect/overlay/temp/hierophant/telegraph/diagonal
icon_state = "hierophant_telegraph_diagonal"
/obj/effect/overlay/temp/hierophant/telegraph/cardinal
icon_state = "hierophant_telegraph_cardinal"
/obj/effect/overlay/temp/hierophant/telegraph/teleport
icon_state = "hierophant_telegraph_teleport"
duration = 9
/obj/effect/overlay/temp/hierophant/blast
icon_state = "hierophant_blast"
name = "vortex blast"
luminosity = 1
desc = "Get out of the way!"
duration = 9
var/damage = 10 //how much damage do we do?
var/list/hit_things = list() //we hit these already, ignore them
var/friendly_fire_check = FALSE
var/bursting = FALSE //if we're bursting and need to hit anyone crossing us
/obj/effect/overlay/temp/hierophant/blast/New(loc, new_caster, friendly_fire)
..()
friendly_fire_check = friendly_fire
if(new_caster)
hit_things += new_caster
if(istype(loc, /turf/closed/mineral)) //drill mineral turfs
var/turf/closed/mineral/M = loc
M.gets_drilled(caster)
addtimer(src, "blast", 0)
/obj/effect/overlay/temp/hierophant/blast/proc/blast()
var/turf/T = get_turf(src)
if(!T)
return
playsound(T,'sound/magic/Blind.ogg', 125, 1, -5) //make a sound
sleep(6) //wait a little
bursting = TRUE
do_damage(T) //do damage and mark us as bursting
sleep(1.3) //slightly forgiving; the burst animation is 1.5 deciseconds
bursting = FALSE //we no longer damage crossers
/obj/effect/overlay/temp/hierophant/blast/Crossed(atom/movable/AM)
..()
if(bursting)
do_damage(get_turf(src))
/obj/effect/overlay/temp/hierophant/blast/proc/do_damage(turf/T)
for(var/mob/living/L in T.contents - hit_things) //find and damage mobs...
hit_things += L
if((friendly_fire_check && caster && caster.faction_check(L)) || L.stat == DEAD)
continue
if(L.client)
flash_color(L.client, "#660099", 1)
playsound(L,'sound/weapons/sear.ogg', 50, 1, -4)
L << "<span class='userdanger'>You're struck by a [name]!</span>"
var/limb_to_hit = L.get_bodypart(pick("head", "chest", "r_arm", "l_arm", "r_leg", "l_leg"))
var/armor = L.run_armor_check(limb_to_hit, "melee", "Your armor absorbs [src]!", "Your armor blocks part of [src]!", 50, "Your armor was penetrated by [src]!")
L.apply_damage(damage, BURN, limb_to_hit, armor)
if(ismegafauna(L) || istype(L, /mob/living/simple_animal/hostile/asteroid))
L.adjustBruteLoss(damage)
add_logs(caster, L, "struck with a [name]")
for(var/obj/mecha/M in T.contents - hit_things) //and mechs.
hit_things += M
if(M.occupant)
if(friendly_fire_check && caster && caster.faction_check(M.occupant))
continue
M.occupant << "<span class='userdanger'>Your [M.name] is struck by a [name]!</span>"
playsound(M,'sound/weapons/sear.ogg', 50, 1, -4)
M.take_damage(damage, "fire", 0)
/obj/effect/hierophant
name = "hierophant rune"
desc = "A powerful magic mark allowing whomever attunes themself to it to return to it at will."
icon = 'icons/obj/rune.dmi'
icon_state = "hierophant"
layer = LOW_OBJ_LAYER
anchored = TRUE
color = "#CC00FF"
/obj/effect/hierophant/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/hierophant_staff))
var/obj/item/weapon/hierophant_staff/H = I
if(H.rune == src)
user << "<span class='notice'>You start removing your hierophant rune...</span>"
H.timer = world.time + 51
if(do_after(user, 50, target = src))
playsound(src,'sound/magic/Blind.ogg', 200, 1, -4)
PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/teleport, list(get_turf(src), user))
user << "<span class='hierophant_warning'>You touch the rune with the staff, dispelling it!</span>"
H.rune = null
user.update_action_buttons_icon()
qdel(src)
else
H.timer = world.time
else
user << "<span class='hierophant_warning'>You touch the rune with the staff, but nothing happens.</span>"
else
..()
/obj/item/device/gps/internal/hierophant
icon_state = null
gpstag = "Zealous Signal"
desc = "Heed its words."
invisibility = 100
/turf/open/indestructible/hierophant
icon_state = "hierophant1"
initial_gas_mix = "o2=14;n2=23;TEMP=300"
desc = "A floor with a square pattern. It's faintly cool to the touch."
/turf/open/indestructible/hierophant/New()
..()
if(prob(50))
icon_state = "hierophant2"
/turf/closed/indestructible/riveted/hierophant
name = "wall"
desc = "A wall made out of smooth, cold stone."
icon = 'icons/turf/walls/hierophant_wall.dmi'
icon_state = "hierophant"
smooth = SMOOTH_TRUE
#undef MEDAL_PREFIX
@@ -110,6 +110,8 @@ Difficulty: Medium
L.update_transform()
update_transform()
L.faction = faction.Copy()
L.GiveTarget(target)
visible_message("<span class='boldannounce'>[src] splits in twain!</span>")
@@ -223,9 +223,8 @@
A.admin_spawned = admin_spawned
A.GiveTarget(target)
A.friends = friends
A.faction = faction
A.faction = faction.Copy()
ranged_cooldown = world.time + ranged_cooldown_time
return
/mob/living/simple_animal/hostile/asteroid/hivelord/AttackingTarget()
OpenFire()
@@ -733,6 +732,7 @@
speak_emote = list("telepathically cries")
attack_sound = 'sound/weapons/bladeslice.ogg'
stat_attack = 1
flying = TRUE
robust_searching = 1
loot = list()
butcher_results = list(/obj/item/weapon/ore/diamond = 2, /obj/item/stack/sheet/sinew = 2, /obj/item/stack/sheet/bone = 1)
-3
View File
@@ -303,9 +303,6 @@
break
. = dense_object_backup
/mob/proc/mob_has_gravity(turf/T)
return has_gravity(src, T)
/mob/proc/mob_negates_gravity()
return 0