From c2266b8f40beaf695fe79f3d48d76685f9391d7b Mon Sep 17 00:00:00 2001 From: Zonespace <41448081+Zonespace27@users.noreply.github.com> Date: Tue, 16 Jul 2024 18:53:52 +0200 Subject: [PATCH] Abomination Tutorial (#6442) # About the pull request "This'll be a nice and simple 2 hour PR" - Me, 6 hours ago ![image](https://github.com/cmss13-devs/cmss13/assets/41448081/9ee648df-4a48-4e94-a2ac-479e8a4a77a5) Adds a tutorial for how to play abom. You cannot roll abom without having completed its tutorial. # Explain why it's good for the game More tutorials are good, and encouraging players to know the basics of a decently complicated and rare xeno before playing it is a good idea. # Changelog :cl: add: Added a tutorial for xenomorph Abominations. You must complete the tutorial before being able to roll for Abomination. /:cl: --------- Co-authored-by: John Doe Co-authored-by: Drathek <76988376+Drulikar@users.noreply.github.com> --- .../signals/atom/mob/living/signals_xeno.dm | 4 + .../dcs/signals/atom/signals_item.dm | 2 + code/__DEFINES/dcs/signals/signals_datum.dm | 2 + code/__HELPERS/game.dm | 7 +- code/_onclick/xeno.dm | 2 +- code/controllers/subsystem/vote.dm | 1 + code/datums/action.dm | 9 +- code/datums/components/bad_leg.dm | 1 + .../datums/statistics/entities/round_stats.dm | 1 + code/datums/tutorial/_tutorial.dm | 5 +- code/datums/tutorial/xenomorph/abomination.dm | 247 ++++++++++++++++++ .../shield_types/vanguard_shield.dm | 2 +- code/game/objects/effects/aliens.dm | 2 +- code/game/objects/items/devices/binoculars.dm | 1 + .../objects/items/devices/helmet_visors.dm | 1 + code/game/objects/items/devices/walkman.dm | 3 + code/game/objects/items/hoverpack.dm | 1 + .../reagent_containers/reagent_container.dm | 1 + code/game/objects/items/storage/backpack.dm | 3 + .../objects/items/storage/large_holster.dm | 1 + .../objects/structures/vulture_spotter.dm | 1 + code/modules/asset_cache/asset_list_items.dm | 4 + code/modules/clothing/glasses/hud.dm | 1 + code/modules/clothing/glasses/night.dm | 1 + .../clothing/suits/marine_armor/ghillie.dm | 1 + .../clothing/suits/marine_armor/intel.dm | 1 + .../clothing/suits/marine_armor/spec_fire.dm | 1 + code/modules/clothing/under/marine_uniform.dm | 1 + code/modules/cm_aliens/structures/fruit.dm | 4 +- code/modules/cm_preds/yaut_actions.dm | 2 + code/modules/cm_preds/yaut_bracers.dm | 18 +- code/modules/cm_tech/hologram.dm | 1 + code/modules/cm_tech/implements/adv_weapon.dm | 2 + .../modules/gear_presets/_select_equipment.dm | 3 + code/modules/mentor/looc_toggle.dm | 1 + code/modules/mob/camera/imaginary_friend.dm | 2 + code/modules/mob/dead/observer/actions.dm | 7 + .../living/carbon/human/human_abilities.dm | 10 + .../human/species/working_joe/_species.dm | 1 + .../mob/living/carbon/xenomorph/Embryo.dm | 2 +- .../living/carbon/xenomorph/XenoOverwatch.dm | 1 + .../mob/living/carbon/xenomorph/XenoProcs.dm | 4 +- .../mob/living/carbon/xenomorph/Xenomorph.dm | 2 + .../abilities/boiler/boiler_powers.dm | 6 +- .../abilities/crusher/crusher_powers.dm | 2 +- .../abilities/defender/defender_powers.dm | 1 + .../xenomorph/abilities/general_abilities.dm | 1 + .../xenomorph/abilities/general_powers.dm | 4 +- .../abilities/lurker/lurker_powers.dm | 2 +- .../praetorian/praetorian_abilities.dm | 4 +- .../abilities/praetorian/praetorian_powers.dm | 4 +- .../abilities/predalien/predalien_powers.dm | 7 +- .../xenomorph/abilities/queen/queen_powers.dm | 1 + .../carbon/xenomorph/abilities/xeno_action.dm | 24 +- .../living/carbon/xenomorph/castes/Crusher.dm | 4 +- .../carbon/xenomorph/castes/Hellhound.dm | 2 +- .../living/carbon/xenomorph/castes/Lurker.dm | 14 +- .../carbon/xenomorph/castes/Predalien.dm | 38 +-- .../living/carbon/xenomorph/castes/Ravager.dm | 2 +- .../living/carbon/xenomorph/castes/Runner.dm | 2 +- .../carbon/xenomorph/castes/Sentinel.dm | 2 +- .../living/carbon/xenomorph/hive_status_ui.dm | 4 +- .../strains/castes/boiler/trapper.dm | 2 +- .../xenomorph/strains/castes/drone/healer.dm | 3 +- .../strains/castes/praetorian/vanguard.dm | 6 +- code/modules/projectiles/gun_attachables.dm | 3 + code/modules/projectiles/guns/energy.dm | 1 + code/modules/projectiles/guns/rifles.dm | 1 + code/modules/projectiles/guns/shotguns.dm | 1 + code/modules/projectiles/guns/smartgun.dm | 2 + .../specialist/launcher/grenade_launcher.dm | 1 + .../projectiles/guns/specialist/sniper.dm | 2 + .../shuttle/computers/dropship_computer.dm | 2 +- code/modules/surgery/surgery_toggle.dm | 1 + colonialmarines.dme | 1 + .../packages/tgui/interfaces/TutorialMenu.tsx | 39 +-- 76 files changed, 460 insertions(+), 96 deletions(-) create mode 100644 code/datums/tutorial/xenomorph/abomination.dm diff --git a/code/__DEFINES/dcs/signals/atom/mob/living/signals_xeno.dm b/code/__DEFINES/dcs/signals/atom/mob/living/signals_xeno.dm index ab233e9cf82c..e76768a82b46 100644 --- a/code/__DEFINES/dcs/signals/atom/mob/living/signals_xeno.dm +++ b/code/__DEFINES/dcs/signals/atom/mob/living/signals_xeno.dm @@ -50,6 +50,10 @@ /// From /datum/action/xeno_action/proc/use_ability_wrapper(): (mob/owner) #define COMSIG_XENO_ACTION_USED "xeno_action_used" +/// From /datum/action/xeno_action/proc/use_ability_wrapper(): (mob/owner) +#define COMSIG_XENO_PRE_ACTION_USED "xeno_pre_action_used" +/// From /datum/action/xeno_action/proc/use_ability_wrapper(): (mob/owner) +#define COMSIG_XENO_FAILED_ACTION_USED "xeno_failed_action_used" /// From /mob/living/carbon/xenomorph/proc/check_blood_splash() #define COMSIG_XENO_DEAL_ACID_DAMAGE "xeno_deal_acid_damage" /// From /mob/living/carbon/xenomorph/proc/recalculate_speed() diff --git a/code/__DEFINES/dcs/signals/atom/signals_item.dm b/code/__DEFINES/dcs/signals/atom/signals_item.dm index 5ba79960657b..88f99bbff578 100644 --- a/code/__DEFINES/dcs/signals/atom/signals_item.dm +++ b/code/__DEFINES/dcs/signals/atom/signals_item.dm @@ -83,3 +83,5 @@ #define COMSIG_CAMERA_SET_AREA "camera_manager_set_area" #define COMSIG_CAMERA_CLEAR "camera_manager_clear_target" #define COMSIG_CAMERA_REFRESH "camera_manager_refresh" + +#define COMSIG_PRED_BRACER_DECLOAKED "pred_bracer_decloaked" diff --git a/code/__DEFINES/dcs/signals/signals_datum.dm b/code/__DEFINES/dcs/signals/signals_datum.dm index b798d510763e..c35038fcf3e9 100644 --- a/code/__DEFINES/dcs/signals/signals_datum.dm +++ b/code/__DEFINES/dcs/signals/signals_datum.dm @@ -34,6 +34,8 @@ #define COMSIG_ACTION_HIDDEN "action_hidden" /// From base of /datum/action/proc/unhide_from(): (mob/owner) #define COMSIG_ACTION_UNHIDDEN "action_unhidden" +/// From base of /datum/action/proc/action_activate() : () +#define COMSIG_ACTION_ACTIVATED "action_activated" ///from /datum/component/bonus_damage_stack #define COMSIG_BONUS_DAMAGE "bonus_damage" diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 5bf36f785746..094f8205c80e 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -235,7 +235,7 @@ * * hive - The hive we're filling a slot for to check if the player is banished * * sorted - Whether to sort by larva_queue_time (default TRUE) or leave unsorted */ -/proc/get_alien_candidates(datum/hive_status/hive = null, sorted = TRUE) +/proc/get_alien_candidates(datum/hive_status/hive = null, sorted = TRUE, abomination = FALSE) var/list/candidates = list() for(var/mob/dead/observer/cur_obs as anything in GLOB.observer_list) @@ -275,6 +275,11 @@ if(banished) continue + if(abomination) + if(!(/datum/tutorial/xenomorph/abomination::tutorial_id in cur_obs.client.prefs.completed_tutorials)) + to_chat(cur_obs, SPAN_BOLDNOTICE("You were passed over for playing as an Abomination because you have not completed its tutorial.")) + continue + candidates += cur_obs // Optionally sort by larva_queue_time diff --git a/code/_onclick/xeno.dm b/code/_onclick/xeno.dm index 3bb69fe05419..15dc1c39f495 100644 --- a/code/_onclick/xeno.dm +++ b/code/_onclick/xeno.dm @@ -3,7 +3,7 @@ */ /mob/living/carbon/xenomorph/UnarmedAttack(atom/target, proximity, click_parameters, tile_attack = FALSE, ignores_resin = FALSE) - if(body_position == LYING_DOWN || HAS_TRAIT(src, TRAIT_ABILITY_BURROWED)) //No attacks while laying down + if(body_position == LYING_DOWN || HAS_TRAIT(src, TRAIT_ABILITY_BURROWED) || cannot_slash) //No attacks while laying down return FALSE var/mob/alt diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 85e2a57cc6d6..25f522753543 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -414,6 +414,7 @@ SUBSYSTEM_DEF(vote) qdel(src) /datum/action/innate/vote/action_activate() + . = ..() owner.vote() /datum/action/innate/vote/proc/remove_from_client() diff --git a/code/datums/action.dm b/code/datums/action.dm index d1768655a2da..8dbf6c9df5a5 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -43,7 +43,9 @@ return /datum/action/proc/action_activate() - return + SHOULD_CALL_PARENT(TRUE) + + SEND_SIGNAL(src, COMSIG_ACTION_ACTIVATED) /// handler for when a keybind signal is received by the action, calls the action_activate proc asynchronous /datum/action/proc/keybind_activation() @@ -158,6 +160,10 @@ hidden = FALSE L.update_action_buttons() +/proc/get_action(mob/action_mob, action_path) + for(var/datum/action/action in action_mob.actions) + if(istype(action, action_path)) + return action /datum/action/item_action name = "Use item" @@ -182,6 +188,7 @@ return ..() /datum/action/item_action/action_activate() + . = ..() if(target) var/obj/item/I = target I.ui_action_click(owner, holder_item) diff --git a/code/datums/components/bad_leg.dm b/code/datums/components/bad_leg.dm index 4a8678c4da76..8793271803dc 100644 --- a/code/datums/components/bad_leg.dm +++ b/code/datums/components/bad_leg.dm @@ -149,6 +149,7 @@ CRASH("No bound wound to link action") /datum/action/human_action/rest_legs/action_activate() + . = ..() var/mob/living/carbon/human/homan = owner if(in_use) to_chat(homan, SPAN_WARNING("You're already doing that!")) diff --git a/code/datums/statistics/entities/round_stats.dm b/code/datums/statistics/entities/round_stats.dm index 10ec04c6da0e..79493ca87ef0 100644 --- a/code/datums/statistics/entities/round_stats.dm +++ b/code/datums/statistics/entities/round_stats.dm @@ -393,6 +393,7 @@ return TRUE /datum/action/show_round_statistics/action_activate() + . = ..() if(!can_use_action()) return diff --git a/code/datums/tutorial/_tutorial.dm b/code/datums/tutorial/_tutorial.dm index ddeddddd0407..b7403da3c0a9 100644 --- a/code/datums/tutorial/_tutorial.dm +++ b/code/datums/tutorial/_tutorial.dm @@ -4,7 +4,7 @@ GLOBAL_LIST_EMPTY_TYPED(ongoing_tutorials, /datum/tutorial) /datum/tutorial /// What the tutorial is called, is player facing var/name = "Base" - /// Internal ID of the tutorial, kept for save files + /// Internal ID of the tutorial, kept for save files. Format is "tutorialtype_specifictutorial_number". So, the first basic xeno tutorial would be "xeno_basic_1", and the 2nd marine medical tutorial would be "marine_medical_2" var/tutorial_id = "base" /// A short 1-2 sentence description of the tutorial itself var/desc = "" @@ -144,6 +144,8 @@ GLOBAL_LIST_EMPTY_TYPED(ongoing_tutorials, /datum/tutorial) /// Ends the tutorial after a certain amount of time. /datum/tutorial/proc/tutorial_end_in(time = 5 SECONDS, completed = TRUE) + if(completed) + mark_completed() // This is done because if you're calling this proc with completed == TRUE, then the tutorial's a done deal. We shouldn't penalize the player if they exit a few seconds before it actually completes. tutorial_ending = TRUE addtimer(CALLBACK(src, PROC_REF(end_tutorial), completed), time) @@ -221,6 +223,7 @@ GLOBAL_LIST_EMPTY_TYPED(ongoing_tutorials, /datum/tutorial) tutorial = WEAKREF(selected_tutorial) /datum/action/tutorial_end/action_activate() + . = ..() if(!tutorial) return diff --git a/code/datums/tutorial/xenomorph/abomination.dm b/code/datums/tutorial/xenomorph/abomination.dm new file mode 100644 index 000000000000..db9b77cf2e75 --- /dev/null +++ b/code/datums/tutorial/xenomorph/abomination.dm @@ -0,0 +1,247 @@ +/datum/tutorial/xenomorph/abomination + name = "Xenomorph - Predalien" + desc = "A tutorial to teach you how to play the \"Predalien\", also known as Abomination, xenomorph caste. Completing this is required to be able to play an Abomination." + icon_state = "predalien" + tutorial_id = "xeno_abom_1" + tutorial_template = /datum/map_template/tutorial/s7x7 + starting_xenomorph_type = /mob/living/carbon/xenomorph/predalien/tutorial + /// How many marines in the kill_marines stage have been killed + var/ending_marines_killed = 0 + +// START OF SCRITPING + +/datum/tutorial/xenomorph/abomination/start_tutorial(mob/starting_mob) + . = ..() + if(!.) + return + + init_mob() + xeno.lock_evolve = TRUE + + message_to_player("Welcome to the tutorial for the Abomination xenomorph. As an Abomination, you are a frontline powerhouse whose damage scales with your kill count.") + message_to_player("Your kill count scales when you kill humans with your slash attack, up to 10 kills. Ability kills do not count towards this.") + + addtimer(CALLBACK(src, PROC_REF(how_to_be_abom)), 12 SECONDS) + +/datum/tutorial/xenomorph/abomination/proc/how_to_be_abom() + message_to_player("Be aware that you are kill-on-sight to all Predators forever, and will very likely need to defend yourself against multiple.") + message_to_player("Be sure to stick close to other xenomorphs or over-extend. While you may be stronger than many, you don't have enough health or armor to go out on your own.") + addtimer(CALLBACK(src, PROC_REF(feral_rush_tutorial)), 10.5 SECONDS) + +/datum/tutorial/xenomorph/abomination/proc/feral_rush_tutorial() + var/datum/action/rush = give_action(xeno, /datum/action/xeno_action/onclick/feralrush) + message_to_player("Your first unique ability is Feral Rush, an ability that temporarily increases your speed and your armor. Use Feral Rush to continue.") + update_objective("Use your Feral Rush ability.") + add_highlight(rush.button) + RegisterSignal(rush, COMSIG_XENO_ACTION_USED, PROC_REF(on_rush_used)) + +/datum/tutorial/xenomorph/abomination/proc/on_rush_used(datum/action/source, mob/owner) + SIGNAL_HANDLER + + UnregisterSignal(source, COMSIG_XENO_ACTION_USED) + remove_highlight(source.button) + addtimer(CALLBACK(src, PROC_REF(predalien_roar_tutorial_1)), 5 SECONDS) + +/datum/tutorial/xenomorph/abomination/proc/predalien_roar_tutorial_1() + hide_action(xeno, /datum/action/xeno_action/onclick/feralrush) + xeno.cannot_slash = TRUE + message_to_player("Your next ability is Roar, a versatile ability that disables any motion detectors or cloaks in a medium radius around you.") + message_to_player("Additionally, it gives a slash and speed bonus to any friendly xenomorphs in range.") + addtimer(CALLBACK(src, PROC_REF(predalien_roar_tutorial_2)), 8 SECONDS) + +/datum/tutorial/xenomorph/abomination/proc/predalien_roar_tutorial_2() + var/datum/action/roar = give_action(xeno, /datum/action/xeno_action/onclick/predalien_roar) + message_to_player("One of Roar's most useful abilities is uncloaking nearby Predators. Use Roar to uncloak the newly spawned Predator.") + update_objective("Use your Roar ability to uncloak the nearby predator.") + add_highlight(roar.button) + var/mob/living/carbon/human/pred = new(loc_from_corner(3, 3)) + add_to_tracking_atoms(pred) + pred.create_hud() + arm_equipment(pred, /datum/equipment_preset/yautja/blooded) + var/obj/item/clothing/gloves/yautja/hunter/bracers = locate() in pred + if(!bracers) + message_to_player("Something has gone wrong. Please make a bug report.") + CRASH("predator spawned without bracers in tutorial") + + bracers.cloaker_internal(pred, TRUE, TRUE, TRUE) + RegisterSignal(bracers, COMSIG_PRED_BRACER_DECLOAKED, PROC_REF(smash_tutorial_1)) + +/datum/tutorial/xenomorph/abomination/proc/smash_tutorial_1(datum/source) + SIGNAL_HANDLER + + var/datum/action/roar = get_action(xeno, /datum/action/xeno_action/onclick/predalien_roar) + remove_highlight(roar.button) + update_objective("") + + UnregisterSignal(source, COMSIG_PRED_BRACER_DECLOAKED) + addtimer(CALLBACK(src, PROC_REF(smash_tutorial_2)), 2.5 SECONDS) + +/datum/tutorial/xenomorph/abomination/proc/smash_tutorial_2() + hide_action(xeno, /datum/action/xeno_action/onclick/predalien_roar) + message_to_player("Good. Roar will be one of your primary tools for defending against Predators. Your next ability is Feral Smash.") + xeno.cannot_slash = FALSE + + TUTORIAL_ATOM_FROM_TRACKING(/mob/living/carbon/human, pred) + remove_from_tracking_atoms(pred) + qdel(pred) + + addtimer(CALLBACK(src, PROC_REF(smash_tutorial_3)), 5 SECONDS) + +/datum/tutorial/xenomorph/abomination/proc/smash_tutorial_3() + var/datum/action/smash = give_action(xeno, /datum/action/xeno_action/activable/feral_smash) + RegisterSignal(smash, COMSIG_XENO_PRE_ACTION_USED, PROC_REF(frenzy_tutorial_1)) + add_highlight(smash.button) + + message_to_player("Feral Smash is a strong lunge with a range of five tiles. It deals decent damage that scales with your kill count.") + message_to_player("Use Feral Smash on the marine to continue.") + update_objective("Use your Feral Smash ability on the marine.") + + xeno.forceMove(loc_from_corner(0, 2)) + xeno.anchored = TRUE + ADD_TRAIT(xeno, TRAIT_IMMOBILIZED, TRAIT_SOURCE_TUTORIAL) + + var/mob/living/carbon/human/marine = new(loc_from_corner(4, 2)) + add_to_tracking_atoms(marine) + arm_equipment(marine, /datum/equipment_preset/uscm/private_equipped) + +/datum/tutorial/xenomorph/abomination/proc/frenzy_tutorial_1(datum/action/source, mob/owner) + SIGNAL_HANDLER + + xeno.anchored = FALSE + REMOVE_TRAIT(xeno, TRAIT_IMMOBILIZED, TRAIT_SOURCE_TUTORIAL) + RegisterSignal(source, COMSIG_XENO_ACTION_USED, PROC_REF(frenzy_tutorial_2)) + RegisterSignal(source, COMSIG_XENO_FAILED_ACTION_USED, PROC_REF(frenzy_tutorial_1_fail)) + +/datum/tutorial/xenomorph/abomination/proc/frenzy_tutorial_1_fail(datum/action/source, mob/owner) + SIGNAL_HANDLER + + xeno.anchored = TRUE + ADD_TRAIT(xeno, TRAIT_IMMOBILIZED, TRAIT_SOURCE_TUTORIAL) + UnregisterSignal(source, list(COMSIG_XENO_FAILED_ACTION_USED, COMSIG_XENO_ACTION_USED)) + +/datum/tutorial/xenomorph/abomination/proc/frenzy_tutorial_2(datum/action/source, mob/owner) + SIGNAL_HANDLER + + if(get_turf(xeno) == loc_from_corner(0, 2)) // xeno didn't lunge at the mob + xeno.anchored = TRUE + UnregisterSignal(source, COMSIG_XENO_ACTION_USED) + ADD_TRAIT(xeno, TRAIT_IMMOBILIZED, TRAIT_SOURCE_TUTORIAL) + return + + update_objective("") + var/datum/action/smash = get_action(xeno, /datum/action/xeno_action/activable/feral_smash) + remove_highlight(smash.button) + UnregisterSignal(source, list(COMSIG_XENO_ACTION_USED, COMSIG_XENO_PRE_ACTION_USED)) + addtimer(CALLBACK(src, PROC_REF(frenzy_tutorial_3)), 2 SECONDS) + +/datum/tutorial/xenomorph/abomination/proc/frenzy_tutorial_3() + remove_action(xeno, /datum/action/xeno_action/activable/feral_smash) + message_to_player("Good. Your final ability is Feral Frenzy, a strong ability that can alternate between hitting a single target or all within a large radius. However, it locks you in place while it winds up.") + + TUTORIAL_ATOM_FROM_TRACKING(/mob/living/carbon/human, marine) + remove_from_tracking_atoms(marine) + qdel(marine) + + addtimer(CALLBACK(src, PROC_REF(frenzy_tutorial_4)), 6 SECONDS) + +/datum/tutorial/xenomorph/abomination/proc/frenzy_tutorial_4() + var/mob/living/carbon/human/marine = new(loc_from_corner(4, 2)) + add_to_tracking_atoms(marine) + arm_equipment(marine, /datum/equipment_preset/uscm/private_equipped) + + var/datum/action/frenzy = give_action(xeno, /datum/action/xeno_action/activable/feralfrenzy) + add_highlight(frenzy.button) + message_to_player("By default, Feral Frenzy is on single-target mode. Use Feral Frenzy on the newly spawned marine.") + update_objective("Use Feral Frenzy on the marine.") + + RegisterSignal(frenzy, COMSIG_XENO_ACTION_USED, PROC_REF(frenzy_tutorial_5)) + +/datum/tutorial/xenomorph/abomination/proc/frenzy_tutorial_5(datum/action/xeno_action/source, mob/owner) + SIGNAL_HANDLER + + TUTORIAL_ATOM_FROM_TRACKING(/mob/living/carbon/human, marine) + if(get_dist(marine, xeno) > 1) + return + + UnregisterSignal(source, COMSIG_XENO_ACTION_USED) + var/datum/action/frenzy = get_action(xeno, /datum/action/xeno_action/activable/feralfrenzy) + remove_highlight(frenzy.button) + var/datum/action/frenzy_toggle = give_action(xeno, /datum/action/xeno_action/onclick/toggle_gut_targeting) + add_highlight(frenzy_toggle.button) + message_to_player("Good, now toggle Feral Frenzy's AOE mode with the newly available Toggle Gutting Type ability.") + update_objective("Use the Toggle Gutting Type ability to change your frenzy mode.") + + RegisterSignal(frenzy_toggle, COMSIG_XENO_ACTION_USED, PROC_REF(frenzy_tutorial_6)) + +/datum/tutorial/xenomorph/abomination/proc/frenzy_tutorial_6(datum/action/xeno_action/source, mob/owner) + SIGNAL_HANDLER + + UnregisterSignal(source, COMSIG_XENO_ACTION_USED) + remove_highlight(source.button) + source.plasma_cost = INFINITY // slightly scuffed way of disabling the switch button + source.update_button_icon() + + message_to_player("Feral Frenzy has now been changed into AOE mode. Use Feral Frenzy again anywhere within 2 tiles of the marine.") + update_objective("Use Feral Frenzy within 2 tiles of the marine.") + TUTORIAL_ATOM_FROM_TRACKING(/mob/living/carbon/human, marine) + marine.rejuvenate() + var/datum/action/xeno_action/activable/feralfrenzy/frenzy = get_action(xeno, /datum/action/xeno_action/activable/feralfrenzy) + frenzy.targeting = AOETARGETGUT + frenzy.reduce_cooldown(frenzy.xeno_cooldown) + add_highlight(frenzy.button) + + RegisterSignal(frenzy, COMSIG_XENO_ACTION_USED, PROC_REF(frenzy_tutorial_7)) + +/datum/tutorial/xenomorph/abomination/proc/frenzy_tutorial_7(datum/action/source) + SIGNAL_HANDLER + + TUTORIAL_ATOM_FROM_TRACKING(/mob/living/carbon/human, marine) + var/datum/action/xeno_action/activable/feralfrenzy/frenzy = get_action(xeno, /datum/action/xeno_action/activable/feralfrenzy) + if(get_dist(xeno, marine) > frenzy.range) + // Not close enough to actually hit the marine + return + + UnregisterSignal(frenzy, COMSIG_XENO_ACTION_USED) + remove_highlight(frenzy.button) + message_to_player("Good. As you may have noticed, the AOE version of Feral Frenzy takes longer to wind up, in addition to doing less overall damage.") + addtimer(CALLBACK(src, PROC_REF(kill_marines)), 6 SECONDS) + +/datum/tutorial/xenomorph/abomination/proc/kill_marines() + message_to_player("To finish the tutorial, kill the three newly-spawned marines using any of your attacks or abilities.") + + // Spawn/rejuv the dummies + TUTORIAL_ATOM_FROM_TRACKING(/mob/living/carbon/human, marine) // we can reuse this one though + marine.rejuvenate() + marine.forceMove(loc_from_corner(4, 2)) + RegisterSignal(marine, COMSIG_MOB_DEATH, PROC_REF(kill_marines_2)) + + var/mob/living/carbon/human/marine_2 = new(loc_from_corner(2, 2)) + arm_equipment(marine_2, /datum/equipment_preset/uscm/private_equipped) + RegisterSignal(marine_2, COMSIG_MOB_DEATH, PROC_REF(kill_marines_2)) + + var/mob/living/carbon/human/marine_3 = new(loc_from_corner(0, 2)) + arm_equipment(marine_3, /datum/equipment_preset/uscm/private_equipped) + RegisterSignal(marine_3, COMSIG_MOB_DEATH, PROC_REF(kill_marines_2)) + + // Arrange the actions about how they'd be in an actual game + remove_action(xeno, /datum/action/xeno_action/activable/feralfrenzy) + remove_action(xeno, /datum/action/xeno_action/onclick/toggle_gut_targeting) + + give_action(xeno, /datum/action/xeno_action/activable/tail_stab) + give_action(xeno, /datum/action/xeno_action/onclick/feralrush) + give_action(xeno, /datum/action/xeno_action/onclick/predalien_roar) + give_action(xeno, /datum/action/xeno_action/activable/feral_smash) + give_action(xeno, /datum/action/xeno_action/activable/feralfrenzy) + give_action(xeno, /datum/action/xeno_action/onclick/toggle_gut_targeting) + +/datum/tutorial/xenomorph/abomination/proc/kill_marines_2(datum/source) + SIGNAL_HANDLER + + if(ending_marines_killed < 2) + ending_marines_killed++ + return + + message_to_player("Good work. The tutorial will end shortly.") + tutorial_end_in(7 SECONDS, TRUE) + +// END OF SCRIPTING diff --git a/code/datums/xeno_shields/shield_types/vanguard_shield.dm b/code/datums/xeno_shields/shield_types/vanguard_shield.dm index 21d9fb12cfd7..cd9e4534e778 100644 --- a/code/datums/xeno_shields/shield_types/vanguard_shield.dm +++ b/code/datums/xeno_shields/shield_types/vanguard_shield.dm @@ -42,7 +42,7 @@ return linked_xeno.overlay_shields() - var/datum/action/xeno_action/activable/cleave/cAction = get_xeno_action_by_type(linked_xeno, /datum/action/xeno_action/activable/cleave) + var/datum/action/xeno_action/activable/cleave/cAction = get_action(linked_xeno, /datum/action/xeno_action/activable/cleave) if (istype(cAction)) addtimer(CALLBACK(cAction, TYPE_PROC_REF(/datum/action/xeno_action/activable/cleave, remove_buff)), 7, TIMER_UNIQUE) diff --git a/code/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm index 10d4e8d098fb..34da5e3d2623 100644 --- a/code/game/objects/effects/aliens.dm +++ b/code/game/objects/effects/aliens.dm @@ -597,7 +597,7 @@ total_hits++ - var/datum/action/xeno_action/activable/boiler_trap/trap = get_xeno_action_by_type(linked_xeno, /datum/action/xeno_action/activable/boiler_trap) + var/datum/action/xeno_action/activable/boiler_trap/trap = get_action(linked_xeno, /datum/action/xeno_action/activable/boiler_trap) trap.reduce_cooldown(total_hits*4 SECONDS) diff --git a/code/game/objects/items/devices/binoculars.dm b/code/game/objects/items/devices/binoculars.dm index 5da4704e0e78..3248115adfa8 100644 --- a/code/game/objects/items/devices/binoculars.dm +++ b/code/game/objects/items/devices/binoculars.dm @@ -403,6 +403,7 @@ COOLDOWN_START(designator, spotting_cooldown, 0) /datum/action/item_action/specialist/spotter_target/action_activate() + . = ..() if(!ishuman(owner)) return var/mob/living/carbon/human/human = owner diff --git a/code/game/objects/items/devices/helmet_visors.dm b/code/game/objects/items/devices/helmet_visors.dm index 8f921a62f3f5..e2005a841bc3 100644 --- a/code/game/objects/items/devices/helmet_visors.dm +++ b/code/game/objects/items/devices/helmet_visors.dm @@ -146,6 +146,7 @@ return /datum/action/item_action/view_publications/helmet_visor/action_activate() + . = ..() var/obj/item/device/helmet_visor/medical/advanced/medical_visor = locate() in holder_item if(!medical_visor) diff --git a/code/game/objects/items/devices/walkman.dm b/code/game/objects/items/devices/walkman.dm index 42c03d757dbd..bef8e8f5ff79 100644 --- a/code/game/objects/items/devices/walkman.dm +++ b/code/game/objects/items/devices/walkman.dm @@ -269,6 +269,7 @@ button.name = name /datum/action/item_action/walkman/play_pause/action_activate() + . = ..() if(target) var/obj/item/device/walkman/WM = target WM.attack_self(owner) @@ -282,6 +283,7 @@ button.name = name /datum/action/item_action/walkman/next_song/action_activate() + . = ..() if(target) var/obj/item/device/walkman/WM = target WM.next_song(owner) @@ -295,6 +297,7 @@ button.name = name /datum/action/item_action/walkman/restart_song/action_activate() + . = ..() if(target) var/obj/item/device/walkman/WM = target WM.restart_song(owner) diff --git a/code/game/objects/items/hoverpack.dm b/code/game/objects/items/hoverpack.dm index 02a2d4be779a..65406eb15dc6 100644 --- a/code/game/objects/items/hoverpack.dm +++ b/code/game/objects/items/hoverpack.dm @@ -208,6 +208,7 @@ return TRUE /datum/action/item_action/hover/action_activate() + . = ..() var/mob/living/carbon/human/H = owner if(H.selected_ability == src) to_chat(H, "You will no longer use [name] with \ diff --git a/code/game/objects/items/reagent_containers/reagent_container.dm b/code/game/objects/items/reagent_containers/reagent_container.dm index 5207df4ca7bb..37029ff247d6 100644 --- a/code/game/objects/items/reagent_containers/reagent_container.dm +++ b/code/game/objects/items/reagent_containers/reagent_container.dm @@ -109,5 +109,6 @@ button.overlays += IMG /datum/action/item_action/reagent_container/set_transfer_amount/action_activate() + . = ..() var/obj/item/reagent_container/cont = holder_item cont.set_APTFT() diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index baa91db19396..06636d2c3f76 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -268,6 +268,7 @@ return TRUE /datum/action/item_action/specialist/santabag/action_activate() + . = ..() var/obj/item/storage/backpack/santabag/santa_bag = holder_item santa_bag.refill_santa_bag(owner) update_button_icon() @@ -537,6 +538,7 @@ GLOBAL_LIST_EMPTY_TYPED(radio_packs, /obj/item/storage/backpack/marine/satchel/r button.overlays += IMG /datum/action/item_action/rto_pack/use_phone/action_activate() + . = ..() for(var/obj/item/storage/backpack/marine/satchel/rto/radio_backpack in owner) radio_backpack.use_phone(owner) return @@ -870,6 +872,7 @@ GLOBAL_LIST_EMPTY_TYPED(radio_packs, /obj/item/storage/backpack/marine/satchel/r return TRUE /datum/action/item_action/specialist/toggle_cloak/action_activate() + . = ..() var/obj/item/storage/backpack/marine/satchel/scout_cloak/SC = holder_item SC.camouflage() diff --git a/code/game/objects/items/storage/large_holster.dm b/code/game/objects/items/storage/large_holster.dm index 02983e1552ed..d8e1ee51d0d8 100644 --- a/code/game/objects/items/storage/large_holster.dm +++ b/code/game/objects/items/storage/large_holster.dm @@ -375,6 +375,7 @@ return TRUE /datum/action/item_action/specialist/toggle_fuel/action_activate() + . = ..() var/obj/item/storage/large_holster/fuelpack/FP = holder_item if (!istype(FP)) return diff --git a/code/game/objects/structures/vulture_spotter.dm b/code/game/objects/structures/vulture_spotter.dm index dc341edf0446..dcbfd88c9c08 100644 --- a/code/game/objects/structures/vulture_spotter.dm +++ b/code/game/objects/structures/vulture_spotter.dm @@ -313,6 +313,7 @@ tripod = WEAKREF(spotting_tripod) /datum/action/vulture_tripod_unscope/action_activate() + . = ..() if(!tripod) return diff --git a/code/modules/asset_cache/asset_list_items.dm b/code/modules/asset_cache/asset_list_items.dm index 0b27cf268a12..e826b0b64767 100644 --- a/code/modules/asset_cache/asset_list_items.dm +++ b/code/modules/asset_cache/asset_list_items.dm @@ -367,6 +367,10 @@ retrieved_icon.Scale(128, 128) Insert("intents", retrieved_icon) + retrieved_icon = icon('icons/mob/xenos/predalien.dmi', "Normal Predalien Walking") + retrieved_icon.Scale(128, 128) + Insert("predalien", retrieved_icon) + return ..() diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index 7406e6baa754..6e086e651a10 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -40,6 +40,7 @@ return TRUE /datum/action/item_action/view_publications/action_activate() + . = ..() var/obj/item/clothing/glasses/hud/health/hud = holder_item hud.tgui_interact(owner) diff --git a/code/modules/clothing/glasses/night.dm b/code/modules/clothing/glasses/night.dm index b2b6f8406dcc..984a906eabed 100644 --- a/code/modules/clothing/glasses/night.dm +++ b/code/modules/clothing/glasses/night.dm @@ -184,6 +184,7 @@ button.overlays += image('icons/mob/hud/actions.dmi', button, action_icon_state) /datum/action/item_action/m56_goggles/far_sight/action_activate() + . = ..() if(target) var/obj/item/clothing/glasses/night/m56_goggles/G = target G.set_far_sight(owner, !G.far_sight) diff --git a/code/modules/clothing/suits/marine_armor/ghillie.dm b/code/modules/clothing/suits/marine_armor/ghillie.dm index 1f1b71227655..44729ac16b2f 100644 --- a/code/modules/clothing/suits/marine_armor/ghillie.dm +++ b/code/modules/clothing/suits/marine_armor/ghillie.dm @@ -150,6 +150,7 @@ return TRUE /datum/action/item_action/specialist/prepare_position/action_activate() + . = ..() var/obj/item/clothing/suit/storage/marine/ghillie/GS = holder_item GS.camouflage() diff --git a/code/modules/clothing/suits/marine_armor/intel.dm b/code/modules/clothing/suits/marine_armor/intel.dm index b3f0f93e004d..12aa824648d1 100644 --- a/code/modules/clothing/suits/marine_armor/intel.dm +++ b/code/modules/clothing/suits/marine_armor/intel.dm @@ -18,6 +18,7 @@ update_icon() /datum/action/item_action/intel/action_activate() + . = ..() if(!ishuman(owner)) return diff --git a/code/modules/clothing/suits/marine_armor/spec_fire.dm b/code/modules/clothing/suits/marine_armor/spec_fire.dm index 52343a204f68..c3f2863b3545 100644 --- a/code/modules/clothing/suits/marine_armor/spec_fire.dm +++ b/code/modules/clothing/suits/marine_armor/spec_fire.dm @@ -145,6 +145,7 @@ return TRUE /datum/action/item_action/specialist/fire_shield/action_activate() + . = ..() var/obj/item/clothing/suit/storage/marine/M35/armor = holder_item if (!istype(armor)) return diff --git a/code/modules/clothing/under/marine_uniform.dm b/code/modules/clothing/under/marine_uniform.dm index c7353840d439..74cb5ea552ee 100644 --- a/code/modules/clothing/under/marine_uniform.dm +++ b/code/modules/clothing/under/marine_uniform.dm @@ -1210,6 +1210,7 @@ button.overlays += button_overlay /datum/action/item_action/specialist/toggle_cbrn_hood/action_activate() + . = ..() var/obj/item/clothing/under/marine/cbrn/armor = holder_item if(!istype(armor)) return diff --git a/code/modules/cm_aliens/structures/fruit.dm b/code/modules/cm_aliens/structures/fruit.dm index f555cac64b8c..b2a0fd27d65b 100644 --- a/code/modules/cm_aliens/structures/fruit.dm +++ b/code/modules/cm_aliens/structures/fruit.dm @@ -185,7 +185,7 @@ bound_xeno.current_fruits.Remove(src) var/number_of_fruit = length(bound_xeno.current_fruits) - var/datum/action/xeno_action/onclick/plant_resin_fruit/plant_action = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/onclick/plant_resin_fruit) + var/datum/action/xeno_action/onclick/plant_resin_fruit/plant_action = get_action(bound_xeno, /datum/action/xeno_action/onclick/plant_resin_fruit) plant_action.button.set_maptext(SMALL_FONTS_COLOR(7, number_of_fruit, "#e69d00"), 19, 2) plant_action.update_button_icon() @@ -377,7 +377,7 @@ /obj/item/reagent_container/food/snacks/resin_fruit/proc/delete_fruit() if(bound_xeno) bound_xeno.current_fruits.Remove(src) - var/datum/action/xeno_action/onclick/plant_resin_fruit/prf = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/onclick/plant_resin_fruit) + var/datum/action/xeno_action/onclick/plant_resin_fruit/prf = get_action(bound_xeno, /datum/action/xeno_action/onclick/plant_resin_fruit) var/number_of_fruit = length(bound_xeno.current_fruits) prf.button.set_maptext(SMALL_FONTS_COLOR(7, number_of_fruit, "#e69d00"), 19, 2) prf.update_button_icon() diff --git a/code/modules/cm_preds/yaut_actions.dm b/code/modules/cm_preds/yaut_actions.dm index f55f58e0a557..0d260363ab15 100644 --- a/code/modules/cm_preds/yaut_actions.dm +++ b/code/modules/cm_preds/yaut_actions.dm @@ -49,6 +49,7 @@ return TRUE /datum/action/predator_action/action_activate() + . = ..() if(!can_use_action()) return FALSE @@ -248,6 +249,7 @@ action_icon_state = "looc_toggle" /datum/action/yautja_emote_panel/action_activate() + . = ..() var/mob/living/carbon/human/human_owner = owner var/datum/species/yautja/yautja_species = human_owner.species yautja_species.open_emote_panel() diff --git a/code/modules/cm_preds/yaut_bracers.dm b/code/modules/cm_preds/yaut_bracers.dm index 5577691d64c2..77efbb7ad4ef 100644 --- a/code/modules/cm_preds/yaut_bracers.dm +++ b/code/modules/cm_preds/yaut_bracers.dm @@ -556,7 +556,7 @@ set src in usr . = cloaker_internal(usr, FALSE) -/obj/item/clothing/gloves/yautja/hunter/proc/cloaker_internal(mob/caller, forced = FALSE) +/obj/item/clothing/gloves/yautja/hunter/proc/cloaker_internal(mob/caller, forced = FALSE, silent = FALSE, instant = FALSE) . = check_random_function(caller, forced) if(.) return @@ -600,15 +600,21 @@ M.see_invisible = SEE_INVISIBLE_LEVEL_ONE log_game("[key_name_admin(usr)] has enabled their cloaking device.") - M.visible_message(SPAN_WARNING("[M] vanishes into thin air!"), SPAN_NOTICE("You are now invisible to normal detection.")) - playsound(M.loc,'sound/effects/pred_cloakon.ogg', 15, 1) - animate(M, alpha = new_alpha, time = 1.5 SECONDS, easing = SINE_EASING|EASE_OUT) + if(!silent) + M.visible_message(SPAN_WARNING("[M] vanishes into thin air!"), SPAN_NOTICE("You are now invisible to normal detection.")) + playsound(M.loc,'sound/effects/pred_cloakon.ogg', 15, 1) + + if(!instant) + animate(M, alpha = new_alpha, time = 1.5 SECONDS, easing = SINE_EASING|EASE_OUT) + else + M.alpha = new_alpha var/datum/mob_hud/security/advanced/SA = GLOB.huds[MOB_HUD_SECURITY_ADVANCED] SA.remove_from_hud(M) var/datum/mob_hud/xeno_infection/XI = GLOB.huds[MOB_HUD_XENO_INFECTION] XI.remove_from_hud(M) - anim(M.loc,M,'icons/mob/mob.dmi',,"cloak",,M.dir) + if(!instant) + anim(M.loc,M,'icons/mob/mob.dmi',,"cloak",,M.dir) var/datum/action/predator_action/bracer/cloak/cloak_action for(cloak_action as anything in M.actions) @@ -634,6 +640,8 @@ if(!user) return + SEND_SIGNAL(src, COMSIG_PRED_BRACER_DECLOAKED) + UnregisterSignal(user, COMSIG_HUMAN_EXTINGUISH) UnregisterSignal(user, COMSIG_HUMAN_PRE_BULLET_ACT) UnregisterSignal(user, COMSIG_MOB_EFFECT_CLOAK_CANCEL) diff --git a/code/modules/cm_tech/hologram.dm b/code/modules/cm_tech/hologram.dm index 1fcba71a4560..1d85df9e49ad 100644 --- a/code/modules/cm_tech/hologram.dm +++ b/code/modules/cm_tech/hologram.dm @@ -102,6 +102,7 @@ GLOBAL_LIST_EMPTY_TYPED(hologram_list, /mob/hologram) var/mob/hologram/linked_hologram /datum/action/leave_hologram/action_activate() + . = ..() qdel(src) /datum/action/leave_hologram/Destroy() diff --git a/code/modules/cm_tech/implements/adv_weapon.dm b/code/modules/cm_tech/implements/adv_weapon.dm index 3cc8f1ceb4d6..f7b1008e0882 100644 --- a/code/modules/cm_tech/implements/adv_weapon.dm +++ b/code/modules/cm_tech/implements/adv_weapon.dm @@ -130,6 +130,7 @@ name = "Start Charging" /datum/action/item_action/techweb_railgun_start_charge/action_activate() + . = ..() if (target) var/obj/item/weapon/gun/rifle/techweb_railgun/TR = target TR.start_charging(owner) @@ -138,6 +139,7 @@ name = "Abort Charge" /datum/action/item_action/techweb_railgun_abort_charge/action_activate() + . = ..() if (target) var/obj/item/weapon/gun/rifle/techweb_railgun/TR = target TR.abort_charge(owner) diff --git a/code/modules/gear_presets/_select_equipment.dm b/code/modules/gear_presets/_select_equipment.dm index 5311a7a79a3b..138e091ad5a4 100644 --- a/code/modules/gear_presets/_select_equipment.dm +++ b/code/modules/gear_presets/_select_equipment.dm @@ -138,6 +138,9 @@ new_human.set_languages(languages) /datum/equipment_preset/proc/load_preset(mob/living/carbon/human/new_human, randomise = FALSE, count_participant = FALSE, client/mob_client, show_job_gear = TRUE) + if(!new_human.hud_used) + new_human.create_hud() + load_race(new_human, mob_client) if(randomise || uses_special_name) load_name(new_human, randomise, mob_client) diff --git a/code/modules/mentor/looc_toggle.dm b/code/modules/mentor/looc_toggle.dm index 7c5b95b1fcb0..b224e72e79d2 100644 --- a/code/modules/mentor/looc_toggle.dm +++ b/code/modules/mentor/looc_toggle.dm @@ -13,6 +13,7 @@ // Called when the action is clicked on. /datum/action/looc_toggle/action_activate() + . = ..() if(owner.looc_overhead) button.icon_state = "template" owner.looc_overhead = FALSE diff --git a/code/modules/mob/camera/imaginary_friend.dm b/code/modules/mob/camera/imaginary_friend.dm index 4e7be80056de..0a4d5ee65c5c 100644 --- a/code/modules/mob/camera/imaginary_friend.dm +++ b/code/modules/mob/camera/imaginary_friend.dm @@ -280,6 +280,7 @@ action_icon_state = "joinmob" /datum/action/innate/imaginary_orbit/action_activate() + . = ..() var/mob/camera/imaginary_friend/friend = owner friend.recall() @@ -288,6 +289,7 @@ action_icon_state = "hidemob" /datum/action/innate/imaginary_hide/action_activate() + . = ..() var/mob/camera/imaginary_friend/friend = owner if(friend.hidden) friend.hidden = FALSE diff --git a/code/modules/mob/dead/observer/actions.dm b/code/modules/mob/dead/observer/actions.dm index 7daae802dc7a..192c6cd1e3b8 100644 --- a/code/modules/mob/dead/observer/actions.dm +++ b/code/modules/mob/dead/observer/actions.dm @@ -3,6 +3,7 @@ action_icon_state = "ghost" /datum/action/ghost/action_activate() + . = ..() if(!owner.client) return @@ -38,6 +39,7 @@ qdel(src) /datum/action/join_ert/action_activate() + . = ..() if(!owner.client) return @@ -50,6 +52,7 @@ listen_signal = COMSIG_KB_OBSERVER_JOIN_PREDATOR /datum/action/join_predator/action_activate() + . = ..() var/mob/dead/observer/activator = owner activator.join_as_yautja() @@ -58,6 +61,7 @@ action_icon_state = "view_crew_manifest" /datum/action/observer_action/view_crew_manifest/action_activate() + . = ..() show_browser(owner, GLOB.data_core.get_manifest(), "Crew Manifest", "manifest", "size=450x750") /datum/action/observer_action/view_hive_status @@ -65,6 +69,7 @@ action_icon_state = "view_hive_status" /datum/action/observer_action/view_hive_status/action_activate() + . = ..() var/mob/dead/observer/activator = owner activator.hive_status() @@ -74,6 +79,7 @@ listen_signal = COMSIG_KB_OBSERVER_JOIN_XENO /datum/action/observer_action/join_xeno/action_activate() + . = ..() if(!owner.client) return @@ -90,6 +96,7 @@ listen_signal = COMSIG_KB_OBSERVER_JOIN_LESSER_DRONE /datum/action/observer_action/join_lesser_drone/action_activate() + . = ..() if(!owner.client) return diff --git a/code/modules/mob/living/carbon/human/human_abilities.dm b/code/modules/mob/living/carbon/human/human_abilities.dm index 76ebbed06de6..9976fe37a4ff 100644 --- a/code/modules/mob/living/carbon/human/human_abilities.dm +++ b/code/modules/mob/living/carbon/human/human_abilities.dm @@ -20,6 +20,7 @@ cooldown = COMMAND_ORDER_COOLDOWN /datum/action/human_action/issue_order/action_activate() + . = ..() if(!ishuman(owner)) return var/mob/living/carbon/human/H = owner @@ -58,6 +59,7 @@ return FALSE /datum/action/human_action/smartpack/action_activate() + . = ..() if(!istype(owner, /mob/living/carbon/human)) return var/mob/living/carbon/human/H = owner @@ -129,6 +131,7 @@ CULT // Called when the action is clicked on. /datum/action/human_action/activable/action_activate() + . = ..() if(!ishuman(owner)) return var/mob/living/carbon/human/H = owner @@ -286,6 +289,7 @@ CULT action_icon_state = "cultist_channel_hivemind" /datum/action/human_action/activable/cult/speak_hivemind/action_activate() + . = ..() if(!can_use_action()) return @@ -316,6 +320,7 @@ CULT var/list/items_to_spawn = list(/obj/item/clothing/suit/cultist_hoodie/, /obj/item/clothing/head/cultist_hood/) /datum/action/human_action/activable/cult/obtain_equipment/action_activate() + . = ..() if(!can_use_action()) return @@ -515,6 +520,7 @@ CULT action_icon_state = "mutineer_begin" /datum/action/human_action/activable/mutineer/mutineer_begin/action_activate() + . = ..() if(!can_use_action()) return @@ -549,6 +555,7 @@ CULT UnregisterSignal(L, COMSIG_MOB_RESET_VIEW) /datum/action/human_action/cancel_view/action_activate() + . = ..() if(!can_use_action()) return @@ -575,6 +582,7 @@ CULT UnregisterSignal(L, COMSIG_MOB_RESET_VIEW) /datum/action/human_action/vehicle_unbuckle/action_activate() + . = ..() if(!can_use_action()) return @@ -600,6 +608,7 @@ CULT action_icon_state = "cancel_view" /datum/action/human_action/mg_exit/action_activate() + . = ..() if(!can_use_action()) return @@ -619,6 +628,7 @@ CULT UnregisterSignal(user, COMSIG_MOB_RESET_VIEW) /datum/action/human_action/toggle_arc_antenna/action_activate() + . = ..() if(!can_use_action()) return diff --git a/code/modules/mob/living/carbon/human/species/working_joe/_species.dm b/code/modules/mob/living/carbon/human/species/working_joe/_species.dm index c032e25708eb..f2c0e8d4cf26 100644 --- a/code/modules/mob/living/carbon/human/species/working_joe/_species.dm +++ b/code/modules/mob/living/carbon/human/species/working_joe/_species.dm @@ -50,6 +50,7 @@ /datum/action/joe_emote_panel/action_activate() + . = ..() if(!can_use_action()) return diff --git a/code/modules/mob/living/carbon/xenomorph/Embryo.dm b/code/modules/mob/living/carbon/xenomorph/Embryo.dm index d0890bd3cf37..61ba87cd001b 100644 --- a/code/modules/mob/living/carbon/xenomorph/Embryo.dm +++ b/code/modules/mob/living/carbon/xenomorph/Embryo.dm @@ -191,7 +191,7 @@ if(!picked) // Get a candidate from observers - var/list/candidates = get_alien_candidates(hive) + var/list/candidates = get_alien_candidates(hive, abomination = (isyautja(affected_mob) || (flags_embryo & FLAG_EMBRYO_PREDATOR))) if(candidates && length(candidates)) // If they were facehugged by a player thats still in queue, they get second dibs on the new larva. if(hugger_ckey) diff --git a/code/modules/mob/living/carbon/xenomorph/XenoOverwatch.dm b/code/modules/mob/living/carbon/xenomorph/XenoOverwatch.dm index 1fb48f699efa..3f37845380f0 100644 --- a/code/modules/mob/living/carbon/xenomorph/XenoOverwatch.dm +++ b/code/modules/mob/living/carbon/xenomorph/XenoOverwatch.dm @@ -18,6 +18,7 @@ return TRUE /datum/action/xeno_action/watch_xeno/action_activate() + . = ..() var/mob/living/carbon/xenomorph/X = owner if (!X.check_state(TRUE)) return FALSE diff --git a/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm b/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm index f0fd8a4d86a7..e7320b17c333 100644 --- a/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm +++ b/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm @@ -264,7 +264,7 @@ /mob/living/carbon/xenomorph/proc/pounced_mob(mob/living/L) // This should only be called back by a mob that has pounce, so no need to check - var/datum/action/xeno_action/activable/pounce/pounceAction = get_xeno_action_by_type(src, /datum/action/xeno_action/activable/pounce) + var/datum/action/xeno_action/activable/pounce/pounceAction = get_action(src, /datum/action/xeno_action/activable/pounce) // Unconscious or dead, or not throwing but used pounce. if(!check_state() || (!throwing && !pounceAction.action_cooldown_check())) @@ -336,7 +336,7 @@ pounced_mob(L) /mob/living/carbon/xenomorph/proc/pounced_obj(obj/O) - var/datum/action/xeno_action/activable/pounce/pounceAction = get_xeno_action_by_type(src, /datum/action/xeno_action/activable/pounce) + var/datum/action/xeno_action/activable/pounce/pounceAction = get_action(src, /datum/action/xeno_action/activable/pounce) // Unconscious or dead, or not throwing but used pounce if(!check_state() || (!throwing && !pounceAction.action_cooldown_check())) diff --git a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm index b07f766b179d..eed2dce5f7a8 100644 --- a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm +++ b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm @@ -343,6 +343,8 @@ var/atom/movable/vis_obj/xeno_wounds/wound_icon_holder var/atom/movable/vis_obj/xeno_pack/backpack_icon_holder + /// If TRUE, the xeno cannot slash anything + var/cannot_slash = FALSE /mob/living/carbon/xenomorph/Initialize(mapload, mob/living/carbon/xenomorph/old_xeno, hivenumber) diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/boiler/boiler_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/boiler/boiler_powers.dm index c749b0adb5ba..2431e4629876 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/boiler/boiler_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/boiler/boiler_powers.dm @@ -108,7 +108,7 @@ var/mob/living/carbon/xenomorph/xeno = owner if(!action_cooldown_check()) // activate c/d only if we already spit for (var/action_type in action_types_to_cd) - var/datum/action/xeno_action/xeno_action = get_xeno_action_by_type(xeno, action_type) + var/datum/action/xeno_action/xeno_action = get_action(xeno, action_type) if (!istype(xeno_action)) continue @@ -149,7 +149,7 @@ to_chat(xeno, SPAN_XENOHIGHDANGER("We dump our acid through our pores, creating a shroud of gas!")) for (var/action_type in action_types_to_cd) - var/datum/action/xeno_action/xeno_action = get_xeno_action_by_type(xeno, action_type) + var/datum/action/xeno_action/xeno_action = get_action(xeno, action_type) if (!istype(xeno_action)) continue @@ -218,7 +218,7 @@ empowered = FALSE empowering_charge_counter = 0 button.overlays -= "+empowered" - var/datum/action/xeno_action/activable/acid_mine/mine = get_xeno_action_by_type(xeno, /datum/action/xeno_action/activable/acid_mine) + var/datum/action/xeno_action/activable/acid_mine/mine = get_action(xeno, /datum/action/xeno_action/activable/acid_mine) if(!mine.empowered) mine.empowered = TRUE mine.button.overlays += "+empowered" diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_powers.dm index e1af5e36a40f..1dd4dc5a1c87 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_powers.dm @@ -82,7 +82,7 @@ // This ties the pounce/throwing backend into the old collision backend /mob/living/carbon/xenomorph/crusher/pounced_obj(obj/O) - var/datum/action/xeno_action/activable/pounce/crusher_charge/CCA = get_xeno_action_by_type(src, /datum/action/xeno_action/activable/pounce/crusher_charge) + var/datum/action/xeno_action/activable/pounce/crusher_charge/CCA = get_action(src, /datum/action/xeno_action/activable/pounce/crusher_charge) if (istype(CCA) && !CCA.action_cooldown_check() && !(O.type in CCA.not_reducing_objects)) CCA.reduce_cooldown(50) diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/defender/defender_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/defender/defender_powers.dm index d7a4f987623a..8736d612c822 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/defender/defender_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/defender/defender_powers.dm @@ -183,6 +183,7 @@ return ..() /datum/action/xeno_action/activable/fortify/action_activate() + . = ..() ..() var/mob/living/carbon/xenomorph/xeno = owner if(xeno.fortify && xeno.selected_ability != src) diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/general_abilities.dm b/code/modules/mob/living/carbon/xenomorph/abilities/general_abilities.dm index c5988f12539d..b262624bfe01 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/general_abilities.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/general_abilities.dm @@ -485,6 +485,7 @@ listen_signal = COMSIG_KB_XENO_EVOLVE /datum/action/xeno_action/onclick/evolve/action_activate() + . = ..() var/mob/living/carbon/xenomorph/xeno = owner xeno.do_evolve() diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm index 014cb3d2f24b..843cfeac540b 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm @@ -398,7 +398,7 @@ return if(X.layer == XENO_HIDING_LAYER) //Xeno is currently hiding, unhide him - var/datum/action/xeno_action/onclick/xenohide/hide = get_xeno_action_by_type(X, /datum/action/xeno_action/onclick/xenohide) + var/datum/action/xeno_action/onclick/xenohide/hide = get_action(X, /datum/action/xeno_action/onclick/xenohide) if(hide) hide.post_attack() @@ -911,7 +911,7 @@ to_chat(stabbing_xeno, SPAN_XENOWARNING("We must be above ground to do this.")) return - if(!stabbing_xeno.check_state()) + if(!stabbing_xeno.check_state() || stabbing_xeno.cannot_slash) return FALSE var/pre_result = pre_ability_act(stabbing_xeno, targetted_atom) diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/lurker/lurker_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/lurker/lurker_powers.dm index 094732300a1f..3c1d3a04543d 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/lurker/lurker_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/lurker/lurker_powers.dm @@ -13,7 +13,7 @@ break if(found) - var/datum/action/xeno_action/onclick/lurker_invisibility/lurker_invis = get_xeno_action_by_type(xeno, /datum/action/xeno_action/onclick/lurker_invisibility) + var/datum/action/xeno_action/onclick/lurker_invisibility/lurker_invis = get_action(xeno, /datum/action/xeno_action/onclick/lurker_invisibility) if(lurker_invis) lurker_invis.invisibility_off() // Full cooldown diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_abilities.dm b/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_abilities.dm index 199df345fb62..4fe0e9107995 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_abilities.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_abilities.dm @@ -87,7 +87,7 @@ if(!X.check_state(1)) return - var/datum/action/xeno_action/activable/cleave/cAction = get_xeno_action_by_type(X, /datum/action/xeno_action/activable/cleave) + var/datum/action/xeno_action/activable/cleave/cAction = get_action(X, /datum/action/xeno_action/activable/cleave) if (!istype(cAction)) return @@ -328,7 +328,7 @@ if(!X.check_state(1)) return - var/datum/action/xeno_action/activable/warden_heal/WH = get_xeno_action_by_type(X, /datum/action/xeno_action/activable/warden_heal) + var/datum/action/xeno_action/activable/warden_heal/WH = get_action(X, /datum/action/xeno_action/activable/warden_heal) if (!istype(WH)) return diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_powers.dm index 4d3a792af89a..3cbf0769514f 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_powers.dm @@ -418,8 +418,8 @@ shake_camera(target_carbon, 2, 1) - var/datum/action/xeno_action/activable/prae_abduct/abduct_action = get_xeno_action_by_type(oppressor_user, /datum/action/xeno_action/activable/prae_abduct) - var/datum/action/xeno_action/activable/tail_lash/tail_lash_action = get_xeno_action_by_type(oppressor_user, /datum/action/xeno_action/activable/tail_lash) + var/datum/action/xeno_action/activable/prae_abduct/abduct_action = get_action(oppressor_user, /datum/action/xeno_action/activable/prae_abduct) + var/datum/action/xeno_action/activable/tail_lash/tail_lash_action = get_action(oppressor_user, /datum/action/xeno_action/activable/tail_lash) if(abduct_action && !abduct_action.action_cooldown_check()) abduct_action.reduce_cooldown(5 SECONDS) if(tail_lash_action && !tail_lash_action.action_cooldown_check()) diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/predalien/predalien_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/predalien/predalien_powers.dm index 3ec4855f9c3a..a240c3928a3c 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/predalien/predalien_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/predalien/predalien_powers.dm @@ -117,7 +117,7 @@ xeno.anchored = FALSE unroot_human(carbon, TRAIT_SOURCE_ABILITY("Devastate")) - return ..() + return ..() /datum/action/xeno_action/onclick/feralrush/use_ability(atom/A) @@ -149,6 +149,7 @@ predatoralien.recalculate_armor() playsound(predatoralien, 'sound/voice/predalien_growl.ogg', 75, 0, status = 0) apply_cooldown() + return ..() /datum/action/xeno_action/onclick/feralrush/proc/remove_rush_effects() @@ -180,7 +181,7 @@ if(!xeno.check_state()) return - var/datum/action/xeno_action/activable/feralfrenzy/guttype = get_xeno_action_by_type(xeno, /datum/action/xeno_action/activable/feralfrenzy) + var/datum/action/xeno_action/activable/feralfrenzy/guttype = get_action(xeno, /datum/action/xeno_action/activable/feralfrenzy) if(!guttype) return @@ -248,7 +249,7 @@ else predalien_smash.visible_message(SPAN_XENOWARNING("[predalien_smash]'s claws twitch."), SPAN_XENOWARNING("We couldn't grab our target. Wait a moment to try again.")) - return TRUE + return ..() /mob/living/carbon/xenomorph/predalien/stop_pulling() if(isliving(pulling) && smashing) diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/queen/queen_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/queen/queen_powers.dm index 381acba92a51..6ef111aed66f 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/queen/queen_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/queen/queen_powers.dm @@ -401,6 +401,7 @@ remove_personal_ally() if("Clear Personal Allies") clear_personal_allies() + return ..() /datum/action/xeno_action/onclick/manage_hive/proc/add_personal_ally() var/mob/living/carbon/xenomorph/queen/user_xeno = owner diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/xeno_action.dm b/code/modules/mob/living/carbon/xenomorph/abilities/xeno_action.dm index 80cf5c1e37ac..bff59186fd04 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/xeno_action.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/xeno_action.dm @@ -51,6 +51,7 @@ // Any strain or caste-specific state should be stored on behavior_delegate objects // which use_ability invocations can modify using typechecks and typecasts where appropriate. /datum/action/xeno_action/proc/use_ability(atom/target) + SHOULD_CALL_PARENT(TRUE) if(!owner) return FALSE track_xeno_ability_stats() @@ -129,10 +130,17 @@ /// A wrapper for use_ability that sends a signal /datum/action/xeno_action/proc/use_ability_wrapper(...) // TODO: make hidden a part of can_use_action - if(!hidden && can_use_action() && use_ability(arglist(args))) + if(!can_use_action()) + SEND_SIGNAL(src, COMSIG_XENO_FAILED_ACTION_USED, owner) + return FALSE + + SEND_SIGNAL(src, COMSIG_XENO_PRE_ACTION_USED, owner) + + if(!hidden && use_ability(arglist(args))) SEND_SIGNAL(src, COMSIG_XENO_ACTION_USED, owner) return TRUE + SEND_SIGNAL(src, COMSIG_XENO_FAILED_ACTION_USED, owner) return FALSE // For actions that do something on each life tick @@ -150,6 +158,7 @@ // For non-activable Xeno actions, this is used to // actually DO the action. /datum/action/xeno_action/activable/action_activate() + . = ..() if(!owner) return if(hidden) @@ -201,6 +210,7 @@ no_cooldown_msg = TRUE /datum/action/xeno_action/onclick/action_activate() + . = ..() use_ability_wrapper(null) // Adds a cooldown to this @@ -362,17 +372,6 @@ deltimer(charge_timer_id) charge_timer_id = TIMER_ID_NULL -// Helper proc to get an action on a target Xeno by type. -// Used to interact with abilities from the outside -/proc/get_xeno_action_by_type(mob/living/carbon/xenomorph/X, typepath) - if (!istype(X)) - CRASH("xeno_action.dm: get_xeno_action_by_type invoked with non-xeno first argument.") - - for (var/datum/action/xeno_action/XA in X.actions) - if (istype(XA, typepath)) - return XA - return null - // Helper proc to check if there is anything blocking the way from mob M to the atom A // Max distance can be supplied to check some of the way instead of the whole way. /proc/check_clear_path_to_target(mob/M, atom/A, smash_windows = TRUE, max_distance = 1000) @@ -420,6 +419,7 @@ return FALSE /datum/action/xeno_action/active_toggle/action_activate() + . = ..() toggle_toggle() /datum/action/xeno_action/active_toggle/life_tick() diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Crusher.dm b/code/modules/mob/living/carbon/xenomorph/castes/Crusher.dm index 24ac22d6bc52..a84b9965f9c3 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Crusher.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Crusher.dm @@ -261,11 +261,11 @@ H.apply_armoured_damage(get_xeno_damage_slash(H, damage), ARMOR_MELEE, BRUTE, bound_xeno.zone_selected) - var/datum/action/xeno_action/activable/pounce/crusher_charge/cAction = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/activable/pounce/crusher_charge) + var/datum/action/xeno_action/activable/pounce/crusher_charge/cAction = get_action(bound_xeno, /datum/action/xeno_action/activable/pounce/crusher_charge) if (!cAction.action_cooldown_check()) cAction.reduce_cooldown(cdr_amount) - var/datum/action/xeno_action/onclick/crusher_shield/sAction = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/onclick/crusher_shield) + var/datum/action/xeno_action/onclick/crusher_shield/sAction = get_action(bound_xeno, /datum/action/xeno_action/onclick/crusher_shield) if (!sAction.action_cooldown_check()) sAction.reduce_cooldown(base_cdr_amount) diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Hellhound.dm b/code/modules/mob/living/carbon/xenomorph/castes/Hellhound.dm index 93d40820bf7b..7df87f63cf3a 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Hellhound.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Hellhound.dm @@ -136,6 +136,6 @@ /datum/behavior_delegate/hellhound_base/melee_attack_additional_effects_self() ..() - var/datum/action/xeno_action/onclick/xenohide/hide = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/onclick/xenohide) + var/datum/action/xeno_action/onclick/xenohide/hide = get_action(bound_xeno, /datum/action/xeno_action/onclick/xenohide) if(hide) hide.post_attack() diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Lurker.dm b/code/modules/mob/living/carbon/xenomorph/castes/Lurker.dm index 0ab9e9862b16..1dca7eb23f70 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Lurker.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Lurker.dm @@ -87,7 +87,7 @@ original_damage *= buffed_slash_damage_ratio target_carbon.set_effect(get_xeno_stun_duration(target_carbon, 3), SUPERSLOW) next_slash_buffed = FALSE - var/datum/action/xeno_action/onclick/lurker_assassinate/ability = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/onclick/lurker_assassinate) + var/datum/action/xeno_action/onclick/lurker_assassinate/ability = get_action(bound_xeno, /datum/action/xeno_action/onclick/lurker_assassinate) if (ability) ability.button.icon_state = "template" @@ -114,19 +114,19 @@ /datum/behavior_delegate/lurker_base/melee_attack_additional_effects_self() ..() - var/datum/action/xeno_action/onclick/lurker_invisibility/lurker_invis_action = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/onclick/lurker_invisibility) + var/datum/action/xeno_action/onclick/lurker_invisibility/lurker_invis_action = get_action(bound_xeno, /datum/action/xeno_action/onclick/lurker_invisibility) if (lurker_invis_action) lurker_invis_action.invisibility_off() // Full cooldown /datum/behavior_delegate/lurker_base/proc/decloak_handler(mob/source) SIGNAL_HANDLER - var/datum/action/xeno_action/onclick/lurker_invisibility/lurker_invis_action = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/onclick/lurker_invisibility) + var/datum/action/xeno_action/onclick/lurker_invisibility/lurker_invis_action = get_action(bound_xeno, /datum/action/xeno_action/onclick/lurker_invisibility) if(istype(lurker_invis_action)) lurker_invis_action.invisibility_off(0.5) // Partial refund of remaining time /// Implementation for enabling invisibility. /datum/behavior_delegate/lurker_base/proc/on_invisibility() - var/datum/action/xeno_action/activable/pounce/lurker/lurker_pounce_action = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/activable/pounce/lurker) + var/datum/action/xeno_action/activable/pounce/lurker/lurker_pounce_action = get_action(bound_xeno, /datum/action/xeno_action/activable/pounce/lurker) if(lurker_pounce_action) lurker_pounce_action.knockdown = TRUE // pounce knocks down lurker_pounce_action.freeze_self = TRUE @@ -137,7 +137,7 @@ /// Implementation for disabling invisibility. /datum/behavior_delegate/lurker_base/proc/on_invisibility_off() - var/datum/action/xeno_action/activable/pounce/lurker/lurker_pounce_action = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/activable/pounce/lurker) + var/datum/action/xeno_action/activable/pounce/lurker/lurker_pounce_action = get_action(bound_xeno, /datum/action/xeno_action/activable/pounce/lurker) if(lurker_pounce_action) lurker_pounce_action.knockdown = FALSE // pounce no longer knocks down lurker_pounce_action.freeze_self = FALSE @@ -155,7 +155,7 @@ . += "Invisibility Remaining: [time_left] second\s." return - var/datum/action/xeno_action/onclick/lurker_invisibility/lurker_invisibility_action = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/onclick/lurker_invisibility) + var/datum/action/xeno_action/onclick/lurker_invisibility/lurker_invisibility_action = get_action(bound_xeno, /datum/action/xeno_action/onclick/lurker_invisibility) if(!lurker_invisibility_action) return @@ -177,7 +177,7 @@ if(!bound_xeno || !bound_xeno.stealth) return - var/datum/action/xeno_action/onclick/lurker_invisibility/lurker_invisibility_action = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/onclick/lurker_invisibility) + var/datum/action/xeno_action/onclick/lurker_invisibility/lurker_invisibility_action = get_action(bound_xeno, /datum/action/xeno_action/onclick/lurker_invisibility) if(!lurker_invisibility_action) return diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Predalien.dm b/code/modules/mob/living/carbon/xenomorph/castes/Predalien.dm index 830f4fc5a9cf..b60f150c442d 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Predalien.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Predalien.dm @@ -69,16 +69,19 @@ weed_food_states = list("Predalien_1","Predalien_2","Predalien_3") weed_food_states_flipped = list("Predalien_1","Predalien_2","Predalien_3") var/smashing = FALSE + /// If the pred alert/player notif should happen when the predalien spawns + var/should_announce_spawn = TRUE /mob/living/carbon/xenomorph/predalien/Initialize(mapload, mob/living/carbon/xenomorph/oldxeno, h_number) . = ..() - addtimer(CALLBACK(src, PROC_REF(announce_spawn)), 3 SECONDS) - hunter_data.dishonored = TRUE - hunter_data.dishonored_reason = "An abomination upon the honor of us all!" - hunter_data.dishonored_set = src - hud_set_hunter() + if(should_announce_spawn) + addtimer(CALLBACK(src, PROC_REF(announce_spawn)), 3 SECONDS) + hunter_data.dishonored = TRUE + hunter_data.dishonored_reason = "An abomination upon the honor of us all!" + hunter_data.dishonored_set = src + hud_set_hunter() AddComponent(/datum/component/footstep, 4, 25, 11, 2, "alien_footstep_medium") @@ -102,8 +105,20 @@ You must still listen to the queen. /mob/living/carbon/xenomorph/predalien/resist_fire() - ..() - SetKnockDown(0.1 SECONDS) + ..() + SetKnockDown(0.1 SECONDS) + +/mob/living/carbon/xenomorph/predalien/get_examine_text(mob/user) + . = ..() + var/datum/behavior_delegate/predalien_base/predalienkills = behavior_delegate + . += "It has [predalienkills.kills] kills to its name!" + +/mob/living/carbon/xenomorph/predalien/tutorial + should_announce_spawn = FALSE + +/mob/living/carbon/xenomorph/predalien/tutorial/gib(datum/cause_data/cause = create_cause_data("gibbing", src)) + death(cause, gibbed = TRUE) + /datum/behavior_delegate/predalien_base name = "Base Predalien Behavior Delegate" @@ -127,12 +142,3 @@ You must still listen to the queen. original_damage *= 1.5 return original_damage + kills * 2.5 - -/mob/living/carbon/xenomorph/predalien/get_examine_text(mob/user) - . = ..() - var/datum/behavior_delegate/predalien_base/predalienkills = behavior_delegate - var/kills = predalienkills.kills - . += "It has [kills] kills to its name!" - - - diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Ravager.dm b/code/modules/mob/living/carbon/xenomorph/castes/Ravager.dm index 6e5da79fbed1..90614e338071 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Ravager.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Ravager.dm @@ -90,7 +90,7 @@ /datum/behavior_delegate/ravager_base/melee_attack_additional_effects_self() ..() - var/datum/action/xeno_action/activable/pounce/charge/cAction = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/activable/pounce/charge) + var/datum/action/xeno_action/activable/pounce/charge/cAction = get_action(bound_xeno, /datum/action/xeno_action/activable/pounce/charge) if (!cAction.action_cooldown_check()) cAction.reduce_cooldown(slash_charge_cdr) diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Runner.dm b/code/modules/mob/living/carbon/xenomorph/castes/Runner.dm index 8721294173e9..12fdb8d02843 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Runner.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Runner.dm @@ -91,6 +91,6 @@ /datum/behavior_delegate/runner_base/melee_attack_additional_effects_self() ..() - var/datum/action/xeno_action/onclick/xenohide/hide = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/onclick/xenohide) + var/datum/action/xeno_action/onclick/xenohide/hide = get_action(bound_xeno, /datum/action/xeno_action/onclick/xenohide) if(hide) hide.post_attack() diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Sentinel.dm b/code/modules/mob/living/carbon/xenomorph/castes/Sentinel.dm index 01963496f967..3e7416f39fc5 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Sentinel.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Sentinel.dm @@ -95,7 +95,7 @@ addtimer(CALLBACK(src, PROC_REF(paralyzing_slash), carbon_target), NEURO_TOUCH_DELAY) next_slash_buffed = FALSE if(!next_slash_buffed) - var/datum/action/xeno_action/onclick/paralyzing_slash/ability = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/onclick/paralyzing_slash) + var/datum/action/xeno_action/onclick/paralyzing_slash/ability = get_action(bound_xeno, /datum/action/xeno_action/onclick/paralyzing_slash) if (ability && istype(ability)) ability.button.icon_state = "template" return original_damage diff --git a/code/modules/mob/living/carbon/xenomorph/hive_status_ui.dm b/code/modules/mob/living/carbon/xenomorph/hive_status_ui.dm index 360b4e8bbdde..eca88761ad9b 100644 --- a/code/modules/mob/living/carbon/xenomorph/hive_status_ui.dm +++ b/code/modules/mob/living/carbon/xenomorph/hive_status_ui.dm @@ -201,7 +201,7 @@ if(xenoSrc.stat == DEAD) return - var/datum/action/xeno_action/A = get_xeno_action_by_type(xenoSrc, /datum/action/xeno_action/activable/queen_give_plasma) + var/datum/action/xeno_action/A = get_action(xenoSrc, /datum/action/xeno_action/activable/queen_give_plasma) A?.use_ability_wrapper(xenoTarget) if("heal") @@ -214,7 +214,7 @@ if(xenoSrc.stat == DEAD) return - var/datum/action/xeno_action/A = get_xeno_action_by_type(xenoSrc, /datum/action/xeno_action/activable/queen_heal) + var/datum/action/xeno_action/A = get_action(xenoSrc, /datum/action/xeno_action/activable/queen_heal) A?.use_ability_wrapper(xenoTarget, TRUE) if("overwatch") diff --git a/code/modules/mob/living/carbon/xenomorph/strains/castes/boiler/trapper.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/boiler/trapper.dm index f64bfd6b500f..857a76969354 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/castes/boiler/trapper.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/castes/boiler/trapper.dm @@ -73,7 +73,7 @@ found = trap break - var/datum/action/xeno_action/activable/boiler_trap/trap_ability = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/activable/boiler_trap) + var/datum/action/xeno_action/activable/boiler_trap/trap_ability = get_action(bound_xeno, /datum/action/xeno_action/activable/boiler_trap) if (found) target_human.apply_armoured_damage(bonus_damage_shotgun_trapped, ARMOR_BIO, BURN) trap_ability.empowering_charge_counter = trap_ability.empower_charge_max diff --git a/code/modules/mob/living/carbon/xenomorph/strains/castes/drone/healer.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/drone/healer.dm index 5ebafc88eaef..7ceaf2fed75e 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/castes/drone/healer.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/castes/drone/healer.dm @@ -276,9 +276,10 @@ addtimer(CALLBACK(xeno.hive, TYPE_PROC_REF(/datum/hive_status, free_respawn), xeno.client), 5 SECONDS) xeno.gib(create_cause_data("sacrificing itself", src)) + return ..() /datum/action/xeno_action/activable/healer_sacrifice/action_activate() - ..() + . = ..() var/mob/living/carbon/xenomorph/xeno = owner if(xeno.selected_ability != src) return diff --git a/code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/vanguard.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/vanguard.dm index 310db35ab370..01f567398c44 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/vanguard.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/vanguard.dm @@ -54,7 +54,7 @@ last_combat_time = world.time /datum/behavior_delegate/praetorian_vanguard/proc/next_pierce_spin() - var/datum/action/xeno_action/activable/pierce/pAction = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/activable/pierce) + var/datum/action/xeno_action/activable/pierce/pAction = get_action(bound_xeno, /datum/action/xeno_action/activable/pierce) if (istype(pAction)) pAction.should_spin_instead = TRUE @@ -62,7 +62,7 @@ return /datum/behavior_delegate/praetorian_vanguard/proc/next_pierce_normal() - var/datum/action/xeno_action/activable/pierce/pAction = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/activable/pierce) + var/datum/action/xeno_action/activable/pierce/pAction = get_action(bound_xeno, /datum/action/xeno_action/activable/pierce) if (istype(pAction)) pAction.should_spin_instead = FALSE return @@ -88,6 +88,6 @@ new_shield.explosive_armor_amount = 1.5*XENO_EXPOSIVEARMOR_MOD_VERY_LARGE to_chat(praetorian, SPAN_XENOHIGHDANGER("We feel our defensive shell regenerate! It will block one hit!")) - var/datum/action/xeno_action/activable/cleave/caction = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/activable/cleave) + var/datum/action/xeno_action/activable/cleave/caction = get_action(bound_xeno, /datum/action/xeno_action/activable/cleave) if (istype(caction)) caction.buffed = TRUE diff --git a/code/modules/projectiles/gun_attachables.dm b/code/modules/projectiles/gun_attachables.dm index 7d015e4bac8d..e2108364e9ac 100644 --- a/code/modules/projectiles/gun_attachables.dm +++ b/code/modules/projectiles/gun_attachables.dm @@ -1054,6 +1054,7 @@ Defined in conflicts.dm of the #defines folder. button.name = name /datum/action/item_action/toggle_zoom_level/action_activate() + . = ..() var/obj/item/weapon/gun/G = holder_item var/obj/item/attachable/scope/variable_zoom/S = G.attachments["rail"] S.toggle_zoom_level() @@ -1674,6 +1675,7 @@ Defined in conflicts.dm of the #defines folder. /datum/action/item_action/vulture /datum/action/item_action/vulture/action_activate() + . = ..() var/obj/item/weapon/gun/gun_holder = holder_item var/obj/item/attachable/vulture_scope/scope = gun_holder.attachments["rail"] if(!istype(scope)) @@ -3515,6 +3517,7 @@ Defined in conflicts.dm of the #defines folder. button.overlays += image('icons/mob/hud/actions.dmi', button, action_icon_state) /datum/action/item_action/bipod/toggle_full_auto_switch/action_activate() + . = ..() var/obj/item/weapon/gun/holder_gun = holder_item var/obj/item/attachable/bipod/attached_bipod = holder_gun.attachments["under"] diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index b2ec3dea63ce..717914e38eba 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -268,6 +268,7 @@ /datum/action/item_action/taser/action_activate() + . = ..() var/obj/item/weapon/gun/energy/taser/taser = holder_item if(!ishuman(owner)) return diff --git a/code/modules/projectiles/guns/rifles.dm b/code/modules/projectiles/guns/rifles.dm index ad85220400fb..fbe24434d542 100644 --- a/code/modules/projectiles/guns/rifles.dm +++ b/code/modules/projectiles/guns/rifles.dm @@ -557,6 +557,7 @@ //---ability actions--\\ /datum/action/item_action/m46c/action_activate() + . = ..() var/obj/item/weapon/gun/rifle/m46c/protag_gun = holder_item if(!ishuman(owner)) return diff --git a/code/modules/projectiles/guns/shotguns.dm b/code/modules/projectiles/guns/shotguns.dm index b1b3bb3c2ab4..a0bb3f8f852c 100644 --- a/code/modules/projectiles/guns/shotguns.dm +++ b/code/modules/projectiles/guns/shotguns.dm @@ -838,6 +838,7 @@ can cause issues with ammo types getting mixed up during the burst. return TRUE /datum/action/item_action/specialist/twobore_brace/action_activate() + . = ..() var/obj/item/weapon/gun/shotgun/double/twobore/G = holder_item if(G.braced) return diff --git a/code/modules/projectiles/guns/smartgun.dm b/code/modules/projectiles/guns/smartgun.dm index e5c9fff3a126..7c628463b1ef 100644 --- a/code/modules/projectiles/guns/smartgun.dm +++ b/code/modules/projectiles/guns/smartgun.dm @@ -178,6 +178,7 @@ //---ability actions--\\ /datum/action/item_action/smartgun/action_activate() + . = ..() var/obj/item/weapon/gun/smartgun/G = holder_item if(!ishuman(owner)) return @@ -595,6 +596,7 @@ // ID lock action \\ /datum/action/item_action/co_sg/action_activate() + . = ..() var/obj/item/weapon/gun/smartgun/co/protag_gun = holder_item if(!ishuman(owner)) return diff --git a/code/modules/projectiles/guns/specialist/launcher/grenade_launcher.dm b/code/modules/projectiles/guns/specialist/launcher/grenade_launcher.dm index e2643c580a16..06ac5428bfc6 100644 --- a/code/modules/projectiles/guns/specialist/launcher/grenade_launcher.dm +++ b/code/modules/projectiles/guns/specialist/launcher/grenade_launcher.dm @@ -222,6 +222,7 @@ update_icon() /datum/action/item_action/toggle_firing_level/action_activate() + . = ..() var/obj/item/weapon/gun/launcher/grenade/G = holder_item if(!ishuman(owner)) return diff --git a/code/modules/projectiles/guns/specialist/sniper.dm b/code/modules/projectiles/guns/specialist/sniper.dm index b40477a8a460..b400350e415b 100644 --- a/code/modules/projectiles/guns/specialist/sniper.dm +++ b/code/modules/projectiles/guns/specialist/sniper.dm @@ -62,6 +62,7 @@ ACTIONS SPECIALSIT SNIPER CAN TAKE */ /datum/action/item_action/specialist/aimed_shot/action_activate() + . = ..() if(!ishuman(owner)) return var/mob/living/carbon/human/H = owner @@ -276,6 +277,7 @@ return TRUE /datum/action/item_action/specialist/toggle_laser/action_activate() + . = ..() var/obj/item/weapon/gun/rifle/sniper/sniper_rifle = holder_item if(owner.get_held_item() != sniper_rifle) diff --git a/code/modules/shuttle/computers/dropship_computer.dm b/code/modules/shuttle/computers/dropship_computer.dm index 08a35b83071d..a28f65ce475d 100644 --- a/code/modules/shuttle/computers/dropship_computer.dm +++ b/code/modules/shuttle/computers/dropship_computer.dm @@ -314,7 +314,7 @@ var/original_evilution = hive.evolution_bonus hive.override_evilution(XENO_HIJACK_EVILUTION_BUFF, TRUE) if(hive.living_xeno_queen) - var/datum/action/xeno_action/onclick/grow_ovipositor/ovi_ability = get_xeno_action_by_type(hive.living_xeno_queen, /datum/action/xeno_action/onclick/grow_ovipositor) + var/datum/action/xeno_action/onclick/grow_ovipositor/ovi_ability = get_action(hive.living_xeno_queen, /datum/action/xeno_action/onclick/grow_ovipositor) ovi_ability.reduce_cooldown(ovi_ability.xeno_cooldown) addtimer(CALLBACK(hive, TYPE_PROC_REF(/datum/hive_status, override_evilution), original_evilution, FALSE), XENO_HIJACK_EVILUTION_TIME) diff --git a/code/modules/surgery/surgery_toggle.dm b/code/modules/surgery/surgery_toggle.dm index b9ca3ca93311..973d1c5b682f 100644 --- a/code/modules/surgery/surgery_toggle.dm +++ b/code/modules/surgery/surgery_toggle.dm @@ -18,6 +18,7 @@ // Called when the action is clicked on. /datum/action/surgery_toggle/action_activate() + . = ..() if(owner.mob_flags & SURGERY_MODE_ON) button.icon_state = "template" owner.mob_flags &= ~SURGERY_MODE_ON diff --git a/colonialmarines.dme b/colonialmarines.dme index b479f0af62c5..254cbb0112ca 100644 --- a/colonialmarines.dme +++ b/colonialmarines.dme @@ -698,6 +698,7 @@ #include "code\datums\tutorial\ss13\basic_ss13.dm" #include "code\datums\tutorial\ss13\intents.dm" #include "code\datums\tutorial\xenomorph\_xenomorph.dm" +#include "code\datums\tutorial\xenomorph\abomination.dm" #include "code\datums\tutorial\xenomorph\xenomorph_basic.dm" #include "code\datums\weather\weather_event.dm" #include "code\datums\weather\weather_map_holder.dm" diff --git a/tgui/packages/tgui/interfaces/TutorialMenu.tsx b/tgui/packages/tgui/interfaces/TutorialMenu.tsx index 14abfa957b1c..c47db9fd746d 100644 --- a/tgui/packages/tgui/interfaces/TutorialMenu.tsx +++ b/tgui/packages/tgui/interfaces/TutorialMenu.tsx @@ -60,25 +60,30 @@ export const TutorialMenu = (props) => { {tutorial_categories.map( (tutorial_category) => tutorial_category.name === categoryIndex && - tutorial_category.tutorials.map((tutorial) => ( -
- -
- )), + + + )), )}