fun: chat

This commit is contained in:
cha0s 2024-07-14 02:26:43 -05:00
parent b1df45baa9
commit 12ce0ccbd5
7 changed files with 161 additions and 8 deletions

View File

@ -77,9 +77,7 @@ export default async function createHomestead(id) {
interacting: 1,
interactScript: `
subject.Interlocutor.dialogue({
// body: '<strong>Hey</strong><rate frequency={1}> </rate><rate frequency={0}><shake>what</shake></rate> <em>is</em> <wave frequency={0.5}>uu<rainbow frequency={2}>uu<blink>uu</blink><fade frequency={5}>uu<shake magnitude={4}>uu</shake>uuu</fade></rainbow>uup</wave>? ^_^',
body: 'This is a fairly decently long amount of text that will be used to show just how the box grows when there is a kinda l<wave>oooooooooooooooo</wave>ng ass bunch of text here',
linger: 5,
body: "Sure, I'm a treasure chest. Probably. Do you really think that means you're about to get some treasure? Hah!",
monopolizer: true,
origin: subject.Position.toJSON(),
position: {x: subject.Position.x, y: subject.Position.y - 32},

View File

@ -19,6 +19,7 @@ export default async function createPlayer(id) {
Emitter: {},
Forces: {},
Interacts: {},
Interlocutor: {},
Inventory: {
slots: {
1: {

View File

@ -156,9 +156,26 @@ export default class Engine {
if (!entity) {
continue;
}
const {Controlled, Ecs, Interacts, Inventory, Wielder} = entity;
const {
Controlled,
Ecs,
Interacts,
Interlocutor,
Inventory,
Position,
Wielder,
} = entity;
for (const payload of payloads) {
switch (payload.type) {
case 'chat': {
Interlocutor.dialogue({
body: payload.value,
linger: 5,
origin: Position.toJSON(),
position: {x: Position.x, y: Position.y - 32},
});
break;
}
case 'paint': {
const ecs = this.ecses[Ecs.path];
const {TileLayers} = ecs.get(1);

View File

@ -0,0 +1,91 @@
import {useEffect, useState} from 'react';
import {useClient} from '@/context/client.js';
import styles from './chat.module.css';
export default function Chat({
chatHistory,
onClose,
message,
setChatHistory,
setMessage,
}) {
const client = useClient();
const [disabled, setDisabled] = useState(true);
const [historyCaret, setHistoryCaret] = useState(0);
useEffect(() => {
setDisabled(false);
}, []);
return (
<div className={styles.chat}>
<form
onSubmit={(event) => {
if (message) {
client.send({
type: 'Action',
payload: {type: 'chat', value: message},
});
setChatHistory([message, ...chatHistory]);
setMessage('');
onClose();
}
event.preventDefault();
}}
>
<input
disabled={disabled}
onChange={(event) => {
setMessage(event.target.value);
}}
onKeyDown={(event) => {
switch (event.key) {
case 'ArrowDown': {
if (0 === historyCaret) {
break;
}
let localHistoryCaret = historyCaret - 1;
setMessage(chatHistory[localHistoryCaret])
setHistoryCaret(localHistoryCaret);
if (0 === localHistoryCaret) {
setChatHistory(chatHistory.slice(1));
}
break;
}
case 'ArrowUp': {
if (historyCaret === chatHistory.length - 1) {
break;
}
let localHistoryCaret = historyCaret;
let localChatHistory = chatHistory;
if (0 === historyCaret) {
localChatHistory = [message, ...localChatHistory];
setChatHistory(localChatHistory);
}
localHistoryCaret += 1;
setMessage(localChatHistory[localHistoryCaret])
setHistoryCaret(localHistoryCaret);
break;
}
case 'Escape': {
onClose();
break;
}
}
}}
onMouseDown={(event) => {
event.stopPropagation();
}}
maxLength="255"
ref={(element) => {
if (element) {
element.focus();
}
}}
type="text"
value={message}
/>
</form>
</div>
);
}

View File

@ -0,0 +1,22 @@
.chat {
background-color: #00000044;
position: absolute;
bottom: 0;
width: 100%;
}
.chat form {
line-height: 0;
input[type="text"] {
background-color: #00000044;
border: 1px solid #333333;
color: #ffffff;
margin: 4px;
width: calc(100% - 8px);
&:focus-visible {
border: 1px solid #999999;
outline: none;
}
}
}

View File

@ -12,11 +12,12 @@
border-radius: 8px;
color: white;
padding: 1em;
position: absolute;
position: fixed;
margin: 0;
margin-right: -33%;
transform: translate(-50%, -50%);
user-select: none;
width: 33%;
max-width: 33%;
}
.letters {

View File

@ -9,6 +9,7 @@ import {useEcs, useEcsTick} from '@/context/ecs.js';
import {useMainEntity} from '@/context/main-entity.js';
import Disconnected from './dom/disconnected.jsx';
import Chat from './dom/chat.jsx';
import Dom from './dom/dom.jsx';
import Entities from './dom/entities.jsx';
import HotBar from './dom/hotbar.jsx';
@ -65,6 +66,9 @@ export default function Ui({disconnected}) {
const [Systems, setSystems] = useState();
const [applyFilters, setApplyFilters] = useState(true);
const [monopolizers, setMonopolizers] = useState([]);
const [message, setMessage] = useState('');
const [chatIsOpen, setChatIsOpen] = useState(false);
const [chatHistory, setChatHistory] = useState([]);
useEffect(() => {
async function setEcsStuff() {
const {default: Components} = await import('@/ecs-components/index.js');
@ -93,6 +97,9 @@ export default function Ui({disconnected}) {
}, [disconnected]);
useEffect(() => {
return addKeyListener(document.body, ({event, type, payload}) => {
if (chatIsOpen) {
return;
}
const KEY_MAP = {
keyDown: 1,
keyUp: 0,
@ -148,6 +155,12 @@ export default function Ui({disconnected}) {
actionPayload = {type: 'use', value: KEY_MAP[type]};
break;
}
case 'Enter': {
if ('keyDown' === type) {
setChatIsOpen(true);
}
break
}
case 'e': {
if (KEY_MAP[type]) {
if (monopolizers.length > 0) {
@ -226,7 +239,7 @@ export default function Ui({disconnected}) {
});
}
});
}, [client, debug, devtoolsIsOpen, monopolizers, setDebug, setScale]);
}, [chatIsOpen, client, debug, devtoolsIsOpen, monopolizers, setDebug, setScale]);
usePacket('EcsChange', async () => {
setMainEntity(undefined);
setEcs(new ClientEcs({Components, Systems}));
@ -356,7 +369,6 @@ export default function Ui({disconnected}) {
});
break;
}
event.preventDefault();
}}
onMouseUp={(event) => {
switch (event.button) {
@ -413,6 +425,17 @@ export default function Ui({disconnected}) {
scale={scale}
setMonopolizers={setMonopolizers}
/>
{chatIsOpen && (
<Chat
chatHistory={chatHistory}
message={message}
setChatHistory={setChatHistory}
setMessage={setMessage}
onClose={() => {
setChatIsOpen(false);
}}
/>
)}
{showDisconnected && (
<Disconnected />
)}