[MIRROR] Harvesters are more fun to play (#894)
* Harvesters are more fun to play * resolve .rej
This commit is contained in:
committed by
Poojawa
parent
593a784583
commit
6617f68604
@@ -127,22 +127,21 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
|
||||
/mob/dead/observer/narsie_act()
|
||||
var/old_color = color
|
||||
color = "#960000"
|
||||
animate(src, color = old_color, time = 10)
|
||||
animate(src, color = old_color, time = 10, flags = ANIMATION_PARALLEL)
|
||||
addtimer(CALLBACK(src, /atom/proc/update_atom_colour), 10)
|
||||
|
||||
/mob/dead/observer/ratvar_act()
|
||||
var/old_color = color
|
||||
color = "#FAE48C"
|
||||
animate(src, color = old_color, time = 10)
|
||||
animate(src, color = old_color, time = 10, flags = ANIMATION_PARALLEL)
|
||||
addtimer(CALLBACK(src, /atom/proc/update_atom_colour), 10)
|
||||
|
||||
/mob/dead/observer/Destroy()
|
||||
GLOB.ghost_images_default -= ghostimage_default
|
||||
qdel(ghostimage_default)
|
||||
ghostimage_default = null
|
||||
QDEL_NULL(ghostimage_default)
|
||||
|
||||
GLOB.ghost_images_simple -= ghostimage_simple
|
||||
qdel(ghostimage_simple)
|
||||
ghostimage_simple = null
|
||||
QDEL_NULL(ghostimage_simple)
|
||||
|
||||
updateallghostimages()
|
||||
return ..()
|
||||
|
||||
@@ -306,17 +306,15 @@
|
||||
reagents.add_reagent("heparin", 5)
|
||||
return FALSE
|
||||
if(client)
|
||||
makeNewConstruct(/mob/living/simple_animal/hostile/construct/harvester, src, null, 0)
|
||||
makeNewConstruct(/mob/living/simple_animal/hostile/construct/harvester, src, cultoverride = TRUE)
|
||||
else
|
||||
switch(rand(1, 10))
|
||||
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))
|
||||
if(6 to 10)
|
||||
new /mob/living/simple_animal/hostile/construct/harvester/hostile(get_turf(src))
|
||||
spawn_dust()
|
||||
gib()
|
||||
return TRUE
|
||||
|
||||
@@ -27,25 +27,22 @@
|
||||
unique_name = 1
|
||||
AIStatus = AI_OFF //normal constructs don't have AI
|
||||
loot = list(/obj/item/weapon/ectoplasm)
|
||||
del_on_death = TRUE
|
||||
initial_language_holder = /datum/language_holder/construct
|
||||
del_on_death = TRUE
|
||||
initial_language_holder = /datum/language_holder/construct
|
||||
deathmessage = "collapses in a shattered heap."
|
||||
var/list/construct_spells = list()
|
||||
var/playstyle_string = "<b>You are a generic construct! Your job is to not exist, and you should probably adminhelp this.</b>"
|
||||
var/master = null
|
||||
var/seeking = FALSE
|
||||
var/can_repair_constructs = FALSE
|
||||
var/can_repair_self = FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/construct/Initialize()
|
||||
. = ..()
|
||||
update_health_hud()
|
||||
for(var/spell in construct_spells)
|
||||
AddSpell(new spell(null))
|
||||
|
||||
/mob/living/simple_animal/hostile/construct/Destroy()
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
qdel(A)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/construct/Login()
|
||||
..()
|
||||
to_chat(src, playstyle_string)
|
||||
@@ -67,7 +64,10 @@
|
||||
to_chat(user, msg)
|
||||
|
||||
/mob/living/simple_animal/hostile/construct/attack_animal(mob/living/simple_animal/M)
|
||||
if(istype(M, /mob/living/simple_animal/hostile/construct/builder))
|
||||
if(isconstruct(M)) //is it a construct?
|
||||
var/mob/living/simple_animal/hostile/construct/C = M
|
||||
if(!C.can_repair_constructs || (C == src && !C.can_repair_self))
|
||||
return
|
||||
if(health < maxHealth)
|
||||
adjustHealth(-5)
|
||||
if(src != M)
|
||||
@@ -128,38 +128,6 @@
|
||||
AIStatus = AI_ON
|
||||
environment_smash = 1 //only token destruction, don't smash the cult wall NO STOP
|
||||
|
||||
|
||||
///////////////////////Master-Tracker///////////////////////
|
||||
|
||||
/datum/action/innate/seek_master
|
||||
name = "Seek your Master"
|
||||
desc = "You and your master share a soul-link that informs you of their location"
|
||||
background_icon_state = "bg_demon"
|
||||
buttontooltipstyle = "cult"
|
||||
button_icon_state = "cult_mark"
|
||||
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(!the_construct.master)
|
||||
to_chat(the_construct, "<span class='cultitalic'>You have no master to seek!</span>")
|
||||
the_construct.seeking = FALSE
|
||||
return
|
||||
if(tracking)
|
||||
tracking = FALSE
|
||||
the_construct.seeking = FALSE
|
||||
to_chat(the_construct, "<span class='cultitalic'>You are no longer tracking your master.</span>")
|
||||
return
|
||||
else
|
||||
tracking = TRUE
|
||||
the_construct.seeking = TRUE
|
||||
to_chat(the_construct, "<span class='cultitalic'>You are now tracking your master.</span>")
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/construct/armored/bullet_act(obj/item/projectile/P)
|
||||
if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam))
|
||||
var/reflectchance = 80 - round(P.damage/3)
|
||||
@@ -203,30 +171,7 @@
|
||||
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, 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)
|
||||
playstyle_string = "<b>You are a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls.</b>"
|
||||
|
||||
/mob/living/simple_animal/hostile/construct/wraith/hostile //actually hostile, will move around, hit things
|
||||
AIStatus = AI_ON
|
||||
@@ -261,6 +206,8 @@
|
||||
use magic missile, repair allied constructs, shades, and yourself (by clicking on them), \
|
||||
<i>and, most important of all,</i> create new constructs by producing soulstones to capture souls, \
|
||||
and shells to place those soulstones into.</b>"
|
||||
can_repair_constructs = TRUE
|
||||
can_repair_self = TRUE
|
||||
|
||||
/mob/living/simple_animal/hostile/construct/builder/Found(atom/A) //what have we found here?
|
||||
if(isconstruct(A)) //is it a construct?
|
||||
@@ -322,22 +269,81 @@
|
||||
icon_living = "harvester"
|
||||
maxHealth = 60
|
||||
health = 60
|
||||
melee_damage_lower = 1
|
||||
melee_damage_upper = 5
|
||||
retreat_distance = 2 //AI harvesters will move in and out of combat, like wraiths, but shittier
|
||||
attacktext = "prods"
|
||||
environment_smash = 3
|
||||
attack_sound = 'sound/weapons/tap.ogg'
|
||||
construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/wall,
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/floor,
|
||||
/obj/effect/proc_holder/spell/targeted/smoke/disable)
|
||||
playstyle_string = "<B>You are a Harvester. You are not strong, but your powers of domination will assist you in your role: \
|
||||
sight = SEE_MOBS
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 20
|
||||
attacktext = "butchers"
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
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>"
|
||||
can_repair_constructs = TRUE
|
||||
|
||||
/mob/living/simple_animal/hostile/construct/harvester/hostile //actually hostile, will move around, hit things
|
||||
AIStatus = AI_ON
|
||||
environment_smash = 1 //only token destruction, don't smash the cult wall NO STOP
|
||||
/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
|
||||
var/atom/movable/stored_pulling = pulling
|
||||
if(stored_pulling)
|
||||
stored_pulling.setDir(get_dir(stored_pulling.loc, loc))
|
||||
stored_pulling.forceMove(loc)
|
||||
forceMove(AM)
|
||||
if(stored_pulling)
|
||||
start_pulling(stored_pulling, TRUE) //drag anything we're pulling through the wall with us by magic
|
||||
|
||||
/mob/living/simple_animal/hostile/construct/harvester/AttackingTarget()
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/C = target
|
||||
var/list/parts = list()
|
||||
var/undismembermerable_limbs = 0
|
||||
for(var/X in C.bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
if(BP.body_part != HEAD && BP.body_part != CHEST)
|
||||
if(BP.dismemberable)
|
||||
parts += BP
|
||||
else
|
||||
undismembermerable_limbs++
|
||||
if(!LAZYLEN(parts))
|
||||
if(undismembermerable_limbs) //they have limbs we can't remove, and no parts we can, attack!
|
||||
return ..()
|
||||
to_chat(src, "<span class='cultlarge'>\"Bring [C.p_them()] to me.\"</span>")
|
||||
return FALSE
|
||||
do_attack_animation(C)
|
||||
var/obj/item/bodypart/BP = pick(parts)
|
||||
BP.dismember()
|
||||
return FALSE
|
||||
. = ..()
|
||||
|
||||
|
||||
///////////////////////Master-Tracker///////////////////////
|
||||
|
||||
/datum/action/innate/seek_master
|
||||
name = "Seek your Master"
|
||||
desc = "You and your master share a soul-link that informs you of their location"
|
||||
background_icon_state = "bg_demon"
|
||||
buttontooltipstyle = "cult"
|
||||
button_icon_state = "cult_mark"
|
||||
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(!the_construct.master)
|
||||
to_chat(the_construct, "<span class='cultitalic'>You have no master to seek!</span>")
|
||||
the_construct.seeking = FALSE
|
||||
return
|
||||
if(tracking)
|
||||
tracking = FALSE
|
||||
the_construct.seeking = FALSE
|
||||
to_chat(the_construct, "<span class='cultitalic'>You are no longer tracking your master.</span>")
|
||||
return
|
||||
else
|
||||
tracking = TRUE
|
||||
the_construct.seeking = TRUE
|
||||
to_chat(the_construct, "<span class='cultitalic'>You are now tracking your master.</span>")
|
||||
|
||||
|
||||
/////////////////////////////ui stuff/////////////////////////////
|
||||
@@ -355,4 +361,4 @@
|
||||
else if(health > maxHealth*0.2)
|
||||
hud_used.healths.icon_state = "[icon_state]_health5"
|
||||
else
|
||||
hud_used.healths.icon_state = "[icon_state]_health6"
|
||||
hud_used.healths.icon_state = "[icon_state]_health6"
|
||||
|
||||
@@ -44,7 +44,10 @@
|
||||
return TRUE //this doesn't make much sense; you'd thing TRUE would mean it'd process spacemove but it means it doesn't
|
||||
|
||||
/mob/living/simple_animal/shade/attack_animal(mob/living/simple_animal/M)
|
||||
if(istype(M, /mob/living/simple_animal/hostile/construct/builder))
|
||||
if(isconstruct(M))
|
||||
var/mob/living/simple_animal/hostile/construct/C = M
|
||||
if(!C.can_repair_constructs)
|
||||
return
|
||||
if(health < maxHealth)
|
||||
adjustHealth(-25)
|
||||
Beam(M,icon_state="sendbeam",time=4)
|
||||
|
||||
@@ -331,12 +331,14 @@
|
||||
changeNext_move(CLICK_CD_GRABBING)
|
||||
|
||||
if(AM.pulledby)
|
||||
visible_message("<span class='danger'>[src] has pulled [AM] from [AM.pulledby]'s grip.</span>")
|
||||
if(!supress_message)
|
||||
visible_message("<span class='danger'>[src] has pulled [AM] from [AM.pulledby]'s grip.</span>")
|
||||
AM.pulledby.stop_pulling() //an object can't be pulled by two mobs at once.
|
||||
|
||||
pulling = AM
|
||||
AM.pulledby = src
|
||||
playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
if(!supress_message)
|
||||
playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
update_pull_hud_icon()
|
||||
|
||||
if(ismob(AM))
|
||||
|
||||
@@ -39,13 +39,12 @@
|
||||
|
||||
narsie_spawn_animation()
|
||||
|
||||
sleep(70)
|
||||
SSshuttle.emergency.request(null, set_coefficient = 0.1) // Cannot recall
|
||||
sleep(19)
|
||||
SSshuttle.emergency.request(null, set_coefficient = 0) //instantly arrives
|
||||
|
||||
|
||||
/obj/singularity/narsie/large/attack_ghost(mob/dead/observer/user as mob)
|
||||
makeNewConstruct(/mob/living/simple_animal/hostile/construct/harvester, user, null, 0, loc_override = src.loc)
|
||||
new /obj/effect/particle_effect/smoke/sleeping(src.loc)
|
||||
makeNewConstruct(/mob/living/simple_animal/hostile/construct/harvester, user, cultoverride = TRUE, loc_override = src.loc)
|
||||
|
||||
|
||||
/obj/singularity/narsie/process()
|
||||
@@ -82,7 +81,8 @@
|
||||
|
||||
|
||||
/obj/singularity/narsie/consume(atom/A)
|
||||
A.narsie_act()
|
||||
if(isturf(A))
|
||||
A.narsie_act()
|
||||
|
||||
|
||||
/obj/singularity/narsie/ex_act() //No throwing bombs at her either.
|
||||
|
||||
@@ -9,6 +9,26 @@
|
||||
cult_req = 1
|
||||
charge_max = 2500
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/area_conversion
|
||||
name = "Area Conversion"
|
||||
desc = "This spell instantly converts a small area around you."
|
||||
|
||||
school = "transmutation"
|
||||
charge_max = 50
|
||||
clothes_req = 0
|
||||
invocation = "none"
|
||||
invocation_type = "none"
|
||||
range = 2
|
||||
action_icon_state = "areaconvert"
|
||||
action_background_icon_state = "bg_cult"
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/area_conversion/cast(list/targets, mob/user = usr)
|
||||
playsound(get_turf(user), 'sound/items/welder.ogg', 75, 1)
|
||||
for(var/turf/T in targets)
|
||||
T.narsie_act(FALSE, TRUE, 100 - (get_dist(user, T) * 25))
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/floor
|
||||
name = "Summon Cult Floor"
|
||||
desc = "This spell constructs a cult floor"
|
||||
|
||||
Reference in New Issue
Block a user