mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-10 09:42:29 +00:00
## About The Pull Request Merges sword, harpoon, glaive and dagger crusher retools into a single item which allows you to pick the skin you want upon being applied to a crusher by converting crusher skins into datums. I've also improved sprites for all skins and redid the retool kit itself, as well as gave dagger and blaster unique animations - you swing with a dagger for normal attacks, stab to rupture the mark, and firing a shot point-blank does a stabbing animation with the blaster.  https://github.com/user-attachments/assets/2d243daf-f1d8-48bf-a661-8a9ac990837c (Apologies for lack of robust gameplay, I was trying to show the animations, not kill the goliath) The harpoon crusher skin now does stabbing animation instead of slashing one, and I've also fixed animations playing incorrectly when attacking large mobs/objects ## Why It's Good For The Game Having multiple items for reskinning crushers feels clunky, and unique animations are just something that makes sense. Having a swinging animation for both dagger and blaster looked odd, as you'd probably only swing one of them at the opponent, so I decided to spice them up. ## Changelog 🆑 add: Dagger-blaster and harpoon crusher skins have received unique attack animations. add: Four base crusher retool kits have been merged into one item. image: Resprited crusher skins and the crusher retool kit fix: Fixed attack animations being offset when attacking large objects or mobs. /🆑
144 lines
5.6 KiB
Plaintext
144 lines
5.6 KiB
Plaintext
/**
|
|
* # Nuclear Bomb Operator
|
|
*
|
|
* Component applied to handless non-carbon mobs to allow them to perform the function of a nuclear operative.
|
|
* Effectively this means they need to be able to:
|
|
* * Strip people
|
|
* * Pick up the nuke disc, without having hands
|
|
* * Place the nuke disc into the nuke
|
|
* * Activate the nuke
|
|
*
|
|
* Human mobs do not need this component because they can already do all of those things.
|
|
*/
|
|
/datum/component/nuclear_bomb_operator
|
|
/// A weak reference to a held nuclear disk, in place of holding it in our inventory, because we don't have one
|
|
var/datum/weakref/disky
|
|
/// Something to call when we collect the disk
|
|
var/datum/callback/on_disk_collected
|
|
/// Should return some overlays to display on the mob to show they're carrying a disk
|
|
var/datum/callback/add_disk_overlays
|
|
|
|
/datum/component/nuclear_bomb_operator/Initialize(datum/callback/on_disk_collected, datum/callback/add_disk_overlays)
|
|
if (!ismob(parent))
|
|
return COMPONENT_INCOMPATIBLE
|
|
if (iscarbon(parent)) // Redundant
|
|
return COMPONENT_INCOMPATIBLE
|
|
|
|
src.on_disk_collected = on_disk_collected
|
|
src.add_disk_overlays = add_disk_overlays
|
|
|
|
/datum/component/nuclear_bomb_operator/RegisterWithParent()
|
|
. = ..()
|
|
RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine))
|
|
RegisterSignals(parent, list(COMSIG_LIVING_DEATH, COMSIG_QDELETING), PROC_REF(on_death))
|
|
RegisterSignal(parent, COMSIG_LIVING_UNARMED_ATTACK, PROC_REF(owner_attacked_atom)) // This only works for players, but I am not sure this should have AI anyway
|
|
RegisterSignal(parent, COMSIG_ATOM_EXITED, PROC_REF(atom_exited_owner))
|
|
RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(on_update_overlays))
|
|
parent.add_traits(list(TRAIT_DISK_VERIFIER, TRAIT_CAN_STRIP, TRAIT_CAN_USE_NUKE), NUKE_OP_MINION_TRAIT)
|
|
|
|
/datum/component/nuclear_bomb_operator/UnregisterFromParent()
|
|
. = ..()
|
|
UnregisterSignal(parent, list(
|
|
COMSIG_ATOM_EXAMINE,
|
|
COMSIG_LIVING_DEATH,
|
|
COMSIG_QDELETING,
|
|
COMSIG_ATOM_ATTACK_HAND,
|
|
COMSIG_ATOM_EXITED,
|
|
COMSIG_ATOM_UPDATE_OVERLAYS,
|
|
))
|
|
parent.remove_traits(list(TRAIT_DISK_VERIFIER, TRAIT_CAN_STRIP, TRAIT_CAN_USE_NUKE), NUKE_OP_MINION_TRAIT)
|
|
|
|
/datum/component/nuclear_bomb_operator/Destroy(force)
|
|
QDEL_NULL(disky)
|
|
on_disk_collected = null
|
|
add_disk_overlays = null
|
|
return ..()
|
|
|
|
/// Drop the disk on the floor, if we have it
|
|
/datum/component/nuclear_bomb_operator/proc/drop_disky()
|
|
var/obj/item/disk/nuclear/held_disk = disky?.resolve()
|
|
if (!held_disk)
|
|
return
|
|
var/mob/mob_parent = parent
|
|
held_disk.forceMove(mob_parent.drop_location())
|
|
mob_parent.visible_message(span_danger("[mob_parent] drops [held_disk] onto the ground!"))
|
|
disky = null
|
|
mob_parent.update_appearance(updates = UPDATE_ICON)
|
|
|
|
/// Add details about carrying the nuke disc to examination.
|
|
/datum/component/nuclear_bomb_operator/proc/on_examine(atom/parent_atom, mob/examiner, list/examine_list)
|
|
SIGNAL_HANDLER
|
|
var/obj/item/disk/nuclear/held_disk = disky?.resolve()
|
|
if (!held_disk)
|
|
return
|
|
var/mob/mob_parent = parent
|
|
examine_list += span_notice("Wait... [mob_parent.p_are()] [mob_parent.p_they()] holding [held_disk]?")
|
|
|
|
/// Drop the disk when we are killed
|
|
/datum/component/nuclear_bomb_operator/proc/on_death(atom/parent_atom)
|
|
SIGNAL_HANDLER
|
|
drop_disky()
|
|
|
|
/// Try to pick up the disk, put it down, or open the nuke panel
|
|
/datum/component/nuclear_bomb_operator/proc/owner_attacked_atom(atom/parent_atom, atom/attacked_target, proximity, modifiers)
|
|
SIGNAL_HANDLER
|
|
if (!proximity)
|
|
return
|
|
if (!LAZYACCESS(modifiers, LEFT_CLICK))
|
|
return
|
|
var/obj/item/disk/nuclear/held_disk = disky?.resolve()
|
|
if (held_disk)
|
|
return try_put_down_disk(held_disk, attacked_target)
|
|
|
|
if (istype(attacked_target, /obj/item/disk/nuclear))
|
|
return try_pick_up_disk(attacked_target)
|
|
|
|
if (istype(attacked_target, /obj/machinery/nuclearbomb))
|
|
attacked_target.ui_interact(parent)
|
|
return COMPONENT_CANCEL_ATTACK_CHAIN
|
|
|
|
/// Picks up the nuke disk, if it can be picked up
|
|
/datum/component/nuclear_bomb_operator/proc/try_pick_up_disk(obj/item/disk/nuclear/potential_disky)
|
|
if(potential_disky.anchored)
|
|
return
|
|
var/mob/mob_parent = parent
|
|
potential_disky.forceMove(mob_parent)
|
|
disky = WEAKREF(potential_disky)
|
|
mob_parent.update_appearance(updates = UPDATE_ICON)
|
|
mob_parent.balloon_alert(mob_parent, "disk secured!")
|
|
on_disk_collected?.InvokeAsync(potential_disky)
|
|
|
|
/// Uses the disk on clicked atom, or places it on the ground
|
|
/datum/component/nuclear_bomb_operator/proc/try_put_down_disk(obj/item/disk/nuclear/held_disk, atom/attacked_target)
|
|
var/mob/mob_parent = parent
|
|
if(!isopenturf(attacked_target))
|
|
INVOKE_ASYNC(held_disk, TYPE_PROC_REF(/obj/item, melee_attack_chain), mob_parent, attacked_target)
|
|
mob_parent.do_item_attack_animation(attacked_target, used_item = held_disk, animation_type = ATTACK_ANIMATION_BLUNT)
|
|
return COMPONENT_CANCEL_ATTACK_CHAIN
|
|
|
|
held_disk.forceMove(attacked_target)
|
|
disky = null
|
|
mob_parent.balloon_alert(mob_parent, "disk dropped!")
|
|
mob_parent.update_appearance(updates = UPDATE_ICON)
|
|
return COMPONENT_CANCEL_ATTACK_CHAIN
|
|
|
|
/// Don't hold onto the reference if we lose the disk somehow
|
|
/datum/component/nuclear_bomb_operator/proc/atom_exited_owner(atom/parent_atom, atom/movable/gone)
|
|
SIGNAL_HANDLER
|
|
var/obj/item/disk/nuclear/held_disk = disky?.resolve()
|
|
if (held_disk != gone)
|
|
return
|
|
disky = null
|
|
var/mob/mob_parent = parent
|
|
mob_parent.update_appearance(updates = UPDATE_ICON)
|
|
|
|
/// Display any disk-related overlays which need displaying
|
|
/datum/component/nuclear_bomb_operator/proc/on_update_overlays(atom/parent_atom, list/overlays)
|
|
SIGNAL_HANDLER
|
|
if (!disky?.resolve())
|
|
return
|
|
var/mob/mob_parent = parent
|
|
if (!istype(mob_parent) || mob_parent.stat == DEAD)
|
|
return
|
|
add_disk_overlays?.InvokeAsync(overlays)
|