mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-22 19:47:22 +01:00
Adds tabs to the cling menu (#22902)
* cling menu * Update code/modules/antagonists/changeling/changeling_power.dm Co-authored-by: Henri215 <77684085+Henri215@users.noreply.github.com> * comment added --------- Co-authored-by: Henri215 <77684085+Henri215@users.noreply.github.com>
This commit is contained in:
@@ -31,6 +31,8 @@
|
||||
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.
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
/// 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."
|
||||
@@ -20,9 +25,15 @@
|
||||
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
|
||||
ability_list += list(list(
|
||||
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),
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
dna_cost = 4
|
||||
active = FALSE
|
||||
power_type = CHANGELING_PURCHASABLE_POWER
|
||||
menu_location = CLING_MENU_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(!..())
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
dna_cost = 2
|
||||
req_human = TRUE
|
||||
power_type = CHANGELING_PURCHASABLE_POWER
|
||||
menu_location = CLING_MENU_DEFENSE
|
||||
|
||||
/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,6 +7,7 @@
|
||||
dna_cost = 4
|
||||
req_human = TRUE
|
||||
power_type = CHANGELING_PURCHASABLE_POWER
|
||||
menu_location = CLING_MENU_DEFENSE
|
||||
/// 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,6 +7,7 @@
|
||||
chemical_cost = 25
|
||||
req_human = TRUE
|
||||
power_type = CHANGELING_PURCHASABLE_POWER
|
||||
menu_location = CLING_MENU_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,6 +5,7 @@
|
||||
chemical_cost = 25
|
||||
dna_cost = 4
|
||||
power_type = CHANGELING_PURCHASABLE_POWER
|
||||
menu_location = CLING_MENU_UTILITY
|
||||
|
||||
/datum/action/changeling/contort_body/Remove(mob/M)
|
||||
REMOVE_TRAIT(M, TRAIT_CONTORTED_BODY, CHANGELING_TRAIT)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
button_icon_state = "digital_camo"
|
||||
dna_cost = 2
|
||||
power_type = CHANGELING_PURCHASABLE_POWER
|
||||
menu_location = CLING_MENU_UTILITY
|
||||
|
||||
/datum/action/changeling/digitalcamo/Remove(mob/M)
|
||||
REMOVE_TRAIT(M, TRAIT_AI_UNTRACKABLE, CHANGELING_TRAIT)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
req_human = TRUE
|
||||
req_stat = UNCONSCIOUS
|
||||
power_type = CHANGELING_PURCHASABLE_POWER
|
||||
menu_location = CLING_MENU_DEFENSE
|
||||
|
||||
//Recover from stuns.
|
||||
/datum/action/changeling/epinephrine/sting_action(mob/living/user)
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
dna_cost = 4
|
||||
req_stat = UNCONSCIOUS
|
||||
power_type = CHANGELING_PURCHASABLE_POWER
|
||||
menu_location = CLING_MENU_DEFENSE
|
||||
|
||||
//Starts healing you every second for 10 seconds. Can be used whilst unconscious.
|
||||
/datum/action/changeling/fleshmend/sting_action(mob/living/user)
|
||||
|
||||
@@ -9,6 +9,7 @@ GLOBAL_LIST_EMPTY(hivemind_bank)
|
||||
chemical_cost = 10
|
||||
dna_cost = 4
|
||||
power_type = CHANGELING_PURCHASABLE_POWER
|
||||
menu_location = CLING_MENU_UTILITY
|
||||
|
||||
/datum/action/changeling/hivemind_pick/on_purchase(mob/user, datum/antagonist/changeling/C)
|
||||
if(!..())
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
dna_cost = 2
|
||||
req_human = TRUE
|
||||
power_type = CHANGELING_PURCHASABLE_POWER
|
||||
menu_location = CLING_MENU_UTILITY
|
||||
|
||||
//Transform into a monkey.
|
||||
/datum/action/changeling/lesserform/sting_action(mob/living/carbon/human/user)
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
dna_cost = 2
|
||||
req_human = TRUE
|
||||
power_type = CHANGELING_PURCHASABLE_POWER
|
||||
menu_location = CLING_MENU_UTILITY
|
||||
|
||||
|
||||
// Fake Voice
|
||||
|
||||
@@ -121,6 +121,7 @@
|
||||
weapon_type = /obj/item/melee/arm_blade
|
||||
weapon_name_simple = "blade"
|
||||
power_type = CHANGELING_PURCHASABLE_POWER
|
||||
menu_location = CLING_MENU_ATTACK
|
||||
|
||||
/obj/item/melee/arm_blade
|
||||
name = "arm blade"
|
||||
@@ -187,6 +188,7 @@
|
||||
weapon_name_simple = "tentacle"
|
||||
silent = TRUE
|
||||
power_type = CHANGELING_PURCHASABLE_POWER
|
||||
menu_location = CLING_MENU_ATTACK
|
||||
|
||||
/obj/item/gun/magic/tentacle
|
||||
name = "tentacle"
|
||||
@@ -391,6 +393,7 @@
|
||||
weapon_type = /obj/item/shield/changeling
|
||||
weapon_name_simple = "shield"
|
||||
power_type = CHANGELING_PURCHASABLE_POWER
|
||||
menu_location = CLING_MENU_DEFENSE
|
||||
|
||||
/datum/action/changeling/weapon/shield/sting_action(mob/user)
|
||||
var/obj/item/shield/changeling/S = ..(user)
|
||||
@@ -443,6 +446,7 @@
|
||||
helmet_name_simple = "space helmet"
|
||||
recharge_slowdown = 0.5
|
||||
blood_on_castoff = 1
|
||||
menu_location = CLING_MENU_UTILITY
|
||||
|
||||
/obj/item/clothing/suit/space/changeling
|
||||
name = "flesh mass"
|
||||
@@ -488,6 +492,7 @@
|
||||
suit_name_simple = "armor"
|
||||
helmet_name_simple = "helmet"
|
||||
recharge_slowdown = 0.25
|
||||
menu_location = CLING_MENU_DEFENSE
|
||||
|
||||
/obj/item/clothing/suit/armor/changeling
|
||||
name = "chitinous mass"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
dna_cost = 2
|
||||
req_stat = UNCONSCIOUS
|
||||
power_type = CHANGELING_PURCHASABLE_POWER
|
||||
menu_location = CLING_MENU_DEFENSE
|
||||
|
||||
//Heals the things that the other regenerative abilities don't.
|
||||
/datum/action/changeling/panacea/sting_action(mob/living/user)
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
dna_cost = 2
|
||||
req_human = TRUE
|
||||
power_type = CHANGELING_PURCHASABLE_POWER
|
||||
menu_location = CLING_MENU_ATTACK
|
||||
|
||||
//A flashy ability, good for crowd control and sowing chaos.
|
||||
/datum/action/changeling/resonant_shriek/sting_action(mob/user)
|
||||
@@ -43,6 +44,7 @@
|
||||
chemical_cost = 30
|
||||
dna_cost = 2
|
||||
power_type = CHANGELING_PURCHASABLE_POWER
|
||||
menu_location = CLING_MENU_UTILITY
|
||||
|
||||
//A flashy ability, good for crowd control and sewing chaos.
|
||||
/datum/action/changeling/dissonant_shriek/sting_action(mob/user)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
dna_cost = 2
|
||||
req_human = TRUE
|
||||
power_type = CHANGELING_PURCHASABLE_POWER
|
||||
menu_location = CLING_MENU_DEFENSE
|
||||
|
||||
/datum/action/changeling/strained_muscles/Remove(mob/living/L)
|
||||
L.remove_status_effect(STATUS_EFFECT_SPEEDLEGS)
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
/// Checks if changeling is already spawning a spider
|
||||
var/is_operating = FALSE
|
||||
power_type = CHANGELING_PURCHASABLE_POWER
|
||||
menu_location = CLING_MENU_UTILITY
|
||||
|
||||
/// Makes a spider. Good for setting traps and combat.
|
||||
/datum/action/changeling/spiders/sting_action(mob/user)
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
dna_cost = 2
|
||||
req_human = TRUE //Monkeys can't grab
|
||||
power_type = CHANGELING_PURCHASABLE_POWER
|
||||
menu_location = CLING_MENU_ATTACK
|
||||
|
||||
/datum/action/changeling/swap_form/can_sting(mob/living/carbon/user)
|
||||
if(!..())
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
name = "Tiny Prick"
|
||||
desc = "Stabby stabby"
|
||||
power_type = CHANGELING_UNOBTAINABLE_POWER
|
||||
menu_location = CLING_MENU_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
|
||||
|
||||
@@ -70,12 +70,12 @@ export class DraggableControl extends Component {
|
||||
};
|
||||
|
||||
this.handleDragMove = (e) => {
|
||||
const { minValue, maxValue, step, dragMatrix, disabled } =
|
||||
this.props;
|
||||
const { minValue, maxValue, step, dragMatrix, disabled } = this.props;
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
const defaultStepPixelSize = this.ref.offsetWidth / ((maxValue - minValue) / step);
|
||||
const defaultStepPixelSize =
|
||||
this.ref.offsetWidth / ((maxValue - minValue) / step);
|
||||
let stepPixelSize = this.props.stepPixelSize ?? defaultStepPixelSize;
|
||||
if (typeof stepPixelSize === 'function') {
|
||||
stepPixelSize = stepPixelSize(defaultStepPixelSize);
|
||||
@@ -83,14 +83,21 @@ export class DraggableControl extends Component {
|
||||
this.setState((prevState) => {
|
||||
const state = { ...prevState };
|
||||
const oldOffset = prevState.oldOffset;
|
||||
const offset = getScalarScreenOffset(e, dragMatrix) - this.ref.getBoundingClientRect().left - window.screenX;
|
||||
const offset =
|
||||
getScalarScreenOffset(e, dragMatrix) -
|
||||
this.ref.getBoundingClientRect().left -
|
||||
window.screenX;
|
||||
if (prevState.dragging) {
|
||||
if (oldOffset !== undefined && oldOffset !== null && offset !== oldOffset) {
|
||||
if (
|
||||
oldOffset !== undefined &&
|
||||
oldOffset !== null &&
|
||||
offset !== oldOffset
|
||||
) {
|
||||
const maxStep = maxValue / step;
|
||||
const toNearestStep = offset > oldOffset
|
||||
? Math.floor // Increasing
|
||||
: Math.ceil // Decreasing
|
||||
;
|
||||
const toNearestStep =
|
||||
offset > oldOffset
|
||||
? Math.floor // Increasing
|
||||
: Math.ceil; // Decreasing
|
||||
/* ● = step, o = oldOffset, n = offset
|
||||
* There are four cases to consider for the following code:
|
||||
* Case 1: Increasing(offset > oldOffset), moving between steps
|
||||
@@ -107,11 +114,23 @@ export class DraggableControl extends Component {
|
||||
* Case 4: Decreasing, offset is behind step
|
||||
* ●-n-●-o-● ; ●-n-●---●-o
|
||||
* Same as Case 3, but decrease instead of increase
|
||||
*/
|
||||
const oldStep = clamp(toNearestStep(oldOffset / stepPixelSize), 0, maxStep);
|
||||
const newStep = clamp(toNearestStep(offset / stepPixelSize), 0, maxStep);
|
||||
*/
|
||||
const oldStep = clamp(
|
||||
toNearestStep(oldOffset / stepPixelSize),
|
||||
0,
|
||||
maxStep
|
||||
);
|
||||
const newStep = clamp(
|
||||
toNearestStep(offset / stepPixelSize),
|
||||
0,
|
||||
maxStep
|
||||
);
|
||||
const stepDifference = newStep - oldStep;
|
||||
state.value = clamp(state.value + stepDifference * step, minValue, maxValue);
|
||||
state.value = clamp(
|
||||
state.value + stepDifference * step,
|
||||
minValue,
|
||||
maxValue
|
||||
);
|
||||
}
|
||||
state.oldOffset = offset;
|
||||
} else if (Math.abs(offset) > 4) {
|
||||
@@ -130,7 +149,7 @@ export class DraggableControl extends Component {
|
||||
this.setState({
|
||||
dragging: false,
|
||||
editing: !dragging,
|
||||
oldOffset: null
|
||||
oldOffset: null,
|
||||
});
|
||||
document.removeEventListener('mousemove', this.handleDragMove);
|
||||
document.removeEventListener('mouseup', this.handleDragEnd);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Fragment } from 'inferno';
|
||||
import { useBackend } from '../backend';
|
||||
import { Box, Button, Flex, Section } from '../components';
|
||||
import { useBackend, useLocalState } from '../backend';
|
||||
import { Box, Button, Flex, Icon, Section, Tabs } from '../components';
|
||||
import { Window } from '../layouts';
|
||||
|
||||
export const EvolutionMenu = (props, context) => {
|
||||
@@ -49,6 +49,7 @@ const EvolutionPoints = (props, context) => {
|
||||
const Abilities = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const { evo_points, ability_list, purchased_abilities, view_mode } = data;
|
||||
const [tab, setTab] = useLocalState(context, 'tab', 0);
|
||||
return (
|
||||
<Section
|
||||
title="Abilities"
|
||||
@@ -78,7 +79,31 @@ const Abilities = (props, context) => {
|
||||
</Fragment>
|
||||
}
|
||||
>
|
||||
{ability_list.map((ability, i) => (
|
||||
<Tabs>
|
||||
<Tabs.Tab
|
||||
selected={tab === 0}
|
||||
onClick={() => {
|
||||
setTab(0);
|
||||
}}
|
||||
>
|
||||
Offense
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab
|
||||
selected={tab === 1}
|
||||
onClick={() => {
|
||||
setTab(1);
|
||||
}}
|
||||
>
|
||||
Defense
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab selected={tab === 2} onClick={() => setTab(2)}>
|
||||
Utility
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab selected={tab === 3} onClick={() => setTab(3)}>
|
||||
Stings
|
||||
</Tabs.Tab>
|
||||
</Tabs>
|
||||
{ability_list[tab].map((ability, i) => (
|
||||
<Box key={i} p={0.5} mx={-1} className="candystripe">
|
||||
<Flex align="center">
|
||||
<Flex.Item ml={0.5} color="#dedede">
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user