[MIRROR] Cult 2017 Overhaul 1.5: The End - Been finished for 5 days edition (#994)
* Cult 2017 Overhaul 1.5: The End - Been finished for 5 days edition * Rej cleanup * update mob.dmi * Update living_defense.dm
This commit is contained in:
committed by
Poojawa
parent
644a31ed98
commit
88ede32216
@@ -13,4 +13,5 @@ GLOBAL_VAR_INIT(sac_image, null)
|
||||
GLOBAL_VAR_INIT(cult_vote_called, FALSE)
|
||||
GLOBAL_VAR_INIT(cult_mastered, FALSE)
|
||||
GLOBAL_VAR_INIT(reckoning_complete, FALSE)
|
||||
GLOBAL_VAR_INIT(sac_complete, FALSE)
|
||||
GLOBAL_VAR_INIT(sac_complete, FALSE)
|
||||
GLOBAL_DATUM(cult_narsie, /obj/singularity/narsie/large/cult)
|
||||
@@ -287,9 +287,9 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
|
||||
GLOB.blood_target = null
|
||||
else
|
||||
blood_target = GLOB.blood_target
|
||||
if(Cviewer)
|
||||
if(Cviewer.seeking && Cviewer.master)
|
||||
blood_target = Cviewer.master
|
||||
if(Cviewer && Cviewer.seeking && Cviewer.master)
|
||||
blood_target = Cviewer.master
|
||||
desc = "Your blood sense is leading you to [Cviewer.master]"
|
||||
if(!blood_target)
|
||||
if(!GLOB.sac_complete)
|
||||
if(icon_state == "runed_sense0")
|
||||
@@ -301,22 +301,21 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
|
||||
desc = "Nar-Sie demands that [GLOB.sac_mind] be sacrificed before the summoning ritual can begin."
|
||||
add_overlay(GLOB.sac_image)
|
||||
else
|
||||
if(SSticker.mode.eldergod)
|
||||
desc = "The sacrifice is complete, prepare to summon Nar-Sie!"
|
||||
else
|
||||
desc = "The summoning is complete, glory to Nar-Sie!"
|
||||
if(icon_state == "runed_sense1")
|
||||
return
|
||||
animate(src, transform = null, time = 1, loop = 0)
|
||||
angle = 0
|
||||
cut_overlays()
|
||||
icon_state = "runed_sense1"
|
||||
desc = "The sacrifice is complete, bring the wrath of Nar-Sie upon the crew!"
|
||||
add_overlay(narnar)
|
||||
return
|
||||
var/turf/P = get_turf(blood_target)
|
||||
var/turf/Q = get_turf(mob_viewer)
|
||||
var/area/A = get_area(P)
|
||||
if(P.z != Q.z) //The target is on a different Z level, we cannot sense that far.
|
||||
icon_state = "runed_sense2"
|
||||
desc = "[blood_target] is no longer in your sector, you cannot sense its presence here."
|
||||
return
|
||||
desc = "You are currently tracking [blood_target] in [A.name]."
|
||||
var/target_angle = Get_Angle(Q, P)
|
||||
|
||||
@@ -284,7 +284,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
//Now animate the cinematic
|
||||
switch(station_missed)
|
||||
if(NUKE_NEAR_MISS) //nuke was nearby but (mostly) missed
|
||||
if( mode && !override )
|
||||
if(mode && !override )
|
||||
override = mode.name
|
||||
switch( override )
|
||||
if("nuclear emergency") //Nuke wasn't on station when it blew up
|
||||
@@ -294,6 +294,17 @@ SUBSYSTEM_DEF(ticker)
|
||||
station_explosion_detonation(bomb)
|
||||
flick("station_intact_fade_red",cinematic)
|
||||
cinematic.icon_state = "summary_nukefail"
|
||||
if("cult")
|
||||
cinematic.icon_state = null
|
||||
flick("intro_cult",cinematic)
|
||||
sleep(25)
|
||||
world << sound('sound/magic/enter_blood.ogg')
|
||||
sleep(28)
|
||||
world << sound('sound/machines/terminal_off.ogg')
|
||||
sleep(20)
|
||||
flick("station_corrupted",cinematic)
|
||||
world << sound('sound/effects/ghost.ogg')
|
||||
actually_blew_up = FALSE
|
||||
if("gang war") //Gang Domination (just show the override screen)
|
||||
cinematic.icon_state = "intro_malf_still"
|
||||
flick("intro_malf",cinematic)
|
||||
@@ -342,6 +353,13 @@ SUBSYSTEM_DEF(ticker)
|
||||
world << sound('sound/effects/explosionfar.ogg')
|
||||
station_explosion_detonation(bomb) //TODO: no idea what this case could be
|
||||
cinematic.icon_state = "summary_selfdes"
|
||||
if("cult") //Station nuked (nuke,explosion,summary)
|
||||
flick("intro_nuke",cinematic)
|
||||
sleep(35)
|
||||
flick("station_explode_fade_red",cinematic)
|
||||
world << sound('sound/effects/explosionfar.ogg')
|
||||
station_explosion_detonation(bomb) //TODO: no idea what this case could be
|
||||
cinematic.icon_state = "summary_cult"
|
||||
if("no_core") //Nuke failed to detonate as it had no core
|
||||
flick("intro_nuke",cinematic)
|
||||
sleep(35)
|
||||
|
||||
@@ -152,7 +152,7 @@
|
||||
return TRUE
|
||||
|
||||
/datum/action/innate/cult/master/IsAvailable()
|
||||
if(!owner.mind || !owner.mind.has_antag_datum(ANTAG_DATUM_CULT_MASTER))
|
||||
if(!owner.mind || !owner.mind.has_antag_datum(ANTAG_DATUM_CULT_MASTER) || GLOB.cult_narsie)
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -148,8 +148,7 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
|
||||
/obj/effect/rune/proc/fail_invoke()
|
||||
//This proc contains the effects of a rune if it is not invoked correctly, through either invalid wording or not enough cultists. By default, it's just a basic fizzle.
|
||||
visible_message("<span class='warning'>The markings pulse with a \
|
||||
small flash of red light, then fall dark.</span>")
|
||||
visible_message("<span class='warning'>The markings pulse with a small flash of red light, then fall dark.</span>")
|
||||
var/oldcolor = color
|
||||
color = rgb(255, 0, 0)
|
||||
animate(src, color = oldcolor, time = 5)
|
||||
@@ -307,10 +306,11 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
A.forceMove(target)
|
||||
if(movedsomething)
|
||||
..()
|
||||
visible_message("<span class='warning'>There is a sharp crack of inrushing air, and everything above the rune disappears!</span>")
|
||||
visible_message("<span class='warning'>There is a sharp crack of inrushing air, and everything above the rune disappears!</span>", null, "<i>You hear a sharp crack.</i>")
|
||||
to_chat(user, "<span class='cult'>You[moveuserlater ? "r vision blurs, and you suddenly appear somewhere else":" send everything above the rune away"].</span>")
|
||||
if(moveuserlater)
|
||||
user.forceMove(target)
|
||||
target.visible_message("<span class='warning'>There is a boom of outrushing air as something appears above the rune!</span>", null, "<i>You hear a boom.</i>")
|
||||
else
|
||||
fail_invoke()
|
||||
|
||||
@@ -478,10 +478,12 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
send_to_playing_players('sound/effects/dimensional_rend.ogg')
|
||||
var/turf/T = get_turf(src)
|
||||
sleep(40)
|
||||
SSticker.mode.eldergod = FALSE
|
||||
if(src)
|
||||
color = "#FF0000"
|
||||
SSticker.mode.eldergod = FALSE
|
||||
new /obj/singularity/narsie/large(T) //Causes Nar-Sie to spawn even if the rune has been removed
|
||||
deltimer(GLOB.blood_target_reset_timer)
|
||||
new /obj/singularity/narsie/large/cult(T) //Causes Nar-Sie to spawn and makes it the blood target even if the rune has been removed
|
||||
|
||||
|
||||
/obj/effect/rune/narsie/attackby(obj/I, mob/user, params) //Since the narsie rune takes a long time to make, add logging to removal.
|
||||
if((istype(I, /obj/item/weapon/tome) && iscultist(user)))
|
||||
@@ -962,4 +964,4 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
"<span class='cultlarge'>Your link to the world fades. Your form breaks apart.</span>")
|
||||
for(var/obj/I in new_human)
|
||||
new_human.dropItemToGround(I, TRUE)
|
||||
new_human.dust()
|
||||
new_human.dust()
|
||||
@@ -210,13 +210,16 @@
|
||||
var/datum/action/innate/seek_master/SM = new()
|
||||
SM.Grant(newstruct)
|
||||
newstruct.key = target.key
|
||||
var/obj/screen/alert/bloodsense/BS
|
||||
if(newstruct.mind && ((stoner && iscultist(stoner)) || cultoverride) && SSticker && SSticker.mode)
|
||||
SSticker.mode.add_cultist(newstruct.mind, 0)
|
||||
BS = newstruct.alerts.Find("bloodsense")
|
||||
if(iscultist(stoner) || cultoverride)
|
||||
to_chat(newstruct, "<b>You are still bound to serve the cult[stoner ? " and [stoner]":""], follow their orders and help them complete their goals at all costs.</b>")
|
||||
else if(stoner)
|
||||
to_chat(newstruct, "<b>You are still bound to serve your creator, [stoner], follow their orders and help them complete their goals at all costs.</b>")
|
||||
var/obj/screen/alert/bloodsense/BS = newstruct.throw_alert("bloodsense", /obj/screen/alert/bloodsense)
|
||||
BS = newstruct.throw_alert("bloodsense", /obj/screen/alert/bloodsense)
|
||||
if(BS)
|
||||
BS.Cviewer = newstruct
|
||||
newstruct.cancel_camera()
|
||||
|
||||
|
||||
@@ -1,361 +1,370 @@
|
||||
|
||||
/mob/living/proc/run_armor_check(def_zone = null, attack_flag = "melee", absorb_text = null, soften_text = null, armour_penetration, penetrated_text)
|
||||
var/armor = getarmor(def_zone, attack_flag)
|
||||
|
||||
//the if "armor" check is because this is used for everything on /living, including humans
|
||||
if(armor && armour_penetration)
|
||||
armor = max(0, armor - armour_penetration)
|
||||
if(penetrated_text)
|
||||
to_chat(src, "<span class='userdanger'>[penetrated_text]</span>")
|
||||
else
|
||||
to_chat(src, "<span class='userdanger'>Your armor was penetrated!</span>")
|
||||
else if(armor >= 100)
|
||||
if(absorb_text)
|
||||
to_chat(src, "<span class='userdanger'>[absorb_text]</span>")
|
||||
else
|
||||
to_chat(src, "<span class='userdanger'>Your armor absorbs the blow!</span>")
|
||||
else if(armor > 0)
|
||||
if(soften_text)
|
||||
to_chat(src, "<span class='userdanger'>[soften_text]</span>")
|
||||
else
|
||||
to_chat(src, "<span class='userdanger'>Your armor softens the blow!</span>")
|
||||
return armor
|
||||
|
||||
|
||||
/mob/living/proc/getarmor(def_zone, type)
|
||||
return 0
|
||||
|
||||
//this returns the mob's protection against eye damage (number between -1 and 2)
|
||||
/mob/living/proc/get_eye_protection()
|
||||
return 0
|
||||
|
||||
//this returns the mob's protection against ear damage (0:no protection; 1: some ear protection; 2: has no ears)
|
||||
/mob/living/proc/get_ear_protection()
|
||||
return 0
|
||||
|
||||
/mob/living/proc/on_hit(obj/item/projectile/P)
|
||||
return
|
||||
|
||||
/mob/living/bullet_act(obj/item/projectile/P, def_zone)
|
||||
var/armor = run_armor_check(def_zone, P.flag, "","",P.armour_penetration)
|
||||
if(!P.nodamage)
|
||||
apply_damage(P.damage, P.damage_type, def_zone, armor)
|
||||
if(P.dismemberment)
|
||||
check_projectile_dismemberment(P, def_zone)
|
||||
return P.on_hit(src, armor)
|
||||
|
||||
/mob/living/proc/check_projectile_dismemberment(obj/item/projectile/P, def_zone)
|
||||
return 0
|
||||
|
||||
/obj/item/proc/get_volume_by_throwforce_and_or_w_class()
|
||||
if(throwforce && w_class)
|
||||
return Clamp((throwforce + w_class) * 5, 30, 100)// Add the item's throwforce to its weight class and multiply by 5, then clamp the value between 30 and 100
|
||||
else if(w_class)
|
||||
return Clamp(w_class * 8, 20, 100) // Multiply the item's weight class by 8, then clamp the value between 20 and 100
|
||||
else
|
||||
return 0
|
||||
|
||||
/mob/living/hitby(atom/movable/AM, skipcatch, hitpush = 1, blocked = 0)
|
||||
if(istype(AM, /obj/item))
|
||||
var/obj/item/I = AM
|
||||
var/zone = ran_zone("chest", 65)//Hits a random part of the body, geared towards the chest
|
||||
var/dtype = BRUTE
|
||||
var/volume = I.get_volume_by_throwforce_and_or_w_class()
|
||||
if(istype(I,/obj/item/weapon)) //If the item is a weapon...
|
||||
var/obj/item/weapon/W = I
|
||||
dtype = W.damtype
|
||||
|
||||
if (W.throwforce > 0) //If the weapon's throwforce is greater than zero...
|
||||
if (W.throwhitsound) //...and throwhitsound is defined...
|
||||
playsound(loc, W.throwhitsound, volume, 1, -1) //...play the weapon's throwhitsound.
|
||||
else if(W.hitsound) //Otherwise, if the weapon's hitsound is defined...
|
||||
playsound(loc, W.hitsound, volume, 1, -1) //...play the weapon's hitsound.
|
||||
else if(!W.throwhitsound) //Otherwise, if throwhitsound isn't defined...
|
||||
playsound(loc, 'sound/weapons/genhit.ogg',volume, 1, -1) //...play genhit.ogg.
|
||||
|
||||
else if(!I.throwhitsound && I.throwforce > 0) //Otherwise, if the item doesn't have a throwhitsound and has a throwforce greater than zero...
|
||||
playsound(loc, 'sound/weapons/genhit.ogg', volume, 1, -1)//...play genhit.ogg
|
||||
if(!I.throwforce)// Otherwise, if the item's throwforce is 0...
|
||||
playsound(loc, 'sound/weapons/throwtap.ogg', 1, volume, -1)//...play throwtap.ogg.
|
||||
if(!blocked)
|
||||
visible_message("<span class='danger'>[src] has been hit by [I].</span>", \
|
||||
"<span class='userdanger'>[src] has been hit by [I].</span>")
|
||||
var/armor = run_armor_check(zone, "melee", "Your armor has protected your [parse_zone(zone)].", "Your armor has softened hit to your [parse_zone(zone)].",I.armour_penetration)
|
||||
apply_damage(I.throwforce, dtype, zone, armor)
|
||||
if(I.thrownby)
|
||||
add_logs(I.thrownby, src, "hit", I)
|
||||
else
|
||||
return 1
|
||||
else
|
||||
playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1)
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/mech_melee_attack(obj/mecha/M)
|
||||
if(M.occupant.a_intent == INTENT_HARM)
|
||||
M.do_attack_animation(src)
|
||||
if(M.damtype == "brute")
|
||||
step_away(src,M,15)
|
||||
switch(M.damtype)
|
||||
if(BRUTE)
|
||||
Paralyse(1)
|
||||
take_overall_damage(rand(M.force/2, M.force))
|
||||
playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
|
||||
if(BURN)
|
||||
take_overall_damage(0, rand(M.force/2, M.force))
|
||||
playsound(src, 'sound/items/Welder.ogg', 50, 1)
|
||||
if(TOX)
|
||||
M.mech_toxin_damage(src)
|
||||
else
|
||||
return
|
||||
updatehealth()
|
||||
visible_message("<span class='danger'>[M.name] has hit [src]!</span>", \
|
||||
"<span class='userdanger'>[M.name] has hit [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
add_logs(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])")
|
||||
else
|
||||
step_away(src,M)
|
||||
add_logs(M.occupant, src, "pushed", M)
|
||||
visible_message("<span class='warning'>[M] pushes [src] out of the way.</span>", null, null, 5)
|
||||
|
||||
/mob/living/fire_act()
|
||||
adjust_fire_stacks(3)
|
||||
IgniteMob()
|
||||
|
||||
/mob/living/proc/grabbedby(mob/living/carbon/user, supress_message = 0)
|
||||
if(user == src || anchored || !isturf(user.loc))
|
||||
return 0
|
||||
if(!user.pulling || user.pulling != src)
|
||||
user.start_pulling(src, supress_message)
|
||||
return
|
||||
|
||||
if(!(status_flags & CANPUSH))
|
||||
to_chat(user, "<span class='warning'>[src] can't be grabbed more aggressively!</span>")
|
||||
return 0
|
||||
grippedby(user)
|
||||
|
||||
//proc to upgrade a simple pull into a more aggressive grab.
|
||||
/mob/living/proc/grippedby(mob/living/carbon/user)
|
||||
if(user.grab_state < GRAB_KILL)
|
||||
user.changeNext_move(CLICK_CD_GRABBING)
|
||||
playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
|
||||
if(user.grab_state) //only the first upgrade is instantaneous
|
||||
var/old_grab_state = user.grab_state
|
||||
var/grab_upgrade_time = 30
|
||||
visible_message("<span class='danger'>[user] starts to tighten [user.p_their()] grip on [src]!</span>", \
|
||||
"<span class='userdanger'>[user] starts to tighten [user.p_their()] grip on you!</span>")
|
||||
if(!do_mob(user, src, grab_upgrade_time))
|
||||
return 0
|
||||
if(!user.pulling || user.pulling != src || user.grab_state != old_grab_state || user.a_intent != INTENT_GRAB)
|
||||
return 0
|
||||
user.grab_state++
|
||||
switch(user.grab_state)
|
||||
if(GRAB_AGGRESSIVE)
|
||||
add_logs(user, src, "grabbed", addition="aggressively")
|
||||
visible_message("<span class='danger'>[user] has grabbed [src] aggressively!</span>", \
|
||||
"<span class='userdanger'>[user] has grabbed [src] aggressively!</span>")
|
||||
drop_all_held_items()
|
||||
stop_pulling()
|
||||
if(GRAB_NECK)
|
||||
visible_message("<span class='danger'>[user] has grabbed [src] by the neck!</span>",\
|
||||
"<span class='userdanger'>[user] has grabbed you by the neck!</span>")
|
||||
update_canmove() //we fall down
|
||||
if(!buckled && !density)
|
||||
Move(user.loc)
|
||||
if(GRAB_KILL)
|
||||
visible_message("<span class='danger'>[user] is strangling [src]!</span>", \
|
||||
"<span class='userdanger'>[user] is strangling you!</span>")
|
||||
update_canmove() //we fall down
|
||||
if(!buckled && !density)
|
||||
Move(user.loc)
|
||||
return 1
|
||||
|
||||
|
||||
/mob/living/attack_slime(mob/living/simple_animal/slime/M)
|
||||
|
||||
/mob/living/proc/run_armor_check(def_zone = null, attack_flag = "melee", absorb_text = null, soften_text = null, armour_penetration, penetrated_text)
|
||||
var/armor = getarmor(def_zone, attack_flag)
|
||||
|
||||
//the if "armor" check is because this is used for everything on /living, including humans
|
||||
if(armor && armour_penetration)
|
||||
armor = max(0, armor - armour_penetration)
|
||||
if(penetrated_text)
|
||||
to_chat(src, "<span class='userdanger'>[penetrated_text]</span>")
|
||||
else
|
||||
to_chat(src, "<span class='userdanger'>Your armor was penetrated!</span>")
|
||||
else if(armor >= 100)
|
||||
if(absorb_text)
|
||||
to_chat(src, "<span class='userdanger'>[absorb_text]</span>")
|
||||
else
|
||||
to_chat(src, "<span class='userdanger'>Your armor absorbs the blow!</span>")
|
||||
else if(armor > 0)
|
||||
if(soften_text)
|
||||
to_chat(src, "<span class='userdanger'>[soften_text]</span>")
|
||||
else
|
||||
to_chat(src, "<span class='userdanger'>Your armor softens the blow!</span>")
|
||||
return armor
|
||||
|
||||
|
||||
/mob/living/proc/getarmor(def_zone, type)
|
||||
return 0
|
||||
|
||||
//this returns the mob's protection against eye damage (number between -1 and 2)
|
||||
/mob/living/proc/get_eye_protection()
|
||||
return 0
|
||||
|
||||
//this returns the mob's protection against ear damage (0:no protection; 1: some ear protection; 2: has no ears)
|
||||
/mob/living/proc/get_ear_protection()
|
||||
return 0
|
||||
|
||||
/mob/living/proc/on_hit(obj/item/projectile/P)
|
||||
return
|
||||
|
||||
/mob/living/bullet_act(obj/item/projectile/P, def_zone)
|
||||
var/armor = run_armor_check(def_zone, P.flag, "","",P.armour_penetration)
|
||||
if(!P.nodamage)
|
||||
apply_damage(P.damage, P.damage_type, def_zone, armor)
|
||||
if(P.dismemberment)
|
||||
check_projectile_dismemberment(P, def_zone)
|
||||
return P.on_hit(src, armor)
|
||||
|
||||
/mob/living/proc/check_projectile_dismemberment(obj/item/projectile/P, def_zone)
|
||||
return 0
|
||||
|
||||
/obj/item/proc/get_volume_by_throwforce_and_or_w_class()
|
||||
if(throwforce && w_class)
|
||||
return Clamp((throwforce + w_class) * 5, 30, 100)// Add the item's throwforce to its weight class and multiply by 5, then clamp the value between 30 and 100
|
||||
else if(w_class)
|
||||
return Clamp(w_class * 8, 20, 100) // Multiply the item's weight class by 8, then clamp the value between 20 and 100
|
||||
else
|
||||
return 0
|
||||
|
||||
/mob/living/hitby(atom/movable/AM, skipcatch, hitpush = 1, blocked = 0)
|
||||
if(istype(AM, /obj/item))
|
||||
var/obj/item/I = AM
|
||||
var/zone = ran_zone("chest", 65)//Hits a random part of the body, geared towards the chest
|
||||
var/dtype = BRUTE
|
||||
var/volume = I.get_volume_by_throwforce_and_or_w_class()
|
||||
if(istype(I,/obj/item/weapon)) //If the item is a weapon...
|
||||
var/obj/item/weapon/W = I
|
||||
dtype = W.damtype
|
||||
|
||||
if (W.throwforce > 0) //If the weapon's throwforce is greater than zero...
|
||||
if (W.throwhitsound) //...and throwhitsound is defined...
|
||||
playsound(loc, W.throwhitsound, volume, 1, -1) //...play the weapon's throwhitsound.
|
||||
else if(W.hitsound) //Otherwise, if the weapon's hitsound is defined...
|
||||
playsound(loc, W.hitsound, volume, 1, -1) //...play the weapon's hitsound.
|
||||
else if(!W.throwhitsound) //Otherwise, if throwhitsound isn't defined...
|
||||
playsound(loc, 'sound/weapons/genhit.ogg',volume, 1, -1) //...play genhit.ogg.
|
||||
|
||||
else if(!I.throwhitsound && I.throwforce > 0) //Otherwise, if the item doesn't have a throwhitsound and has a throwforce greater than zero...
|
||||
playsound(loc, 'sound/weapons/genhit.ogg', volume, 1, -1)//...play genhit.ogg
|
||||
if(!I.throwforce)// Otherwise, if the item's throwforce is 0...
|
||||
playsound(loc, 'sound/weapons/throwtap.ogg', 1, volume, -1)//...play throwtap.ogg.
|
||||
if(!blocked)
|
||||
visible_message("<span class='danger'>[src] has been hit by [I].</span>", \
|
||||
"<span class='userdanger'>[src] has been hit by [I].</span>")
|
||||
var/armor = run_armor_check(zone, "melee", "Your armor has protected your [parse_zone(zone)].", "Your armor has softened hit to your [parse_zone(zone)].",I.armour_penetration)
|
||||
apply_damage(I.throwforce, dtype, zone, armor)
|
||||
if(I.thrownby)
|
||||
add_logs(I.thrownby, src, "hit", I)
|
||||
else
|
||||
return 1
|
||||
else
|
||||
playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1)
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/mech_melee_attack(obj/mecha/M)
|
||||
if(M.occupant.a_intent == INTENT_HARM)
|
||||
M.do_attack_animation(src)
|
||||
if(M.damtype == "brute")
|
||||
step_away(src,M,15)
|
||||
switch(M.damtype)
|
||||
if(BRUTE)
|
||||
Paralyse(1)
|
||||
take_overall_damage(rand(M.force/2, M.force))
|
||||
playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
|
||||
if(BURN)
|
||||
take_overall_damage(0, rand(M.force/2, M.force))
|
||||
playsound(src, 'sound/items/Welder.ogg', 50, 1)
|
||||
if(TOX)
|
||||
M.mech_toxin_damage(src)
|
||||
else
|
||||
return
|
||||
updatehealth()
|
||||
visible_message("<span class='danger'>[M.name] has hit [src]!</span>", \
|
||||
"<span class='userdanger'>[M.name] has hit [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
add_logs(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])")
|
||||
else
|
||||
step_away(src,M)
|
||||
add_logs(M.occupant, src, "pushed", M)
|
||||
visible_message("<span class='warning'>[M] pushes [src] out of the way.</span>", null, null, 5)
|
||||
|
||||
/mob/living/fire_act()
|
||||
adjust_fire_stacks(3)
|
||||
IgniteMob()
|
||||
|
||||
/mob/living/proc/grabbedby(mob/living/carbon/user, supress_message = 0)
|
||||
if(user == src || anchored || !isturf(user.loc))
|
||||
return 0
|
||||
if(!user.pulling || user.pulling != src)
|
||||
user.start_pulling(src, supress_message)
|
||||
return
|
||||
|
||||
if(!(status_flags & CANPUSH))
|
||||
to_chat(user, "<span class='warning'>[src] can't be grabbed more aggressively!</span>")
|
||||
return 0
|
||||
grippedby(user)
|
||||
|
||||
//proc to upgrade a simple pull into a more aggressive grab.
|
||||
/mob/living/proc/grippedby(mob/living/carbon/user)
|
||||
if(user.grab_state < GRAB_KILL)
|
||||
user.changeNext_move(CLICK_CD_GRABBING)
|
||||
playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
|
||||
if(user.grab_state) //only the first upgrade is instantaneous
|
||||
var/old_grab_state = user.grab_state
|
||||
var/grab_upgrade_time = 30
|
||||
visible_message("<span class='danger'>[user] starts to tighten [user.p_their()] grip on [src]!</span>", \
|
||||
"<span class='userdanger'>[user] starts to tighten [user.p_their()] grip on you!</span>")
|
||||
if(!do_mob(user, src, grab_upgrade_time))
|
||||
return 0
|
||||
if(!user.pulling || user.pulling != src || user.grab_state != old_grab_state || user.a_intent != INTENT_GRAB)
|
||||
return 0
|
||||
user.grab_state++
|
||||
switch(user.grab_state)
|
||||
if(GRAB_AGGRESSIVE)
|
||||
add_logs(user, src, "grabbed", addition="aggressively")
|
||||
visible_message("<span class='danger'>[user] has grabbed [src] aggressively!</span>", \
|
||||
"<span class='userdanger'>[user] has grabbed [src] aggressively!</span>")
|
||||
drop_all_held_items()
|
||||
stop_pulling()
|
||||
if(GRAB_NECK)
|
||||
visible_message("<span class='danger'>[user] has grabbed [src] by the neck!</span>",\
|
||||
"<span class='userdanger'>[user] has grabbed you by the neck!</span>")
|
||||
update_canmove() //we fall down
|
||||
if(!buckled && !density)
|
||||
Move(user.loc)
|
||||
if(GRAB_KILL)
|
||||
visible_message("<span class='danger'>[user] is strangling [src]!</span>", \
|
||||
"<span class='userdanger'>[user] is strangling you!</span>")
|
||||
update_canmove() //we fall down
|
||||
if(!buckled && !density)
|
||||
Move(user.loc)
|
||||
return 1
|
||||
|
||||
|
||||
/mob/living/attack_slime(mob/living/simple_animal/slime/M)
|
||||
if(!SSticker.HasRoundStarted())
|
||||
to_chat(M, "You cannot attack people before the game has started.")
|
||||
return
|
||||
|
||||
if(M.buckled)
|
||||
if(M in buckled_mobs)
|
||||
M.Feedstop()
|
||||
return // can't attack while eating!
|
||||
|
||||
if (stat != DEAD)
|
||||
add_logs(M, src, "attacked")
|
||||
M.do_attack_animation(src)
|
||||
visible_message("<span class='danger'>The [M.name] glomps [src]!</span>", \
|
||||
"<span class='userdanger'>The [M.name] glomps [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
return 1
|
||||
|
||||
/mob/living/attack_animal(mob/living/simple_animal/M)
|
||||
M.face_atom(src)
|
||||
if(M.melee_damage_upper == 0)
|
||||
M.visible_message("<span class='notice'>\The [M] [M.friendly] [src]!</span>")
|
||||
return 0
|
||||
else
|
||||
if(M.attack_sound)
|
||||
playsound(loc, M.attack_sound, 50, 1, 1)
|
||||
M.do_attack_animation(src)
|
||||
visible_message("<span class='danger'>\The [M] [M.attacktext] [src]!</span>", \
|
||||
"<span class='userdanger'>\The [M] [M.attacktext] [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
add_logs(M, src, "attacked")
|
||||
return 1
|
||||
|
||||
|
||||
/mob/living/attack_paw(mob/living/carbon/monkey/M)
|
||||
if(isturf(loc) && istype(loc.loc, /area/start))
|
||||
to_chat(M, "No attacking people at spawn, you jackass.")
|
||||
return 0
|
||||
|
||||
if (M.a_intent == INTENT_HARM)
|
||||
if(M.is_muzzled() || (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSMOUTH))
|
||||
to_chat(M, "<span class='warning'>You can't bite with your mouth covered!</span>")
|
||||
return 0
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_BITE)
|
||||
if (prob(75))
|
||||
add_logs(M, src, "attacked")
|
||||
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
|
||||
visible_message("<span class='danger'>[M.name] bites [src]!</span>", \
|
||||
"<span class='userdanger'>[M.name] bites [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
return 1
|
||||
else
|
||||
visible_message("<span class='danger'>[M.name] has attempted to bite [src]!</span>", \
|
||||
"<span class='userdanger'>[M.name] has attempted to bite [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
return 0
|
||||
|
||||
/mob/living/attack_larva(mob/living/carbon/alien/larva/L)
|
||||
switch(L.a_intent)
|
||||
if("help")
|
||||
visible_message("<span class='notice'>[L.name] rubs its head against [src].</span>")
|
||||
return 0
|
||||
|
||||
else
|
||||
L.do_attack_animation(src)
|
||||
if(prob(90))
|
||||
add_logs(L, src, "attacked")
|
||||
visible_message("<span class='danger'>[L.name] bites [src]!</span>", \
|
||||
"<span class='userdanger'>[L.name] bites [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
|
||||
return 1
|
||||
else
|
||||
visible_message("<span class='danger'>[L.name] has attempted to bite [src]!</span>", \
|
||||
"<span class='userdanger'>[L.name] has attempted to bite [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
return 0
|
||||
|
||||
/mob/living/attack_alien(mob/living/carbon/alien/humanoid/M)
|
||||
switch(M.a_intent)
|
||||
if ("help")
|
||||
visible_message("<span class='notice'>[M] caresses [src] with its scythe like arm.</span>")
|
||||
return 0
|
||||
|
||||
if ("grab")
|
||||
grabbedby(M)
|
||||
return 0
|
||||
if("harm")
|
||||
M.do_attack_animation(src)
|
||||
return 1
|
||||
if("disarm")
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
|
||||
return 1
|
||||
|
||||
/mob/living/ex_act(severity, target, origin)
|
||||
if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src))
|
||||
return
|
||||
..()
|
||||
|
||||
//Looking for irradiate()? It's been moved to radiation.dm under the rad_act() for mobs.
|
||||
|
||||
/mob/living/acid_act(acidpwr, acid_volume)
|
||||
take_bodypart_damage(acidpwr * min(1, acid_volume * 0.1))
|
||||
return 1
|
||||
|
||||
/mob/living/proc/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
|
||||
to_chat(M, "You cannot attack people before the game has started.")
|
||||
return
|
||||
|
||||
if(M.buckled)
|
||||
if(M in buckled_mobs)
|
||||
M.Feedstop()
|
||||
return // can't attack while eating!
|
||||
|
||||
if (stat != DEAD)
|
||||
add_logs(M, src, "attacked")
|
||||
M.do_attack_animation(src)
|
||||
visible_message("<span class='danger'>The [M.name] glomps [src]!</span>", \
|
||||
"<span class='userdanger'>The [M.name] glomps [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
return 1
|
||||
|
||||
/mob/living/attack_animal(mob/living/simple_animal/M)
|
||||
M.face_atom(src)
|
||||
if(M.melee_damage_upper == 0)
|
||||
M.visible_message("<span class='notice'>\The [M] [M.friendly] [src]!</span>")
|
||||
return 0
|
||||
else
|
||||
if(M.attack_sound)
|
||||
playsound(loc, M.attack_sound, 50, 1, 1)
|
||||
M.do_attack_animation(src)
|
||||
visible_message("<span class='danger'>\The [M] [M.attacktext] [src]!</span>", \
|
||||
"<span class='userdanger'>\The [M] [M.attacktext] [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
add_logs(M, src, "attacked")
|
||||
return 1
|
||||
|
||||
|
||||
/mob/living/attack_paw(mob/living/carbon/monkey/M)
|
||||
if(isturf(loc) && istype(loc.loc, /area/start))
|
||||
to_chat(M, "No attacking people at spawn, you jackass.")
|
||||
return 0
|
||||
|
||||
if (M.a_intent == INTENT_HARM)
|
||||
if(M.is_muzzled() || (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSMOUTH))
|
||||
to_chat(M, "<span class='warning'>You can't bite with your mouth covered!</span>")
|
||||
return 0
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_BITE)
|
||||
if (prob(75))
|
||||
add_logs(M, src, "attacked")
|
||||
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
|
||||
visible_message("<span class='danger'>[M.name] bites [src]!</span>", \
|
||||
"<span class='userdanger'>[M.name] bites [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
return 1
|
||||
else
|
||||
visible_message("<span class='danger'>[M.name] has attempted to bite [src]!</span>", \
|
||||
"<span class='userdanger'>[M.name] has attempted to bite [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
return 0
|
||||
|
||||
/mob/living/attack_larva(mob/living/carbon/alien/larva/L)
|
||||
switch(L.a_intent)
|
||||
if("help")
|
||||
visible_message("<span class='notice'>[L.name] rubs its head against [src].</span>")
|
||||
return 0
|
||||
|
||||
else
|
||||
L.do_attack_animation(src)
|
||||
if(prob(90))
|
||||
add_logs(L, src, "attacked")
|
||||
visible_message("<span class='danger'>[L.name] bites [src]!</span>", \
|
||||
"<span class='userdanger'>[L.name] bites [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
|
||||
return 1
|
||||
else
|
||||
visible_message("<span class='danger'>[L.name] has attempted to bite [src]!</span>", \
|
||||
"<span class='userdanger'>[L.name] has attempted to bite [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
return 0
|
||||
|
||||
/mob/living/attack_alien(mob/living/carbon/alien/humanoid/M)
|
||||
switch(M.a_intent)
|
||||
if ("help")
|
||||
visible_message("<span class='notice'>[M] caresses [src] with its scythe like arm.</span>")
|
||||
return 0
|
||||
|
||||
if ("grab")
|
||||
grabbedby(M)
|
||||
return 0
|
||||
if("harm")
|
||||
M.do_attack_animation(src)
|
||||
return 1
|
||||
if("disarm")
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
|
||||
return 1
|
||||
|
||||
/mob/living/ex_act(severity, target, origin)
|
||||
if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src))
|
||||
return
|
||||
..()
|
||||
|
||||
//Looking for irradiate()? It's been moved to radiation.dm under the rad_act() for mobs.
|
||||
|
||||
/mob/living/acid_act(acidpwr, acid_volume)
|
||||
take_bodypart_damage(acidpwr * min(1, acid_volume * 0.1))
|
||||
return 1
|
||||
|
||||
/mob/living/proc/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
|
||||
if(tesla_shock && HAS_SECONDARY_FLAG(src, TESLA_IGNORE))
|
||||
return FALSE
|
||||
if(shock_damage > 0)
|
||||
if(!illusion)
|
||||
adjustFireLoss(shock_damage)
|
||||
visible_message(
|
||||
"<span class='danger'>[src] was shocked by \the [source]!</span>", \
|
||||
"<span class='userdanger'>You feel a powerful shock coursing through your body!</span>", \
|
||||
"<span class='italics'>You hear a heavy electrical crack.</span>" \
|
||||
)
|
||||
return shock_damage
|
||||
|
||||
/mob/living/emp_act(severity)
|
||||
var/list/L = src.get_contents()
|
||||
for(var/obj/O in L)
|
||||
O.emp_act(severity)
|
||||
..()
|
||||
|
||||
/mob/living/singularity_act()
|
||||
var/gain = 20
|
||||
investigate_log("([key_name(src)]) has been consumed by the singularity.","singulo") //Oh that's where the clown ended up!
|
||||
gib()
|
||||
return(gain)
|
||||
|
||||
/mob/living/narsie_act()
|
||||
if(status_flags & GODMODE)
|
||||
return
|
||||
|
||||
if(is_servant_of_ratvar(src) && !stat)
|
||||
to_chat(src, "<span class='userdanger'>You resist Nar-Sie's influence... but not all of it. <i>Run!</i></span>")
|
||||
adjustBruteLoss(35)
|
||||
if(src && reagents)
|
||||
reagents.add_reagent("heparin", 5)
|
||||
return FALSE
|
||||
if(client)
|
||||
return FALSE
|
||||
if(shock_damage > 0)
|
||||
if(!illusion)
|
||||
adjustFireLoss(shock_damage)
|
||||
visible_message(
|
||||
"<span class='danger'>[src] was shocked by \the [source]!</span>", \
|
||||
"<span class='userdanger'>You feel a powerful shock coursing through your body!</span>", \
|
||||
"<span class='italics'>You hear a heavy electrical crack.</span>" \
|
||||
)
|
||||
return shock_damage
|
||||
|
||||
/mob/living/emp_act(severity)
|
||||
var/list/L = src.get_contents()
|
||||
for(var/obj/O in L)
|
||||
O.emp_act(severity)
|
||||
..()
|
||||
|
||||
/mob/living/singularity_act()
|
||||
var/gain = 20
|
||||
investigate_log("([key_name(src)]) has been consumed by the singularity.","singulo") //Oh that's where the clown ended up!
|
||||
gib()
|
||||
return(gain)
|
||||
|
||||
/mob/living/narsie_act()
|
||||
if(status_flags & GODMODE)
|
||||
return
|
||||
|
||||
if(is_servant_of_ratvar(src) && !stat)
|
||||
to_chat(src, "<span class='userdanger'>You resist Nar-Sie's influence... but not all of it. <i>Run!</i></span>")
|
||||
adjustBruteLoss(35)
|
||||
if(src && reagents)
|
||||
reagents.add_reagent("heparin", 5)
|
||||
return FALSE
|
||||
if(GLOB.cult_narsie && GLOB.cult_narsie.souls_needed[src])
|
||||
GLOB.cult_narsie.resize(1.1)
|
||||
GLOB.cult_narsie.souls_needed -= src
|
||||
GLOB.cult_narsie.souls += 1
|
||||
if((GLOB.cult_narsie.souls == GLOB.cult_narsie.soul_goal) && (GLOB.cult_narsie.resolved == FALSE))
|
||||
GLOB.cult_narsie.resolved = TRUE
|
||||
world << sound('sound/machines/Alarm.ogg')
|
||||
addtimer(CALLBACK(GLOBAL_PROC, .proc/cult_ending_helper, 1), 120)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, .proc/ending_helper), 270)
|
||||
if(client)
|
||||
makeNewConstruct(/mob/living/simple_animal/hostile/construct/harvester, src, cultoverride = TRUE)
|
||||
else
|
||||
else
|
||||
switch(rand(1, 6))
|
||||
if(1)
|
||||
new /mob/living/simple_animal/hostile/construct/armored/hostile(get_turf(src))
|
||||
if(2)
|
||||
new /mob/living/simple_animal/hostile/construct/wraith/hostile(get_turf(src))
|
||||
if(3 to 6)
|
||||
new /mob/living/simple_animal/hostile/construct/builder/hostile(get_turf(src))
|
||||
spawn_dust()
|
||||
gib()
|
||||
return TRUE
|
||||
|
||||
|
||||
/mob/living/ratvar_act()
|
||||
if(status_flags & GODMODE)
|
||||
return
|
||||
|
||||
if(stat != DEAD && !is_servant_of_ratvar(src))
|
||||
for(var/obj/item/weapon/implant/mindshield/M in implants)
|
||||
qdel(M)
|
||||
if(!add_servant_of_ratvar(src))
|
||||
to_chat(src, "<span class='userdanger'>A blinding light boils you alive! <i>Run!</i></span>")
|
||||
adjustFireLoss(35)
|
||||
if(src)
|
||||
adjust_fire_stacks(1)
|
||||
IgniteMob()
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
//called when the mob receives a bright flash
|
||||
/mob/living/proc/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /obj/screen/fullscreen/flash)
|
||||
if(get_eye_protection() < intensity && (override_blindness_check || !(disabilities & BLIND)))
|
||||
overlay_fullscreen("flash", type)
|
||||
addtimer(CALLBACK(src, .proc/clear_fullscreen, "flash", 25), 25)
|
||||
return 1
|
||||
|
||||
//called when the mob receives a loud bang
|
||||
/mob/living/proc/soundbang_act()
|
||||
return 0
|
||||
|
||||
//to damage the clothes worn by a mob
|
||||
/mob/living/proc/damage_clothes(damage_amount, damage_type = BRUTE, damage_flag = 0, def_zone)
|
||||
return
|
||||
|
||||
|
||||
/mob/living/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y)
|
||||
if(A != src)
|
||||
end_pixel_y = get_standard_pixel_y_offset(lying)
|
||||
used_item = get_active_held_item()
|
||||
..()
|
||||
floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement.
|
||||
if(1)
|
||||
new /mob/living/simple_animal/hostile/construct/armored/hostile(get_turf(src))
|
||||
if(2)
|
||||
new /mob/living/simple_animal/hostile/construct/wraith/hostile(get_turf(src))
|
||||
if(3 to 6)
|
||||
new /mob/living/simple_animal/hostile/construct/builder/hostile(get_turf(src))
|
||||
spawn_dust()
|
||||
gib()
|
||||
return TRUE
|
||||
|
||||
|
||||
/mob/living/ratvar_act()
|
||||
if(status_flags & GODMODE)
|
||||
return
|
||||
|
||||
if(stat != DEAD && !is_servant_of_ratvar(src))
|
||||
for(var/obj/item/weapon/implant/mindshield/M in implants)
|
||||
qdel(M)
|
||||
if(!add_servant_of_ratvar(src))
|
||||
to_chat(src, "<span class='userdanger'>A blinding light boils you alive! <i>Run!</i></span>")
|
||||
adjustFireLoss(35)
|
||||
if(src)
|
||||
adjust_fire_stacks(1)
|
||||
IgniteMob()
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
//called when the mob receives a bright flash
|
||||
/mob/living/proc/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /obj/screen/fullscreen/flash)
|
||||
if(get_eye_protection() < intensity && (override_blindness_check || !(disabilities & BLIND)))
|
||||
overlay_fullscreen("flash", type)
|
||||
addtimer(CALLBACK(src, .proc/clear_fullscreen, "flash", 25), 25)
|
||||
return 1
|
||||
|
||||
//called when the mob receives a loud bang
|
||||
/mob/living/proc/soundbang_act()
|
||||
return 0
|
||||
|
||||
//to damage the clothes worn by a mob
|
||||
/mob/living/proc/damage_clothes(damage_amount, damage_type = BRUTE, damage_flag = 0, def_zone)
|
||||
return
|
||||
|
||||
|
||||
/mob/living/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y)
|
||||
if(A != src)
|
||||
end_pixel_y = get_standard_pixel_y_offset(lying)
|
||||
used_item = get_active_held_item()
|
||||
..()
|
||||
floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement.
|
||||
@@ -171,7 +171,30 @@
|
||||
attacktext = "slashes"
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
construct_spells = list(/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift)
|
||||
playstyle_string = "<b>You are a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls.</b>"
|
||||
playstyle_string = "<b>You are a Wraith. Though relatively fragile, you are fast, deadly, can phase through walls, and your attacks will lower the cooldown on phasing.</b>"
|
||||
var/attack_refund = 10 //1 second per attack
|
||||
var/crit_refund = 50 //5 seconds when putting a target into critical
|
||||
var/kill_refund = 250 //full refund on kills
|
||||
|
||||
/mob/living/simple_animal/hostile/construct/wraith/AttackingTarget() //refund jaunt cooldown when attacking living targets
|
||||
var/prev_stat
|
||||
if(isliving(target) && !iscultist(target))
|
||||
var/mob/living/L = target
|
||||
prev_stat = L.stat
|
||||
|
||||
. = ..()
|
||||
|
||||
if(. && isnum(prev_stat))
|
||||
var/mob/living/L = target
|
||||
var/refund = 0
|
||||
if(QDELETED(L) || (L.stat == DEAD && prev_stat != DEAD)) //they're dead, you killed them
|
||||
refund += kill_refund
|
||||
else if(L.InCritical() && prev_stat == CONSCIOUS) //you knocked them into critical
|
||||
refund += crit_refund
|
||||
if(L.stat != DEAD && prev_stat != DEAD)
|
||||
refund += attack_refund
|
||||
for(var/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift/S in mob_spell_list)
|
||||
S.charge_counter = min(S.charge_counter + refund, S.charge_max)
|
||||
|
||||
/mob/living/simple_animal/hostile/construct/wraith/hostile //actually hostile, will move around, hit things
|
||||
AIStatus = AI_ON
|
||||
@@ -265,8 +288,8 @@
|
||||
name = "Harvester"
|
||||
real_name = "Harvester"
|
||||
desc = "A long, thin construct built to herald Nar-Sie's rise. It'll be all over soon."
|
||||
icon_state = "harvester"
|
||||
icon_living = "harvester"
|
||||
icon_state = "chosen"
|
||||
icon_living = "chosen"
|
||||
maxHealth = 60
|
||||
health = 60
|
||||
sight = SEE_MOBS
|
||||
@@ -277,9 +300,10 @@
|
||||
construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/area_conversion,
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/lesserforcewall)
|
||||
playstyle_string = "<B>You are a Harvester. You are incapable of directly killing humans, but your attacks will remove their limbs: \
|
||||
Bring those who still cling to this world of illusion back to the Geometer so they may know Truth.</B>"
|
||||
Bring those who still cling to this world of illusion back to the Geometer so they may know Truth. Your form and any you are pulling can pass through runed walls effortlessly.</B>"
|
||||
can_repair_constructs = TRUE
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/construct/harvester/Bump(atom/AM)
|
||||
. = ..()
|
||||
if(istype(AM, /turf/closed/wall/mineral/cult) && AM != loc) //we can go through cult walls
|
||||
@@ -306,6 +330,8 @@
|
||||
if(!LAZYLEN(parts))
|
||||
if(undismembermerable_limbs) //they have limbs we can't remove, and no parts we can, attack!
|
||||
return ..()
|
||||
C.Weaken(30)
|
||||
visible_message("<span class='danger'>[src] paralyzes [C]!</span>")
|
||||
to_chat(src, "<span class='cultlarge'>\"Bring [C.p_them()] to me.\"</span>")
|
||||
return FALSE
|
||||
do_attack_animation(C)
|
||||
@@ -314,6 +340,11 @@
|
||||
return FALSE
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/construct/harvester/Initialize()
|
||||
. = ..()
|
||||
var/datum/action/innate/seek_prey/seek = new()
|
||||
seek.Grant(src)
|
||||
seek.Activate()
|
||||
|
||||
///////////////////////Master-Tracker///////////////////////
|
||||
|
||||
@@ -326,11 +357,14 @@
|
||||
var/tracking = FALSE
|
||||
var/mob/living/simple_animal/hostile/construct/the_construct
|
||||
|
||||
|
||||
/datum/action/innate/seek_master/Grant(var/mob/living/C)
|
||||
the_construct = C
|
||||
..()
|
||||
|
||||
/datum/action/innate/seek_master/Activate()
|
||||
if(!SSticker.mode.eldergod)
|
||||
the_construct.master = GLOB.blood_target
|
||||
if(!the_construct.master)
|
||||
to_chat(the_construct, "<span class='cultitalic'>You have no master to seek!</span>")
|
||||
the_construct.seeking = FALSE
|
||||
@@ -346,6 +380,43 @@
|
||||
to_chat(the_construct, "<span class='cultitalic'>You are now tracking your master.</span>")
|
||||
|
||||
|
||||
/datum/action/innate/seek_prey
|
||||
name = "Seek the Harvest"
|
||||
desc = "None can hide from Nar'Sie, activate to track a survivor attempting to flee the red harvest!"
|
||||
background_icon_state = "bg_demon"
|
||||
buttontooltipstyle = "cult"
|
||||
button_icon_state = "cult_mark"
|
||||
var/tracking = FALSE
|
||||
var/mob/living/simple_animal/hostile/construct/harvester/the_construct
|
||||
|
||||
/datum/action/innate/seek_prey/Grant(var/mob/living/C)
|
||||
the_construct = C
|
||||
..()
|
||||
|
||||
/datum/action/innate/seek_prey/Activate()
|
||||
if(GLOB.cult_narsie == null)
|
||||
return
|
||||
if(tracking)
|
||||
desc = "None can hide from Nar'Sie, activate to track a survivor attempting to flee the red harvest!"
|
||||
button_icon_state = "cult_mark"
|
||||
tracking = FALSE
|
||||
the_construct.seeking = FALSE
|
||||
the_construct.master = GLOB.cult_narsie
|
||||
to_chat(the_construct, "<span class='cultitalic'>You are now tracking Nar'Sie, return to reap the harvest!</span>")
|
||||
return
|
||||
else
|
||||
if(LAZYLEN(GLOB.cult_narsie.souls_needed))
|
||||
the_construct.master = pick(GLOB.cult_narsie.souls_needed)
|
||||
to_chat(the_construct, "<span class='cultitalic'>You are now tracking your prey, [the_construct.master] - harvest them!</span>")
|
||||
else
|
||||
to_chat(the_construct, "<span class='cultitalic'>Nar'Sie has completed her harvest!</span>")
|
||||
return
|
||||
desc = "Activate to track Nar'Sie!"
|
||||
button_icon_state = "sintouch"
|
||||
tracking = TRUE
|
||||
the_construct.seeking = TRUE
|
||||
|
||||
|
||||
/////////////////////////////ui stuff/////////////////////////////
|
||||
|
||||
/mob/living/simple_animal/hostile/construct/update_health_hud()
|
||||
|
||||
@@ -36,11 +36,59 @@
|
||||
if(A)
|
||||
var/mutable_appearance/alert_overlay = mutable_appearance('icons/effects/effects.dmi', "ghostalertsie")
|
||||
notify_ghosts("Nar-Sie has risen in \the [A.name]. Reach out to the Geometer to be given a new shell for your soul.", source = src, alert_overlay = alert_overlay, action=NOTIFY_ATTACK)
|
||||
INVOKE_ASYNC(src, .proc/narsie_spawn_animation)
|
||||
|
||||
narsie_spawn_animation()
|
||||
/obj/singularity/narsie/large/cult // For the new cult ending, guaranteed to end the round within 3 minutes
|
||||
var/list/souls_needed = list()
|
||||
var/soul_goal = 0
|
||||
var/souls = 0
|
||||
var/resolved = FALSE
|
||||
|
||||
sleep(19)
|
||||
SSshuttle.emergency.request(null, set_coefficient = 0) //instantly arrives
|
||||
/obj/singularity/narsie/large/cult/proc/resize(var/ratio)
|
||||
var/matrix/ntransform = matrix(transform) //aka transform.Copy()
|
||||
ntransform.Scale(ratio)
|
||||
animate(src, transform = ntransform, time = 40, easing = EASE_IN|EASE_OUT)
|
||||
|
||||
/obj/singularity/narsie/large/cult/Initialize()
|
||||
. = ..()
|
||||
GLOB.cult_narsie = src
|
||||
GLOB.blood_target = src
|
||||
resize(0.6)
|
||||
for(var/datum/mind/cult_mind in SSticker.mode.cult)
|
||||
if(isliving(cult_mind.current))
|
||||
var/mob/living/L = cult_mind.current
|
||||
L.narsie_act()
|
||||
for(var/mob/living/player in GLOB.player_list)
|
||||
if(player.stat != DEAD && player.loc.z == ZLEVEL_STATION && !iscultist(player) && isliving(player))
|
||||
souls_needed[player] = TRUE
|
||||
soul_goal = round(1 + LAZYLEN(souls_needed) * 0.6)
|
||||
INVOKE_ASYNC(src, .proc/begin_the_end)
|
||||
|
||||
/obj/singularity/narsie/large/cult/proc/begin_the_end()
|
||||
sleep(50)
|
||||
priority_announce("An acausal dimensional event has been detected in your sector. Event has been flagged EXTINCTION-CLASS. Directing all available assets toward simulating solutions. SOLUTION ETA: 60 SECONDS.","Central Command Higher Dimensional Affairs", 'sound/misc/airraid.ogg')
|
||||
sleep(550)
|
||||
priority_announce("Simulations on acausal dimensional event complete. Deploying solution package now. Deployment ETA: TWO MINUTES. ","Central Command Higher Dimensional Affairs")
|
||||
sleep(50)
|
||||
set_security_level("delta")
|
||||
SSshuttle.registerHostileEnvironment(src)
|
||||
SSshuttle.lockdown = TRUE
|
||||
sleep(1150)
|
||||
if(resolved == FALSE)
|
||||
resolved = TRUE
|
||||
world << sound('sound/machines/Alarm.ogg')
|
||||
addtimer(CALLBACK(GLOBAL_PROC, .proc/cult_ending_helper), 120)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, .proc/ending_helper), 220)
|
||||
|
||||
/obj/singularity/narsie/large/cult/Destroy()
|
||||
GLOB.cult_narsie = null
|
||||
return ..()
|
||||
|
||||
/proc/ending_helper()
|
||||
SSticker.force_ending = 1
|
||||
|
||||
/proc/cult_ending_helper(var/no_explosion = 0)
|
||||
SSticker.station_explosion_cinematic(no_explosion, "cult", null)
|
||||
|
||||
|
||||
/obj/singularity/narsie/large/attack_ghost(mob/dead/observer/user as mob)
|
||||
@@ -134,7 +182,7 @@
|
||||
return
|
||||
to_chat(target, "<span class='cultsmall'>NAR-SIE HAS LOST INTEREST IN YOU.</span>")
|
||||
target = food
|
||||
if(isliving(target))
|
||||
if(ishuman(target))
|
||||
to_chat(target, "<span class ='cult'>NAR-SIE HUNGERS FOR YOUR SOUL.</span>")
|
||||
else
|
||||
to_chat(target, "<span class ='cult'>NAR-SIE HAS CHOSEN YOU TO LEAD HER TO HER NEXT MEAL.</span>")
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.3 MiB After Width: | Height: | Size: 5.2 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 249 KiB After Width: | Height: | Size: 258 KiB |
+4
-4
@@ -710,10 +710,10 @@
|
||||
#include "code\game\objects\effects\decals\decal.dm"
|
||||
#include "code\game\objects\effects\decals\misc.dm"
|
||||
#include "code\game\objects\effects\decals\remains.dm"
|
||||
#include "code\game\objects\effects\decals\cleanable\aliens.dm"
|
||||
#include "code\game\objects\effects\decals\cleanable\humans.dm"
|
||||
#include "code\game\objects\effects\decals\cleanable\misc.dm"
|
||||
#include "code\game\objects\effects\decals\cleanable\robots.dm"
|
||||
#include "code\game\objects\effects\decals\Cleanable\aliens.dm"
|
||||
#include "code\game\objects\effects\decals\Cleanable\humans.dm"
|
||||
#include "code\game\objects\effects\decals\Cleanable\misc.dm"
|
||||
#include "code\game\objects\effects\decals\Cleanable\robots.dm"
|
||||
#include "code\game\objects\effects\effect_system\effect_system.dm"
|
||||
#include "code\game\objects\effects\effect_system\effects_explosion.dm"
|
||||
#include "code\game\objects\effects\effect_system\effects_foam.dm"
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
diff a/tgstation.dme b/tgstation.dme (rejected hunks)
|
||||
@@ -677,10 +677,10 @@
|
||||
#include "code\game\objects\effects\decals\decal.dm"
|
||||
#include "code\game\objects\effects\decals\misc.dm"
|
||||
#include "code\game\objects\effects\decals\remains.dm"
|
||||
-#include "code\game\objects\effects\decals\Cleanable\aliens.dm"
|
||||
-#include "code\game\objects\effects\decals\Cleanable\humans.dm"
|
||||
-#include "code\game\objects\effects\decals\Cleanable\misc.dm"
|
||||
-#include "code\game\objects\effects\decals\Cleanable\robots.dm"
|
||||
+#include "code\game\objects\effects\decals\cleanable\aliens.dm"
|
||||
+#include "code\game\objects\effects\decals\cleanable\humans.dm"
|
||||
+#include "code\game\objects\effects\decals\cleanable\misc.dm"
|
||||
+#include "code\game\objects\effects\decals\cleanable\robots.dm"
|
||||
#include "code\game\objects\effects\effect_system\effect_system.dm"
|
||||
#include "code\game\objects\effects\effect_system\effects_explosion.dm"
|
||||
#include "code\game\objects\effects\effect_system\effects_foam.dm"
|
||||
Reference in New Issue
Block a user