Kills /obj/shapeshift_holder, replaces it with /datum/status_effect/shapechange_mob, also does a lot of Wabbajack refactoring (#69091)

About The Pull Request

    Deletes /obj/shapeshift_holder, replaces it with /datum/status_effect/shapechange_mob
    Refactors Heretic worm form into a shapeshift spell
    Refactors Wabbajack, and associated code

Fixes #69117
Fixes #65653
Fixes #59127
Fixes #52786
Why It's Good For The Game

/obj/shapeshift_holder was one of the worst remaining abuses of /obj direct subtypes, so I replaced it with a cool fancy datum.

This also decouples the shapeshifting behavior entirely from the shapeshifting spell. So we have support for shapeshifted mobs not sourced from a spell. Which is neat, we could technically swap Wabbajack to use this in the future.
Changelog

cl Melbert
fix: Wabbajacking a shapeshifted mob no longer runtimes horribly. When a shapeshifted mob is wabbajacked, they'll now be removed from their shapeshift and stunned.
fix: Transforming via a shapeshift should no longer rob you of your hearing / runechat awareness.
fix: Shapeshifting plays nicer with holoparasites.
fix: Being polymorphed from a xeno to a non-xeno correctly makes you a non-xeno
refactor: Refactored shapeshifting, the shapeshift holder is now a status effect instead of an object.
refactor: Heretic worm form is a shapeshift spell now, this might have some minor behavioral changes but should overall be the same.
refactor: Refactored Wabbajack (+ cursed pool). Overall a bit more clean / consistent behavior.
/cl
This commit is contained in:
MrMelbert
2022-09-02 09:44:41 +12:00
committed by GitHub
parent c7cf23ae7e
commit de04b3be80
31 changed files with 710 additions and 346 deletions
@@ -9,6 +9,19 @@
/obj/item/ammo_casing/magic/change
projectile_type = /obj/projectile/magic/change
/obj/item/ammo_casing/magic/change/ready_proj(atom/target, mob/living/user, quiet, zone_override = "", atom/fired_from)
if (!loaded_projectile)
return
// If we were fired by a Staff of Change, we can try to inherent their preset vars for our wabbajack
var/obj/item/gun/magic/staff/change/change_staff = fired_from
var/obj/projectile/magic/change/change_projectile = loaded_projectile
if(istype(change_staff) && istype(change_projectile))
change_projectile.set_wabbajack_effect = change_staff.preset_wabbajack_type
change_projectile.set_wabbajack_changeflags = change_staff.preset_wabbajack_changeflag
return ..()
/obj/item/ammo_casing/magic/animate
projectile_type = /obj/projectile/magic/animate
+41 -13
View File
@@ -6,6 +6,8 @@
lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi'
item_flags = NEEDS_PERMIT | NO_MAT_REDEMPTION
/// Can non-magic folk use our staff?
/// If FALSE, only wizards or survivalists can use the staff to its full potential - If TRUE, anyone can
var/allow_intruder_use = FALSE
/obj/item/gun/magic/staff/proc/is_wizard_or_friend(mob/user)
@@ -34,6 +36,10 @@
icon_state = "staffofchange"
inhand_icon_state = "staffofchange"
school = SCHOOL_TRANSMUTATION
/// If set, all wabbajacks this staff produces will be of this type, instead of random
var/preset_wabbajack_type
/// If set, all wabbajacks this staff produces will be of this changeflag, instead of only WABBAJACK
var/preset_wabbajack_changeflag
/obj/item/gun/magic/staff/change/unrestricted
allow_intruder_use = TRUE
@@ -46,8 +52,11 @@
/obj/item/gun/magic/staff/change/on_intruder_use(mob/living/user, atom/target)
user.dropItemToGround(src, TRUE)
var/randomize = pick("monkey","humanoid","animal")
var/mob/new_body = user.wabbajack(randomize)
var/wabbajack_into = preset_wabbajack_type || pick(WABBAJACK_MONKEY, WABBAJACK_HUMAN, WABBAJACK_ANIMAL)
var/mob/living/new_body = user.wabbajack(wabbajack_into, preset_wabbajack_changeflag)
if(!new_body)
return
balloon_alert(new_body, "wabbajack, wabbajack!")
/obj/item/gun/magic/staff/animate
@@ -67,6 +76,7 @@
icon_state = "staffofhealing"
inhand_icon_state = "staffofhealing"
school = SCHOOL_RESTORATION
/// Our internal healbeam, used if an intruder (non-magic person) tries to use our staff
var/obj/item/gun/medbeam/healing_beam
/obj/item/gun/magic/staff/healing/pickup(mob/user)
@@ -81,7 +91,7 @@
healing_beam.mounted = TRUE
/obj/item/gun/magic/staff/healing/Destroy()
qdel(healing_beam)
QDEL_NULL(healing_beam)
return ..()
/obj/item/gun/magic/staff/healing/unrestricted
@@ -111,18 +121,36 @@
recharge_rate = 2
no_den_usage = 1
school = SCHOOL_FORBIDDEN //this staff is evil. okay? it just is. look at this projectile type list. this is wrong.
var/allowed_projectile_types = list(/obj/projectile/magic/change, /obj/projectile/magic/animate, /obj/projectile/magic/resurrection,
/obj/projectile/magic/death, /obj/projectile/magic/teleport, /obj/projectile/magic/door, /obj/projectile/magic/fireball,
/obj/projectile/magic/spellblade, /obj/projectile/magic/arcane_barrage, /obj/projectile/magic/locker, /obj/projectile/magic/flying,
/obj/projectile/magic/bounty, /obj/projectile/magic/antimagic, /obj/projectile/magic/fetch, /obj/projectile/magic/sapping,
/obj/projectile/magic/necropotence, /obj/projectile/magic, /obj/projectile/temp/chill, /obj/projectile/magic/wipe)
/// Static list of all projectiles we can fire from our staff.
/// Doesn't contain all subtypes of magic projectiles, unlike what it looks like
var/static/list/allowed_projectile_types = list(
/obj/projectile/magic/animate,
/obj/projectile/magic/antimagic,
/obj/projectile/magic/arcane_barrage,
/obj/projectile/magic/bounty,
/obj/projectile/magic/change,
/obj/projectile/magic/death,
/obj/projectile/magic/door,
/obj/projectile/magic/fetch,
/obj/projectile/magic/fireball,
/obj/projectile/magic/flying,
/obj/projectile/magic/locker,
/obj/projectile/magic/necropotence,
/obj/projectile/magic/resurrection,
/obj/projectile/magic/sapping,
/obj/projectile/magic/spellblade,
/obj/projectile/magic/teleport,
/obj/projectile/magic/wipe,
/obj/projectile/temp/chill,
)
/obj/item/gun/magic/staff/chaos/unrestricted
allow_intruder_use = TRUE
/obj/item/gun/magic/staff/chaos/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
chambered.projectile_type = pick(allowed_projectile_types)
. = ..()
return ..()
/obj/item/gun/magic/staff/chaos/on_intruder_use(mob/living/user)
if(!user.can_cast_magic()) // Don't let people with antimagic use the staff of chaos.
@@ -179,10 +207,10 @@
/obj/item/gun/magic/staff/spellblade/Initialize(mapload)
. = ..()
AddComponent(/datum/component/butchering, \
speed = 1.5 SECONDS, \
effectiveness = 125, \
bonus_modifier = 0, \
butcher_sound = hitsound, \
speed = 1.5 SECONDS, \
effectiveness = 125, \
bonus_modifier = 0, \
butcher_sound = hitsound, \
)
/obj/item/gun/magic/staff/spellblade/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
+1 -1
View File
@@ -147,7 +147,7 @@
max_charges = 10 //10, 5, 5, 4
/obj/item/gun/magic/wand/polymorph/zap_self(mob/living/user)
..() //because the user mob ceases to exists by the time wabbajack fully resolves
. = ..() //because the user mob ceases to exists by the time wabbajack fully resolves
user.wabbajack()
charges--
+5 -1
View File
@@ -162,13 +162,17 @@
damage = 0
damage_type = BURN
nodamage = TRUE
/// If set, this projectile will only do a certain wabbajack effect
var/set_wabbajack_effect
/// If set, this projectile will only pass certain changeflags to wabbajack
var/set_wabbajack_changeflags
/obj/projectile/magic/change/on_hit(atom/target)
. = ..()
if(isliving(target))
var/mob/living/victim = target
victim.wabbajack()
victim.wabbajack(set_wabbajack_effect, set_wabbajack_changeflags)
if(istype(target, /obj/machinery/hydroponics))
var/obj/machinery/hydroponics/plant_tray = target