[MIRROR] transform the paper wizard from a simple to a basic [MDB IGNORE] (#22452)

* transform the paper wizard from a simple to a basic (#76688)

## About The Pull Request
i transfered paper wizard from simple to a basic and i also gaved him
new fetures he can go and do. now when he will go and walked when he
walks there will be a paper effects when he goes to walk. also he will
he will now go to look for paperes on the floor and then he will write
stuff inside the paper, so a player can maybe distracted the wizard with
a paper because the wizard will stop atacked him for a bit until he
finished writted stuff inside the paper. i follow the instrucions in the
learn-ai md to maked this to a new ai subtree behavier.

## Why It's Good For The Game
the paper wizard is now a basic so he is a better ai and he also have
more feture to gaved him depth mechanics

## Changelog
🆑
refactor: paper wizard have been refactored, please report any
bugs/unintended behavior
refactor: refacted the datum/elememt/trial to an bespoken element
add: paper wizard now have effects when he walking and he will now go
and look for paperes and write stuff in them
/🆑

* transform the paper wizard from a simple to a basic

---------

Co-authored-by: Ben10Omintrix <138636438+Ben10Omintrix@users.noreply.github.com>
This commit is contained in:
SkyratBot
2023-07-14 19:10:55 +02:00
committed by GitHub
parent c53dd97296
commit ed294532c6
15 changed files with 352 additions and 225 deletions
@@ -740,7 +740,7 @@
/turf/open/indestructible/paper,
/area/ruin/space/has_grav/powered)
"cc" = (
/mob/living/simple_animal/hostile/boss/paper_wizard,
/mob/living/basic/paper_wizard,
/turf/open/indestructible/paper,
/area/ruin/space/has_grav/powered)
"cd" = (
+9
View File
@@ -310,6 +310,15 @@
/// Key where we store the charging apc ability
#define BB_FESTIVE_APC "BB_festive_apc"
//Paperwizard AI keys
/// Key where we store the summon minions ability
#define BB_WIZARD_SUMMON_MINIONS "BB_summon_minions"
/// Key where we store the mimics ability
#define BB_WIZARD_MIMICS "BB_summon_mimics"
/// Key where we store the paper target
#define BB_FOUND_PAPER "BB_found_paper"
/// Key where we store the list of things we can write on a paper
#define BB_WRITING_LIST "BB_writing_list"
/// Key where we store the tentacleing ability
#define BB_GOLIATH_TENTACLES "BB_goliath_tentacles"
/// Key where goliath stores a hole it wants to get into
@@ -0,0 +1,16 @@
/datum/ai_behavior/write_on_paper
/datum/ai_behavior/write_on_paper/perform(seconds_per_tick, datum/ai_controller/controller, found_paper, list_of_writings)
. = ..()
var/mob/living/wizard = controller.pawn
var/list/writing_list = controller.blackboard[list_of_writings]
var/obj/item/paper/target = controller.blackboard[found_paper]
if(length(writing_list))
target.add_raw_text(pick(writing_list))
target.update_appearance()
wizard.dropItemToGround(target)
finish_action(controller, TRUE, found_paper)
/datum/ai_behavior/write_on_paper/finish_action(datum/ai_controller/controller, succeeded, target_key)
. = ..()
controller.clear_blackboard_key(target_key)
@@ -0,0 +1,23 @@
/datum/ai_planning_subtree/find_paper_and_write
/datum/ai_planning_subtree/find_paper_and_write/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
var/obj/item/inhand_paper = controller.blackboard[BB_SIMPLE_CARRY_ITEM]
var/mob/living/basic/wizard = controller.pawn
if(!QDELETED(inhand_paper))
controller.queue_behavior(/datum/ai_behavior/write_on_paper, BB_SIMPLE_CARRY_ITEM, BB_WRITING_LIST)
return SUBTREE_RETURN_FINISH_PLANNING
var/obj/item/paper/target = controller.blackboard[BB_FOUND_PAPER]
if(QDELETED(target))
controller.queue_behavior(/datum/ai_behavior/find_and_set/empty_paper, BB_FOUND_PAPER, /obj/item/paper)
return
if(get_turf(wizard) != get_turf(target))
controller.queue_behavior(/datum/ai_behavior/travel_towards, BB_FOUND_PAPER)
return SUBTREE_RETURN_FINISH_PLANNING
if(!(target in wizard.contents))
controller.queue_behavior(/datum/ai_behavior/pick_up_item, BB_FOUND_PAPER, BB_SIMPLE_CARRY_ITEM)
return SUBTREE_RETURN_FINISH_PLANNING
+5 -5
View File
@@ -3,14 +3,17 @@
*/
/datum/element/effect_trail
element_flags = ELEMENT_BESPOKE
argument_hash_start_idx = 2
/// The effect used for the trail generation.
var/obj/effect/chosen_effect
var/chosen_effect
/datum/element/effect_trail/Attach(datum/target)
/datum/element/effect_trail/Attach(datum/target, chosen_effect = /obj/effect/forcefield/cosmic_field)
. = ..()
if(!ismovable(target))
return ELEMENT_INCOMPATIBLE
RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(generate_effect))
src.chosen_effect = chosen_effect
/datum/element/effect_trail/Detach(datum/target)
. = ..()
@@ -23,6 +26,3 @@
var/turf/open/open_turf = get_turf(target_object)
if(istype(open_turf))
new chosen_effect(open_turf)
/datum/element/effect_trail/cosmic_trail
chosen_effect = /obj/effect/forcefield/cosmic_field/fast
@@ -182,7 +182,7 @@
if(target.mind && target.stat != DEAD)
increase_combo_duration()
if(combo_counter == 4)
source.AddElement(/datum/element/effect_trail/cosmic_trail)
source.AddElement(/datum/element/effect_trail, /obj/effect/forcefield/cosmic_field/fast)
third_target = second_target
second_target = WEAKREF(target)
@@ -191,7 +191,7 @@
second_target = null
third_target = null
if(combo_counter > 3)
source.RemoveElement(/datum/element/effect_trail/cosmic_trail)
source.RemoveElement(/datum/element/effect_trail, /obj/effect/forcefield/cosmic_field/fast)
combo_duration = combo_duration_amount
combo_counter = 0
new /obj/effect/temp_visual/cosmic_cloud(get_turf(source))
@@ -35,7 +35,7 @@
/obj/projectile/magic/star_ball/Initialize(mapload)
. = ..()
AddElement(/datum/element/effect_trail/cosmic_trail)
AddElement(/datum/element/effect_trail, /obj/effect/forcefield/cosmic_field/fast)
/obj/projectile/magic/star_ball/on_hit(atom/target, blocked = FALSE, pierce_hit)
. = ..()
@@ -230,7 +230,7 @@
/// What to add when the beam connects to a target
/datum/status_effect/cosmic_beam/proc/on_beam_hit(mob/living/target)
if(!istype(target, /mob/living/basic/star_gazer))
target.AddElement(/datum/element/effect_trail/cosmic_trail)
target.AddElement(/datum/element/effect_trail, /obj/effect/forcefield/cosmic_field/fast)
return
/// What to process when the beam is connected to a target
@@ -242,5 +242,5 @@
/// What to remove when the beam disconnects from a target
/datum/status_effect/cosmic_beam/proc/on_beam_release(mob/living/target)
if(!istype(target, /mob/living/basic/star_gazer))
target.RemoveElement(/datum/element/effect_trail/cosmic_trail)
target.RemoveElement(/datum/element/effect_trail, /obj/effect/forcefield/cosmic_field/fast)
return
@@ -52,7 +52,7 @@
AddElement(/datum/element/footstep, FOOTSTEP_MOB_SHOE)
AddElement(/datum/element/wall_smasher, ENVIRONMENT_SMASH_RWALLS)
AddElement(/datum/element/simple_flying)
AddElement(/datum/element/effect_trail/cosmic_trail)
AddElement(/datum/element/effect_trail, /obj/effect/forcefield/cosmic_field/fast)
AddElement(/datum/element/ai_target_damagesource)
AddComponent(/datum/component/regenerator, outline_colour = "#b97a5d")
ADD_TRAIT(src, TRAIT_SPACEWALK, INNATE_TRAIT)
@@ -0,0 +1,90 @@
/datum/action/cooldown/spell/conjure/wizard_summon_minions
name = "Summon Minions"
button_icon = 'icons/mob/actions/actions_minor_antag.dmi'
button_icon_state = "art_summon"
invocation = "Rise, my creations! Jump off your pages and into this realm!"
invocation_type = INVOCATION_SHOUT
spell_requirements = NONE
cooldown_time = 15 SECONDS
summon_type = list(
/mob/living/basic/stickman,
/mob/living/basic/stickman/ranged,
/mob/living/basic/stickman/dog,
)
summon_radius = 1
summon_amount = 2
///How many minions we summoned
var/summoned_minions = 0
///How many minions we can have at once
var/max_minions = 6
/datum/action/cooldown/spell/conjure/wizard_summon_minions/can_cast_spell(feedback = TRUE)
. = ..()
if(!.)
return FALSE
if(summoned_minions >= max_minions)
return FALSE
return TRUE
/datum/action/cooldown/spell/conjure/wizard_summon_minions/post_summon(atom/summoned_object, atom/cast_on)
var/mob/living/chosen_minion = summoned_object
RegisterSignals(chosen_minion, list(COMSIG_QDELETING, COMSIG_LIVING_DEATH), PROC_REF(lost_minion))
summoned_minions++
/datum/action/cooldown/spell/conjure/wizard_summon_minions/proc/lost_minion(mob/source)
SIGNAL_HANDLER
UnregisterSignal(source, list(COMSIG_QDELETING, COMSIG_LIVING_DEATH))
summoned_minions--
/datum/action/cooldown/spell/pointed/wizard_mimic
name = "Craft Mimicry"
button_icon = 'icons/mob/actions/actions_minor_antag.dmi'
button_icon_state = "mimic_summon"
invocation = "My craft defines me, you could even say it IS me!"
invocation_type = INVOCATION_SHOUT
spell_requirements = NONE
cooldown_time = 25 SECONDS
///when the clones will die
var/clone_lifespan = 15 SECONDS
///list of clones
var/list/copies = list()
/datum/action/cooldown/spell/pointed/wizard_mimic/Grant(mob/grant_to)
. = ..()
if(!owner)
return
RegisterSignal(owner, COMSIG_LIVING_HEALTH_UPDATE, PROC_REF(delete_clones))
/datum/action/cooldown/spell/pointed/wizard_mimic/is_valid_target(atom/cast_on)
if(!isliving(cast_on))
return FALSE
return TRUE
/datum/action/cooldown/spell/pointed/wizard_mimic/cast(mob/living/cast_on)
. = ..()
var/list/directions = GLOB.cardinals.Copy()
for(var/i in 1 to 3)
var/mob/living/basic/paper_wizard/copy/copy = new (get_step(cast_on, pick_n_take(directions)))
invocation(copy)
RegisterSignals(copy, list(COMSIG_QDELETING, COMSIG_LIVING_DEATH), PROC_REF(lost_minion))
copies += copy
QDEL_IN(copy, clone_lifespan)
owner.forceMove(get_step(cast_on, pick_n_take(directions)))
/datum/action/cooldown/spell/pointed/wizard_mimic/proc/lost_minion(mob/living/basic/paper_wizard/copy/source)
SIGNAL_HANDLER
copies -= source
UnregisterSignal(source, list(COMSIG_QDELETING, COMSIG_LIVING_DEATH), PROC_REF(lost_minion))
/datum/action/cooldown/spell/pointed/wizard_mimic/proc/delete_clones(mob/source)
SIGNAL_HANDLER
QDEL_LIST(copies)
/datum/action/cooldown/spell/pointed/wizard_mimic/Destroy()
QDEL_LIST(copies)
return ..()
@@ -0,0 +1,196 @@
/mob/living/basic/paper_wizard
name = "Mjor the Creative"
desc = "A wizard with a taste for the arts."
mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
faction = list(FACTION_HOSTILE, FACTION_STICKMAN)
icon = 'icons/mob/simple/simple_human.dmi'
icon_state = "paperwizard"
gender = MALE
response_help_continuous = "brushes"
response_help_simple = "brush"
response_disarm_continuous = "pushes"
response_disarm_simple = "push"
basic_mob_flags = DEL_ON_DEATH
maxHealth = 1000
health = 1000
melee_damage_lower = 10
melee_damage_upper = 20
obj_damage = 50
attack_sound = 'sound/hallucinations/growl1.ogg'
ai_controller = /datum/ai_controller/basic_controller/paper_wizard
///spell to summon minions
var/datum/action/cooldown/spell/conjure/wizard_summon_minions/summon
///spell to summon clones
var/datum/action/cooldown/spell/pointed/wizard_mimic/mimic
///the loot we will drop
var/static/list/dropped_loot = list(/obj/effect/temp_visual/paperwiz_dying)
/mob/living/basic/paper_wizard/Initialize(mapload)
. = ..()
apply_dynamic_human_appearance(src, mob_spawn_path = /obj/effect/mob_spawn/corpse/human/wizard/paper)
grant_abilities()
grant_loot()
AddElement(/datum/element/effect_trail, /obj/effect/temp_visual/paper_scatter)
/mob/living/basic/paper_wizard/proc/grant_abilities()
summon = new(src)
summon.Grant(src)
ai_controller.set_blackboard_key(BB_WIZARD_SUMMON_MINIONS, summon)
mimic = new(src)
mimic.Grant(src)
ai_controller.set_blackboard_key(BB_WIZARD_MIMICS, mimic)
/mob/living/basic/paper_wizard/proc/grant_loot()
AddElement(/datum/element/death_drops, dropped_loot)
/mob/living/basic/paper_wizard/Destroy()
QDEL_NULL(summon)
QDEL_NULL(mimic)
return ..()
/datum/ai_controller/basic_controller/paper_wizard
blackboard = list(
BB_TARGETTING_DATUM = new /datum/targetting_datum/basic,
BB_WRITING_LIST = list(
"I can turn the paper into gold and ink into diamonds!",
"Your fate is written and sealed!",
"You shall suffer the wrath of a thousand paper cuts!",
)
)
ai_movement = /datum/ai_movement/basic_avoidance
idle_behavior = /datum/idle_behavior/idle_random_walk/less_walking
planning_subtrees = list(
/datum/ai_planning_subtree/simple_find_target,
/datum/ai_planning_subtree/targeted_mob_ability/wizard_mimic,
/datum/ai_planning_subtree/use_mob_ability/wizard_summon_minions,
/datum/ai_planning_subtree/basic_melee_attack_subtree,
/datum/ai_planning_subtree/attack_obstacle_in_path/paper_wizard,
/datum/ai_planning_subtree/find_paper_and_write,
)
/datum/ai_planning_subtree/attack_obstacle_in_path/paper_wizard
target_key = BB_FOUND_PAPER
attack_behaviour = /datum/ai_behavior/attack_obstructions/paper_wizard
/datum/ai_behavior/attack_obstructions/paper_wizard
action_cooldown = 0.4 SECONDS
can_attack_turfs = TRUE
can_attack_dense_objects = TRUE
/datum/ai_planning_subtree/targeted_mob_ability/wizard_mimic
ability_key = BB_WIZARD_MIMICS
finish_planning = FALSE
/datum/ai_planning_subtree/use_mob_ability/wizard_summon_minions
ability_key = BB_WIZARD_SUMMON_MINIONS
finish_planning = FALSE
/datum/ai_behavior/find_and_set/empty_paper
action_cooldown = 10 SECONDS
/datum/ai_behavior/find_and_set/empty_paper/search_tactic(datum/ai_controller/controller, locate_path, search_range)
var/list/empty_papers = list()
for(var/obj/item/paper/target_paper in oview(search_range, controller.pawn))
if(target_paper.is_empty())
empty_papers += target_paper
if(empty_papers.len)
return pick(empty_papers)
/mob/living/basic/paper_wizard/copy
desc = "'Tis a ruse!"
health = 1
maxHealth = 1
alpha = 200
faction = list(FACTION_STICKMAN)
melee_damage_lower = 1
melee_damage_upper = 5
ai_controller = /datum/ai_controller/basic_controller/wizard_copy
/mob/living/basic/paper_wizard/copy/Initialize(mapload)
. = ..()
AddElement(/datum/element/relay_attackers)
RegisterSignal(src, COMSIG_ATOM_WAS_ATTACKED, PROC_REF(on_attacked))
/mob/living/basic/paper_wizard/copy/grant_abilities()
return
/mob/living/basic/paper_wizard/copy/grant_loot()
return
//Hit a fake? eat pain!
/mob/living/basic/paper_wizard/copy/proc/on_attacked(mob/source, mob/living/attacker, attack_flags)
SIGNAL_HANDLER
if(!(attack_flags & (ATTACKER_STAMINA_ATTACK|ATTACKER_SHOVING)))
attacker.adjustBruteLoss(20)
to_chat(attacker, span_warning("The clone casts a spell to damage you before he dies!"))
/mob/living/basic/paper_wizard/copy/examine(mob/user)
. = ..()
if(isobserver(user))
. += span_notice("It's an illusion - what is it hiding?")
else
new /obj/effect/temp_visual/small_smoke/halfsecond(get_turf(src))
qdel(src) //I see through your ruse!
/datum/ai_controller/basic_controller/wizard_copy
blackboard = list(
BB_TARGETTING_DATUM = new /datum/targetting_datum/basic,
)
ai_movement = /datum/ai_movement/basic_avoidance
idle_behavior = /datum/idle_behavior/idle_random_walk
planning_subtrees = list(
/datum/ai_planning_subtree/simple_find_target,
/datum/ai_planning_subtree/basic_melee_attack_subtree,
)
//fancy effects
/obj/effect/temp_visual/paper_scatter
name = "scattering paper"
desc = "Pieces of paper scattering to the wind."
layer = ABOVE_NORMAL_TURF_LAYER
plane = GAME_PLANE
icon = 'icons/effects/effects.dmi'
icon_state = "paper_scatter"
anchored = TRUE
duration = 0.5 SECONDS
randomdir = FALSE
/obj/effect/temp_visual/paperwiz_dying
name = "craft portal"
desc = "A wormhole sucking the wizard into the void. Neat."
layer = ABOVE_NORMAL_TURF_LAYER
plane = GAME_PLANE
icon = 'icons/effects/effects.dmi'
icon_state = "paperwiz_poof"
anchored = TRUE
duration = 1.8 SECONDS
randomdir = FALSE
/obj/effect/temp_visual/paperwiz_dying/Initialize(mapload)
. = ..()
visible_message(span_boldannounce("The wizard cries out in pain as a gate appears behind him, sucking him in!"))
playsound(get_turf(src), 'sound/magic/mandswap.ogg', 50, vary = TRUE, pressure_affected = TRUE)
playsound(get_turf(src), 'sound/hallucinations/wail.ogg', 50, vary = TRUE, pressure_affected = TRUE)
RegisterSignal(src, COMSIG_PREQDELETED, PROC_REF(on_delete))
/obj/effect/temp_visual/paperwiz_dying/proc/on_delete()
SIGNAL_HANDLER
for(var/mob/nearby in range(7, src))
shake_camera(nearby, duration = 7 SECONDS, strength = 1)
var/turf/current_turf = get_turf(src)
playsound(current_turf,'sound/magic/summon_magic.ogg', 50, vary = TRUE, vary = TRUE)
new /obj/effect/temp_visual/paper_scatter(current_turf)
new /obj/item/clothing/suit/wizrobe/paper(current_turf)
new /obj/item/clothing/head/collectable/paper(current_turf)
@@ -1,210 +0,0 @@
//Paper Wizard Boss
/mob/living/simple_animal/hostile/boss/paper_wizard
name = "Mjor the Creative"
desc = "A wizard with a taste for the arts."
mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
boss_abilities = list(/datum/action/boss/wizard_summon_minions, /datum/action/boss/wizard_mimic)
faction = list(FACTION_HOSTILE,FACTION_STICKMAN)
del_on_death = TRUE
icon = 'icons/mob/simple/simple_human.dmi'
icon_state = "paperwizard"
ranged = TRUE
environment_smash = ENVIRONMENT_SMASH_NONE
minimum_distance = 3
retreat_distance = 3
obj_damage = 0
melee_damage_lower = 10
melee_damage_upper = 20
health = 1000
maxHealth = 1000
loot = list(/obj/effect/temp_visual/paperwiz_dying)
projectiletype = /obj/projectile/temp
projectilesound = 'sound/weapons/emitter.ogg'
attack_sound = 'sound/hallucinations/growl1.ogg'
footstep_type = FOOTSTEP_MOB_SHOE
var/list/copies = list()
/mob/living/simple_animal/hostile/boss/paper_wizard/Initialize(mapload)
. = ..()
apply_dynamic_human_appearance(src, mob_spawn_path = /obj/effect/mob_spawn/corpse/human/wizard/paper)
/mob/living/simple_animal/hostile/boss/paper_wizard/Destroy()
QDEL_LIST(copies)
return ..()
//Summon Ability
//Lets the wizard summon his art to fight for him
/datum/action/boss/wizard_summon_minions
name = "Summon Minions"
button_icon = 'icons/mob/actions/actions_minor_antag.dmi'
button_icon_state = "art_summon"
usage_probability = 40
boss_cost = 30
boss_type = /mob/living/simple_animal/hostile/boss/paper_wizard
needs_target = FALSE
say_when_triggered = "Rise, my creations! Jump off your pages and into this realm!"
///How many minions we summoned
var/summoned_minions = 0
///How many minions we can have at once
var/max_minions = 6
///How many minions we should spawn
var/minions_to_summon = 3
/datum/action/boss/wizard_summon_minions/IsAvailable(feedback = FALSE)
. = ..()
if(!.)
return FALSE
if(summoned_minions >= max_minions)
return FALSE
return TRUE
/datum/action/boss/wizard_summon_minions/Trigger(trigger_flags)
. = ..()
if(!.)
return
var/list/minions = list(
/mob/living/basic/stickman,
/mob/living/basic/stickman/ranged,
/mob/living/basic/stickman/dog)
var/list/directions = GLOB.cardinals.Copy()
var/summon_amount = min(minions_to_summon, max_minions - summoned_minions)
for(var/i in 1 to summon_amount)
var/atom/chosen_minion = pick_n_take(minions)
chosen_minion = new chosen_minion(get_step(boss, pick_n_take(directions)))
RegisterSignals(chosen_minion, list(COMSIG_QDELETING, COMSIG_LIVING_DEATH), PROC_REF(lost_minion))
summoned_minions++
/// Called when a minion is qdeleted or dies, removes it from our minion list
/datum/action/boss/wizard_summon_minions/proc/lost_minion(mob/source)
SIGNAL_HANDLER
UnregisterSignal(source, list(COMSIG_QDELETING, COMSIG_LIVING_DEATH))
summoned_minions--
//Mimic Ability
//Summons mimics of himself with magical papercraft
//Hitting a decoy hurts nearby people excluding the wizard himself
//Hitting the wizard himself destroys all decoys
/datum/action/boss/wizard_mimic
name = "Craft Mimicry"
button_icon = 'icons/mob/actions/actions_minor_antag.dmi'
button_icon_state = "mimic_summon"
usage_probability = 30
boss_cost = 40
boss_type = /mob/living/simple_animal/hostile/boss/paper_wizard
say_when_triggered = ""
/datum/action/boss/wizard_mimic/Trigger(trigger_flags)
if(..())
var/mob/living/target
if(!boss.client) //AI's target
target = boss.target
else //random mob
var/list/threats = boss.PossibleThreats()
if(threats.len)
target = pick(threats)
if(target)
var/mob/living/simple_animal/hostile/boss/paper_wizard/wiz = boss
var/directions = GLOB.cardinals.Copy()
for(var/i in 1 to 3)
var/mob/living/simple_animal/hostile/boss/paper_wizard/copy/C = new (get_step(target,pick_n_take(directions)))
wiz.copies += C
C.original = wiz
C.say("My craft defines me, you could even say it IS me!")
wiz.say("My craft defines me, you could even say it IS me!")
wiz.forceMove(get_step(target,pick_n_take(directions)))
wiz.minimum_distance = 1 //so he doesn't run away and ruin everything
wiz.retreat_distance = 0
else
boss.atb.refund(boss_cost)
/mob/living/simple_animal/hostile/boss/paper_wizard/copy
desc = "'Tis a ruse!"
health = 1
maxHealth = 1
alpha = 200
boss_abilities = list()
melee_damage_lower = 1
melee_damage_upper = 5
minimum_distance = 0
retreat_distance = 0
ranged = 0
loot = list()
var/mob/living/simple_animal/hostile/boss/paper_wizard/original
/mob/living/simple_animal/hostile/boss/paper_wizard/copy/Destroy()
if(original)
original.copies -= src
original = null
return ..()
//Hit a fake? eat pain!
/mob/living/simple_animal/hostile/boss/paper_wizard/copy/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
if(amount > 0) //damage
if(original)
original.minimum_distance = 3
original.retreat_distance = 3
for(var/c in original.copies)
qdel(c)
for(var/mob/living/L in range(5,src))
if(L == original || istype(L, type))
continue
L.adjustBruteLoss(50)
qdel(src)
else
. = ..()
//Hit the real guy? copies go bai-bai
/mob/living/simple_animal/hostile/boss/paper_wizard/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
. = ..()
if(. > 0)//damage
minimum_distance = 3
retreat_distance = 3
for(var/copy in copies)
qdel(copy)
/mob/living/simple_animal/hostile/boss/paper_wizard/copy/examine(mob/user)
. = ..()
if(isobserver(user))
. += span_notice("It's an illusion - what is it hiding?")
else
qdel(src) //I see through your ruse!
//fancy effects
/obj/effect/temp_visual/paper_scatter
name = "scattering paper"
desc = "Pieces of paper scattering to the wind."
layer = ABOVE_NORMAL_TURF_LAYER
plane = GAME_PLANE
icon = 'icons/effects/effects.dmi'
icon_state = "paper_scatter"
anchored = TRUE
duration = 5
randomdir = FALSE
/obj/effect/temp_visual/paperwiz_dying
name = "craft portal"
desc = "A wormhole sucking the wizard into the void. Neat."
layer = ABOVE_NORMAL_TURF_LAYER
plane = GAME_PLANE
icon = 'icons/effects/effects.dmi'
icon_state = "paperwiz_poof"
anchored = TRUE
duration = 18
randomdir = FALSE
/obj/effect/temp_visual/paperwiz_dying/Initialize(mapload)
. = ..()
visible_message(span_boldannounce("The wizard cries out in pain as a gate appears behind him, sucking him in!"))
playsound(get_turf(src),'sound/magic/mandswap.ogg', 50, TRUE, TRUE)
playsound(get_turf(src),'sound/hallucinations/wail.ogg', 50, TRUE, TRUE)
/obj/effect/temp_visual/paperwiz_dying/Destroy()
for(var/mob/M in range(7,src))
shake_camera(M, 7, 1)
var/turf/T = get_turf(src)
playsound(T,'sound/magic/summon_magic.ogg', 50, TRUE, TRUE)
new /obj/effect/temp_visual/paper_scatter(T)
new /obj/item/clothing/suit/wizrobe/paper(T)
new /obj/item/clothing/head/collectable/paper(T)
return ..()
@@ -114,8 +114,6 @@
/mob/living/simple_animal/hostile/blob/blobspore/independent,
/mob/living/simple_animal/hostile/blob/blobspore/weak,
/mob/living/simple_animal/hostile/boss,
/mob/living/simple_animal/hostile/boss/paper_wizard,
/mob/living/simple_animal/hostile/boss/paper_wizard/copy,
/mob/living/simple_animal/hostile/construct,
/mob/living/simple_animal/hostile/construct/artificer,
/mob/living/simple_animal/hostile/construct/artificer/angelic,
+4 -1
View File
@@ -854,8 +854,10 @@
#include "code\datums\ai\basic_mobs\basic_ai_behaviors\tipped_reaction.dm"
#include "code\datums\ai\basic_mobs\basic_ai_behaviors\travel_towards.dm"
#include "code\datums\ai\basic_mobs\basic_ai_behaviors\ventcrawling.dm"
#include "code\datums\ai\basic_mobs\basic_ai_behaviors\write_on_paper.dm"
#include "code\datums\ai\basic_mobs\basic_subtrees\attack_obstacle_in_path.dm"
#include "code\datums\ai\basic_mobs\basic_subtrees\find_food.dm"
#include "code\datums\ai\basic_mobs\basic_subtrees\find_paper_and_write.dm"
#include "code\datums\ai\basic_mobs\basic_subtrees\flee_target.dm"
#include "code\datums\ai\basic_mobs\basic_subtrees\opportunistic_ventcrawler.dm"
#include "code\datums\ai\basic_mobs\basic_subtrees\simple_attack_target.dm"
@@ -4138,6 +4140,8 @@
#include "code\modules\mob\living\basic\space_fauna\netherworld\blankbody.dm"
#include "code\modules\mob\living\basic\space_fauna\netherworld\creature.dm"
#include "code\modules\mob\living\basic\space_fauna\netherworld\migo.dm"
#include "code\modules\mob\living\basic\space_fauna\paper_wizard\paper_abilities.dm"
#include "code\modules\mob\living\basic\space_fauna\paper_wizard\paper_wizard.dm"
#include "code\modules\mob\living\basic\space_fauna\spider\giant_spider\giant_spider.dm"
#include "code\modules\mob\living\basic\space_fauna\spider\giant_spider\giant_spider_ai.dm"
#include "code\modules\mob\living\basic\space_fauna\spider\giant_spider\giant_spider_subtrees.dm"
@@ -4385,7 +4389,6 @@
#include "code\modules\mob\living\simple_animal\hostile\wizard.dm"
#include "code\modules\mob\living\simple_animal\hostile\zombie.dm"
#include "code\modules\mob\living\simple_animal\hostile\bosses\boss.dm"
#include "code\modules\mob\living\simple_animal\hostile\bosses\paperwizard.dm"
#include "code\modules\mob\living\simple_animal\hostile\constructs\artificer.dm"
#include "code\modules\mob\living\simple_animal\hostile\constructs\constructs.dm"
#include "code\modules\mob\living\simple_animal\hostile\constructs\harvester.dm"
@@ -0,0 +1,2 @@
/mob/living/simple_animal/hostile/boss/paper_wizard : /mob/living/basic/paper_wizard{@OLD}