feat: adds search to changeling evolution menu (#22936)

* refactor: make changeling ability categories more flexible, adjust serach for categories

* refactor: adjust to codestyle

* fix: fix compilation error
This commit is contained in:
Gaxeer
2023-12-10 19:32:31 +02:00
committed by GitHub
parent 1927a4c76e
commit e39d7c5464
25 changed files with 184 additions and 83 deletions
@@ -13,6 +13,8 @@
background_icon_state = "bg_changeling"
/// A reference to the changeling's changeling antag datum.
var/datum/antagonist/changeling/cling
/// Datum path used to determine the location and name of the power in changeling evolution menu UI
var/datum/changeling_power_category/category
/// Determines whether the power is always given to the changeling or if it must be purchased.
var/power_type = CHANGELING_UNOBTAINABLE_POWER
/// A description of what the power does.
@@ -31,8 +33,6 @@
var/active = FALSE
/// If this power can be used while the changeling has the `TRAIT_FAKE_DEATH` trait.
var/bypass_fake_death = FALSE
/// Where this ability should be stored in the changeling menu
var/menu_location
/*
* Changeling code relies on on_purchase to grant powers.
@@ -0,0 +1,21 @@
/datum/changeling_power_category
/// The name of the category
var/name = "common"
/// The number used to determine category position in changeling evolution menu UI
var/priority = 0
/datum/changeling_power_category/offence
name = "Offence"
priority = 1
/datum/changeling_power_category/defence
name = "Defence"
priority = 2
/datum/changeling_power_category/utility
name = "Utility"
priority = 3
/datum/changeling_power_category/stings
name = "Stings"
priority = 4
@@ -3,11 +3,6 @@
/// The evolution menu will be shown in the expanded mode, with powers, costs, and power descriptions being displayed.
#define EXPANDED_MODE 1
#define CLING_MENU_ATTACK 1
#define CLING_MENU_DEFENSE 2
#define CLING_MENU_UTILITY 3
#define CLING_MENU_STINGS 4
/datum/action/changeling/evolution_menu
name = "Evolution Menu"
desc = "Choose our method of subjugation."
@@ -17,29 +12,8 @@
var/view_mode = EXPANDED_MODE
/// A list containing the typepaths of bought changeling abilities. For use with the UI.
var/list/purchased_abilities = list()
/// A list containing every purchasable changeling power. Includes its name, description, helptext and cost.
var/static/list/ability_list = list()
/datum/action/changeling/evolution_menu/Grant(mob/M)
..()
if(length(ability_list))
return // List is already populated.
// This is a list of lists, each lower-level list corresponding to one of the CLING_MENU section
ability_list = list(list(), list(), list(), list())
for(var/power_path in cling.purchaseable_powers)
var/datum/action/changeling/C = power_path
if(!C.menu_location)
stack_trace("Cling power [C], [C.type] had no corresponding menu location!")
continue
ability_list[C.menu_location] += list(list(
"name" = initial(C.name),
"description" = initial(C.desc),
"helptext" = initial(C.helptext),
"cost" = initial(C.dna_cost),
"power_path" = power_path
))
/// A list containing lists of category and abilities, related to this category. For each ability includes its name, description, helptext and cost. For use with the UI.
var/static/list/ability_tabs = list()
/datum/action/changeling/evolution_menu/try_to_sting(mob/user, mob/target)
ui_interact(user)
@@ -62,7 +36,7 @@
/datum/action/changeling/evolution_menu/ui_static_data(mob/user)
var/list/data = list(
"ability_list" = ability_list
"ability_tabs" = get_ability_tabs()
)
return data
@@ -92,6 +66,8 @@
return TRUE
/datum/action/changeling/evolution_menu/proc/try_purchase_power(power_type)
PRIVATE_PROC(TRUE)
if(!(power_type in cling.purchaseable_powers))
return FALSE
if(power_type in purchased_abilities)
@@ -110,3 +86,55 @@
cling.give_power(new power_type)
return TRUE
/datum/action/changeling/evolution_menu/proc/get_ability_tabs()
PRIVATE_PROC(TRUE)
if(!length(ability_tabs))
ability_tabs = build_ability_tabs()
return ability_tabs
/datum/action/changeling/evolution_menu/proc/build_ability_tabs()
PRIVATE_PROC(TRUE)
var/list/abilities_by_category_name = get_abilities_grouped_by_category_name()
if(!length(abilities_by_category_name))
return list()
var/list/sorted_ability_categories = sortTim(subtypesof(/datum/changeling_power_category), GLOBAL_PROC_REF(cmp_changeling_power_category_asc))
var/list/sorted_ability_tabs = list()
for(var/datum/changeling_power_category/category as anything in sorted_ability_categories)
var/list/abilities = abilities_by_category_name[initial(category.name)]
sorted_ability_tabs += list(list(
"category" = initial(category.name),
"abilities" = abilities))
return sorted_ability_tabs
/datum/action/changeling/evolution_menu/proc/get_abilities_grouped_by_category_name()
PRIVATE_PROC(TRUE)
var/list/abilities_by_category_name = list()
for(var/power_path in cling.purchaseable_powers)
var/datum/action/changeling/changeling_ability = power_path
if(!changeling_ability.category)
stack_trace("Cling power [changeling_ability], [changeling_ability.type] had no assigned category!")
continue
var/category_name = initial(changeling_ability.category.name)
var/list/abilities = abilities_by_category_name[category_name]
if(!islist(abilities))
abilities_by_category_name[category_name] = abilities = list()
abilities += list(list(
"name" = initial(changeling_ability.name),
"description" = initial(changeling_ability.desc),
"helptext" = initial(changeling_ability.helptext),
"cost" = initial(changeling_ability.dna_cost),
"power_path" = power_path
))
return abilities_by_category_name
@@ -7,7 +7,7 @@
dna_cost = 4
active = FALSE
power_type = CHANGELING_PURCHASABLE_POWER
menu_location = CLING_MENU_UTILITY
category = /datum/changeling_power_category/utility
/datum/action/changeling/augmented_eyesight/on_purchase(mob/user, /datum/antagonist/changeling/C) //The ability starts inactive, so we should be protected from flashes.
if(!..())
@@ -9,7 +9,7 @@
req_stat = DEAD
bypass_fake_death = TRUE
power_type = CHANGELING_PURCHASABLE_POWER
menu_location = CLING_MENU_DEFENSE
category = /datum/changeling_power_category/defence
/datum/action/changeling/headslug/try_to_sting(mob/user, mob/target)
if(alert("Are you sure you wish to do this? This action cannot be undone.",,"Yes","No") == "No")
@@ -7,7 +7,7 @@
dna_cost = 4
req_human = TRUE
power_type = CHANGELING_PURCHASABLE_POWER
menu_location = CLING_MENU_DEFENSE
category = /datum/changeling_power_category/defence
/// Type of acid hand we give to person
var/hand = /obj/item/melee/changeling_corrosive_acid
/// Current hand given to human, null is we did not give hand, object if hand is given
@@ -7,7 +7,7 @@
chemical_cost = 25
req_human = TRUE
power_type = CHANGELING_PURCHASABLE_POWER
menu_location = CLING_MENU_UTILITY
category = /datum/changeling_power_category/utility
/datum/action/changeling/chameleon_skin/sting_action(mob/user)
var/mob/living/carbon/human/H = user //SHOULD always be human, because req_human = TRUE
@@ -5,7 +5,7 @@
chemical_cost = 25
dna_cost = 4
power_type = CHANGELING_PURCHASABLE_POWER
menu_location = CLING_MENU_UTILITY
category = /datum/changeling_power_category/utility
/datum/action/changeling/contort_body/Remove(mob/M)
REMOVE_TRAIT(M, TRAIT_CONTORTED_BODY, CHANGELING_TRAIT)
@@ -5,7 +5,7 @@
button_icon_state = "digital_camo"
dna_cost = 2
power_type = CHANGELING_PURCHASABLE_POWER
menu_location = CLING_MENU_UTILITY
category = /datum/changeling_power_category/utility
/datum/action/changeling/digitalcamo/Remove(mob/M)
REMOVE_TRAIT(M, TRAIT_AI_UNTRACKABLE, CHANGELING_TRAIT)
@@ -8,7 +8,7 @@
req_human = TRUE
req_stat = UNCONSCIOUS
power_type = CHANGELING_PURCHASABLE_POWER
menu_location = CLING_MENU_DEFENSE
category = /datum/changeling_power_category/defence
//Recover from stuns.
/datum/action/changeling/epinephrine/sting_action(mob/living/user)
@@ -7,7 +7,7 @@
dna_cost = 4
req_stat = UNCONSCIOUS
power_type = CHANGELING_PURCHASABLE_POWER
menu_location = CLING_MENU_DEFENSE
category = /datum/changeling_power_category/defence
//Starts healing you every second for 10 seconds. Can be used whilst unconscious.
/datum/action/changeling/fleshmend/sting_action(mob/living/user)
@@ -9,7 +9,7 @@ GLOBAL_LIST_EMPTY(hivemind_bank)
chemical_cost = 10
dna_cost = 4
power_type = CHANGELING_PURCHASABLE_POWER
menu_location = CLING_MENU_UTILITY
category = /datum/changeling_power_category/utility
/datum/action/changeling/hivemind_pick/on_purchase(mob/user, datum/antagonist/changeling/C)
if(!..())
@@ -7,7 +7,7 @@
dna_cost = 2
req_human = TRUE
power_type = CHANGELING_PURCHASABLE_POWER
menu_location = CLING_MENU_UTILITY
category = /datum/changeling_power_category/utility
//Transform into a monkey.
/datum/action/changeling/lesserform/sting_action(mob/living/carbon/human/user)
@@ -7,7 +7,7 @@
dna_cost = 2
req_human = TRUE
power_type = CHANGELING_PURCHASABLE_POWER
menu_location = CLING_MENU_UTILITY
category = /datum/changeling_power_category/utility
// Fake Voice
@@ -128,8 +128,8 @@
weapon_type = /obj/item/melee/arm_blade
weapon_name_simple = "blade"
power_type = CHANGELING_PURCHASABLE_POWER
menu_location = CLING_MENU_ATTACK
recharge_slowdown = 0.75
category = /datum/changeling_power_category/offence
/obj/item/melee/arm_blade
name = "arm blade"
@@ -194,7 +194,7 @@
weapon_name_simple = "tentacle"
silent = TRUE
power_type = CHANGELING_PURCHASABLE_POWER
menu_location = CLING_MENU_ATTACK
category = /datum/changeling_power_category/offence
/obj/item/gun/magic/tentacle
name = "tentacle"
@@ -398,7 +398,7 @@
weapon_type = /obj/item/shield/changeling
weapon_name_simple = "shield"
power_type = CHANGELING_PURCHASABLE_POWER
menu_location = CLING_MENU_DEFENSE
category = /datum/changeling_power_category/defence
/datum/action/changeling/weapon/shield/sting_action(mob/user)
var/obj/item/shield/changeling/S = ..(user)
@@ -453,7 +453,7 @@
helmet_name_simple = "space helmet"
recharge_slowdown = 0.5
blood_on_castoff = 1
menu_location = CLING_MENU_UTILITY
category = /datum/changeling_power_category/utility
/obj/item/clothing/suit/space/changeling
name = "flesh mass"
@@ -499,7 +499,7 @@
suit_name_simple = "armor"
helmet_name_simple = "helmet"
recharge_slowdown = 0.25
menu_location = CLING_MENU_DEFENSE
category = /datum/changeling_power_category/defence
/obj/item/clothing/suit/armor/changeling
name = "chitinous mass"
@@ -7,7 +7,7 @@
dna_cost = 2
req_stat = UNCONSCIOUS
power_type = CHANGELING_PURCHASABLE_POWER
menu_location = CLING_MENU_DEFENSE
category = /datum/changeling_power_category/defence
//Heals the things that the other regenerative abilities don't.
/datum/action/changeling/panacea/sting_action(mob/living/user)
@@ -7,7 +7,7 @@
dna_cost = 2
req_human = TRUE
power_type = CHANGELING_PURCHASABLE_POWER
menu_location = CLING_MENU_ATTACK
category = /datum/changeling_power_category/offence
//A flashy ability, good for crowd control and sowing chaos.
/datum/action/changeling/resonant_shriek/sting_action(mob/user)
@@ -44,7 +44,7 @@
chemical_cost = 30
dna_cost = 2
power_type = CHANGELING_PURCHASABLE_POWER
menu_location = CLING_MENU_UTILITY
category = /datum/changeling_power_category/utility
//A flashy ability, good for crowd control and sewing chaos.
/datum/action/changeling/dissonant_shriek/sting_action(mob/user)
@@ -10,7 +10,7 @@
dna_cost = 2
req_human = TRUE
power_type = CHANGELING_PURCHASABLE_POWER
menu_location = CLING_MENU_DEFENSE
category = /datum/changeling_power_category/defence
/datum/action/changeling/strained_muscles/Remove(mob/living/L)
L.remove_status_effect(STATUS_EFFECT_SPEEDLEGS)
@@ -16,7 +16,7 @@
/// Checks if changeling is already spawning a spider
var/is_operating = FALSE
power_type = CHANGELING_PURCHASABLE_POWER
menu_location = CLING_MENU_UTILITY
category = /datum/changeling_power_category/utility
/// Makes a spider. Good for setting traps and combat.
/datum/action/changeling/spiders/sting_action(mob/user)
@@ -7,7 +7,7 @@
dna_cost = 2
req_human = TRUE //Monkeys can't grab
power_type = CHANGELING_PURCHASABLE_POWER
menu_location = CLING_MENU_ATTACK
category = /datum/changeling_power_category/offence
/datum/action/changeling/swap_form/can_sting(mob/living/carbon/user)
if(!..())
@@ -2,7 +2,7 @@
name = "Tiny Prick"
desc = "Stabby stabby"
power_type = CHANGELING_UNOBTAINABLE_POWER
menu_location = CLING_MENU_STINGS
category = /datum/changeling_power_category/stings
var/sting_icon = null
/// A middle click override used to intercept changeling stings performed on a target.
var/datum/middleClickOverride/callback_invoker/click_override