Revamped the paper wizard robes. (#12348)
* Better paper wizard robes. * return value. * ooo * Aaa * aaaa
This commit is contained in:
@@ -23,29 +23,21 @@
|
||||
for(var/ab in boss_abilities)
|
||||
boss_abilities -= ab
|
||||
var/datum/action/boss/AB = new ab()
|
||||
AB.boss = src
|
||||
AB.Grant(src)
|
||||
boss_abilities += AB
|
||||
|
||||
atb.assign_abilities(boss_abilities)
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/boss/Destroy()
|
||||
qdel(atb)
|
||||
atb = null
|
||||
for(var/ab in boss_abilities)
|
||||
var/datum/action/boss/AB = ab
|
||||
AB.boss = null
|
||||
AB.Remove(src)
|
||||
qdel(AB)
|
||||
boss_abilities.Cut()
|
||||
QDEL_NULL(atb)
|
||||
QDEL_LIST(boss_abilities)
|
||||
return ..()
|
||||
|
||||
|
||||
//Action datum for bosses
|
||||
//Override Trigger() as shown below to do things
|
||||
/datum/action/boss
|
||||
check_flags = AB_CHECK_CONSCIOUS //Incase the boss is given a player
|
||||
required_mobility_flags = NONE
|
||||
var/boss_cost = 100 //Cost of usage for the boss' AI 1-100
|
||||
var/usage_probability = 100
|
||||
var/mob/living/simple_animal/hostile/boss/boss
|
||||
@@ -53,23 +45,34 @@
|
||||
var/needs_target = TRUE //Does the boss need to have a target? (Only matters for the AI)
|
||||
var/say_when_triggered = "" //What does the boss Say() when the ability triggers?
|
||||
|
||||
/datum/action/boss/Destroy()
|
||||
boss = null
|
||||
return ..()
|
||||
|
||||
/datum/action/boss/Grant(mob/M)
|
||||
. = ..()
|
||||
boss = owner
|
||||
|
||||
/datum/action/boss/Remove(mob/M)
|
||||
. = ..()
|
||||
boss = null
|
||||
|
||||
/datum/action/boss/Trigger()
|
||||
. = ..()
|
||||
if(.)
|
||||
if(!istype(boss, boss_type))
|
||||
return 0
|
||||
if(!boss.atb)
|
||||
return 0
|
||||
if(boss.atb.points < boss_cost)
|
||||
return 0
|
||||
if(!boss.client)
|
||||
if(needs_target && !boss.target)
|
||||
return 0
|
||||
if(boss)
|
||||
if(say_when_triggered)
|
||||
boss.say(say_when_triggered, forced = "boss action")
|
||||
if(!boss.atb.spend(boss_cost))
|
||||
return 0
|
||||
if(!.)
|
||||
return
|
||||
if(!istype(boss, boss_type))
|
||||
return FALSE
|
||||
if(!boss.atb)
|
||||
return FALSE
|
||||
if(boss.atb.points < boss_cost)
|
||||
return FALSE
|
||||
if(!boss.client && needs_target && !boss.target)
|
||||
return FALSE
|
||||
if(!boss.atb.spend(boss_cost))
|
||||
return FALSE
|
||||
if(say_when_triggered)
|
||||
boss.say(say_when_triggered, forced = "boss action")
|
||||
|
||||
//Example:
|
||||
/*
|
||||
@@ -83,7 +86,8 @@
|
||||
/datum/boss_active_timed_battle
|
||||
var/list/abilities //a list of /datum/action/boss owned by a boss mob
|
||||
var/point_regen_delay = 5
|
||||
var/points = 50 //1-100, start with 50 so we can use some abilities but not insta-buttfug somebody
|
||||
var/max_points = 100
|
||||
var/points = 50 //start with 50 so we can use some abilities but not insta-buttfug somebody
|
||||
var/next_point_time = 0
|
||||
var/chance_to_hold_onto_points = 50
|
||||
var/highest_cost = 0
|
||||
@@ -108,22 +112,22 @@
|
||||
/datum/boss_active_timed_battle/proc/spend(cost)
|
||||
if(cost <= points)
|
||||
points = max(0,points-cost)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
/datum/boss_active_timed_battle/proc/refund(cost)
|
||||
points = min(points+cost, 100)
|
||||
points = min(points+cost, max_points)
|
||||
|
||||
|
||||
/datum/boss_active_timed_battle/process()
|
||||
if(world.time >= next_point_time)
|
||||
if(world.time >= next_point_time && points < max_points)
|
||||
next_point_time = world.time + point_regen_delay
|
||||
points = min(100, ++points) //has to be out of 100
|
||||
points = min(max_points, ++points) //has to be out of 100
|
||||
|
||||
if(abilities)
|
||||
chance_to_hold_onto_points = highest_cost*0.5
|
||||
if(points != 100 && prob(chance_to_hold_onto_points))
|
||||
if(points != max_points && prob(chance_to_hold_onto_points))
|
||||
return //Let's save our points for a better ability (unless we're at max points, in which case we can't save anymore!)
|
||||
if(!boss.client)
|
||||
abilities = shuffle(abilities)
|
||||
@@ -135,5 +139,5 @@
|
||||
|
||||
/datum/boss_active_timed_battle/Destroy()
|
||||
abilities = null
|
||||
SSobj.processing.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
@@ -32,25 +32,47 @@
|
||||
name = "Summon Minions"
|
||||
icon_icon = 'icons/mob/actions/actions_minor_antag.dmi'
|
||||
button_icon_state = "art_summon"
|
||||
usage_probability = 40
|
||||
usage_probability = 20
|
||||
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!"
|
||||
var/static/summoned_minions = 0
|
||||
var/list/summoned_minions = list()
|
||||
var/maximum_stickmen = 6
|
||||
var/stickmen_to_summon = 3
|
||||
|
||||
/datum/action/boss/wizard_summon_minions/Trigger()
|
||||
if(summoned_minions <= 6 && ..())
|
||||
var/list/minions = list(
|
||||
/mob/living/simple_animal/hostile/stickman,
|
||||
/mob/living/simple_animal/hostile/stickman/ranged,
|
||||
/mob/living/simple_animal/hostile/stickman/dog)
|
||||
var/list/directions = GLOB.cardinals.Copy()
|
||||
for(var/i in 1 to 3)
|
||||
var/minions_chosen = pick_n_take(minions)
|
||||
new minions_chosen (get_step(boss,pick_n_take(directions)), 1)
|
||||
summoned_minions += 3;
|
||||
. =..()
|
||||
if(!.)
|
||||
return
|
||||
var/to_summon = stickmen_to_summon
|
||||
var/current_len = length(summoned_minions)
|
||||
if(current_len > maximum_stickmen - stickmen_to_summon)
|
||||
for(var/a in (maximum_stickmen - stickmen_to_summon) to current_len)
|
||||
var/mob/living/simple_animal/hostile/stickman/S = popleft(summoned_minions)
|
||||
if(!S.client)
|
||||
qdel(S)
|
||||
else
|
||||
S.forceMove(boss.drop_location())
|
||||
S.revive(TRUE)
|
||||
summoned_minions += S
|
||||
to_summon--
|
||||
|
||||
var/static/list/minions = list(
|
||||
/mob/living/simple_animal/hostile/stickman,
|
||||
/mob/living/simple_animal/hostile/stickman/ranged,
|
||||
/mob/living/simple_animal/hostile/stickman/dog)
|
||||
|
||||
var/list/directions = GLOB.cardinals.Copy()
|
||||
for(var/i in 1 to to_summon)
|
||||
var/minions_chosen = pick(minions)
|
||||
var/mob/living/simple_animal/hostile/stickman/S = new minions_chosen (get_step(boss,pick_n_take(directions)), 1)
|
||||
S.faction = boss.faction
|
||||
RegisterSignal(S, COMSIG_PARENT_QDELETING, .proc/remove_from_list)
|
||||
summoned_minions += S
|
||||
|
||||
/datum/action/boss/wizard_summon_minions/proc/remove_from_list(datum/source, forced)
|
||||
summoned_minions -= source
|
||||
|
||||
//Mimic Ability
|
||||
//Summons mimics of himself with magical papercraft
|
||||
@@ -66,28 +88,32 @@
|
||||
say_when_triggered = ""
|
||||
|
||||
/datum/action/boss/wizard_mimic/Trigger()
|
||||
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
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
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)
|
||||
else
|
||||
boss.atb.refund(boss_cost)
|
||||
to_chat(owner, "<span class='warning'>There is no potential foe of different faction around to attack</span>")
|
||||
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!"
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
var/casingtype //set ONLY it and NULLIFY projectiletype, if we have projectile IN CASING
|
||||
var/move_to_delay = 3 //delay for the automated movement.
|
||||
var/list/friends = list()
|
||||
var/list/foes = list()
|
||||
var/list/emote_taunt = list()
|
||||
var/taunt_chance = 0
|
||||
|
||||
@@ -62,6 +63,8 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/Destroy()
|
||||
targets_from = null
|
||||
friends = null
|
||||
foes = null
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/Life()
|
||||
@@ -193,7 +196,7 @@
|
||||
|
||||
// Please do not add one-off mob AIs here, but override this function for your mob
|
||||
/mob/living/simple_animal/hostile/CanAttack(atom/the_target)//Can we actually attack a possible target?
|
||||
if(isturf(the_target) || !the_target || the_target.type == /atom/movable/lighting_object) // bail out on invalids
|
||||
if(!the_target || the_target.type == /atom/movable/lighting_object || isturf(the_target)) // bail out on invalids
|
||||
return FALSE
|
||||
|
||||
if(ismob(the_target)) //Target is in godmode, ignore it.
|
||||
@@ -208,13 +211,13 @@
|
||||
if(search_objects < 2)
|
||||
if(isliving(the_target))
|
||||
var/mob/living/L = the_target
|
||||
var/faction_check = faction_check_mob(L)
|
||||
var/faction_check = !foes[L] && faction_check_mob(L)
|
||||
if(robust_searching)
|
||||
if(faction_check && !attack_same)
|
||||
return FALSE
|
||||
if(L.stat > stat_attack)
|
||||
if(L.stat > stat_attack || (L.stat == UNCONSCIOUS && stat_attack == UNCONSCIOUS && HAS_TRAIT(L, TRAIT_DEATHCOMA)))
|
||||
return FALSE
|
||||
if(L in friends)
|
||||
if(friends[L] > 0 && foes[L] < 1)
|
||||
return FALSE
|
||||
else
|
||||
if((faction_check && !attack_same) || L.stat)
|
||||
|
||||
@@ -298,5 +298,5 @@
|
||||
var/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/A = new /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion(user.loc)
|
||||
A.flags_1 |= (flags_1 & ADMIN_SPAWNED_1)
|
||||
A.GiveTarget(target)
|
||||
A.friends = user
|
||||
A.friends[user]++
|
||||
A.faction = user.faction.Copy()
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
speed = 0
|
||||
blood_volume = 0
|
||||
stat_attack = UNCONSCIOUS
|
||||
robust_searching = 1
|
||||
robust_searching = TRUE //This is also required for the paper robe rallying to work.
|
||||
environment_smash = ENVIRONMENT_SMASH_NONE
|
||||
maxHealth = 100
|
||||
health = 100
|
||||
@@ -30,8 +30,6 @@
|
||||
faction = list("hostile","stickman")
|
||||
check_friendly_fire = 1
|
||||
status_flags = CANPUSH
|
||||
var/datum/action/boss/wizard_summon_minions/changesummons = /datum/action/boss/wizard_summon_minions
|
||||
var/summoned_by_wizard = 0
|
||||
|
||||
/mob/living/simple_animal/hostile/stickman/ranged
|
||||
ranged = 1
|
||||
@@ -43,7 +41,6 @@
|
||||
projectilesound = 'sound/misc/bang.ogg'
|
||||
loot = list(/obj/item/gun/ballistic/automatic/pistol/stickman)
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/stickman/dog
|
||||
name = "Angry Stick Dog"
|
||||
desc = "Stickman's best friend, if he could see him at least."
|
||||
@@ -52,12 +49,6 @@
|
||||
icon_dead = "stickdog_dead"
|
||||
mob_biotypes = MOB_BEAST
|
||||
|
||||
/mob/living/simple_animal/hostile/stickman/Initialize(mapload, var/wizard_summoned)
|
||||
/mob/living/simple_animal/hostile/stickman/Initialize(mapload)
|
||||
. = ..()
|
||||
new /obj/effect/temp_visual/paper_scatter(src)
|
||||
summoned_by_wizard = wizard_summoned
|
||||
|
||||
/mob/living/simple_animal/hostile/stickman/death()
|
||||
..()
|
||||
if(summoned_by_wizard == 1)
|
||||
changesummons.summoned_minions --
|
||||
|
||||
@@ -373,7 +373,7 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA
|
||||
return FALSE
|
||||
|
||||
new /obj/effect/temp_visual/point(A,invisibility)
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_MOB_POINTED, A)
|
||||
return TRUE
|
||||
|
||||
/mob/proc/can_resist()
|
||||
|
||||
Reference in New Issue
Block a user