[MIRROR] [NO GBP] Emote Panel TGUI, now should be fixed [MDB IGNORE] (#25021)

* [NO GBP] Emote Panel TGUI, now should be fixed (#79481)

* [NO GBP] Emote Panel TGUI, now should be fixed

---------

Co-authored-by: larentoun <31931237+larentoun@users.noreply.github.com>
This commit is contained in:
SkyratBot
2023-11-14 19:38:01 -05:00
committed by GitHub
co-authored by larentoun
parent 35dd7b524d
commit 2a3466cbbb
6 changed files with 358 additions and 0 deletions
+5
View File
@@ -14,6 +14,8 @@
var/key = ""
/// This will also call the emote.
var/key_third_person = ""
/// Needed for more user-friendly emote names, so emotes with keys like "aflap" will show as "flap angry". Defaulted to key.
var/name = ""
/// Message displayed when emote is used.
var/message = ""
/// Message displayed if the user is a mime.
@@ -77,6 +79,9 @@
mob_type_blacklist_typecache = typecacheof(mob_type_blacklist_typecache)
mob_type_ignore_stat_typecache = typecacheof(mob_type_ignore_stat_typecache)
if(!name)
name = key
/**
* Handles the modifications and execution of emotes.
*
+64
View File
@@ -0,0 +1,64 @@
/datum/emote_panel
var/list/blacklisted_emotes = list("me", "help")
/datum/emote_panel/ui_static_data(mob/user)
var/list/data = list()
var/list/emotes = list()
var/list/keys = list()
for(var/key in GLOB.emote_list)
for(var/datum/emote/emote in GLOB.emote_list[key])
if(emote.key in keys)
continue
if(emote.key in blacklisted_emotes)
continue
if(emote.can_run_emote(user, status_check = FALSE, intentional = FALSE))
keys += emote.key
emotes += list(list(
"key" = emote.key,
"name" = emote.name,
"hands" = emote.hands_use_check,
"visible" = emote.emote_type & EMOTE_VISIBLE,
"audible" = emote.emote_type & EMOTE_AUDIBLE,
"sound" = !isnull(emote.get_sound(user)),
"use_params" = emote.message_param,
))
data["emotes"] = emotes
return data
/datum/emote_panel/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
. = ..()
if(.)
return
switch(action)
if("play_emote")
var/emote_key = params["emote_key"]
if(isnull(emote_key) || !GLOB.emote_list[emote_key])
return
var/use_params = params["use_params"]
var/datum/emote/emote = GLOB.emote_list[emote_key][1]
var/emote_param
if(emote.message_param && use_params)
emote_param = tgui_input_text(ui.user, "Add params to the emote...", emote.message_param)
ui.user.emote(emote_key, message = emote_param, intentional = TRUE)
/datum/emote_panel/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "EmotePanel")
ui.open()
/datum/emote_panel/ui_state(mob/user)
return GLOB.always_state
/mob/living/verb/emote_panel()
set name = "Emote Panel"
set category = "IC"
var/static/datum/emote_panel/emote_panel
if(isnull(emote_panel))
emote_panel = new
emote_panel.ui_interact(src)
+1
View File
@@ -13,6 +13,7 @@
/datum/emote/living/carbon/blink_r
key = "blink_r"
name = "blink (Rapid)"
message = "blinks rapidly."
//SKYRAT EDIT REMOVAL BEGIN - EMOTES - (Moved to modular_skyrat/modules/emotes/code/emotes.dm as /datum/emote/living/clap)
+4
View File
@@ -167,6 +167,7 @@
/datum/emote/living/flap/aflap
key = "aflap"
key_third_person = "aflaps"
name = "flap (Angry)"
message = "flaps their wings ANGRILY!"
hands_use_check = TRUE
wing_time = 10
@@ -194,6 +195,7 @@
/datum/emote/living/gasp_shock
key = "gaspshock"
key_third_person = "gaspsshock"
name = "gasp (Shock)"
message = "gasps in shock!"
message_mime = "gasps in silent shock!"
emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE
@@ -529,6 +531,7 @@
/datum/emote/living/twitch_s
key = "twitch_s"
name = "twitch (Slight)"
message = "twitches."
/datum/emote/living/twitch_s/run_emote(mob/living/user, params, type_override, intentional)
@@ -553,6 +556,7 @@
/datum/emote/living/wsmile
key = "wsmile"
key_third_person = "wsmiles"
name = "smile (Weak)"
message = "smiles weakly."
/// The base chance for your yawn to propagate to someone else if they're on the same tile as you
+1
View File
@@ -3822,6 +3822,7 @@
#include "code\modules\economy\account.dm"
#include "code\modules\economy\holopay.dm"
#include "code\modules\emoji\emoji_parse.dm"
#include "code\modules\emote_panel\emote_panel.dm"
#include "code\modules\error_handler\error_handler.dm"
#include "code\modules\error_handler\error_viewer.dm"
#include "code\modules\escape_menu\details.dm"
@@ -0,0 +1,283 @@
import { useBackend, useLocalState } from '../backend';
import { Window } from '../layouts';
import { Button, Section, Flex, Icon, Box } from '../components';
import { BooleanLike } from '../../common/react';
import { SearchBar } from './Fabrication/SearchBar';
import { capitalizeFirst } from '../../common/string';
type Emote = {
key: string;
name: string;
hands: BooleanLike;
visible: BooleanLike;
audible: BooleanLike;
sound: BooleanLike;
use_params: BooleanLike;
};
type EmotePanelData = {
emotes: Emote[];
};
export const EmotePanelContent = (props, context) => {
const { act, data } = useBackend<EmotePanelData>(context);
const { emotes } = data;
const [filterVisible, toggleVisualFilter] = useLocalState<boolean>(
context,
'filterVisible',
false
);
const [filterAudible, toggleAudibleFilter] = useLocalState<boolean>(
context,
'filterAudible',
false
);
const [filterSound, toggleSoundFilter] = useLocalState<boolean>(
context,
'filterSound',
false
);
const [filterHands, toggleHandsFilter] = useLocalState<boolean>(
context,
'filterHands',
false
);
const [filterUseParams, toggleUseParamsFilter] = useLocalState<boolean>(
context,
'filterUseParams',
false
);
const [useParams, toggleUseParams] = useLocalState<boolean>(
context,
'useParams',
false
);
const [searchText, setSearchText] = useLocalState<string>(
context,
'search_text',
''
);
const [showNames, toggleShowNames] = useLocalState<boolean>(
context,
'showNames',
true
);
const [showIcons, toggleShowIcons] = useLocalState<boolean>(
context,
'showIcons',
false
);
return (
<Section>
<Section
title="Filters"
buttons={
<Flex>
<Button
icon="eye"
width="100%"
height="100%"
align="center"
tooltip="Visible"
selected={filterVisible}
onClick={() => toggleVisualFilter(!filterVisible)}
/>
<Button
icon="comment"
width="100%"
height="100%"
align="center"
tooltip="Audible"
selected={filterAudible}
onClick={() => toggleAudibleFilter(!filterAudible)}
/>
<Button
icon="volume-up"
width="100%"
height="100%"
align="center"
tooltip="Sound"
selected={filterSound}
onClick={() => toggleSoundFilter(!filterSound)}
/>
<Button
icon="hand-paper"
width="100%"
height="100%"
align="center"
tooltip="Hands"
selected={filterHands}
onClick={() => toggleHandsFilter(!filterHands)}
/>
<Button
icon="crosshairs"
width="100%"
height="100%"
align="center"
tooltip="Params"
selected={filterUseParams}
onClick={() => toggleUseParamsFilter(!filterUseParams)}
/>
</Flex>
}>
<SearchBar
searchText={searchText}
onSearchTextChanged={setSearchText}
hint={'Search all emotes...'}
/>
</Section>
<Section
title={
searchText.length > 0
? `Search results of "${searchText}"`
: `All Emotes`
}
buttons={
<Flex>
<Flex.Item>
<Button onClick={() => toggleShowNames(!showNames)}>
{showNames ? 'Show Names' : 'Show Keys'}
</Button>
<Button
selected={showIcons}
onClick={() => toggleShowIcons(!showIcons)}>
Show Icons
</Button>
</Flex.Item>
<Flex.Item>
<Button
icon="crosshairs"
selected={useParams}
onClick={() => toggleUseParams(!useParams)}>
Use Params
</Button>
</Flex.Item>
</Flex>
}>
<Flex>
<Flex.Item>
{emotes
.filter(
(emote) =>
emote.key &&
(searchText.length > 0
? emote.key
.toLowerCase()
.includes(searchText.toLowerCase()) ||
emote.name.toLowerCase().includes(searchText.toLowerCase())
: true) &&
(filterVisible ? emote.visible : true) &&
(filterAudible ? emote.audible : true) &&
(filterSound ? emote.sound : true) &&
(filterHands ? emote.hands : true) &&
(filterUseParams ? emote.use_params : true)
)
.sort((a, b) => (a.name > b.name ? 1 : -1))
.map((emote) => (
<Button
width={showIcons ? 16 : 8}
key={emote.name}
tooltip={
showIcons ? (
''
) : (
<EmoteIcons
visible={emote.visible}
audible={emote.audible}
sound={emote.sound}
hands={emote.hands}
use_params={emote.use_params}
margin={0.5}
/>
)
}
onClick={() =>
act('play_emote', {
emote_key: emote.key,
use_params: useParams,
})
}>
<Box inline width="50%">
{showNames
? capitalizeFirst(emote.name.toLowerCase())
: emote.key}
</Box>
{showIcons ? (
<EmoteIcons
visible={emote.visible}
audible={emote.audible}
sound={emote.sound}
hands={emote.hands}
use_params={emote.use_params}
margin={0}
/>
) : (
''
)}
</Button>
))}
</Flex.Item>
</Flex>
</Section>
</Section>
);
};
const EmoteIcons = (props, context) => {
const { visible, audible, sound, hands, use_params, margin } = props;
return (
<Box inline align="right">
<Icon
name="eye"
m={margin}
color={!visible ? 'red' : ''}
opacity={!visible ? 0.5 : 1}
/>
<Icon
name="comment"
m={margin}
color={!audible ? 'red' : ''}
opacity={!audible ? 0.5 : 1}
/>
<Icon
name="volume-up"
m={margin}
color={!sound ? 'red' : ''}
opacity={!sound ? 0.5 : 1}
/>
<Icon
name="hand-paper"
m={margin}
color={!hands ? 'red' : ''}
opacity={!hands ? 0.5 : 1}
/>
<Icon
name="crosshairs"
m={margin}
color={!use_params ? 'red' : ''}
opacity={!use_params ? 0.5 : 1}
/>
</Box>
);
};
export const EmotePanel = (props, context) => {
return (
<Window width={630} height={500}>
<Window.Content scrollable>
<EmotePanelContent />
</Window.Content>
</Window>
);
};