Skip to content

Commit

Permalink
[MIRROR] Basic Constructs: Wraith [MDB IGNORE] (#356)
Browse files Browse the repository at this point in the history
* Basic Constructs: Wraith (#79235)

* Update defcon2.dmm

---------
Co-authored-by: lizardqueenlexi <[email protected]>
Co-authored-by: Giz <[email protected]>
  • Loading branch information
Steals-The-PRs authored Oct 31, 2023
1 parent 1f0ca6f commit c6f41e1
Show file tree
Hide file tree
Showing 17 changed files with 184 additions and 117 deletions.
22 changes: 11 additions & 11 deletions _maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon2.dmm
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@
/turf/open/floor/cult,
/area/ruin/space/has_grav/port_tarkon/porthall)
"aO" = (
/mob/living/simple_animal/hostile/construct/wraith/hostile{
/mob/living/basic/construct/wraith/hostile{
health = 125;
maxHealth = 125
},
Expand Down Expand Up @@ -1462,7 +1462,7 @@
/area/ruin/space/has_grav/port_tarkon/secoff)
"id" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/mob/living/simple_animal/hostile/construct/wraith/hostile{
/mob/living/basic/construct/wraith/hostile{
health = 125;
maxHealth = 125
},
Expand Down Expand Up @@ -1794,7 +1794,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/firealarm/directional/east,
/mob/living/simple_animal/hostile/construct/wraith/hostile,
/mob/living/basic/construct/wraith/hostile,
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/ruin/space/has_grav/port_tarkon/starboardhall)
Expand Down Expand Up @@ -2901,7 +2901,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/structure/cable,
/mob/living/simple_animal/hostile/construct/wraith/hostile{
/mob/living/basic/construct/wraith/hostile{
health = 125;
maxHealth = 125
},
Expand Down Expand Up @@ -6493,7 +6493,7 @@
"Kb" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/obj/effect/decal/cleanable/blood,
/mob/living/simple_animal/hostile/construct/wraith/hostile{
/mob/living/basic/construct/wraith/hostile{
health = 125;
maxHealth = 125
},
Expand Down Expand Up @@ -6918,7 +6918,7 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/mob/living/simple_animal/hostile/construct/wraith/hostile{
/mob/living/basic/construct/wraith/hostile{
health = 125;
maxHealth = 125
},
Expand Down Expand Up @@ -7253,7 +7253,7 @@
/turf/open/floor/engine,
/area/ruin/space/has_grav/port_tarkon/atmos)
"Od" = (
/mob/living/simple_animal/hostile/construct/wraith/hostile{
/mob/living/basic/construct/wraith/hostile{
health = 125;
maxHealth = 125
},
Expand Down Expand Up @@ -7972,7 +7972,7 @@
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 8
},
/mob/living/simple_animal/hostile/construct/wraith/hostile{
/mob/living/basic/construct/wraith/hostile{
health = 125;
maxHealth = 125
},
Expand Down Expand Up @@ -8302,7 +8302,7 @@
/area/ruin/space/has_grav/port_tarkon/developement)
"Uh" = (
/obj/effect/decal/cleanable/blood,
/mob/living/simple_animal/hostile/construct/wraith/hostile{
/mob/living/basic/construct/wraith/hostile{
health = 125;
maxHealth = 125
},
Expand Down Expand Up @@ -8613,7 +8613,7 @@
/turf/open/floor/iron,
/area/ruin/space/has_grav/port_tarkon/secoff)
"Wi" = (
/mob/living/simple_animal/hostile/construct/wraith/hostile,
/mob/living/basic/construct/wraith/hostile,
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/ruin/space/has_grav/port_tarkon/starboardhall)
Expand Down Expand Up @@ -9060,7 +9060,7 @@
/area/ruin/space/has_grav/port_tarkon/trauma)
"Zt" = (
/obj/machinery/light/dim/directional/north,
/mob/living/simple_animal/hostile/construct/wraith/hostile{
/mob/living/basic/construct/wraith/hostile{
health = 125;
maxHealth = 125
},
Expand Down
2 changes: 1 addition & 1 deletion _maps/shuttles/emergency_narnar.dmm
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@
/turf/open/floor/cult,
/area/shuttle/escape)
"H" = (
/mob/living/simple_animal/hostile/construct/wraith,
/mob/living/basic/construct/wraith,
/turf/open/floor/cult,
/area/shuttle/escape)
"I" = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
living_targets += filtered_targets
if(living_targets.len)
sortTim(living_targets, GLOBAL_PROC_REF(cmp_mob_health))
return living_targets[1]
return pop(living_targets)
return ..()
66 changes: 66 additions & 0 deletions code/datums/components/recharging_attacks.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/// Reduces the cooldown of a given action upon landing attacks, critting, or killing mobs.
/datum/component/recharging_attacks
/// The target of the most recent attack
var/last_target
/// The stat of the most recently attacked mob
var/last_stat
/// The action to recharge when attacking
var/datum/action/cooldown/recharged_action
/// The amount of cooldown to refund on a successful attack
var/attack_refund
/// The amount of cooldown to refund when putting a target into critical
var/crit_refund

/datum/component/recharging_attacks/Initialize(
datum/action/cooldown/recharged_action,
attack_refund = 1 SECONDS,
crit_refund = 5 SECONDS,
)
. = ..()
if (!isbasicmob(parent) || !istype(recharged_action))
return COMPONENT_INCOMPATIBLE
src.recharged_action = recharged_action
src.attack_refund = attack_refund
src.crit_refund = crit_refund

/datum/component/recharging_attacks/Destroy()
UnregisterSignal(recharged_action, COMSIG_QDELETING)
recharged_action = null
return ..()

/datum/component/recharging_attacks/RegisterWithParent()
. = ..()
RegisterSignal(parent, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, PROC_REF(set_old_stat))
RegisterSignal(parent, COMSIG_HOSTILE_POST_ATTACKINGTARGET, PROC_REF(check_stat))
RegisterSignal(recharged_action, COMSIG_QDELETING, PROC_REF(on_action_qdel))

/datum/component/recharging_attacks/UnregisterFromParent()
. = ..()
UnregisterSignal(parent, list(COMSIG_HOSTILE_PRE_ATTACKINGTARGET, COMSIG_HOSTILE_POST_ATTACKINGTARGET))
if(recharged_action)
UnregisterSignal(recharged_action, COMSIG_QDELETING)

/datum/component/recharging_attacks/proc/set_old_stat(mob/attacker, mob/attacked)
SIGNAL_HANDLER
if(!isliving(attacked))
return
last_target = attacked
last_stat = attacked.stat

/datum/component/recharging_attacks/proc/check_stat(mob/living/attacker, mob/living/attacked, success)
SIGNAL_HANDLER
if(!isliving(attacked) || attacked != last_target || attacker.faction_check_atom(attacked))
return

var/final_refund = attack_refund
if(QDELETED(attacked) || (attacked.stat == DEAD && last_stat != DEAD)) //The target is dead and we killed them - full refund
final_refund = recharged_action.cooldown_time
else if(attacked.stat > CONSCIOUS && last_stat == CONSCIOUS) //We knocked the target unconscious - partial refund
final_refund = crit_refund

recharged_action.next_use_time -= final_refund
recharged_action.build_all_button_icons()

/datum/component/recharging_attacks/proc/on_action_qdel()
SIGNAL_HANDLER
qdel(src)
2 changes: 1 addition & 1 deletion code/game/alternate_appearance.dm
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ GLOBAL_LIST_EMPTY(active_alternate_appearances)
/datum/atom_hud/alternate_appearance/basic/blessed_aware/mobShouldSee(mob/M)
if(M.mind?.holy_role)
return TRUE
if (istype(M, /mob/living/simple_animal/hostile/construct/wraith))
if (istype(M, /mob/living/basic/construct/wraith))
return TRUE
if(isrevenant(M) || IS_WIZARD(M))
return TRUE
Expand Down
14 changes: 7 additions & 7 deletions code/modules/antagonists/wizard/equipment/soulstone.dm
Original file line number Diff line number Diff line change
Expand Up @@ -470,18 +470,18 @@
if(THEME_HOLY)
makeNewConstruct(/mob/living/basic/construct/juggernaut/angelic, target, creator, cultoverride, loc_override)
if(THEME_CULT)
makeNewConstruct(/mob/living/basic/construct/juggernaut/noncult, target, creator, cultoverride, loc_override)
makeNewConstruct(/mob/living/basic/construct/juggernaut, target, creator, cultoverride, loc_override)
if(CONSTRUCT_WRAITH)
if(IS_CULTIST(creator))
makeNewConstruct(/mob/living/simple_animal/hostile/construct/wraith, target, creator, cultoverride, loc_override) // ignore themes, the actual giving of cult info is in the makeNewConstruct proc
makeNewConstruct(/mob/living/basic/construct/wraith, target, creator, cultoverride, loc_override) // ignore themes, the actual giving of cult info is in the makeNewConstruct proc
return
switch(theme)
if(THEME_WIZARD)
makeNewConstruct(/mob/living/simple_animal/hostile/construct/wraith/mystic, target, creator, cultoverride, loc_override)
makeNewConstruct(/mob/living/basic/construct/wraith/mystic, target, creator, cultoverride, loc_override)
if(THEME_HOLY)
makeNewConstruct(/mob/living/simple_animal/hostile/construct/wraith/angelic, target, creator, cultoverride, loc_override)
makeNewConstruct(/mob/living/basic/construct/wraith/angelic, target, creator, cultoverride, loc_override)
if(THEME_CULT)
makeNewConstruct(/mob/living/simple_animal/hostile/construct/wraith/noncult, target, creator, cultoverride, loc_override)
makeNewConstruct(/mob/living/basic/construct/wraith, target, creator, cultoverride, loc_override)
if(CONSTRUCT_ARTIFICER)
if(IS_CULTIST(creator))
makeNewConstruct(/mob/living/basic/construct/artificer, target, creator, cultoverride, loc_override) // ignore themes, the actual giving of cult info is in the makeNewConstruct proc
Expand All @@ -494,10 +494,10 @@
if(THEME_CULT)
makeNewConstruct(/mob/living/basic/construct/artificer/noncult, target, creator, cultoverride, loc_override)

/proc/makeNewConstruct(mob/living/simple_animal/hostile/construct/ctype, mob/target, mob/stoner = null, cultoverride = FALSE, loc_override = null)
/proc/makeNewConstruct(mob/living/basic/construct/ctype, mob/target, mob/stoner = null, cultoverride = FALSE, loc_override = null)
if(QDELETED(target))
return
var/mob/living/simple_animal/hostile/construct/newstruct = new ctype((loc_override) ? (loc_override) : (get_turf(target)))
var/mob/living/basic/construct/newstruct = new ctype((loc_override) ? (loc_override) : (get_turf(target)))
var/makeicon = newstruct.icon_state
var/theme = newstruct.theme
flick("make_[makeicon][theme]", newstruct)
Expand Down
2 changes: 1 addition & 1 deletion code/modules/events/portal_storm.dm
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
boss_types = list(/mob/living/basic/construct/artificer/hostile = 6)
hostile_types = list(
/mob/living/basic/construct/juggernaut/hostile = 8,
/mob/living/simple_animal/hostile/construct/wraith/hostile = 6,
/mob/living/basic/construct/wraith/hostile = 6,
)

/datum/round_event/portal_storm
Expand Down
10 changes: 8 additions & 2 deletions code/modules/mob/living/basic/constructs/_construct.dm
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
response_disarm_simple = "flail at"
response_harm_continuous = "punches"
response_harm_simple = "punch"
melee_attack_cooldown = CLICK_CD_MELEE

// Vivid red, cause cult theme
lighting_cutoff_red = 30
Expand All @@ -42,14 +43,19 @@
var/can_repair_self = FALSE
/// Theme controls color. THEME_CULT is red THEME_WIZARD is purple and THEME_HOLY is blue
var/theme = THEME_CULT
/// What flavor of gunk does this construct drop on death?
var/static/list/remains = list(/obj/item/ectoplasm/construct)
/// Can this construct smash walls? Gets the wall_smasher element if so.
var/smashes_walls = FALSE
/// The different flavors of goop constructs can drop, depending on theme.
var/static/list/remains_by_theme = list(
THEME_CULT = list(/obj/item/ectoplasm/construct),
THEME_HOLY = list(/obj/item/ectoplasm/angelic),
THEME_WIZARD = list(/obj/item/ectoplasm/mystic),
)

/mob/living/basic/construct/Initialize(mapload)
. = ..()
AddElement(/datum/element/simple_flying)
var/list/remains = string_list(remains_by_theme[theme])
if(length(remains))
AddElement(/datum/element/death_drops, remains)
if(smashes_walls)
Expand Down
1 change: 1 addition & 0 deletions code/modules/mob/living/basic/constructs/artificer.dm
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
/mob/living/basic/construct/artificer/hostile
ai_controller = /datum/ai_controller/basic_controller/artificer
smashes_walls = FALSE
melee_attack_cooldown = 2 SECONDS

// Alternate artificer themes
/mob/living/basic/construct/artificer/angelic
Expand Down
34 changes: 32 additions & 2 deletions code/modules/mob/living/basic/constructs/construct_ai.dm
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
/// Artificers
/**
* Artificers
*
* Artificers will seek out and heal the most wounded construct or shade they can see.
* If there is no one to heal, they will run away from any non-allied mobs.
*/
/datum/ai_controller/basic_controller/artificer
blackboard = list(
BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/same_faction/construct,
Expand All @@ -15,7 +20,12 @@
/datum/ai_planning_subtree/flee_target/from_flee_key,
)

/// Juggernauts
/**
* Juggernauts
*
* Juggernauts slowly walk toward non-allied mobs and pummel them into hardcrit.
* They do not finish off carbons, as that's the job of wraiths.
*/
/datum/ai_controller/basic_controller/juggernaut
blackboard = list(
BB_TARGETTING_DATUM = new /datum/targetting_datum/basic,
Expand All @@ -26,6 +36,26 @@
idle_behavior = /datum/idle_behavior/idle_random_walk
planning_subtrees = list(
/datum/ai_planning_subtree/simple_find_target,
/datum/ai_planning_subtree/attack_obstacle_in_path,
/datum/ai_planning_subtree/basic_melee_attack_subtree,
)

/**
* Wraiths
*
* Wraiths seek out the most injured non-allied mob to beat to death.
*/
/datum/ai_controller/basic_controller/wraith
blackboard = list(
BB_TARGETTING_DATUM = new /datum/targetting_datum/basic,
BB_TARGET_MINIMUM_STAT = HARD_CRIT,
)

ai_movement = /datum/ai_movement/basic_avoidance
idle_behavior = /datum/idle_behavior/idle_random_walk
planning_subtrees = list(
/datum/ai_planning_subtree/simple_find_wounded_target,
/datum/ai_planning_subtree/attack_obstacle_in_path,
/datum/ai_planning_subtree/basic_melee_attack_subtree,
)

Expand Down
3 changes: 1 addition & 2 deletions code/modules/mob/living/basic/constructs/juggernaut.dm
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
/mob/living/basic/construct/juggernaut/hostile
ai_controller = /datum/ai_controller/basic_controller/juggernaut
smashes_walls = FALSE
melee_attack_cooldown = 2 SECONDS

/mob/living/basic/construct/juggernaut/bullet_act(obj/projectile/bullet)
if(!istype(bullet, /obj/projectile/energy) && !istype(bullet, /obj/projectile/beam))
Expand Down Expand Up @@ -58,5 +59,3 @@

/mob/living/basic/construct/juggernaut/mystic
theme = THEME_WIZARD

/mob/living/basic/construct/juggernaut/noncult
50 changes: 50 additions & 0 deletions code/modules/mob/living/basic/constructs/wraith.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/mob/living/basic/construct/wraith
name = "Wraith"
real_name = "Wraith"
desc = "A wicked, clawed shell constructed to assassinate enemies and sow chaos behind enemy lines."
icon_state = "wraith"
icon_living = "wraith"
maxHealth = 65
health = 65
melee_damage_lower = 20
melee_damage_upper = 20
attack_verb_continuous = "slashes"
attack_verb_simple = "slash"
attack_sound = 'sound/weapons/bladeslice.ogg'
attack_vis_effect = ATTACK_EFFECT_SLASH
construct_spells = list(
/datum/action/cooldown/spell/jaunt/ethereal_jaunt/shift,
/datum/action/innate/cult/create_rune/tele,
)
playstyle_string = span_bold("You are a Wraith. Though relatively fragile, you are fast, deadly, and can phase through walls. Your attacks will lower the cooldown on phasing, moreso for fatal blows.")

/mob/living/basic/construct/wraith/Initialize(mapload)
. = ..()
var/datum/action/cooldown/spell/jaunt/ethereal_jaunt/shift/jaunt = locate() in actions
if(isnull(jaunt))
return .
AddComponent(/datum/component/recharging_attacks, recharged_action = jaunt)

/// Hostile NPC version. Attempts to kill the lowest-health mob it can see.
/mob/living/basic/construct/wraith/hostile
ai_controller = /datum/ai_controller/basic_controller/wraith
melee_attack_cooldown = 1.5 SECONDS

// Alternate wraith themes
/mob/living/basic/construct/wraith/angelic
theme = THEME_HOLY
construct_spells = list(
/datum/action/cooldown/spell/jaunt/ethereal_jaunt/shift/angelic,
/datum/action/innate/cult/create_rune/tele,
)

/mob/living/basic/construct/wraith/angelic/Initialize(mapload)
. = ..()
ADD_TRAIT(src, TRAIT_ANGELIC, INNATE_TRAIT)

/mob/living/basic/construct/wraith/mystic
theme = THEME_WIZARD
construct_spells = list(
/datum/action/cooldown/spell/jaunt/ethereal_jaunt/shift/mystic,
/datum/action/innate/cult/create_rune/tele,
)
Loading

0 comments on commit c6f41e1

Please sign in to comment.